python - 消除或忽略大轮廓/矩形opencv中的所有小或重叠轮廓或矩形
问题描述
我想忽略所有重叠或在大矩形内的矩形或轮廓,我找到了很多解决方案,但没有一个适合我的情况。
import numpy as np
import cv2
import imutils
cap = cv2.VideoCapture('rtsp://admin:admin@192.168.1.72')
#read the first frame from camera for our background
_,first_frame = cap.read()
#We’ll also convert the image to grayscale since color has no bearing on our motion detection
first_gray = cv2.cvtColor(first_frame, cv2.COLOR_BGR2GRAY)
#Due to tiny variations in the digital camera sensors, no two frames will be 100% same, to account for this and apply Gaussian smoothing
first_gray = cv2.GaussianBlur(first_gray, (21, 21), 0)
open('/tmp/test.txt', 'w').close()
while(1):
_, frame = cap.read()
#We’ll also convert the image to grayscale since color has no bearing on our motion detection
gray_frame = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
#Due to tiny variations in the digital camera sensors, no two frames will be 100% same, to account for this and apply Gaussian smoothing
blurFrame = cv2.GaussianBlur(gray_frame, (21, 21), 0)
#Computing the difference between two frames is a simple subtraction
diff = cv2.absdiff(first_gray, blurFrame)
_,thresh = cv2.threshold(diff, 25, 255, cv2.THRESH_BINARY)
# dilate the thresholded image to fill in holes
thresh = cv2.dilate(thresh, None, iterations=2)
#find contours on thresholded image
contours,_ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
pixelList = \[\]
for contour in contours:
if( cv2.contourArea(contour) > 100):
(x, y, w, h) = cv2.boundingRect(contour)
pixelList.append(list((x, y, w, h)))
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
if len(pixelList) !=0:
with open("/tmp/test.txt", "a") as myfile:
myfile.write(str(pixelList)+'\n')
orgFrame = cv2.resize(frame, (600, 600))
diffFrame = cv2.resize(diff, (300, 300))
cv2.imshow('diffFrameBlur',diff)
cv2.imshow('frameBlur',frame)
k = cv2.waitKey(1) & 0xff
if k == 27:
break
cap.release()
cv2.destroyAllWindows()
请看这里附上的图片,你会发现在一个大轮廓内检测到很多轮廓,我真的想消除这些在一个大轮廓内的所有轮廓(小),甚至你可以说是矩形,我在计算后绘制区域。
解决方案
比较每个矩形的左上角和右下角,包含在另一个矩形中,然后消除它们。
使用下面的这个函数来检查一个点是否在矩形内。
def rectContains(rect,pt):
in = rect[0] < pt[0] < rect[0]+rect[2] and rect[1] < pt[1] < rect[1]+rect[3]
return in
仅对每个矩形的左上角和右下角调用此函数,如果它包含在另一个矩形内,则消除它们。
如果您打算使其更快,请减少比较次数。
对于检测到的所有轮廓,按大小顺序对它们进行排序,
cntsSorted = sorted(cnts, key=lambda x: cv2.contourArea(x))
从排序后的轮廓开始,从最小的开始,与最大的矩形进行比较。基本上是第一个元素和最后一个元素,依此类推
推荐阅读
- geocoding - 谷歌地理编码 API 方法
- mysql - 在 MySQL 中将行转换为列
- python - 从多维数组到 Keras 中的其他形状
- ios - 开发人员在浏览代码库时会遇到两种不同的语法来创建具有给定整数的 NSString。(在 MRC 中实现)
- ios - 外部 API 链接已损坏,我无法从 iOS 开发中 Json 文件中的错误 API 获取任何数据
- centos - 建立 IKE_SA 失败,对等体没有响应 - Strongswan 与 Centos 7 [可能重复]
- javascript - Javascript:推送函数在有引用和无引用的数组中表现不同
- tensorflow - 如何在keras tensorflow中将图像作为输入并获取另一个图像作为输出
- reactjs - 未处理的拒绝(TypeError):尝试从rest api获取数据以做出反应时无法获取错误
- azure-active-directory - 使用 Azure AD 对应用程序进行身份验证和授权以访问 Azure 服务总线实体