gpt4 book ai didi

python - 如何在分割中找到边界之间的最大值?

转载 作者:行者123 更新时间:2023-12-05 04:31:23 26 4
gpt4 key购买 nike

这里有一个问题:我想在不规则形状的分割图像中找到边界的实际最大宽度 ( this )下面我发布了一些用于测试的示例图像到目前为止,我设法获得了边界和骨架线,但是如何测量垂直于骨架线的等高线之间的距离?

def get_skeleton(image_path):

im = cv2.imread(img_path , cv2.IMREAD_GRAYSCALE)
binary = im > filters.threshold_otsu(im)
skeleton = morphology.skeletonize(binary)
return skeleton

skeleton = get_skeleton(img_path)
plt.imshow(skeleton, cmap="gray")

def get_boundary(image_path):
reading_Img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
reading_Img = cv2.cvtColor(reading_Img,cv2.COLOR_BGR2RGB)
canny_Img = cv2.Canny(reading_Img,90,100)
contours,_ = cv2.findContours(canny_Img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
canvas = np.zeros_like(reading_Img)
boundary = cv2.drawContours(canvas , contours, -1, (255, 0, 0), 1)
return boundary

boundary = get_boundary(img_path)
plt.imshow(boundary)

Sample input image

编辑:

首先感谢您的回答,我想添加更多关于我正在尝试做的事情的细节。所以我制作了一个检测混凝土裂缝的分割模型(它们可以是任何形状,垂直、水平、对角线等),现在我需要确定它们的最大宽度并画一条线来显示它发生的位置。

我发现中轴返回与边界的距离,通过过滤最大值我能够获得宽度(参见下面的 colab)及其在中轴上的坐标。现在我需要画一条线连接边界之间的宽度,但我不知道如何找到这样一条线的坐标。

我想到了一种算法,它从中轴上最大距离出现的点开始并扩展直到找到边界,但我不知道如何实现它。

这张图片显示了我需要的东西:

enter image description here

enter image description here

找到点的 x 和 y 后,我将能够计算两点之间的欧氏距离

dist=sqrt((y2-y1)^2+(x2-x1)^2)

请查看我在 colab 笔记本中的代码:https://colab.research.google.com/drive/1NvEyfrxpKGJ1kxjP48PGNB_UUSp6f6Ze?usp=sharing

示例输入图像:

https://imgur.com/ewTmH8M

https://imgur.com/JRAQCke

https://imgur.com/7QQFfAv

最佳答案

从您的方法开始,您可以使用中轴函数

  • 在找到的点处插入轴的方向
  • 从方向导出正交
  • 查看正交到达边界的位置。

下面的示例显示了原理并适用于您的示例图像。但我敢肯定会有一些尚未考虑的边界条件。我把它留给你来让它对真实的实时数据具有鲁棒性。

import cv2
import numpy as np
from skimage.morphology import medial_axis
from skimage import img_as_ubyte

delta = 3 # delta index for interpolation

# get crack
im = cv2.imread("img.png", cv2.IMREAD_GRAYSCALE)
rgb = cv2.cvtColor(im, cv2.COLOR_GRAY2RGB) # rgb just for demo purpose
_, crack = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY)

# get medial axis
medial, distance = medial_axis(im, return_distance=True)
med_img = img_as_ubyte(medial)
med_contours, _ = cv2.findContours(med_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cv2.drawContours(rgb, med_contours, -1, (255, 0, 0), 1)
med_pts = [v[0] for v in med_contours[0]]

# get point with maximal distance from medial axis
max_idx = np.argmax(distance)
max_pos = np.unravel_index(max_idx, distance.shape)
max_dist = distance[max_pos]
coords = np.array([max_pos[1], max_pos[0]])
print(f"max distance from medial axis to boundary = {max_dist} at {coords}")

# interpolate orthogonal of medial axis at coords
idx = next(i for i, v in enumerate(med_pts) if (v == coords).all())
px1, py1 = med_pts[(idx-delta) % len(med_pts)]
px2, py2 = med_pts[(idx+delta) % len(med_pts)]
orth = np.array([py1 - py2, px2 - px1]) * max(im.shape)

# intersect orthogonal with crack and get contour
orth_img = np.zeros(crack.shape, dtype=np.uint8)
cv2.line(orth_img, coords + orth, coords - orth, color=255, thickness=1)
gap_img = cv2.bitwise_and(orth_img, crack)
gap_contours, _ = cv2.findContours(gap_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
gap_pts = [v[0] for v in gap_contours[0]]

# determine the end points of the gap contour by negative dot product
n = len(gap_pts)
gap_ends = [
p for i, p in enumerate(gap_pts)
if np.dot(p - gap_pts[(i-1) % n], gap_pts[(i+1) % n] - p) < 0
]
print(f"Maximum gap found from {gap_ends[0]} to {gap_ends[1]}")
cv2.line(rgb, gap_ends[0], gap_ends[1], color=(0, 0, 255), thickness=1)

cv2.imwrite("test_out.png", rgb)

关于python - 如何在分割中找到边界之间的最大值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71848173/

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