首页 > 解决方案 > 检测图像中物体的宽度

问题描述

我有如下图像(这些是原始图像上 UNET 的输出):

示例1, 示例2,示例3

我认为分割原始图像是一项艰巨的任务,但我一直在努力完成以下任务:对于每张图像,我必须计算与红色区域相对应的绿色区域的宽度,如下所示:

距离1, 距离2,距离3

我试图做的事情:

检测绿色区域的边缘很简单。然后我通过霍夫变换找到了极坐标中的线:

image = cv2.imread("../../../../example_1.png")
image[:, :, 2] = 0
canny = cv2.Canny(image, 150, 250, 3)
lines = cv2.HoughLinesP(canny, cv2.HOUGH_PROBABILISTIC, np.pi/180, 20)
for line in lines:
    for x0, y0, x1, y1 in line:
        cv2.line(image, (x0,y0), (x1,y1), (255, 255, 255), 1)

fig = plt.figure(figsize = (15, 10))
fig.add_subplot(1, 2, 1).set_title("canny")
plt.imshow(canny, cmap = "gray")
fig.add_subplot(1, 2, 2).set_title("lines")
plt.imshow(image)

这使:

精明的加粗

正如你所看到的,有很多候选行(很多误报),我正在努力保留我需要的那些。此外:您将如何计算宽度?

在极坐标中使用水平线我能够检索每条线与轴原点的角度,因此要计算宽度,我应该找到一对与原点距离不同的平行线(相同角度或几乎相同角度)。我不确定这是最好的方法。

感谢您的帮助

标签: pythonopencv

解决方案


正如@Micka 建议的那样,您可以使用它cv2.minAreaRect来执行此操作。为此,您可以在两个红色和绿色平面上应用简单的阈值,然后进行轮廓估计。然后可以取最大的轮廓,并可以找到面积最小的矩形。使用它的坐标可以计算高度和宽度,然后计算它们的比率。代码是

img = cv2.imread('red_green.png')
red = img[:, :, 2] # to segment out red area
green = img[:, :, 1] # to segment out green are
ret, thresh1 = cv2.threshold(red, 5, 255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(green, 5, 255, cv2.THRESH_BINARY)
_, cnts1, _ = cv2.findContours(thresh1,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
_, cnts2, _ = cv2.findContours(thresh2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
c1 = max(cnts1, key = cv2.contourArea)
c2 = max(cnts2, key = cv2.contourArea)
rect1 = cv2.minAreaRect(c1)
rect2 = cv2.minAreaRect(c2)
box1 = cv2.boxPoints(rect1)
box2 = cv2.boxPoints(rect2)
box1 = np.int0(box1)
box2 = np.int0(box2)
cv2.drawContours(img, [box1], 0, (0, 255, 255), 2)
cv2.drawContours(img, [box2], 0, (0, 255, 255), 2)
(p1, p2, p3, p4) = box1 # Unpacking tuple
h1 = (((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2)**0.5) # calculating width by calculating distance
w1 = (((p2[0]-p3[0])**2 + (p2[1]-p3[1])**2)**0.5) # calculating height by calculating distance
(p1, p2, p3, p4) = box2 # Unpacking tuple
h2 = (((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2)**0.5) # calculating width by calculating distance
w2 = (((p2[0]-p3[0])**2 + (p2[1]-p3[1])**2)**0.5) # calculating height by calculating distance
rofh = h2/h1
rofw = w2/w1
print("ratio of height = ", rofh, "and ratio by width = ", rofw)
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果图像是

在此处输入图像描述


推荐阅读