下面第一张图是原始图像,显示了一个网络。网中的绳索有两种类型:粗绳和细绳。需要通过OpenCV区分哪些是粗绳,哪些是细绳,并分别测量它们的角度。
import cv2
import numpy as np
def measure_rope_width(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow('Grayscale Image', gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
cv2.imshow('Binary Image', thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
widths = []
for contour in contours:
rect = cv2.minAreaRect(contour)
width = max(rect[1])
widths.append(width)
threshold = 10
thick_ropes = [width for width in widths if width > threshold]
thin_ropes = [width for width in widths if width <= threshold]
for contour in contours:
rect = cv2.minAreaRect(contour)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(image, [box], 0, (0, 255, 0), 2)
return image, thick_ropes, thin_ropes
if __name__ == "__main__":
image = cv2.imread('.\pics\webFebric.png')
image, thick_ropes, thin_ropes = measure_rope_width(image)
cv2.imshow('Image with Rectangles', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
print("thick ropes width:", thick_ropes)
print("thin ropes width:", thin_ropes)
我检测到了轮廓的最小外接矩形,但是这种方法无法让我测量轮廓的宽度网绳,而是网格间隙的宽度。如果能有一种稳定可靠的方法来测量两种网绳的宽度,我将不胜感激。
我衷心希望的是:我想知道OpenCV是否可以识别网绳的面积,如如下图红色和绿色矩形框所示。这样,通过测量矩形盒子的宽度就可以得到绳索的宽度。如果您能在这方面帮助我,我将不胜感激。
当然,我们可以使用OpenCV更准确地测量绳索宽度和角度。 以下是一种改进的方法:
1. 图像预处理:
- 灰度化: 将图像转换为灰度。
- 高斯模糊: 使用高斯滤波器平滑图像,减少噪声干扰。
- 自适应阈值: 使用自适应阈值技术,根据图像的局部区域设置不同的阈值,可以更好地分割出绳索。
2. 提取绳索骨架:
- 形态学操作: 使用腐蚀和细化等形态学操作,提取绳索的骨架线。
3. 计算宽度和角度:
- 轮廓检测: 检测骨架线的轮廓。
- 最小外接矩形: 计算每个轮廓的最小外接矩形。
- 宽度: 矩形的较短边长度可以近似表示绳索的宽度。
- 角度: 矩形的旋转角度可以表示绳索的角度。
代码示例:
import cv2
import numpy as np
def measure_rope_width_and_angle(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 11, 2)
kernel = np.ones((3,3), np.uint8)
erosion = cv2.erode(thresh, kernel, iterations=1)
skeleton = cv2.ximgproc.thinning(erosion, thinningType=cv2.ximgproc.THINNING_ZHANGSUEN)
contours, _ = cv2.findContours(skeleton, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
thick_ropes = []
thin_ropes = []
for contour in contours:
rect = cv2.minAreaRect(contour)
box = cv2.boxPoints(rect)
box = np.int0(box)
width = min(rect[1])
angle = rect[2]
if width > 10:
thick_ropes.append((width, angle))
cv2.drawContours(image, [box], 0, (0, 255, 0), 2)
else:
thin_ropes.append((width, angle))
cv2.drawContours(image, [box], 0, (0, 0, 255), 2)
return image, thick_ropes, thin_ropes
if __name__ == "__main__":
image = cv2.imread('./pics/webFebric.png')
image, thick_ropes, thin_ropes = measure_rope_width_and_angle(image)
cv2.imshow('Image with Rectangles', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
print("Thick ropes (width, angle):", thick_ropes)
print("Thin ropes (width, angle):", thin_ropes)
代码解释:
- 图像预处理: 将图像转换为灰度,进行高斯模糊,然后使用自适应阈值进行二值化。
- 提取骨架: 使用腐蚀和细化操作提取绳索骨架。
- 计算宽度和角度: 检测骨架轮廓,计算最小外接矩形,并提取宽度和角度信息。
注意:
- 代码中使用的阈值(例如,宽度阈值为 10)可能需要根据实际图像进行调整。
-
确保已安装
opencv-contrib-python
包,其中包含ximgproc
模块,用于骨架化操作。
希望这个改进后的方法可以帮助更准确地测量绳索的宽度和角度。
标签:python,opencv,computer-vision From: 78784792