Python ROI 未从轮廓中正确裁剪

Python ROI not being croped properly from contour

大家好,在关闭这个问题之前,我已经搜索过了, here too and also

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

代码如下

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)

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

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

当我尝试使用

填充轮廓以创建蒙版时,您可以看到这一点
 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)

输出