You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用OpenCV识别网绳粗细并准确测量其宽度与角度?

网绳宽度与角度测量方案

问题说明

需要处理含粗细两类网绳的图像,用OpenCV实现以下目标:

  • 区分粗、细网绳
  • 分别测量两类网绳的宽度与倾斜角度
    此前尝试的轮廓最小外接矩形方法误测了网格间隙,需调整方案以准确识别网绳区域并测量绳宽。

稳定实现方案

核心思路

  1. 预处理优化:采用高斯降噪+自适应阈值分割,适配光照不均的场景,精准分离网绳与背景
  2. 形态学修正:用闭操作填充网绳区域的细小空隙,再用开操作消除噪声点,突出网绳的连通区域
  3. 轮廓筛选:通过面积、长宽比过滤掉网格间隙等无效轮廓,只保留网绳的有效区域
  4. 精准测量:对网绳轮廓计算最小外接矩形,取矩形短边为绳宽,矩形旋转角度为绳的倾斜角度
  5. 分类统计:设定合理宽度阈值,将网绳分为粗、细两类并统计数据

完整代码实现

import cv2
import numpy as np

def measure_rope_properties(image):
    # 1. 图像预处理:灰度化 + 高斯降噪
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)
    
    # 2. 自适应阈值分割:适配光照不均,分割网绳与背景
    thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, 
                                   cv2.THRESH_BINARY_INV, 11, 2)
    
    # 3. 形态学操作:闭操作填充网绳空隙,开操作去除噪声
    kernel_close = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel_close, iterations=2)
    kernel_open = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
    opened = cv2.morphologyEx(closed, cv2.MORPH_OPEN, kernel_open, iterations=1)
    
    # 4. 提取轮廓并筛选有效网绳区域
    contours, _ = cv2.findContours(opened, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # 筛选条件:面积大于阈值,长宽比符合网绳形态(避免间隙轮廓)
    min_area = 50
    valid_contours = []
    for cnt in contours:
        area = cv2.contourArea(cnt)
        if area < min_area:
            continue
        rect = cv2.minAreaRect(cnt)
        w, h = rect[1]
        if w == 0 or h == 0:
            continue
        aspect_ratio = max(w, h) / min(w, h)
        # 网绳的长宽比通常远大于1,过滤掉接近正方形的间隙轮廓
        if aspect_ratio > 3:
            valid_contours.append(cnt)
    
    # 5. 测量网绳宽度、角度并分类
    thick_ropes = []  # 存储(宽度, 角度)
    thin_ropes = []
    width_threshold = 10  # 根据实际场景调整阈值
    
    for cnt in valid_contours:
        rect = cv2.minAreaRect(cnt)
        center, (w, h), angle = rect
        # 绳宽取矩形的短边
        rope_width = min(w, h)
        # 统一角度表示:转换为0-90度范围
        if angle < -45:
            angle = 90 + angle
        # 分类
        if rope_width > width_threshold:
            thick_ropes.append((round(rope_width, 2), round(angle, 2)))
            # 绘制粗绳矩形(红色)
            box = cv2.boxPoints(rect)
            box = np.int0(box)
            cv2.drawContours(image, [box], 0, (0, 0, 255), 2)
        else:
            thin_ropes.append((round(rope_width, 2), round(angle, 2)))
            # 绘制细绳矩形(绿色)
            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')
    if image is None:
        print("无法读取图像,请检查路径")
        exit()
    
    result_img, thick_data, thin_data = measure_rope_properties(image)
    
    # 显示结果
    cv2.imshow('Rope Measurement Result', result_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    # 输出统计数据
    print("粗绳(宽度, 角度):", thick_data)
    print("细绳(宽度, 角度):", thin_data)

关键细节说明

  • 自适应阈值:相比固定阈值,能更好处理光照不均的网绳图像,避免局部过亮或过暗导致的分割错误
  • 形态学操作:闭操作填充网绳上的细小断裂,开操作去除背景噪声,确保网绳区域的连通性
  • 轮廓筛选:通过面积和长宽比过滤掉网格间隙——间隙的轮廓通常接近正方形,而网绳是长条状,长宽比远大于1
  • 角度统一:将OpenCV最小外接矩形的角度转换为0-90度范围,更符合直观的倾斜角度认知
  • 阈值调整:width_threshold和min_area需根据实际图像的分辨率和网绳尺寸调整,确保分类准确

内容的提问来源于stack exchange,提问作者viktor2000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 08:57:11