繁体   English   中英

消除或忽略大轮廓/矩形opencv中的所有小轮廓或重叠轮廓或矩形

[英]Eliminate or Ignore all small or overlapping contours or rectangles inside a big contours/rectangle 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))

从排序的轮廓开始,从最小的轮廓开始,然后将其与最大的矩形进行比较。 基本上是第一个元素,最后一个元素,依此类推

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM