OpenCV,用矩形覆盖轮廓

问题描述 投票:0回答:1

OpenCV如何用多个矩形覆盖不规则形状?参见示例人物。

矩形应覆盖对象的最大区域,并且可以任意角度。重要的是它们不能互相重叠。如果矩形覆盖了某些背景,则完全可以。

我发现这个thread会将轮廓分割成小矩形,但可能不会合并成最大的矩形。 [https://answers.opencv.org/question/25912/split-contours-into-many-small-rectangles/]

我确实将OpenCV与python一起使用,但是如果您在C ++中有示例代码,那是完全可以的。

Before image

Wanted result

python opencv contour
1个回答
0
投票

这是使用Python / OpenCV将其分成4个矩形的一种简单方法。

  • 读取输入
  • 转换为灰色
  • 阈值
  • 获得两个轮廓
  • 计算两条垂直线,即外部(较大)轮廓高度的长度,但沿着内部(较小)轮廓的侧面的长度
  • 在阈值图像上绘制这些垂直线
  • 在上一张图像上绘制轮廓并绘制轮廓
  • 保存结果

输入:

enter image description here

import cv2
import numpy as np

# read image
img = cv2.imread('rectangles.png')
hh, ww = img.shape[:2]

# convert to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# threshold
thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY)[1]

# get contours and get the largest and smallest ones
contour_img = img.copy()
contours = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
min_area_thresh = hh * ww
max_area_thresh = 0
for cntr in contours:
    cv2.drawContours(contour_img, [cntr], -1, (0, 255, 0), 1)
    area = cv2.contourArea(cntr)
    if area < min_area_thresh:
        xs,ys,ws,hs = cv2.boundingRect(cntr)
        min_area_thresh = area
        small_contour = cntr
    if area > max_area_thresh:
        xl,yl,wl,hl = cv2.boundingRect(cntr)
        max_area_thresh = area
        large_contour = cntr


# compute vertical lines of height of large contour along the sides of the inner contours
x1 = xs
y1 = yl
x2 = x1
y2 = yl + hl - 1
x3 = xs + ws - 1
y3 = yl
x4 = x3
y4 = y2

# draw two vertical lines in black on thresholded image to separate segments
thresh2 = thresh.copy()
cv2.line(thresh2, (x1,y1), (x2,y2), 0, 1) 
cv2.line(thresh2, (x3,y3), (x4,y4), 0, 1) 

# get and draw contours from thresh2
result = thresh2.copy()
result = cv2.merge([result,result,result])
contours = cv2.findContours(thresh2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
for cntr in contours:
    color = list(np.random.random(size=3) * 256)
    cv2.drawContours(result, [cntr], -1, color, 2)

# show thresh and result    
cv2.imshow("input", img)
cv2.imshow("thresh", thresh)
cv2.imshow("contours", contour_img)
cv2.imshow("thresh2", thresh2)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

# save resulting images
cv2.imwrite('rectangles_contours.png',contour_img)
cv2.imwrite('rectangles_thresh2.png',thresh2)
cv2.imwrite('rectangles_result.png',result)

在阈值图像上的大小轮廓:

enter image description here

在阈值图像上绘制两条黑色竖线:

enter image description here

作为结果在上一张图像上绘制的随机颜色轮廓:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.