Two-dimensional crack detection: crack skeleton map extraction

Refinement Algorithm Selection and Analysis

It is very necessary to extract the skeleton of the crack. If we can get the skeleton diagram of the crack, it is easy to get the length of the whole crack. Current classic thinning algorithms, such as Zhang parallel thinning algorithm, Hilditch thinning algorithm, Rosenfeld thinning algorithm, etc., are widely used in skeleton extraction algorithms.

Among them, the Zhang parallel thinning algorithm has a simple thinning process and is also the most widely used one. After thinning, the skeleton is located on the center line of the image, but the resulting image often has many protrusions and glitches. Hilditch is based on the binarized image, and the skeleton is extracted by combining serial and parallel methods. Although the refinement effect is good, the algorithm's judgment conditions are complicated and redundant, resulting in a long processing time. Considering these factors, Hilditch is not used. Rosenfeld is a thinning algorithm based on boundary tracking. Compared with algorithms such as Zhang-Suen and Hilditch, Rosenfeld algorithm is also widely used in skeleton extraction. It usually produces a relatively smooth skeleton with fewer protrusions and burrs.

This article uses the Zhang-Suen algorithm integrated by skimage.

install skimage

pip install scikit-image -i https://pypi.tuna.tsinghua.edu.cn/simple

picture selection

At present, my own data set has not been completed. Here I use CrackForest as an example, which is a deep learning algorithm and data set for crack (crack) detection and segmentation. You can find it by searching for crack forest on kaggle.

The first thing that needs to be explained is that it is marked with matlab, so it is a file with the suffix mat. You can use the script below to convert a file with a suffix of mat into a picture with a suffix of png.

# Mat2png.py

from os.path import isdir
from scipy import io
import os, sys
import numpy as np
from PIL import Image

if __name__ == '__main__':
    file_path = './groundTruth/'
    png_img_dir = './groundTruthPngImg/'
    if not isdir(png_img_dir):
        os.makedirs(png_img_dir)
    image_path_lists = os.listdir(file_path)
    images_path = []
    for index in range(len(image_path_lists)):
        image_file = os.path.join(file_path, image_path_lists[index])
        # print(image_file)#./CrackForest-dataset-master/groundTruth/001.mat
        images_path.append(image_file)
        image_mat = io.loadmat(image_file)
        segmentation_image = image_mat['groundTruth']['Segmentation'][0]
        segmentation_image_array = np.array(segmentation_image[0])
        image = Image.fromarray((segmentation_image_array - 1) * 255)
        png_image_path = os.path.join(png_img_dir, "%s.png" % image_path_lists[index][0:3])
        image.save(png_image_path)

You only need to modify the file location and save location. Then, we can go to groundTruthPngImg to see how our label map looks.

080.png

Next, we can save the converted pictures to other folders. Subsequently, we need to perform skeleton extraction on these images. I've tried to research and write the Zhang-Suen algorithm for skeleton extraction by myself before, but I keep getting errors. Later, I found some existing code on GitHub, but I also encountered problems such as timeouts during runtime. Fortunately, I later found that the skeleton extraction algorithm has been integrated in the skimage library, and after testing, I found it very easy to use and stable. So I plan to use the extraction algorithm in skimage to complete the skeleton extraction task, which can avoid cumbersome error handling and timeout problems, and also ensure the reliability and efficiency of the algorithm.

Skeleton extraction test

The image format here should be an RGB image, otherwise an error will be reported in the subsequent binarization.

import numpy as np
from skimage.filters import threshold_otsu,median
from skimage.morphology import skeletonize,dilation,disk
import os
import cv2
from skimage import io, morphology

def sketion(mode='multifile', input_folder='num', output_folder='output', single_pic='num/001.png'):
    """
    :param mode: 检测模式——single_pic检测单张图片并保存,multifile检测多张图片并保存
    :param input_folder: 目标文件夹
    :param output_folder: 输出文件夹
    :param single_pic: 用于检测单张图片的路径
    :return: 返回输出文件夹的路径的骨架图
    """
    if mode == 'single':
        image = io.imread(single_pic, as_gray=True)
        # 使用Otsu阈值方法进行二值化处理
        thresh = threshold_otsu(image)
        binary = image > thresh
        skeleton = skeletonize(binary)
        io.imshow(skeleton)
        io.imsave('output.png', skeleton)
        io.show()


    elif mode == 'multifile':
        if not os.path.exists(output_folder):
            os.makedirs(output_folder)  # 如果输出文件夹不存在,就创建它

        for filename in os.listdir(input_folder):
            if filename.endswith('.jpg') or filename.endswith('.png'):
                image = io.imread(os.path.join(input_folder, filename), as_gray=True)

                thresh = threshold_otsu(image)
                binary = image > thresh
                binary = dilation(binary, disk(3))
                binary = median(binary, selem=morphology.disk(5))
                # 效果不错
                binary = dilation(binary, disk(2))
                binary = median(binary, selem=morphology.disk(5))
                # 添加闭运算
                selem = morphology.disk(3)
                binary = morphology.closing(binary, selem)

                skeleton = skeletonize(binary)
                output_filename = os.path.join(output_folder, filename)
                io.imsave(output_filename, skeleton)

        return output_folder

You can use the above code to detect the effect of a single image. Choose single, because it has been written for a long time. Here I will only mention one point. In the multi-file part, you can see that after binarization, I have undergone several times of expansion and median filtering. You can choose the filter yourself. After testing, I found that using median filtering has a better effect on eliminating glitches.

Let me take the 001.png detected by single as an example:

The 001.png image obtained after my multi-file detection:

The combination here requires everyone to test their own data sets, so that good data can be obtained in the later two-dimensional detection.

Guess you like

Origin blog.csdn.net/m0_62919535/article/details/131909413