裂缝面积
总面积计算
这一部分主要面对网状裂缝,上一节判断裂缝走势的时候,我们就讲到了可以使用裂缝面积去衡量受损程度,而想网状裂缝这种明显需要修补的,其可以求解的也只有面积了。
请需要明白的是一点是这里统计计算的是图像像素个数,实际还要涉及到相机参数,本文这里暂不考虑。
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}")
图像中裂缝(白色)的个数: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}
在这里很轻松的就能判定每条裂缝的对应的面积。原图如下所示:
这里原本是有四条的,但经过闭运算后,就将中间的两条合并在了一起。
label这个函数可以用于标记整数数组的连接区域,所以我们需要对图片进行二值化,我并不希望有其他的颜色混入,connectivity指考虑像素之间的连接性,这个可以看API里面是怎么解释的:
很显然,我希望的是八连通的区域。
regionprops返回的是一个列表,其中的每个元素表示一个连通区域的属性。每个元素是一个对象,包含了与该连通区域相关的各种属性信息,例如面积、质心坐标、外接矩形框、周长等。
个数检测
个数检测就想对比较的简单了,因为我们已经求出了每条对应的裂缝面积,并用标签进行了标记。
len(area)
可视化
怎么在原图上显示呢?怎么检测到我所获得的是正确的呢?你可以想下面这样:
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)