如何使用OpenCV和Python在ROI内查找轮廓?

7

我试图在图像的特定区域中找到轮廓。是否可能只显示ROI内的轮廓而不是整个图像中的轮廓?我在另一篇类似的帖子中读到,应该使用掩码,但我认为我没有正确使用它。我是openCV和Python的新手,所以非常感谢任何帮助。

import numpy as np
import cv2

cap = cv2.VideoCapture('size4.avi')
x, y, w, h= 150, 50, 400 ,350
roi = (x, y, w, h)

while(True): 
    ret, frame = cap.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    _, thresh = cv2.threshold(gray, 127, 255, 0)
    im2, contours, hierarchy = cv2.findContours(thresh,    cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

    roi = cv2.rectangle(frame, (x,y), (x+w, y+h), (0,0,255), 2)
    mask = np.zeros(roi.shape,np.uint8)
    cv2.drawContours(mask, contours, -1, (0,255,0), 3)

    cv2.imshow('img', frame)
2个回答

12

既然你声称自己是一名新手,我已经准备好了解决方案以及说明。

请认为以下是您的原始图像:

输入图像描述

假设红色区域是您感兴趣的区域(ROI),您想在其中找到轮廓:

输入图像描述

首先,构建一个大小相同的黑色像素图像。它必须与原图像大小相同

black = np.zeros((img.shape[0], img.shape[1], 3), np.uint8) #---black in RGB

输入图像描述

现在要形成掩码并突出显示ROI:

black1 = cv2.rectangle(black,(185,13),(407,224),(255, 255, 255), -1)   #---the dimension of the ROI
gray = cv2.cvtColor(black,cv2.COLOR_BGR2GRAY)               #---converting to gray
ret,b_mask = cv2.threshold(gray,127,255, 0)                 #---converting to binary image

输入图片描述

现在使用您的原始图像遮盖上面的图像:

fin = cv2.bitwise_and(th,th,mask = mask)

输入图像描述

现在使用cv2.findContours()函数在上述图像中查找轮廓。

然后使用cv2.drawContours()函数在原始图像上绘制轮廓。最终您将得到以下结果:

输入图像描述

可能还有更好的方法,但这样做是为了让您了解OpenCV中独家用于掩蔽的按位与操作。


2
我提供了此解决方案,因为您想知道如何在图像中执行掩码操作。关键是要有效地使用函数cv2.bitwise_and() - Jeru Luke
是的,这是一个很好的理解如何进行掩蔽的方法,谢谢 ;) 一个小的后续问题:当我绘制轮廓时,除了内部轮廓之外,我还会得到ROI边框周围的轮廓,这是否应该发生?我看你的示例中没有它。 - agrom
1
如果您没有翻转图像,可能会发生这种情况。 - Jeru Luke

6

在Python中设置ROI时,使用标准的NumPy索引,例如以下示例

因此,要选择正确的ROI,不使用cv2.rectangle函数(该函数用于绘制矩形),而是使用以下方法:

 _, thresh = cv2.threshold(gray, 127, 255, 0)
 roi = thresh[x:(x+w), y:(y+h)]
 im2, contours, hierarchy = cv2.findContours(roi, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

2
你可以将矩形的偏移量传递给 findContours,以便检索到的轮廓点与原始图像相关联。 - Miki
谢谢,当我改变了写roi的方式时,它起作用了。Miki,您建议如何偏移矩形? - agrom
3
这段话的意思是,OpenCV中的一个函数cv2.findContours()的最后一个参数是一个元组,用于指定偏移量。例如:im2, contours, hierarchy = cv2.findContours(roi, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE, (x, y))。如果需要了解更多信息,请参考文档:http://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=findcontours - Tomáš M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接