【问题标题】:Eliminate or Ignore all small or overlapping contours or rectangles inside a big contours/rectangle opencv消除或忽略大轮廓/矩形opencv中的所有小或重叠轮廓或矩形
【发布时间】:2019-12-03 08:54:13
【问题描述】:

我想忽略所有重叠或在大矩形内的矩形或轮廓,我找到了很多解决方案,但没有一个适合我的情况。

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()

请看这里的图片,你会发现在一个大轮廓内检测到很多轮廓,我真的想消除这些在大轮廓内的所有轮廓(小),甚至你可以说矩形,我计算面积后绘制。

【问题讨论】:

  • 您可以仅通过坐标检查一个矩形是否包含在更大的矩形中。困难在哪里?

标签: python algorithm numpy opencv contour


【解决方案1】:

比较每个矩形的左上角和右下角,包含在另一个矩形中,然后消除它们。

使用下面的这个函数来检查一个点是否在矩形内。

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))

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

【讨论】:

  • 感谢@venkata krishnan,我在每个循环后进行了排序部分,我删除了第一个最大的矩形并存储在另一个列表中,还删除了位于大矩形中的矩形,这会使我的迭代次数减少.
  • 如果您觉得此答案有用,请将其标记为已接受的答案,这将对未来的用户有所帮助。如果您喜欢,请随时点赞。
  • @RupeshArora 是上面正确解决您的查询的答案吗?你应该让每个人都知道。
猜你喜欢
  • 1970-01-01
  • 2021-11-19
  • 2021-09-01
  • 1970-01-01
  • 2019-12-07
  • 2012-05-10
  • 1970-01-01
  • 2018-03-11
  • 2018-02-13
相关资源
最近更新 更多