gpt4 book ai didi

python - 如何划分轮廓?

转载 作者:太空宇宙 更新时间:2023-11-03 21:24:23 25 4
gpt4 key购买 nike

我想检测图像中的物体并测量它们之间的距离。只要物体不太靠近,这就有效。不幸的是,图像的照明不是最佳的,所以看起来物体正在接触,但实际上并没有。我试图借助代表对象的线来确定距离。问题是一旦对象轮廓连接起来,我就无法确定代表对象的线,因此无法计算距离。

输入图像:

enter image description here

代码:

import cv2
import numpy as np

#import image
img = cv2.imread('img.png', 0)

#Thresh
_, thresh = cv2.threshold(img, 200, 255, cv2.THRESH_BINARY)

#Finding the contours in the image
_, contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

#Convert img to RGB and draw contour
img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
cv2.drawContours(img, contours, -1, (0,0,255), 2)

#Object1
v = np.matrix([[0], [1]])
rect = cv2.minAreaRect(contours[0])

#determine angle
if rect[1][0] > rect[1][1]:
ang = (rect[2] + 90)* np.pi / 180
else:
ang = rect[2]* np.pi / 180
rot = np.matrix([[np.cos(ang), -np.sin(ang)],[np.sin(ang), np.cos(ang)]])
rv = rot*v

#draw angle line
lineSize = max(rect[1])*0.45 #length of line
p1 = tuple(np.array(rect[0] - lineSize*rv.T)[0].astype(int))
p2 = tuple(np.array(rect[0] + lineSize*rv.T)[0].astype(int))
cv2.line(img, p1, p2, (255,0,0), 2)

#Object2
if len(contours) > 1:
rect = cv2.minAreaRect(contours[1])

#determine angle
if rect[1][0] > rect[1][1]:
ang = (rect[2] + 90)* np.pi / 180
else:
ang = rect[2]* np.pi / 180
rot = np.matrix([[np.cos(ang), -np.sin(ang)],[np.sin(ang), np.cos(ang)]])
rv = rot*v

#draw angle line
lineSize = max(rect[1])*0.45 #length of line
p1 = tuple(np.array(rect[0] - lineSize*rv.T)[0].astype(int))
p2 = tuple(np.array(rect[0] + lineSize*rv.T)[0].astype(int))
cv2.line(img, p1, p2, (255,0,0), 2)


#save output img
cv2.imwrite('output_img.png', img)

输出图像:

enter image description here

这很好用,但是一旦我使用带有连接轮廓的图像,就会发生这种情况:

enter image description here enter image description here

是否有分割轮廓的方法或解决方法?

编辑

感谢B.M.的建议我试过侵 eclipse 是否是一种解决方案,但不幸的是新问题出现了。似乎无法在侵 eclipse 和阈值/轮廓之间找到平衡。

例子:

enter image description here enter image description here enter image description here enter image description here

最佳答案

如果您先搜索等高线并检查实际上是否有两个呢?如果只有一个,你可以做一个循环来腐 eclipse 并在腐 eclipse 图像上搜索轮廓,直到你得到两个轮廓。当事件发生时,制作一个黑色边界框,该边界框比侵 eclipse 图像上使用的内核数量更大,并在“原始图像”上绘制,这将物理地划分并创建 2 个轮廓。然后将您的代码应用于生成的图像。也许你可以上传你处理前最困难的图片吗?希望对你有帮助或者给你一个新的思路。干杯!

示例代码:

import cv2
import numpy as np

img = cv2.imread('cont.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, threshold = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)
_, contours, hierarchy = cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
k = 2

if len(contours)==1:
for i in range (0,1000):
kernel = np.ones((1,k),np.uint8)
erosion = cv2.erode(threshold,kernel,iterations = 1)
_, contours, hierarchy = cv2.findContours(erosion,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
if len(contours) == 1:
k+=1
if len(contours) == 2:
break
if len(contours) > 2:
print('more than one contour')

x,y,w,h = cv2.boundingRect(contours[0])
cv2.rectangle(threshold,(x-k,y-k),(x+w+k,y+h+k), 0, 1)
_, contours, hierarchy = cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cv2.drawContours(img, contours, -1, (0,0,255), 2)

#Object1
v = np.matrix([[0], [1]])
rect = cv2.minAreaRect(contours[0])

#determine angle
if rect[1][0] > rect[1][1]:
ang = (rect[2] + 90)* np.pi / 180
else:
ang = rect[2]* np.pi / 180
rot = np.matrix([[np.cos(ang), -np.sin(ang)],[np.sin(ang), np.cos(ang)]])
rv = rot*v

#draw angle line
lineSize = max(rect[1])*0.45 #length of line
p1 = tuple(np.array(rect[0] - lineSize*rv.T)[0].astype(int))
p2 = tuple(np.array(rect[0] + lineSize*rv.T)[0].astype(int))
cv2.line(img, p1, p2, (255,0,0), 2)

#Object2
if len(contours) > 1:
rect = cv2.minAreaRect(contours[1])

#determine angle
if rect[1][0] > rect[1][1]:
ang = (rect[2] + 90)* np.pi / 180
else:
ang = rect[2]* np.pi / 180
rot = np.matrix([[np.cos(ang), -np.sin(ang)],[np.sin(ang), np.cos(ang)]])
rv = rot*v

#draw angle line
lineSize = max(rect[1])*0.45 #length of line
p1 = tuple(np.array(rect[0] - lineSize*rv.T)[0].astype(int))
p2 = tuple(np.array(rect[0] + lineSize*rv.T)[0].astype(int))
cv2.line(img, p1, p2, (255,0,0), 2)


#save output img

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果:

enter image description here

关于python - 如何划分轮廓?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53582446/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com