Watershed Algorithm for marker-based image segmentation
Watershed 알고리즘을 사용하여 이미지 세그멘테이션을 수행
이미지 세그멘테이션
이미지에서 특정 객체 또는 물체를 식별하고 분할하는 프로세스를 의미
Watershed 알고리즘
이미지를 일종의 지형 표면으로 해석하여, 물이 지형에서의 골짜기를 따라 내려가듯이 이미지에서 낮은 부분을 채워가며 객체를 분리
여기 물에 잠겨있는 동전들이 있는 이미지 이다.
# Load image
img = cv2.imread('water_coins.jpg')
imshow("Original image", img)
# Grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Threshold using OTSU
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
imshow("Thresholded", thresh)
grayscale 후 Otsu 방식을 이용해서 이진화를 했다.
사람은 원본 이미지나 이진화 된 이미지를 보아도 동전의 개수가 몇개인지 셀수 있지만
컴퓨터는 저런 이어진 부분으로 인해 저 물체들이 다른거라고 인식하지 못한다.
이것처럼 Watershed 알고리즘은 이미지 세그멘테이션을 향상시키기 위해 사용되며
아래와 같은 상황에서 사용된다.
물체 분리: 이미지에서 서로 붙어있는 물체를 분리하는 데 사용
배경 제거: 이미지에서 원하는 객체를 강조하고 배경을 제거하는 데 사용
물체 인식 및 추적: 이미지에서 특정 물체를 인식하고 추적하는 데 사용
의료 영상 및 생물학적 영상: 의료 영상에서 조직이나 세포 등을 분할하거나, 생물학적 영상에서 세포핵을 식별하는 데 사용
그렇다면 우선 저 닿아서 경계가 애매한 것들을 없애주자.
# noise removal
kernel = np.ones((3,3), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN,kernel, iterations = 2)
# sure background area
sure_bg = cv2.dilate(opening, kernel, iterations=3)
# Finding sure foreground area
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2,5)
ret, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0)
# Finding unknown region
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)
imshow("SureFG", sure_fg)
imshow("SureBG", sure_bg)
imshow("unknown", unknown)
# Marker labelling
# Connected Components determines the connectivity of blob-like regions in a binary image.
ret, markers = cv2.connectedComponents(sure_fg)
# Add one to all labels so that sure background is not 0, but 1
markers = markers+1
# Now, mark the region of unknown with zero
markers[unknown==255] = 0
markers = cv2.watershed(img,markers)
img[markers == -1] = [255,0,0]
imshow("img", img)
Connected Components를 사용하여 마커 생성:
cv2.connectedComponents() 함수를 사용하여 확실한 전경 영역(sure_fg)을 기반으로 이미지에서 연결된 컴포넌트를 찾아 마커를 생성
반환된 markers 배열에는 각 픽셀이 속한 컴포넌트에 대한 레이블이 포함
Watershed 알고리즘 적용:
cv2.watershed() 함수를 사용하여 이미지와 수정된 마커를 입력으로 하여 Watershed 알고리즘을 적용, 이를 통해 마커가 업데이트되고, 각 물체의 경계는 -1로 표시
-1인 픽셀은 BGR[255,0,0] 이므로 파란색으로 표시