利用OpenCV计算条形物体的长度

这篇具有很好参考价值的文章主要介绍了利用OpenCV计算条形物体的长度。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文提供了一种利用opencv计算条形物体长度的方法,思路新奇,实现简单,同时也提供了代码实现。

目录

0、前言

1、解决步骤

1.1 利用分割方法得到物体mask

1.2 提取骨骼线

1.3 计算骨架线长度

 2、验证


0、前言

        在图像处理中,我们可能会遇到求一个线条长度的场景,比如,现在有一条裂缝,需要求其长度,或者有一个长条形的零件需要知道其长度。

        本文利用OpenCV和skimage两个库,提供了一个解决方案。

1、解决步骤

        主要步骤包括三个部分:

  • 获取物体mask;
  • 提取骨骼线;
  • 计算骨骼线长度;

        其中,提取骨骼线的方法为:

def skeletonize(image, *, method=None):
    """Compute the skeleton of a binary image.

    Thinning is used to reduce each connected component in a binary image
    to a single-pixel wide skeleton.

    Parameters
    ----------
    image : ndarray, 2D or 3D
        An image containing the objects to be skeletonized. Zeros
        represent background, nonzero values are foreground.
    method : {'zhang', 'lee'}, optional
        Which algorithm to use. Zhang's algorithm [Zha84]_ only works for
        2D images, and is the default for 2D. Lee's algorithm [Lee94]_
        works for 2D or 3D images and is the default for 3D.

    Returns
    -------
    skeleton : ndarray
        The thinned image.

    See Also
    --------
    medial_axis

    References
    ----------
    .. [Lee94] T.-C. Lee, R.L. Kashyap and C.-N. Chu, Building skeleton models
           via 3-D medial surface/axis thinning algorithms.
           Computer Vision, Graphics, and Image Processing, 56(6):462-478, 1994.

    .. [Zha84] A fast parallel algorithm for thinning digital patterns,
           T. Y. Zhang and C. Y. Suen, Communications of the ACM,
           March 1984, Volume 27, Number 3.

    Examples
    --------
    >>> X, Y = np.ogrid[0:9, 0:9]
    >>> ellipse = (1./3 * (X - 4)**2 + (Y - 4)**2 < 3**2).astype(np.uint8)
    >>> ellipse
    array([[0, 0, 0, 1, 1, 1, 0, 0, 0],
           [0, 0, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 1, 1, 1, 1, 1, 0, 0],
           [0, 0, 0, 1, 1, 1, 0, 0, 0]], dtype=uint8)
    >>> skel = skeletonize(ellipse)
    >>> skel.astype(np.uint8)
    array([[0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 1, 0, 0, 0, 0],
           [0, 0, 0, 0, 1, 0, 0, 0, 0],
           [0, 0, 0, 0, 1, 0, 0, 0, 0],
           [0, 0, 0, 0, 1, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)

    """

        计算骨骼线长度的方法,我们用到了 cv2.arcLength这个函数,但是它求得的是mask的周长;对于骨骼线,其周长其实就是长度的两倍,因此我们调用cv2.arcLength得到的结果需要除以2。cv2.arcLength定义如下:

def arcLength(curve, closed): # real signature unknown; restored from __doc__
    """
    arcLength(curve, closed) -> retval
    .   @brief Calculates a contour perimeter or a curve length.
    .   
    .   The function computes a curve length or a closed contour perimeter.
    .   
    .   @param curve Input vector of 2D points, stored in std::vector or Mat.
    .   @param closed Flag indicating whether the curve is closed or not.
    """

1.1 利用分割方法得到物体mask

        这部分根据不同的业务需求,选用不同的方法,可以用深度学习相关的模型进行分割,也可以用传统方法得到;这部分不做过多介绍,总之可以得到一个mask。

1.2 提取骨骼线

        对得到的mask,利用skimage库进行骨骼线提取:

from skimage.morphology import skeletonize

def get_skeleton(blobs):
    """
    骨骼提取
    """
    skeleton = skeletonize(blobs)  # ndarray, 为TRUE的元素代表骨骼线的位置
    skeleton_pts = np.argwhere(skeleton)
    return skeleton, skeleton_pts

        这时,可以得到一个二值化的骨架图:

opencv 计算长度,CV数据处理,Python opencv,opencv,计算机视觉,图像处理,计算长度

1.3 计算骨架线长度

对于上一步得到的二值化骨架图,先转化为mask(注意,这里的mask是宽度为1个像素的骨架图的mask),然后求轮廓,最后对于每个轮廓求周长的1/2,加起来即为整个骨架线的长度:

import cv2
import numpy as np

length = 0

# 求skeleton
s_skeleton, s_skeleton_pts = get_skeleton(s_instance)
# 利用骨骼线得到轮廓
s_bpixel = np.zeros_like(s_skeleton, dtype=np.uint8)
s_bpixel[s_skeleton] = 255
s_contours, _ = cv2.findContours(s_bpixel, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 计算长度
for s_contour in s_contours:
    length += cv2.arcLength(s_contour, True) / 2

print("长度:", length)

这里主要是将线条长度计算的问题转换成了线条周长的计算,这样就可以利用cv2.arcLength来计算周长再除以2即为长度。

 2、验证

为了验证方法的有效性,可以人工绘制一些简单的线条,然后利用上面的方法求一下长度,即可知道是否计算正确;以下是一些验证的示例:

给出一些示例(“=” 前后分别为:arcLength算出来的值、人为解释):

a. 5.656854152679443 = 4*sqrt(2)

opencv 计算长度,CV数据处理,Python opencv,opencv,计算机视觉,图像处理,计算长度

b. 7.242640614509582 = 3*sqrt(2) + 3

opencv 计算长度,CV数据处理,Python opencv,opencv,计算机视觉,图像处理,计算长度

c. 4.2426406145095825 = 3*sqrt(2)

opencv 计算长度,CV数据处理,Python opencv,opencv,计算机视觉,图像处理,计算长度

d. 9.485281374238571 = 2*3*sqrt(2) + 1

opencv 计算长度,CV数据处理,Python opencv,opencv,计算机视觉,图像处理,计算长度

e. 11.899494936611665 = (3 + 1 + 3)* sqrt(2) + 2

opencv 计算长度,CV数据处理,Python opencv,opencv,计算机视觉,图像处理,计算长度

f. 5.656854249492381 = 4 * sqrt(2)

opencv 计算长度,CV数据处理,Python opencv,opencv,计算机视觉,图像处理,计算长度


参考:

Morphological Filtering — skimage 0.22.0 documentation

cv2.arcLength() -- OpenCV | We all are data.文章来源地址https://www.toymoban.com/news/detail-605871.html

到了这里,关于利用OpenCV计算条形物体的长度的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【计算机视觉】---OpenCV实现物体追踪

    OpenCV中的物体追踪算法基于视觉目标跟踪的原理。物体追踪的目标是在连续的图像序列中定位和跟踪特定物体的位置。 在物体追踪中,我们需要对目标对象进行表示。通常使用边界框(bounding box)来表示目标的位置和大小。边界框是一个矩形区域,由左上角的坐标(x,y)和

    2024年02月08日
    浏览(51)
  • opencv 基础54-利用形状场景算法比较轮廓-cv2.createShapeContextDistanceExtractor()

    注意:新版本的opencv 4 已经没有这个函数 cv2.createShapeContextDistanceExtractor() 形状场景算法是一种用于比较轮廓或形状的方法。这种算法通常用于计算两个形状之间的相似性或差异性,以及找到最佳的匹配方式。 下面是一种基本的比较轮廓的流程,使用了形状场景算法: 数据准

    2024年02月13日
    浏览(34)
  • 【OpenCV】计算视频的光流并跟踪物体calcOpticalFlowPyrLK

            计算光流可以使用OpenCV的calcOpticalFlowPyrLK方法,cv2.calcOpticalFlowPyrLK是OpenCV库中的一个函数,用于计算稀疏光流。它实现的是Lucas-Kanade方法,这是一种常用的光流计算方法。         光流是图像中物体运动的近似表示,它描述了图像中每个像素点在连续两帧之间

    2024年02月02日
    浏览(32)
  • 详解OpenCV的视频背景/前景分割(背景建模/前景提取)类cv::BackgroundSubtractorMOG2,并利用它实现对道路监控视频前景/背景的提取

    cv::BackgroundSubtractorMOG2和cv::bgsegm::BackgroundSubtractorMOG一样,都是基于高斯混合模型的背景与前景分割算法。 cv::BackgroundSubtractorMOG2是对cv::bgsegm::BackgroundSubtractorMOG的改进,经过改进,它实现了自适应高斯混合模型参数的更新,增强了复杂场景背景检测的性能。 具体的算法原理可

    2023年04月18日
    浏览(35)
  • opencv_04条形码区域分割

    基于OpenCV的条形码区域分割 要基于OpenCV实现条形码区域分割,可以按照以下步骤进行: 加载图像:使用OpenCV中的imread函数读取待处理图像。 灰度化:使用OpenCV中的cvtColor函数将彩色图像转换为灰度图像。 边缘检测:使用OpenCV中的Canny函数对灰度图像进行边缘检测,得到二值

    2024年02月06日
    浏览(42)
  • 【OpenCV4】计算对称矩阵特征值和特征向量 cv::eigen() 用法详解和代码示例(c++)

    解析: src:输入矩阵,只能是 CV_32FC1 或 CV_64FC1 类型的方阵(即矩阵转置后还是自己) eigenvalues:输出的特征值组成的向量,数据类型同输入矩阵,排列从大到小 eigenvectors:输出的特征向量组成的矩阵,数据类型同输入矩阵,每一行是一个特征向量,对应相应位置的特征值

    2024年02月13日
    浏览(49)
  • opencv检测二维码和条形码

    使用excel可以实现制作二维码,但只能实现做英文和数字类型的,步骤如下: 在任意单元格输入内容 选项卡里找到开发工具—插入—点击ActiveX控件的最右下角。 弹出的窗口内,往下滑动选择Microsoft BarCode Control 16.0后,点击确定。 在任意区域,摁住鼠标左键不放,拖动鼠标,

    2024年02月10日
    浏览(56)
  • Python Opencv实践 - 二维码和条形码识别

            使用pyzbar模块来识别二维码和条形码。ZBar是一个开源软件,用来从图像中读取条形码,支持多种编码,比如EAN-13/UPC-A、UPC-E、EAN-8、代码128、代码39、交错2/5以及二维码。         pyzbar是python封装ZBar的模块,我们用它来做条形码和二维码的识别。         安装方法:

    2024年02月04日
    浏览(47)
  • opencv实战--角度测量和二维码条形码识别

    首先导入一个带有角度的照片 然后下面的代码注册了一个鼠标按下的回调函数, 还有一个点的数列,鼠标事件为按下的时候就记录点,并画出点,由于点是画在图像上面的,那么就要求了img是需要刷新的所以将他们放在while True里面 当有按键按下的的时候就把图片归为原来的

    2024年02月16日
    浏览(61)
  • Android OpenCV(七十五): 看看刚”转正“的条形码识别

    2021年,我们写过一篇《OpenCV 条码识别 Android 平台实践》,当时的条形码识别模块位于 opencv_contrib 仓库,但是 OpenCV 4.8.0 版本开始, 条形码识别模块已移动到 OpenCV 主仓库,至此我们无需自行编译即可轻松地调用条形码识别能力。 Bar code detector and decoder moved from Contrib to main re

    2024年02月12日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包