裂缝二值图面积计算与个数检测

裂缝面积

总面积计算

这一部分主要面对网状裂缝,上一节判断裂缝走势的时候,我们就讲到了可以使用裂缝面积去衡量受损程度,而想网状裂缝这种明显需要修补的,其可以求解的也只有面积了。

请需要明白的是一点是这里统计计算的是图像像素个数,实际还要涉及到相机参数,本文这里暂不考虑。

import cv2
import numpy as np
import pyzjr as pz

path = r"D:\PythonProject\RoadCrack\dimension2_data\num\001.png"
img  = cv2.imread(path)
thresh = pz.BinaryImg(img)

image_array = np.array(thresh)
white_pixels = np.count_nonzero(image_array)
print(f"图像中裂缝(白色)的个数:{white_pixels}")

裂缝二值图面积计算与个数检测_第1张图片

图像中裂缝(白色)的个数:1831

后面我用ps统计了一次,与计算所得符合。np.count_nonzero这个函数是用于统计数组中非零元素的数量,在opencv中你可以使用cv2.countNonZero()进行替代,效果都是相同的。

每条裂缝面积

在这里我想采用大写字母和每条裂缝面积构成字典结构,在我看来这已经足够用了,毕竟如果裂缝多了那就怎么也得判断为网状裂缝。

import cv2
import numpy as np
import pyzjr as pz
from skimage import morphology
from skimage import measure

Bbox = pz.Boundingbox()

path = r"D:\PythonProject\RoadCrack\dimension2_data\num\046.png"
img  = cv2.imread(path)
thresh = pz.BinaryImg(img)

merge_threshold=3
area_threshold=50
connected_image = morphology.closing(thresh, morphology.disk(merge_threshold))
labeled_image = measure.label(connected_image, connectivity=2)
region_props = measure.regionprops(labeled_image)
area = {}
crack_label = ord('A')
for region in region_props:
    area_value = region.area
    if area_value >= area_threshold:
        if crack_label <= ord('Z'):
            area[chr(crack_label)] = area_value
            crack_label += 1

print(area)

{'A': 623, 'B': 781, 'C': 226}

在这里很轻松的就能判定每条裂缝的对应的面积。原图如下所示:

裂缝二值图面积计算与个数检测_第2张图片

这里原本是有四条的,但经过闭运算后,就将中间的两条合并在了一起。

label这个函数可以用于标记整数数组的连接区域,所以我们需要对图片进行二值化,我并不希望有其他的颜色混入,connectivity指考虑像素之间的连接性,这个可以看API里面是怎么解释的:

裂缝二值图面积计算与个数检测_第3张图片

很显然,我希望的是八连通的区域。

regionprops返回的是一个列表,其中的每个元素表示一个连通区域的属性。每个元素是一个对象,包含了与该连通区域相关的各种属性信息,例如面积、质心坐标、外接矩形框、周长等。

个数检测

个数检测就想对比较的简单了,因为我们已经求出了每条对应的裂缝面积,并用标签进行了标记。

len(area)

可视化

怎么在原图上显示呢?怎么检测到我所获得的是正确的呢?你可以想下面这样:

裂缝二值图面积计算与个数检测_第4张图片

A中间有一点小间隔,但实际经过闭运算后,这条裂缝是连接在一起的,而C裂缝虽然是分开的,但分开部分的面积小于了设定的50,所以也没有算进去。 

import cv2
import numpy as np
import pyzjr as pz
from skimage import morphology
from skimage import measure

Bbox = pz.Boundingbox()

path = r"D:\PythonProject\RoadCrack\dimension2_data\num\046.png"
img  = cv2.imread(path)
draw_img = img.copy()
thresh = pz.BinaryImg(img)

merge_threshold=3
area_threshold=50
connected_image = morphology.closing(thresh, morphology.disk(merge_threshold))
labeled_image = measure.label(connected_image, connectivity=2)
region_props = measure.regionprops(labeled_image)
area = {}
crack_label = ord('A')
for region in region_props:
    area_value = region.area
    if area_value >= area_threshold:
        minr, minc, maxr, maxc = region.bbox
        Bbox.putBoxText(draw_img, [minc, minr, maxc, maxr], chr(crack_label), mode=0)
        if crack_label <= ord('Z'):
            area[chr(crack_label)] = area_value
            crack_label += 1

print(area)
cv2.imshow("detect crack nums",draw_img)
cv2.waitKey(0)

你可能感兴趣的:(二维检测,计算机视觉,opencv,人工智能)