균열의 2차원 검출: 균열 영역 및 균열 번호

이 글에서 소개하는

이 장의 목표는 균열 수를 감지하고 각 균열의 해당 면적을 계산하는 것입니다.

구현 아이디어

여기서는 여전히 함수 형태로 작성해야 합니다.결국 감지해야 할 2차원 데이터가 많습니다.여기서 균열 영역 감지를 나타내기 위해 이름을 detect_crack_areas로 지정했지만 동시에 균열 수를 반환할 수 있습니다. 매개변수는 이미지 img가 될 수 있다.게다가 크랙에 대한 바운딩박스를 그릴지 여부를 판단하고 싶어서 Bbox라는 bool 값을 주고 크랙 병합을 위한 거리 임계값을 주고 싶다. 또한 일부는 단절되어 있지만 실제로는 너무 작아 계산할 필요가 없으므로 크랙 영역 필터링을 위한 임계값도 있으며 이 매개 변수는 임계값보다 면적이 작은 크랙 영역을 필터링하는 데 사용됩니다.

암호

여기서 우리는 위의 아이디어를 실현하기 위해 단계별로 진행합니다.

첫 번째 단계: BGR 이미지를 이진 이미지로 변환하고 닫힌 작업을 수행합니다.

크랙 병합을 위한 거리 임계값, 여기서는 3을 제공합니다. 이 값은 CrackForest의 그림을 기반으로 한 내 테스트에서 얻습니다. morphology.square(), morphology.rectangle() 또는 morphology.disk()는 닫는 연산에 사용되는 구조적 요소의 한 형태로, 직접 해보셔야 합니다.

binary_image = pz.BinaryImg(img)
connected_image = morphology.closing(binary_image, morphology.disk(3))

2단계: 연결된 지역 표시 및 지역 속성 얻기

레이블 함수는 정수배열의 연결된 영역을 표시하는데 사용할 수 있으므로 이미지를 이진화해야 합니다. 다른 색상이 섞이는 것을 원하지 않습니다.

1-연결 2-연결 대각선 연결 클로즈업

     [ ] [ ] [ ] [ ] [ ]
      | \ | / | <- 홉 2
[ ]--[x]--[ ] [ ]--[x]--[ ] [x]--[ ]
      | / | \ 홉 1
     [ ] [ ] [ ] [ ]

분명히 내가 원하는 것은 8개의 연결 영역입니다.

regionprops는 각 요소가 연결된 영역의 속성을 나타내는 목록을 반환합니다. 각 요소는 면적, 중심 좌표, 경계 사각형, 둘레 등 연결된 영역과 관련된 다양한 속성 정보를 포함하는 객체입니다.

labeled_image = measure.label(connected_image, connectivity=2)
region_props = measure.regionprops(labeled_image)

3단계: 균열 표시

여기 마킹은 이해하기 쉽네요 간단하게 말씀드리자면 크랙에 대한 정보를 매일매일 알아야 하기에 이름을 붙여야겠네요 여기서는 대문자로 표기하겠습니다 보통의 경우 수평, 수직, 사선 크랙의 갯수는 그리 많지 않다고 생각합니다.

area = {}
crack_label = ord('A')

4단계: 골절 영역 필터링

for region in region_props:
    area_value = region.area
    if area_value >= 50:

균열이 정말 멀리 떨어져 있어도 너무 작아서 더 이상 균열이라고 생각할 필요가 없습니다.

5단계: 액자에 넣을지 여부

if Bbox:
    minr, minc, maxr, maxc = region.bbox
    pz.Boxcenter_text(img, [minc, minr, maxc, maxr], Z.green, chr(crack_label), Z.red, 0.7, 2)

영역이 필터링된 후 부울 값 Bbox를 사용하여 표시 여부와 대화 상자를 결정할 수 있습니다.

전체 텍스트 코드

import cv2
import pyzjr as pz
import pyzjr.Z as Z
from skimage import morphology
from skimage import measure

def detect_crack_areas(img, Bbox=True, merge_threshold=3, area_threshold=50):
    """
    检测裂缝区域并计算裂缝面积。
    morphology.square()、morphology.rectangle() 或者 morphology.disk()
    :param img: 输入图像。
    :param Bbox: 是否绘制边界框,默认为 True。
    :param merge_threshold: 裂缝合并的距离阈值,默认为 3。
    :param area_threshold: 裂缝面积过滤的阈值,默认为 50。
    :return: 裂缝面积的字典和裂缝数量。
    """
    binary_image = pz.BinaryImg(img)
    connected_image = morphology.closing(binary_image, 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 Bbox:
                minr, minc, maxr, maxc = region.bbox
                pz.Boxcenter_text(img, [minc, minr, maxc, maxr], Z.green, chr(crack_label), Z.red, 0.7, 2)
            if crack_label <= ord('Z'):
                area[chr(crack_label)] = area_value
                crack_label += 1
    if Bbox:
        cv2.imshow("Image with Bounding Boxes", img)
        cv2.waitKey(0)

    CrackNum = len(area)
    return area, CrackNum

if __name__=="__main__":
    file_path = r"E:\pythonconda2\dimension2_data\num"
    img_paths = pz.getPhotopath(file_path)
    for img_path in img_paths:
        img = cv2.imread(img_path)
        area, CrackNum = detect_crack_areas(img, False)
        print(f"图片{img_path[-7:]}裂缝个数为{CrackNum},裂缝的面积为:{area}")

여기서 우리는 Bbox가 False로 설정된 그림의 마킹을 봅니다.

다음과 같이 수정할 수 있습니다.

if __name__=="__main__":
    img_path = r"E:\pythonconda2\dimension2_data\num\046.png"
    img = cv2.imread(img_path)
    area, CrackNum = detect_crack_areas(img)
    print(f"裂缝个数为{CrackNum},裂缝的面积为:{area}")

마크 A의 상황을 설명드리자면 중간에 약간의 틈이 있지만 실제 닫힘 작업 후 크랙이 서로 연결되어 크랙 C는 분리되지만 분리된 부분의 면적은 세트 50보다 작아서 포함하지 않습니다. 

Supongo que te gusta

Origin blog.csdn.net/m0_62919535/article/details/131919958
Recomendado
Clasificación