如何利用Python实现对以上图像中纤维目标的长度和直径检测,其中检测直径时,首先画出纤维目标的中轴线,再画中轴线垂直方向n条交于纤维边缘轮廓的垂线,计算这n条垂线的长度之和再取平均值,即为纤维直径。计算长度时计算纤维目标中轴线,其中中轴线,起止均在纤维两端,所以中轴线长度就是纤维长度,计算中轴线长度,即为纤维长度,最后输出结果。
python ,图像识别,长度直径检测
如何利用Python实现对以上图像中纤维目标的长度和直径检测,其中检测直径时,首先画出纤维目标的中轴线,再画中轴线垂直方向n条交于纤维边缘轮廓的垂线,计算这n条垂线的长度之和再取平均值,即为纤维直径。计算长度时计算纤维目标中轴线,其中中轴线,起止均在纤维两端,所以中轴线长度就是纤维长度,计算中轴线长度,即为纤维长度,最后输出结果。
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
3条回答 默认 最新
关注 让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
问题分析: 本题要求利用Python实现对纤维目标的长度和直径检测,其中直径的检测需要先画出中轴线,再画出垂线,计算长度之和取平均值。而长度的计算则需要计算中轴线,得出中轴线的长度即为纤维长度。 解决方案:- 图像处理 本题需要处理的是一幅灰度图像,可利用OpenCV的cv2.imread()函数读取图像,并通过cv2.cvtColor()函数将其转化为灰度图像。然后利用cv2.threshold()函数进行二值化处理,使得图像中的目标部分变为白色,背景部分变为黑色。
- 直径检测 先通过cv2.findContours()函数找到纤维的边缘轮廓,然后利用OpenCV中的minAreaRect()函数来拟合轮廓的最小外接矩形,得到矩形的长和宽作为纤维的长和宽,即纤维的直径。然后得到最终的直径需要将得到的n条垂线长度之和除以n。
- 长度检测 由题目可知,利用膨胀与腐蚀操作,可以得到纤维的中轴线。先利用cv2.dilate()函数进行膨胀操作,拓宽纤维。再利用cv2.erode()函数进行腐蚀操作,缩小纤维。这样得到的图像即为中轴线。然后根据这个中轴线计算长度即可。 代码实现:
import cv2 import numpy as np # 读取图像 img = cv2.imread('fiber.png') # 将图像转化为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 二值化处理 _, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) # 直径检测 contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 得到最小外接矩形 rect = cv2.minAreaRect(contours[0]) # 得到最小外接矩形的长和宽作为纤维的长和宽 diameter = max(rect[1]) # 得到n条垂线长度之和除以n作为纤维的直径 n = 20 # 垂线条数 line_length_sum = 0 sin_theta = np.sin(rect[2]*np.pi/180) cos_theta = np.cos(rect[2]*np.pi/180) for i in range(n): y = i * diameter/n - diameter/2 x = y * sin_theta / cos_theta x = int(round(x)) + int(rect[0][0]) y = int(round(y)) + int(rect[0][1]) line_length_sum += cv2.pointPolygonTest(contours[0], (x, y), True) fiber_diameter = line_length_sum / n # 中轴线计算 # 先膨胀 kernel = np.ones((5,5), np.uint8) dilate = cv2.dilate(thresh, kernel, iterations=5) # 再腐蚀 erosion = cv2.erode(dilate, kernel, iterations=5) # 得到中轴线的轮廓 contours, hierarchy = cv2.findContours(erosion, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 利用最小外接矩形的四个点计算中轴线 top_left, top_right, bottom_left, bottom_right = cv2.boxPoints(rect) k1 = (top_left[1] - bottom_left[1]) / (top_left[0] - bottom_left[0]) b1 = top_left[1] - k1 * top_left[0] k2 = (top_right[1] - bottom_right[1]) / (top_right[0] - bottom_right[0]) b2 = top_right[1] - k2 * top_right[0] cross_x = (b2 - b1) / (k1 - k2) cross_y = k1 * cross_x + b1 fiber_length = int(round(np.sqrt((cross_x - top_left[0])**2 + (cross_y - top_left[1])**2))) print('纤维长度为:', fiber_length) print('纤维直径为:', fiber_diameter) cv2.imshow('fiber', img) cv2.waitKey(0) cv2.destroyAllWindows()
参考文献: [1] OpenCV-Python Tutorials. https://opencv-python-tutroals.readthedocs.io/en/latest/index.html [2] OpenCV官方文档. https://docs.opencv.org/4.5.2/
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 1无用
悬赏问题
- ¥15 数据库原理及应用上机练习题
- ¥30 征集Python提取PDF文字属性的代码
- ¥15 如何联系真正的开发者而非公司
- ¥15 有偿求苍穹外卖环境配置
- ¥15 代码在keil5里变成了这样怎么办啊,文件图像也变了,
- ¥20 Ue4.26打包win64bit报错,如何解决?(语言-c++)
- ¥15 clousx6整点报时指令怎么写
- ¥30 远程帮我安装软件及库文件
- ¥15 关于#自动化#的问题:如何通过电脑控制多相机同步拍照或摄影(相机或者摄影模组数量大于60),并将所有采集的照片或视频以一定编码规则存放至规定电脑文件夹内
- ¥20 (求远程解决)深信服vpn-2050这台设备如何配置才能成功联网?