找到部分闭合的精巧边缘的中间
Find middle of partially closed canny edges
我有如下(低分辨率)图像:
(原图 1)
最终目标是为图像中的每条线定义线段坐标:
我试过的策略是扩张 -> 找到轮廓 -> 模糊 -> 侵蚀 -> canny 边缘检测:
import numpy as np
import cv2
from skimage.feature import canny
image = cv2.imread('image.png')
kernel = np.ones((1,1),np.uint8)
dilated_img = cv2.dilate(gray, kernel, iterations = 1)
canvas = cv2.cvtColor(dilated_img, cv2.COLOR_GRAY2RGB)
contours, hierarchy = cv2.findContours(dilated_img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
for i,cont in enumerate(contours):
if ( hierarchy[0][i][3] != -1 ):
cv2.fillPoly(canvas, pts =[cont], color=(0, 180, 0))
else:
cv2.drawContours(canvas, cont, -1, (255, 0, 0), 1)
canvas = cv2.GaussianBlur(canvas,(1, 1),39)
edges = canny(image, 3, 1, 25)
输出 (edges
) 看起来像下图,除了绿色,我添加绿色是为了表示我希望通过此策略实现的目标:如果我能找到管子的中间(绿色),然后我可以从中构建线段。也许这是实现目标的一种不必要的复杂方式...
边缘出来的大多是这些管状结构,可以完全封闭也可以不封闭。
图像中的绿线表示我想要找到的东西——基本上只是管子的大约中间。
我尝试对 edge
对象做的是逐行(和逐列)逐个像素地根据白色和黑色像素的方式找到管的中间出现,但结果很乱,并且在许多管方向上效果不佳。
(图像1边缘,颜色反转)
所以假设这个策略对于实现上述目标是可行的,我怎样才能找到管子的中点?如果攻略不好,怎么办?
谢谢!
希望这个方法对你有所帮助
你的绿线是阈值图像的骨架图像。查看 here 了解更多关于骨架图像的信息。
import cv2
import numpy as np
from skimage.morphology import skeletonize
def read_image(image_path):
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(image, 200, 255, cv2.THRESH_BINARY_INV)
return thresh
def get_skeleton_iamge(threshold_image):
skeleton = skeletonize(threshold_image / 255)
skeleton = skeleton.astype(np.uint8)
skeleton *= 255
return skeleton
if __name__ == "__main__":
threshold_image = read_image("image.png")
cv2.imshow("threshold_image", threshold_image)
skeleton_iamge = get_skeleton_iamge(threshold_image)
cv2.imshow("skeleton_iamge", skeleton_iamge)
canny_edges = cv2.Canny(threshold_image, 100, 200)
cv2.imshow("canny_edges", canny_edges)
# for displaying image only
colour_skeleton_iamge = cv2.cvtColor(skeleton_iamge, cv2.COLOR_GRAY2BGR)
colour_canny_edges = cv2.cvtColor(canny_edges, cv2.COLOR_GRAY2BGR)
colour_skeleton_iamge[skeleton_iamge == 255] = [0, 255, 0]
combined_image = cv2.scaleAdd(colour_skeleton_iamge, 0.5, colour_canny_edges, 0.5)
cv2.imshow("combined_image", combined_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出:
image
threshold_image
skeleton_iamge
canny_edges
combined_image
我有如下(低分辨率)图像:
最终目标是为图像中的每条线定义线段坐标:
我试过的策略是扩张 -> 找到轮廓 -> 模糊 -> 侵蚀 -> canny 边缘检测:
import numpy as np
import cv2
from skimage.feature import canny
image = cv2.imread('image.png')
kernel = np.ones((1,1),np.uint8)
dilated_img = cv2.dilate(gray, kernel, iterations = 1)
canvas = cv2.cvtColor(dilated_img, cv2.COLOR_GRAY2RGB)
contours, hierarchy = cv2.findContours(dilated_img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
for i,cont in enumerate(contours):
if ( hierarchy[0][i][3] != -1 ):
cv2.fillPoly(canvas, pts =[cont], color=(0, 180, 0))
else:
cv2.drawContours(canvas, cont, -1, (255, 0, 0), 1)
canvas = cv2.GaussianBlur(canvas,(1, 1),39)
edges = canny(image, 3, 1, 25)
输出 (edges
) 看起来像下图,除了绿色,我添加绿色是为了表示我希望通过此策略实现的目标:如果我能找到管子的中间(绿色),然后我可以从中构建线段。也许这是实现目标的一种不必要的复杂方式...
边缘出来的大多是这些管状结构,可以完全封闭也可以不封闭。
图像中的绿线表示我想要找到的东西——基本上只是管子的大约中间。
我尝试对 edge
对象做的是逐行(和逐列)逐个像素地根据白色和黑色像素的方式找到管的中间出现,但结果很乱,并且在许多管方向上效果不佳。
所以假设这个策略对于实现上述目标是可行的,我怎样才能找到管子的中点?如果攻略不好,怎么办?
谢谢!
希望这个方法对你有所帮助
你的绿线是阈值图像的骨架图像。查看 here 了解更多关于骨架图像的信息。
import cv2
import numpy as np
from skimage.morphology import skeletonize
def read_image(image_path):
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(image, 200, 255, cv2.THRESH_BINARY_INV)
return thresh
def get_skeleton_iamge(threshold_image):
skeleton = skeletonize(threshold_image / 255)
skeleton = skeleton.astype(np.uint8)
skeleton *= 255
return skeleton
if __name__ == "__main__":
threshold_image = read_image("image.png")
cv2.imshow("threshold_image", threshold_image)
skeleton_iamge = get_skeleton_iamge(threshold_image)
cv2.imshow("skeleton_iamge", skeleton_iamge)
canny_edges = cv2.Canny(threshold_image, 100, 200)
cv2.imshow("canny_edges", canny_edges)
# for displaying image only
colour_skeleton_iamge = cv2.cvtColor(skeleton_iamge, cv2.COLOR_GRAY2BGR)
colour_canny_edges = cv2.cvtColor(canny_edges, cv2.COLOR_GRAY2BGR)
colour_skeleton_iamge[skeleton_iamge == 255] = [0, 255, 0]
combined_image = cv2.scaleAdd(colour_skeleton_iamge, 0.5, colour_canny_edges, 0.5)
cv2.imshow("combined_image", combined_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出:
image | threshold_image | skeleton_iamge | canny_edges | combined_image |
---|---|---|---|---|