728x90
728x90
모폴로지 변환의 팽창(dilation)과 침식(erosion)을 기본 연산으로 사용해
고급 형태학을 적용하는 변환 연산
입력 이미지가 이진화된 이미지라면 팽창과 침식 연산으로도 우수한 결과를 얻을 수 있다.
하지만, 그레이스케일이나 다중 채널 이미지를 사용하는 경우 더 복잡한 연산을 필요
▪ 모폴로지(Morphology) 연산이란?
• 영상을 형태학적인 측면에서 다루는 기법
• 다양한 영상 처리 시스템에서 전처리(pre-processing) 또는 후처리(post-processing)
형태로 널리 사용
• 수학적 모폴로지(mathematical morphology)
▪ 구조 요소(Structuring element)
• 모폴로지 연산의 결과를 결정하는 커널, 마스크, 윈도우
# 만약 세로방향으로만 침식 or 팽창 하고싶다면
# ksize(가로, 세로) 가로를 작게하고 세로를 크게
# kernel
se = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 3))
'''
cv2.MORPH_RECT 사각형 모양
cv2.MORPH_CROSS 십자가 모양
cv2.MORPH_ELLIPSE 사각형에 내접하는 타원
'''
dst1 = cv2.erode(src, se)
dst2 = cv2.dilate(src, None)
침식 Erosion
구조 요소가 객체 영역 내부에 완전히 포함될 경우 고정점 픽셀을 255로 설정
객체 크기는 감소 & 배경은 확대
- 작은 크기의 객체(잡음=noise)제거
- 객체 내부의 홀(구멍)이 점점 커짐
팽창 Dilation
구조 요소와 객체 영역이 한 픽셀이라도 만날 경우 고정점 픽셀을 255로 설정
객체 크기는 증가& 배경은 감소
- Noise가 커진다
- 객체 내부의 홀(구멍)이 채워짐
열림(Opening)
opening = dilate(erode(src))
# cv2.morphologyEx
cv2.morphologyEx(원본 배열, 연산 방법, 구조 요소, 고정점, 반복 횟수, 테두리 외삽법, 테두리 색상)
opening = cv.morphologyEx(thresh, cv.MORPH_OPEN, kernel, iterations=5)
src = cv2.imread('ch07\\images\\rice.png', cv2.IMREAD_GRAYSCALE)
if src is None:
print('Image load failed!')
sys.exit()
dst1 = np.zeros(src.shape, np.uint8)
bw = src.shape[1] // 4
bh = src.shape[0] // 4
# adaptiveThreshold 사용해도 되는데 느림
for y in range(4):
for x in range(4):
src_ = src[y*bh:(y+1)*bh, x*bw:(x+1)*bw]
dst_ = dst1[y*bh:(y+1)*bh, x*bw:(x+1)*bw]
cv2.threshold(src_, 0, 255, cv2.THRESH_OTSU, dst_)
cnt1, _ = cv2.connectedComponents(dst1)
print('cnt1:', cnt1)
dst2 = cv2.morphologyEx(dst1, cv2.MORPH_OPEN, None)
# open = 보통 noise를 제거할 때 사용
#dst2 = cv2.erode(dst1, None)
#dst2 = cv2.dilate(dst2, None)
cnt2, _ = cv2.connectedComponents(dst2)
print('cnt2:', cnt2)
'''
cv2.connectedComponents(image, labels=None, connectivity=None,
ltype=None) -> retval, labels
흰색 덩어리의 개수를 정수 형태로 return( retval, labels)
retval 덩어리 개수 + 1 의 형태로 나옴
labels = np.ndarray 나오고 각 덩어리에 label 값부여됨
'''
cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.waitKey()
침식 연산을 적용한 다음, 팽창 연산을 적용
침식 연산으로 인해 밝은 영역이 줄어들고 어두운 영역이 늘어난다.
opening = 줄어든 영역을 다시 복구하기 위해 팽창 연산을 적용하면 반대로 어두운 영역이
줄어들고 밝은 영역이 늘어남
스펙클(speckle)이 사라지면서 발생한 객체의 크기 감소를 원래대로 복구
= 노이즈를 제거하는데 유용
닫힘(Closing)
closing = erode(dilate(src))
closing = cv.morphologyEx(thresh, cv.MORPH_CLOSE, kernel, iterations=5)
팽창 연산을 적용한 다음, 침식 연산을 적용
팽창 연산으로 인해 어두운 영역이 줄어들고 밝은 영역이 늘어난다.
closing = 늘어난 영역을 다시 복구하기 위해 침식 연산을 적용하면 밝은 영역이 줄어들고
어두운 영역이 늘어남
객체 내의 작은 구멍이나 검은 점을 없애는데 도움
Gradient(Edge 반환)
gradient = dilate(erode(src)) - erode(dilate(src))
gradient = cv.morphologyEx(thresh, cv.MORPH_GRADIENT, kernel, iterations=1)
팽창 연산자와 침식 연산자의 조합
입력 이미지에 객체의 가장자리가 반환 = iterations= 낮을 수록 edge 반환
* 연산 방법( op )
cv2.MORPH_DILATE | 팽창 연산 |
cv2.MORPH_ERODE | 침식 연산 |
cv2.MORPH_OPEN ( O ) | 열림 연산 |
cv2.MORPH_CLOSE ( O ) | 닫힘 연산 |
cv2.MORPH_GRADIENT ( O ) | 그레이디언트 연산 |
cv2.MORPH_TOPHAT | 탑햇 연산 |
cv2.MORPH_BLACKHAT | 블랙햇 연산 |
cv2.MORPH_HITMISS | 히트미스 연산 |
728x90
'OpenCV > OpenCV-basic' 카테고리의 다른 글
특징 검출 (0) | 2021.12.24 |
---|---|
이미지 연산, 배열 정합(addWeighted) (0) | 2021.12.12 |
opencv-VideoCapture, VideoWriter (0) | 2021.12.11 |
opencv-HSV, YCrCb(특정 색 추출) (0) | 2021.12.11 |
opencv-findContours (0) | 2021.12.11 |
댓글