首页 > 编程问答 >如何使用OpenCV测量两条相交绳索的宽度和角度?

如何使用OpenCV测量两条相交绳索的宽度和角度?

时间:2024-07-24 09:29:56浏览次数:15  
标签:python opencv computer-vision

下面第一张图是原始图像,显示了一个网络。网中的绳索有两种类型:粗绳和细绳。需要通过OpenCV区分哪些是粗绳,哪些是细绳,并分别测量它们的角度。 enter image description here

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)

我检测到了轮廓的最小外接矩形,但是这种方法无法让我测量轮廓的宽度网绳,而是网格间隙的宽度。如果能有一种稳定可靠的方法来测量两种网绳的宽度,我将不胜感激。

enter image description here

我衷心希望的是:我想知道OpenCV是否可以识别网绳的面积,如如下图红色和绿色矩形框所示。这样,通过测量矩形盒子的宽度就可以得到绳索的宽度。如果您能在这方面帮助我,我将不胜感激。

enter image description here


当然,我们可以使用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)

代码解释:

  1. 图像预处理: 将图像转换为灰度,进行高斯模糊,然后使用自适应阈值进行二值化。
  2. 提取骨架: 使用腐蚀和细化操作提取绳索骨架。
  3. 计算宽度和角度: 检测骨架轮廓,计算最小外接矩形,并提取宽度和角度信息。

注意:

  • 代码中使用的阈值(例如,宽度阈值为 10)可能需要根据实际图像进行调整。
  • 确保已安装 opencv-contrib-python 包,其中包含 ximgproc 模块,用于骨架化操作。

希望这个改进后的方法可以帮助更准确地测量绳索的宽度和角度。

标签:python,opencv,computer-vision
From: 78784792

相关文章

  • Python 检测 USB 设备 - IDLE 和 CMD 解释器之间的不同结果
    我正在尝试解决VDI解决方案中智能卡设备的USB重定向问题。我正在使用pyscard模块作为智能卡。对于进一步的上下文,主要问题是当浏览器插件调用用于处理智能卡的python脚本时,未检测到读卡器。关于问题,当我从CMD解释器运行此代码片段时,我收到空列表,表示系统上未找......
  • Python查找字符串的CRC32
    我尝试获取字符串数据类型变量的CRC32,但出现以下错误:>>>message='helloworld!'>>>importbinascii>>>binascii.crc32(message)Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:aby......
  • 使用python,如何创建重复的工作时间表
    这是我们公司的小组工作安排表。为三班制,2组日夜工作,1组休息。重复白天工作4天休息2天,然后再次夜间工作4天休息2天的时间表。我想使用python(pandas)自动安排在8月9日之后。抱歉英语不好,提前感谢您的帮助以下是使用Python和Pandas创建重复工作时间表的代码......
  • venv 已激活,但 pip 安装仍然默认进行,并且 python 在源代码中看不到该库
    在终端shell中的vscode中输入“whichpython”显示默认路径:C:\Users\erjan\AppData\Local\Programs\Python\Python311\python.exe(my_venv)但是(my_venv)意味着我的venv处于活动状态,我做了pipinstalltransformers,但下面的代码仍然显示错误-无法看到......
  • 在Python多处理中执行二进制信号量或互斥体以进行上下文切换操作
    我正在尝试自动化win应用程序和java应用程序之间的同步关系。我的标准是:启动win和jav应用程序在jav应用程序中执行命令等待jav应用程序的响应使用jav应用程序的响应到Windows应用程序作为输入。在jav应用程序中执行命令win应用程序......
  • 在spyder-python上随机出现的这些奇怪的亮点是什么
    在此处输入图像描述每次我单击此按钮或进行任何更改时,都会创建奇怪的突出显示,当我最小化功能时更是如此。有什么建议如何摆脱这些或可能的原因是什么?谢谢!我尝试更改外观首选项中的设置,但无法影响问题。很抱歉,我无法直接查看或与Spyder界面交互。我是一个AI......
  • 比较Python字典并找到缺失的元素
    我遇到了一个问题,我已经尝试了几天但没有得到任何结果。我想比较两个字典,在一个字典中有“赛前”足球比赛,在第二个字典中有“现场”足球比赛。我想将它们相互比较并打印它们(如果有)没有赛前比赛直播。示例1pre=[{"Home":"Genoa","Away":"In......
  • Python使用Visual Studio打印功能不显示输出
    任务:检查一个整数是正数还是负数。检查整数是否能被2整除。当输入0时,我需要退出循环并报告每个计数和总和。print函数没有显示任何输出。这是我从defmain()开始使用的代码defmain():countpositive=0countnegative=0count_divisible_by_2=0sump......
  • Python 中的像素最小二乘法
    我有一个非线性前向模型,它计算每个像素参数w的灰度图像。我还可以使用scipys优化函数来反转模型。我目前遇到的唯一问题是图像的大小使得这个解决方案非常慢...比如7%的像素在40分钟内计算得很慢。我使用for循环遍历所有像素并按像素应用模型。我尝试过......
  • SQL 命令在手动运行时工作正常(SQL Developer),但在 Python 的 oracledb 模块中给出 ORA-
    我正在使用OracleSQL数据库,并且我想运行该命令ALTERSESSIONSETNLS_DATE_FORMAT='YYYY-MM-DD';当我从SQLDeveloper应用程序手动运行它时,它工作正常。但是,当我使用oracledb模块从Python运行它时,出现以下错误:ErrorrunningSQLscript:ORA-00922:mi......