如何利用Python将图片中两根交叉纤维轮廓分离,使其不再先交,连接,可以通过识别出两根纤维的重叠区域,然后提取出重叠区,就得到四根纤维,然后识别四根纤维的斜率,然后对比斜率大小,以斜率相差最小的为同一根纤维上的,然后将定义为同一根纤维上的两部分纤维,与重叠区再连接起来,即分离出一根纤维,同理分离出第二根纤维即可。
Python,图像处理,轮廓分离
如何利用Python将图片中两根交叉纤维轮廓分离,使其不再先交,连接,可以通过识别出两根纤维的重叠区域,然后提取出重叠区,就得到四根纤维,然后识别四根纤维的斜率,然后对比斜率大小,以斜率相差最小的为同一根纤维上的,然后将定义为同一根纤维上的两部分纤维,与重叠区再连接起来,即分离出一根纤维,同理分离出第二根纤维即可。
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
5条回答 默认 最新
关注 引自免费微信小程序:皆我百晓生
为了实现这个目标,我们将分步进行操作。首先,我们需要导入必要的库,然后对图像进行预处理,接着找到边缘并找到重叠区域,之后根据斜率分割纤维,最后合并相同的纤维。以下是详细的步骤和代码示例:
- 导入库:
import cv2 import numpy as np from skimage import measure from scipy.ndimage import morphology
- 读取原始图像,并转换为灰度图像:
img = cv2.imread('figure_1.png') gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
- 对灰度图像进行二值化处理,以便于后续的边缘检测:
_, binary_img = cv2.threshold(gray_img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
- 找到图像中的边缘:
edges = cv2.Canny(binary_img, 50, 150)
- 使用骨架算法(skeletonization)减少边缘宽度,便于找到可能的交叉点:
skel = morphology.skeletonize(binary_img)
- 从边缘图像中找出所有的轮廓:
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
- 定义一个函数,用于计算两点之间的斜率:
def slope(point1, point2): if point2[0] - point1[0] == 0: return float('inf') # 如果是水平线,斜率为无穷大 else: return (point2[1] - point1[1]) / (point2[0] - point1[0])
- 创建一个字典,用于存储每条轮廓的斜率及其对应的点列表:
contour_slopes = {} for contour in contours: points = [(x, y) for x, y in zip(contour[:, 0, 0], contour[:, 0, 1])] sorted_points = sorted(points, key=lambda p: p[0]) slopes = [slope(sorted_points[i], sorted_points[i+1]) for i in range(len(sorted_points)-1)] avg_slope = sum(slopes) / len(slopes) contour_slopes[avg_slope] = sorted_points
- 确定两条纤维的重叠区域:
overlapping_contours = [] for slope1, points1 in contour_slopes.items(): for slope2, points2 in contour_slopes.items(): if slope1 != slope2 and abs(slope1 - slope2) < 0.1: # 可调整此阈值以匹配实际需求 overlapping_contours.append((slope1, points1, slope2, points2))
- 根据斜率分离纤维并将它们重新组合:
separated_fibers = [] for overlap in overlapping_contours: slope1, points1, slope2, points2 = overlap # 找到交叉点 cross_point = None for i in range(1, len(points1)): for j in range(1, len(points2)): if points1[i] == points2[j]: cross_point = points1[i] break if cross_point is not None: break # 将纤维分割成两部分 fiber1_points = [p for p in points1 if p[0] <= cross_point[0]] fiber2_points = [p for p in points1 if p[0] > cross_point[0]] # 同样地,分割另一根纤维 fiber3_points = [p for p in points2 if p[0] <= cross_point[0]] fiber4_points = [p for p in points2 if p[0] > cross_point[0]] separated_fibers.extend([fiber1_points, fiber2_points, fiber3_points, fiber4_points])
- 最后,我们可以将这些纤维绘制出来以验证结果:
result_image = img.copy() cv2.drawContours(result_image, separated_fibers, -1, (0, 255, 0), 2) # 保存结果 cv2.imwrite("separated_fibers.png", result_image)
注意:上述代码只是一个基本的示例,可能需要根据实际情况进行调整。例如,斜率阈值、边缘检测参数等可能需要根据输入图像进行优化。此外,对于复杂的图像,可能需要更复杂的方法来确定交叉点和纤维的正确分割。在实际应用中,可能还需要考虑噪声和其他可能影响结果的因素。
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报 编辑记录
悬赏问题
- ¥15 数据库原理及应用上机练习题
- ¥30 征集Python提取PDF文字属性的代码
- ¥15 如何联系真正的开发者而非公司
- ¥15 有偿求苍穹外卖环境配置
- ¥15 代码在keil5里变成了这样怎么办啊,文件图像也变了,
- ¥20 Ue4.26打包win64bit报错,如何解决?(语言-c++)
- ¥15 clousx6整点报时指令怎么写
- ¥30 远程帮我安装软件及库文件
- ¥15 关于#自动化#的问题:如何通过电脑控制多相机同步拍照或摄影(相机或者摄影模组数量大于60),并将所有采集的照片或视频以一定编码规则存放至规定电脑文件夹内
- ¥20 (求远程解决)深信服vpn-2050这台设备如何配置才能成功联网?