【问题标题】:Unable to find and draw biggest contour无法找到并绘制最大轮廓
【发布时间】:2020-04-15 20:17:39
【问题描述】:

我想在这个框架上找到并画出最大的轮廓。

我可以找到轮廓。但是当我试图找到最大的轮廓时,它会在框架上显示一个小轮廓作为最大的框架。当我只画轮廓时,我可以清楚地看到物体周围有一个大轮廓

这是我的尝试:

import cv2
import numpy as np
#capture.release()
cv2.destroyAllWindows()
capture = cv2.VideoCapture(1)
panel = np.zeros([100, 700], np.uint8)
cv2.namedWindow('panel')
def nothing(x):
    pass

#some code about trackbar and panel here

while(True):

    ret, frame = capture.read()

    #some code about trackbar and panel here      
    roi = frame[s_r: e_r, s_c: e_c]
    roi =  cv2.GaussianBlur(roi, (5, 5), 0) #sigma = 0
    hsv = cv2.cvtColor( roi, cv2.COLOR_RGB2HSV)    

    #some code about trackbar and panel here


    mask = cv2.inRange(hsv, lower_green, upper_green)
    mask_inv = cv2.bitwise_not(mask)

    bg = cv2.bitwise_and( roi,  roi, mask=mask)
    fg = cv2.bitwise_and( roi,  roi, mask=mask_inv)
    gray = cv2.cvtColor(fg, cv2.COLOR_BGR2GRAY)
    contours, hierarchy = cv2.findContours(gray,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

    max_area = 0
    for contour in contours:
        area = cv2.contourArea(contour)
        if area > max_area:
            area = max_area
            x,y,w,h = cv2.boundingRect(contour)

    cv2.rectangle(fg,(x,y),(x+w,y+h),(0,255,0),2)

    cv2.imshow('bg', bg)
    cv2.imshow('fg', fg)
    cv2.imshow('panel', panel)

    if cv2.waitKey(30) == 27: #siradaki frame'e gecmeden once 30 ms bekle
        break

capture.release()
cv2.destroyAllWindows()

【问题讨论】:

    标签: python opencv image-processing contour opencv-contour


    【解决方案1】:

    这种方法在 Python/OpenCV 中似乎对我有用。我做了一个简单的门槛。然后用形态学来平滑和填充一些。然后我得到轮廓并过滤区域。然后我在图像上绘制轮廓。注意,它对形态核的大小很敏感,需要至少为10或11。但是如果你让它太大,它会改变区域的形状。

    输入:

    import cv2
    import numpy as np
    
    # load image
    img = cv2.imread("green_and_red_regions.png")
    
    # convert to gray
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # threshold image
    thresh = cv2.threshold(gray,4,255,0)[1]
    
    # apply morphology open to smooth the outline
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
    
    # find contours
    cntrs = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    cntrs = cntrs[0] if len(cntrs) == 2 else cntrs[1]
    
    # Contour filtering to get largest area
    area_thresh = 0
    for c in cntrs:
        area = cv2.contourArea(c)
        if area > area_thresh:
            area = area_thresh
            big_contour = c
    
    # draw the contour on a copy of the input image
    results = img.copy()
    cv2.drawContours(results,[big_contour],0,(0,0,255),2)
    
    
    # write result to disk
    cv2.imwrite("greengreen_and_red_regions_threshold.png", thresh)
    cv2.imwrite("green_and_red_regions_big_contour.png", results)
    
    cv2.imshow("THRESH", thresh)
    cv2.imshow("RESULTS", results)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    


    阈值和平滑图像:

    在输入上绘制轮廓轮廓:

    【讨论】:

    • 这一行是什么 cntrs = cntrs[0] if len(cntrs) == 2 else cntrs[1]
    • 它解释了不同版本的 OpenCV 为 findContours() 返回不同数量的值的事实。它使代码更具可移植性。我从@nathancy 那里学到的。
    • 看一下this post的解释
    【解决方案2】:

    Python/OpenCV 解决方案:

    在您的轮廓循环中,只需自己查找该轮廓的最大区域和相应的 boundingRect 即可。

    max_area = 0
    for contour in contours:
       area = cv2.contourArea(contour)
       if area > max_area:
          area = max_area
          x,y,w,h = cv2.boundingRect(contour)
    


    或者,只需获取外部轮廓(可能只有一个),如果这与您的图像相关。 (以后请出示您的输入图片)。

    contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    


    【讨论】:

    • 我尝试了这段代码并编辑了帖子。我将另一个小轮廓视为最大轮廓
    • 第一种方法应该只产生一个轮廓,它应该有最大的面积。第二个可能会产生多个外轮廓。
    • 我没有看到您在 inRange() 阈值中定义 lower_green、upper_green 的位置。查看 inRange() 的结果以查看它选择的内容。请始终发布原始图像,而不是带有边框的屏幕快照。
    • 这是我完整的code。未显示的区域在图像中都是黑色的。
    • 查看我的新答案。您可能需要做一些形态学打开然后关闭以平滑阈值图像并填充一些孔。
    猜你喜欢
    • 1970-01-01
    • 2019-08-19
    • 1970-01-01
    • 2011-11-27
    • 1970-01-01
    • 2015-02-25
    • 2017-04-06
    • 2020-09-14
    • 2017-11-19
    相关资源
    最近更新 更多