사람의 인체 모양을 인식하고 어떠한 판단을 내리기 위해서는 신체에 윤곽선을 그리고, 해당 윤곽선에 대한 좌표 데이터를 획득해야 한다.
이러한 목표를 성취하기 위해서 첫 번째로 해야 할 작업은 이미지 안에 특정 사물의 윤곽선을 그리는 것부터 시작한다.
이 글은 파이썬의 이미지 처리 라이브러리인 OpenCV를 통해서 이미지 내 윤곽선을 검출하는 방법을 기술한다.
앞서 작성한 OpenCV의 설명을 보자면 OpenCV는 이미지를 흑백으로 변경을 하거나 이미지의 특정 위치의 좌표값을 얻는 등 여러 처리를 할 수 있는 라이브러리다.
해당 라이브러리를 사용하여 윤곽선을 검출하기 위해 과정을 단계별로 나누자면
- 이미지의 윤곽선을 검출하는 과정
- 이미지 회색 처리
- 이미지 바이너리 처리
- 위 모든 과정을 거친 이미지의 윤곽선 검출
- 해당 윤곽선 이미지에 그리기
위와 같은 단계를 거친다.
1. 이미지 회색 처리
img = cv2.imread('card.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
- cv2.cvtColor() 는 이미지를 특정 색상으로 변환해준다.
- 첫 번째 파라미터로 이미지를 삽입하고 두 번째 파라미터로 색상 변환 방법을 삽입한다.
- cv2.COLOR_BGR2GRAY 는 기존 BGR 방식의 색상에서 회색계열로 이미지를 변환한다는 의미이다.
2. 이미지 바이너리 처리
ret, otsu = cv2.threshold(gray, -1, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
- 이미지를 바이너리(이진화) 시키면 픽셀 값은 0과 255만 갖게 할 수 있기 때문에 흰색과 검은색만 존재하게 할 수 있다.
- 흰색과 검은색만 이루어진 이미지를 윤곽선 검출하기가 수월하기 때문에 이 과정을 꼭 거쳐야 한다.
- cv2.threshold() 함수는 여러 개의 숫자 값을 특정한 임계값을 기준으로 두 가지 값으로 나누어 정의하는 함수이다.
- cv2.threshold(image, threshold, value, type_flag)
=> image: 변환할 이미지, 이미지가 픽셀 값으로 변환되어 들어간다.
=> threshold: 임계값, 우리는 해당 임계값을 오츠 알고리즘이라는 것을 이용하여 자동으로 탐색할 것이기 때문에
-1을 넣어주면 된다.
=> value: threshold에 기입한 임계값의 특정 조건에 만족하면 변환할 값
=> type_flag: 이진화 적용 방법, cv2.THRESH_BINARY는 픽셀 값이 임계값을 넘으면 value로 지정하고,
넘지 못하면 0으로 지정하는 방법이다.
해당 파라미터로 OR 조건으로 cv2.THRESH_OTSU 도 함께 기입할 시 오츠 알고리즘이 적용된다.
- 오츠 알고리즘이란?
=> 이미지의 픽셀을 보고 이미지의 색상이 두 부류로 나뉘었을 때
그림의 명암 분포가 가장 균일할 때의 임계값을 자동으로 계산하여 선택하는 알고리즘이다.
3. 위 모든 과정을 거친 이미지의 윤곽선 검출
contours, hierarchy = cv2.findContours(otsu, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
- 앞서 변환한 바이너리 이미지에 대해 윤곽선을 검출한다.
- contours 에 검출한 윤곽선의 좌표값들이 들어가기에, 윤곽선에 대한 작업 진행 시 이 변수를 적극 활용하면 된다.
- cv2.findContours(image, mode, method)
=> image: 입력 이미지
=> mode: 윤곽선 검출 모드
- cv2.RETR_EXTERNAL : 가장 외곽의 윤곽선만 찾음
- cv2.PETR_LIST : 모든 윤곽선 찾음
=> method: 윤곽선 좌표값 반환 방법
- APPROX_NONE: 윤곽선의 모든 좌표를 반환
- APPROX_SIMPLE: 윤곽선의 꼭짓점 좌표만 반환
- 윤곽선이 단순한 경우, 예를 들어 사각형인 경우에는 APPROX_SIMPLE을 사용하는 것이 메모리 성능에도
효율적일 것이다.
4. 해당 윤곽선 이미지에 그리기
COLOR = (0, 200, 0) # 녹색
cv2.drawContours(img, contours, -1, COLOR, 2)
# cv2.drawContours(이미지, 윤곽선 정보, 인덱스, 색상, 두께)
# 인덱스가 -1이면 전체
- 초록색에 두께 2로 전체 윤곽선을 이미지에 그린다.
※ 결과

'Python > OpenCV' 카테고리의 다른 글
[OpenCV] 이미지의 특정 위치 좌표 추출 (0) | 2024.02.21 |
---|---|
[OpenCV] 이미지 합성 (0) | 2024.02.08 |
[OpenCV] OpenCV 미니 창에 마우스 이벤트 처리하기 (0) | 2023.12.30 |
[OpenCV] OpenCV를 이용하여 동영상 출력 (2) | 2023.12.19 |