如何丢弃图像中的重叠矩形? [英] How to discard overlapping rectangles in an image?

查看:53
本文介绍了如何丢弃图像中的重叠矩形?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了 openCV 库来检测图像的对象(图1),请参见下文.

I used the openCV library to detect an object of the image (Fig 1), see below.

为此,我编写了以下代码:

To do this, I have written the following codes:

import matplotlib.pyplot as plt
import cv2 

# source data
img_file= "Fig1.jpg"

# create an OpenCV image
img= cv2.imread(img_file)

# convert color image to grey image
gray_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

im_gauss = cv2.GaussianBlur(gray_img, (5, 5), 0)
ret, thresh = cv2.threshold(im_gauss, 127, 255, 0)
# get contours
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

margin = 40
# calculate area and filter 
for con in contours:
    area = cv2.contourArea(con)
    if 100 < area < 500:
        x,y,w,h = cv2.boundingRect(con)
        cv2.rectangle(img, (x-margin, y-margin), (x + w+margin, y + h+margin), (0,255,0), 2)
        
plt.imshow(img, cmap='gray')

这些代码将为您提供带有检测到的对象的图像,请参见下图.

These codes will able to give you an image with the detected object see below figure .

现在在这里您可以看到,在检测物体时,一些矩形是重叠的.这不是预期的结果.我想要一个图,该图将丢弃所有重叠的矩形,并附带另一个图,该图仅包含那些不重叠的矩形.任何想法如何做到这一点?预先感谢.

Now here you can see, while detecting objects, some rectangles are overlapping. This is not the expected outcome. I want a Figure which discards all overlap rectangles and comes with another figure that includes only those rectangle which is not overlapping. Any idea how to do this? Thanks in advance.

推荐答案

假设每个矩形都有 x y ,宽度和高度,则需要每个两个矩形的成对比较,通过比较if

Assuming you have x, y, width, and height for each rectangle, you'll need pairwise comparisons for each two rectangles, checking for overlaps by comparing if

    矩形#1的
  • x x x +矩形#2的宽度之间,或者
  • 矩形#1的
  • y y y +矩形#2的高度之间,或者
  • ...
  • x of rectangle #1 is between x and x + width of rectangle #2, or
  • y of rectangle #1 is between y and y + height of rectangle #2, or
  • ...

幸运的是,您可以使用NumPy的矢量化功能来避免嵌套循环.

Fortunately, you can use NumPy's vectorization abilities to avoid nested loops.

在下面的代码中,我生成了一些随机矩形,并过滤掉了那些重叠的矩形:

In the following code, I generate some random rectangles, and filter out those overlapping:

import cv2
import numpy as np

# Randomly generate n white rectangles on black background
n = 20
rects = [[np.random.randint(0, 350),
          np.random.randint(0, 250),
          np.random.randint(10, 50),
          np.random.randint(10, 50)] for i in range(n)]

img = np.zeros((300, 400), np.uint8)

for rect in rects:
    img = cv2.rectangle(img, (rect[0], rect[1]),
                        (rect[0] + rect[2], rect[1] + rect[3]), 255, 1)

# Calculate left, right, top, bottom limits
rects = np.array(rects)
left = np.expand_dims(rects[:, 0], axis=1)
right = np.expand_dims(rects[:, 0] + rects[:, 2], axis=1)
top = np.expand_dims(rects[:, 1], axis=1)
bottom = np.expand_dims(rects[:, 1] + rects[:, 3], axis=1)

# Check for left limit intrusions, right limit intrusions, ...
check_l = (left <= left.T) & (left.T <= right)
check_r = (left <= right.T) & (right.T <= right)
check_t = (top <= top.T) & (top.T <= bottom)
check_b = (top <= bottom.T) & (bottom.T <= bottom)

# Check for combinations of left-top intrusions, left-bottom intrusions, ...
check_lt = check_l & check_t
check_lb = check_l & check_b
check_rt = check_r & check_t
check_rb = check_r & check_b

# Get all combinations; get rid of self identical matches
check = check_lt | check_lb | check_rt | check_rb
check = np.bitwise_xor(check, np.eye(n).astype(bool))
check = np.argwhere(check)

# Get unique indices of corrupted rectangles
corrupted = np.unique(check)

# Draw cleaned image
img_clean = np.zeros_like(img)
for i, rect in enumerate(rects):
    if i not in corrupted:
        img_clean = cv2.rectangle(img_clean, (rect[0], rect[1]),
                                  (rect[0] + rect[2], rect[1] + rect[3]), 255, 1)

# Output
cv2.imshow('Original image', img)
cv2.imshow('Cleaned image', img_clean)
cv2.waitKey(0)
cv2.destroyAllWindows()

首先,让我们看一下输入"和输出":

First, let's have a look at the "input" and "output":

基本上,计算每个矩形的左,右,上和下限.然后,矩形#1的每个组合侵入".从左侧,顶部或右侧等等进入矩形2.

Basically, the left, right, top, and bottom limit of each rectangle is computed. Then, each combination of rectangle #1 "intrudes" into rectangle #2 from the left, or from the top, or from the right, and so on, is calculated.

几个大小为(n,n) bool 矩阵,其中 n 是矩形的数量,内存存储在中间,但是我想对于 n< = 2000 左右,内存消耗应该可以忽略不计.由于矢量化,这种方法非常快.

Several bool matrices of size (n, n), with n is the number of rectangles, are stored intermediately, but I guess, for n <= 2000 or so, the memory consumption should be negligible. Due to the vectorization, this approach is quite fast.

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
NumPy:         1.20.2
OpenCV:        4.5.1
----------------------------------------

这篇关于如何丢弃图像中的重叠矩形?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆