
안녕하세요. 오늘은 Instance Segmentation 정보를 이용해 시각화하는 방법을 공부하려고 합니다.
OpenCV에서는 Polygon 정보를 이용해 이미지 시각화하는데 유용한 API입니다.
따라서 이번 장에서는 OpenCV를 이용해 시각화 하는 방법을 공부하겠습니다.
OpenCV를 이용해 Segmentation 시각화를 진행하려면 우선 Polygon에 대해 알 필요가 있습니다.
Polygon을 직역하자면, '다각형'이라는 의미입니다.

보통 CV(Computer Vision)에서는 Polygon 좌표라는 말을 많이 사용합니다. 이는 다각형을 그리기 위한 좌표를 의미합니다.
import cv2
img_array = cv2.polylines(img_array, pts, True, (0, 255, 0), 1)

OpenCV의 polylines 메서드를 이용하면 Polygon 좌표를 이용해 다각형을 시각화 할 수 있습니다.
polylines 메서드의 주요 인자는 다음과 같습니다.
Parameter
- img: 이미지 array
- pts: polygon 좌표 [[x1, y1], [x2, y2], [x3, y3], ...] 형태
- isClosed: 다각형이 열린 다각형인지 닫힌 다각형인지 판별
- color: 선 색깔
- thickness: 선 두께
- lineType: 선 유형(cv2.FILLED, cv2.LINE_4, cv2.LINE_8, cv2.LINE_AA)
import cv2
img_array = cv2.fillPoly(img_array, pts, (0, 255, 0))

fillPoly 메서드를 이용하면 기존 line을 그려준 Polylines 메서드와는 다르게 Polygon 내부를 채워줍니다.
fillPoly 메서드의 주요 인자는 다음과 같습니다.
Parameter
- img: 이미지 arrray
- pts: polygon 좌표 [[x1, y1], [x2, y2], [x3, y3], ...] 형태
- color: 내부를 채울 색깔(1이 들어가면 gray image인 경우 1 pixel, RGB인 경우 (1, 1, 1)이 들어감)
- lineType: 경계 선 유형(cv2.FILLED, cv2.LINE_4, cv2.LINE_8, cv2.LINE_AA)
fillPoly 메서드를 이용하면 이미지에서 mask 정보만 그릴 수도 있습니다.
import cv2
# zero_array는 0으로만 채워진 array
mask_img = cv2.fillPoly(zero_array, pts, 1)

import cv2
contours, hierarchy = cv2.findContours(s_mask_int, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
findContours 메서드를 이용하면 입력된 이진 마스크 이미지에서 윤곽선을 찾아줍니다.
바로 위에서 살펴본 마스크 이미지를 예로 들어볼 수 있습니다.
이때, 반환되는 값은 contours, hierarchy로 두개입니다. 이는 각각 선택적으로 검출된 윤곽선을 저장한 배열, 선택적으로 윤곽선의 계층 구조를 저장한 배열입니다.
findContours 메서드의 주요 인자는 다음과 같습니다.
Parameter
- image: 윤관선을 찾을 이미지 (보통 mask 정보(이진 array)로 입력됨)
- mode: 윤곽선을 찾는 방법을 지정하는 플래그 (cv.RETR_EXTERNAL, cv2.RETR_LIST, cv2.RETR_CCOMP, cv2.RETR_TREE, cv2.RETR_FLOODFILL)
- method: 윤곽선을 근사화 하는 방법을 지정하는 플래그 (cv2.CHAIN_APPROX_NONE, cv2.CHAIN_APPROX_SIMPLE, cv2.CHAIN_APPROX_TC89_L1, cv2.CHAIN_APPROX_TC89_KCOS)
import cv2
masked_image = cv2.drawContours(draw_img, contours, -1, (255, 0, 0), 1, cv2.LINE_8, hierarchy, 100)

drawContours 메서드를 이용하면 이렇게 반환된 contours, hierarchy를 통해 이미지에 마스크를 씌울 수 있습니다.
drawContours 메서드의 주요 인자는 다음과 같습니다.
Parameter
- image: 그릴 이미지 array
- contours: polygon 좌표 (앞에서 구한 contours)
- contouridx: 그릴 contour index (-1이면 전체 다 그려줌)
- color: 선 색깔
- thickness: 선 두께 (-1이면 내부까지 다 채움)
- lineType: 선 유형 (cv2.FILLED, cv2.LINE_4, cv2.LINE_8, cv2.LINE_AA)
- hierarchy: 앞에서 구한 hierarchy 배열
- maxLevel: hierarchy가 있을 때 유용한 파라미터로, 몇 단계의 윤곽선까지 그릴지 정하는 플래그(-1이면 모두 그림)
이번 장에서는 OpenCV를 이용해서 마스크 정보를 통해 그림 그리는 법을 공부했습니다.
색이 진한 것이 마음에 들지 않다면, 알파 블렌딩과 같은 기법을 동원해도 좋을 것 같습니다.
비트연산이라고 대학교 1학년에 이산수학에서 들어본 것 같긴합니다..
시각화라고 말할 순 없지만, bitwise를 통해 mask 시각화도 가능하기 때문에 공부하려고 합니다.
대표적인 비트연산으로 AND, NOT, OR, XOR 연산이 있습니다.
비트연산 AND: 모두 참일 때, 참 나머지는 거짓
비트연산 NOT: 참이면 거짓, 거짓이면 참
비트연산 OR: 둘중 하나라도 참일 때, 참 나머지는 거짓
비트연산 XOR: 둘중 하나만 참일 때, 참 나머지는 거짓
import cv2
and_array = cv2.bitwise_and(img_array, img_array, mask=mask)

bitwise_and 메서드를 이용하면 비트연산 AND를 사용할 수 있습니다.
다만, 일반적인 비트연산 AND와 다른 점은 인자로 들어오는 arr1과 arr2의 이미지가 같은 경우가 참이고, 나머지가 거짓이라는 점입니다.
주요 인자는 다음과 같습니다.
Parameter
- src1: 첫번 째 이미지 array
- src2: 두번 째 이미지 array
- mask: mask array(mask에서 1인 부분(참인 부분)에 대해서만 비트연산 진행, 나머지는 0으로 반환)
import cv2
not_array = cv2.bitwise_not(array1)
bitwise_not 메서드를 이용하면 비트연산자 NOT을 사용할 수 있습니다.
주요 인자는 다음과 같습니다.
Parameter
- src: 이미지 array
- mask: mask array(이미지가 gray인 경우 해당되는 부분은 255 - x를 적용. RGB인 경우, 보색으로 적용)
import cv2
and_array = cv2.bitwise_or(array1, array2, mask=mask)
bitwise_or 메서드를 이용하면 비트연산자 OR를 사용할 수 있습니다.
주요 인자는 다음과 같습니다.
Parameter
- src1: 첫번 째 이미지 array
- src2: 두번 째 이미지 array
- mask: mask array(mask에서 1인 부분(참인 부분)에 대해서만 비트연산 진행, 나머지는 0으로 반환)
import cv2
and_array = cv2.bitwise_xor(array1, array2, mask=mask)
bitwise_xor 메서드를 이용하면 비트연산자 XOR를 사용할 수 있습니다.
주요 인자는 다음과 같습니다.
Parameter
- src1: 첫번 째 이미지 array
- src2: 두번 째 이미지 array
- mask: mask array(mask에서 1인 부분(참인 부분)에 대해서만 비트연산 진행, 나머지는 0으로 반환)