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

0、前言

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

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

1、解决步骤

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计算条形物体的长度_第1张图片

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计算条形物体的长度_第2张图片

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

利用OpenCV计算条形物体的长度_第3张图片

c. 4.2426406145095825 = 3*sqrt(2)

利用OpenCV计算条形物体的长度_第4张图片

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

利用OpenCV计算条形物体的长度_第5张图片

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

利用OpenCV计算条形物体的长度_第6张图片

f. 5.656854249492381 = 4 * sqrt(2)

利用OpenCV计算条形物体的长度_第7张图片

你可能感兴趣的:(CV数据处理,Python,opencv,opencv,计算机视觉,图像处理,计算长度)