You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python OpenCV逐次显示单个轮廓如何避免保留之前绘制内容

问题示意图

问题描述
  • 预期实现逐次单独显示单个检测轮廓的效果,判断问题出在for循环逻辑上
  • 曾尝试使用break语句,但不符合需求:break会在绘制完第一个轮廓后直接跳出整个循环,无法完成全量轮廓遍历
  • 检测得到的contour为三维列表结构,单个轮廓数据格式示例:
[[[125 300]] [[124 301]] [[124 302]] [[124 303]] [[124 304]] [[125 304]] [[126 304]] [[127 304]] [[128 304]] [[129 304]] [[130 304]] [[131 304]] [[132 304]] [[133 304]] [[132 303]] [[131 302]] [[130 301]] [[129 301]] [[128 300]] [[127 300]] [[126 300]]]
  • 疑问:该问题是否和Python队列有关?
原始问题代码
import cv2
import math
from matplotlib import pyplot as plt


def lines():

    # reading image in BGR format
    img = cv2.imread("C://Users/ranz/Desktop/1.bmp")
    res = cv2.resize(img, (570,610), cv2.INTER_LINEAR)

    cnt_point = []

    #grayscale
    gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    #threshold for black pixel
    _, thresh = cv2.threshold(gry,0,255,cv2.THRESH_BINARY_INV)
    
    #find all contours
    cnt,_ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    
    #draw blank mask 
    blank_mask = np.zeros((thresh.shape[0], thresh.shape[2], 3), np.uint8)

    for i in range(len(cnt)):
        cv2.drawContours(blank_mask, cnt[i], -1, (0, 255, 0), 1)
        print(cnt[i])
        cv2.imshow('test',blank_mask)
        cv2.waitKey(0)
        
cv2.destroyAllWindows()
lines()
问题原因与修复方案

这个问题和Python队列没有关系,核心是4处代码错误:

  1. 空白mask在循环外只初始化一次,每次绘制轮廓是在原有mask上叠加,显示的是历史所有轮廓的累加结果,而非单个轮廓
  2. 创建mask时维度参数错误:二值化后的thresh是单通道灰度图,不存在shape[2]属性,直接写会触发维度报错
  3. 缺少numpy导入,代码中np.zeros无法正常执行
  4. cv2.drawContours的第二个参数要求传入轮廓列表,直接传入单个轮廓cnt[i]会导致绘制异常;另外窗口销毁语句放在函数调用前,执行逻辑顺序错误

修正后可正常运行的代码:

import cv2
import numpy as np
import math
from matplotlib import pyplot as plt


def lines():
    # 读取BGR格式图像
    img = cv2.imread("C://Users/ranz/Desktop/1.bmp")
    res = cv2.resize(img, (570,610), cv2.INTER_LINEAR)

    cnt_point = []

    # 转灰度图
    gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # 反色二值化,提取黑色像素区域
    _, thresh = cv2.threshold(gry,0,255,cv2.THRESH_BINARY_INV)
    
    # 查找所有轮廓
    cnt,_ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    
    for i in range(len(cnt)):
        # 每次循环重新生成空白mask,避免轮廓叠加
        blank_mask = np.zeros((thresh.shape[0], thresh.shape[1], 3), np.uint8)
        # 单个轮廓需要包装为列表传入drawContours接口
        cv2.drawContours(blank_mask, [cnt[i]], -1, (0, 255, 0), 1)
        print(cnt[i])
        cv2.imshow('test',blank_mask)
        # 按任意键切换显示下一个轮廓
        cv2.waitKey(0)
    # 所有轮廓遍历完成后销毁窗口
    cv2.destroyAllWindows()

lines()

内容的提问来源于stack exchange,提问作者peter teoh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 12:24:10