python - 检测图像中物体的宽度
问题描述
我有如下图像(这些是原始图像上 UNET 的输出):
我认为分割原始图像是一项艰巨的任务,但我一直在努力完成以下任务:对于每张图像,我必须计算与红色区域相对应的绿色区域的宽度,如下所示:
我试图做的事情:
检测绿色区域的边缘很简单。然后我通过霍夫变换找到了极坐标中的线:
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)
这使:
正如你所看到的,有很多候选行(很多误报),我正在努力保留我需要的那些。此外:您将如何计算宽度?
在极坐标中使用水平线我能够检索每条线与轴原点的角度,因此要计算宽度,我应该找到一对与原点距离不同的平行线(相同角度或几乎相同角度)。我不确定这是最好的方法。
感谢您的帮助
解决方案
正如@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()
结果图像是
推荐阅读
- javascript - foreach 循环追加一个循环并暂停事件 javascript
- objective-c - 在 iOS 静态库中使用 socket.io-client-cpp 发生错误
- swift - 斯威夫特:设置@IBOutlet 静态
- php - 无法通过codeigniter中的数组更新数据
- javascript - Hyperledger Composer 在客户端创建卡片数据以发送导入请求
- r - 默认情况下,tapply 会排除传递给分段的变量的 NA 吗?
- python - 不使用 AJAX 和 jQuery 的 Django 多文件上传
- java - NoHostAvailableException :: Java 到 Cassandra SSL 集群的连接失败
- excel - 过滤多个非空白列
- django - Django 迁移,在删除旧的之前添加了字段