【问题标题】:Python ROI not being croped properly from contourPython ROI 未从轮廓正确裁剪
【发布时间】:2025-12-06 03:55:01
【问题描述】:

大家好,在结束这个问题之前,我已经搜索了herehere toohere

我正在使用 python 代码检测图像中的叶子,使用轮廓查找然后找出最大的轮廓,这部分效果最好,但是我只想要图像的叶子部分并跳过图像的其余部分为了避免结果输出中出现不必要的内容,链接中的一些方法建议使用边界框,但这仍然包括图像中的额外内容,因为形状不是矩形,它是不规则的,附上示例

代码如下

import cv2
import numpy as np

img = cv2.imread("blob.jpg", -1)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 101, 3)

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
blob = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9,9))
blob = 255 - cv2.morphologyEx(blob, cv2.MORPH_CLOSE, kernel)

cnts = cv2.findContours(blob, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

if len(cnts) == 2:
    cnts = cnts[0]
else:
    cnts = cnts[1]
    
big_contour = max(cnts, key = cv2.contourArea)

blob_area_thresh = 1000
blob_area = cv2.contourArea(big_contour)
if blob_area < blob_area_thresh:
    print("Leaf is Too Small")
else:
    #problem starts from here . i tested big_contour is just perfect by drawing on actual image
    mask = np.zeros_like(img)
    cv2.drawContours(mask, big_contour, -1, 255, -1) 
    out = np.zeros_like(img) 
    out[mask == 255] = img[mask == 255]
    cv2.imwrite('output.jpg', out)

现在的问题是我得到的结果图像是黑色的,没有裁剪所有黑色像素

【问题讨论】:

    标签: python-3.x opencv-python roi


    【解决方案1】:

    你的轮廓有问题,因为它没有循环叶子,因为右边叶子的末端不在图像中。

    当我尝试填充轮廓以创建蒙版时,您可以看到这一点

     cv2.fillPoly(mask, pts =[big_contour], color=(255,255,255))
    

    它没有填满叶子。

    但是我尝试了一些虽然不完美并且有一些背景的东西,但它在一定程度上裁剪了叶子。

    import cv2
    import numpy as np
    
    img = cv2.imread("96Klg.jpg", -1)
    
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 101, 3)
    
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
    blob = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
    
    #kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9,9))
    #blob = 255 - cv2.morphologyEx(blob, cv2.MORPH_CLOSE, kernel)
    
    cnts = cv2.findContours(blob, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    if len(cnts) == 2:
        cnts = cnts[0]
    else:
        cnts = cnts[1]
        
    big_contour = max(cnts, key = cv2.contourArea)
    blob_area_thresh = 1000
    blob_area = cv2.contourArea(big_contour)
    if blob_area < blob_area_thresh:
        print("Leaf is Too Small")
    else:
        #problem starts from here . i tested big_contour is just perfect by drawing on actual image
        mask = np.ones_like(img)
        mask.fill(255)
        cv2.fillPoly(mask, pts =[big_contour], color=(0,0,0))
    
        #cv2.drawContours(mask, big_contour, -1,  (255,255,255), 1) 
        out = np.zeros_like(img) 
        out[mask == 255] = img[mask == 255]
        
    
        
    
    width = int(gray.shape[1] * 0.25)
    height = int(gray.shape[0] * 0.25)
    dim = (width, height)
    # resize image
    resized = cv2.resize(out, dim, interpolation = cv2.INTER_AREA)
    resizedmask = cv2.resize(mask, dim, interpolation = cv2.INTER_AREA)
    
    cv2.imshow('gray',resized)
    cv2.imshow('out',resizedmask)
    

    输出

    【讨论】:

    • 是的,没关系,它留下了一些背景痕迹,可以通过调整一些阈值来处理它,但是你的解决方案解决了我的问题,现在我有了一个起点,顺便谢谢