在Python/OpenCV中,如何计算轮廓是否已远离边缘

在Python/OpenCV中,如何计算轮廓是否已远离边缘,python,opencv,computer-vision,logic,Python,Opencv,Computer Vision,Logic,我正在使用两种不同的技术创建一个跟踪系统,MOSSE就是其中之一,我有一个基于背景减法轮廓的边界框-我正在尝试找出最好的方法来获得屏幕上的轮廓,以了解它们是否已经远离图像边界(甚至距离边界边缘一个像素),因此我可以使用它作为边界框,从中开始苔藓跟踪 我目前正在遍历轮廓,需要对照上面的参数检查每个轮廓 我曾考虑过使用PointPolyContest,为整个帧区域创建一个轮廓,检查轮廓是否在该区域内(没有点接触到边界)。但似乎无法解决如何为整个帧创建轮廓,而且这可能会非常低效 while(1):

我正在使用两种不同的技术创建一个跟踪系统,MOSSE就是其中之一,我有一个基于背景减法轮廓的边界框-我正在尝试找出最好的方法来获得屏幕上的轮廓,以了解它们是否已经远离图像边界(甚至距离边界边缘一个像素),因此我可以使用它作为边界框,从中开始苔藓跟踪

我目前正在遍历轮廓,需要对照上面的参数检查每个轮廓

我曾考虑过使用PointPolyContest,为整个帧区域创建一个轮廓,检查轮廓是否在该区域内(没有点接触到边界)。但似乎无法解决如何为整个帧创建轮廓,而且这可能会非常低效

while(1):
ret,frame=cap.read()
轮廓,继承人=cv2.找到的轮廓(fgmask,cv2.翻新树,cv2.链约无)
对于轮廓中的cnt:
#等等。。。
#在这里,我将检查轮廓是否与帧边界/边接触
结果应该是,如果轮廓边缘不接触边界(之间没有像素间隙),我将获得输出,通知我这一点,以便我可以为MOSSE添加边界框-这应该发生在帧中的每个轮廓上


如果我没有提供足够的细节,或者您需要澄清,请随时发表评论,我们非常感谢您的帮助。

一个可能的解决方案是使用泛光填充来清除白色像素的所有边缘。当您在之后找到轮廓时,您将保证它们在帧内。我使用此代码一次就可以完成这一点。

这可能不是最好的解决方案,但仍然是一个解决方案

将numpy导入为np
将cv2作为cv导入
#然后图像将是二进制的,0或255。
def泛光填充_边缘(图像):
where=np.where(图像[:,0]==255)
而其中[0]。大小>0:
x、 y=0,其中[0][0]
等速漫灌(图像,无,(x,y),0)
where=np.where(图像[:,0]==255)
where=np.where(图像[:,-1]==255)
而其中[0]。大小>0:
x、 y=图像.形状[1]-1,其中[0][0]
等速漫灌(图像,无,(x,y),0)
where=np.where(图像[:,-1]==255)
where=np.where(图像[0,:]=255)
而其中[0]。大小>0:
x、 y=其中[0][0],0
等速漫灌(图像,无,(x,y),0)
where=np.where(图像[0,:]=255)
where=np.where(图像[-1,:]==255)
而其中[0]。大小>0:
x、 y=其中[0][0],image.shape[0]-1
等速漫灌(图像,无,(x,y),0)
where=np.where(图像[-1,:]==255)
返回图像

我不确定效率,所以您必须对此进行测试。

一个可能的解决方案是使用泛光填充来清除白色像素的所有边缘。当您在之后找到轮廓时,您将保证它们位于帧内。我曾经使用此代码来实现这一点

这可能不是最好的解决方案,但仍然是一个解决方案

将numpy导入为np
将cv2作为cv导入
#然后图像将是二进制的,0或255。
def泛光填充_边缘(图像):
where=np.where(图像[:,0]==255)
而其中[0]。大小>0:
x、 y=0,其中[0][0]
等速漫灌(图像,无,(x,y),0)
where=np.where(图像[:,0]==255)
where=np.where(图像[:,-1]==255)
而其中[0]。大小>0:
x、 y=图像.形状[1]-1,其中[0][0]
等速漫灌(图像,无,(x,y),0)
where=np.where(图像[:,-1]==255)
where=np.where(图像[0,:]=255)
而其中[0]。大小>0:
x、 y=其中[0][0],0
等速漫灌(图像,无,(x,y),0)
where=np.where(图像[0,:]=255)
where=np.where(图像[-1,:]==255)
而其中[0]。大小>0:
x、 y=其中[0][0],image.shape[0]-1
等速漫灌(图像,无,(x,y),0)
where=np.where(图像[-1,:]==255)
返回图像

我不确定效率,所以您必须对此进行测试。

这里是另一个解决方案,使用您建议的轮廓

我使用了简化矩形并包含了一些东西。转换成普通的OpenCV和Numpy并不难,只是有点乏味

将cv2作为cv导入
将numpy作为np导入
将opencv_包装器作为cvw导入
image=cv.imread(“路径/目标/图像”)
灰色=cvw.bgr2gray(图像)
阈值=cvw.阈值\u大津(灰色)
#返回轮廓对象
轮廓=cvw。查找外部轮廓(阈值)
#创建一个矩形,表示中1个像素的边界。
边界=cvw.Rect(1,1,image.shape[1]-2,image.shape[0]-2)
对于等高线中的等高线:
#返回一个Rect对象
rect=轮廓。边界\u rect
如果(
rect.tl不在边界中
或rect.tr不在边界中
或rect.bl不在边界中
或rect.br不在边界中
):
持续
#创建跟踪器
cvw.矩形(图像,矩形,cvw.Color.RED,1)
cv.imshow(“图像”,np.hstack([图像,cvw.GRY2BGR(阈值)])
cvw.等待键(0)

披露:我是OpenCV包装器的作者。

这里是另一个解决方案,使用您建议的轮廓

我使用了简化矩形并包含了一些东西。转换成普通的OpenCV和Numpy并不难,只是有点乏味

将cv2作为cv导入
将numpy作为np导入
将opencv_包装器作为cvw导入
image=cv.imread(“路径/目标/图像”)
灰色=cvw.bgr2gray(图像)
阈值=cvw.阈值\u大津(灰色)
#返回轮廓对象
轮廓=cvw。查找外部轮廓(阈值)
#创建一个矩形,表示中1个像素的边界。
边界=cvw.Rect(1,1,image.shape[1]-2,image.shape[0]-2)
对于等高线中的等高线:
#返回一个Rect对象
rect=轮廓。边界\u rect
如果(
rect.tl不在边界中
或rect.tr不在边界中
或者rect.bl不是