Python, OpenCV에서 윤곽 검출을 시도

전제 조건



우분투 18.04
파이썬 2.7
OpenCV 3.3

할 일



Python의 OpenCV를 사용하여 고양이 이미지의 윤곽 감지를 시도합니다.

이번 흐름



0. 전처리
1. 이미지 로드
2.네가 포지 반전
3. 그레이 스케일링
4.2 값화
5. 등고선 작성
6. 이미지 표시
7. 이미지 저장
8. 정리
9. 라벨이 있는 Bounding Box 만들기

실제로 해보자



0. 전처리



라이브러리를 가져옵니다.

python2
import cv2

1. 이미지 로드



두 번째 인수를 1로 설정하여 컬러 이미지로 로드합니다.
이번에는 같은 폴더에있는 sample_000.jpg라는 이미지를 사용합니다.

python2
img_origin = cv2.imread('./sample_000.jpg', 1)

2.네가 포지 반전



2-4에서는 고양이와 배경의 경계를 밝히기 위한 화상 처리를 실시해 갑니다.
cv2.bitwise_not() 를 이용해 색의 반전을 실시합니다.

python2
img = cv2.bitwise_not(img_origin)



3. 그레이 스케일링



반전한 이미지를 한층 더 흰색과 검정, 회색으로 표현합니다. (그레이 스케일링)

python2
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)



4.2 값화



어떤 색을 기준으로 흑백으로 표현해 경계를 밝힙니다.

python2
ret, img_binary = cv2.threshold(img_gray, 150, 255,cv2.THRESH_BINARY)



5. 등고선 작성



이진화된 이미지를 기반으로 경계를 만듭니다.
이번에는 경계 안에 존재하는 경계는 경계로 간주되지 않도록 처리했습니다.

python2
contours, hierarchy = cv2.findContours(img_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
img_contour = cv2.drawContours(img_origin, contours, -1, (0, 255, 0), 5)



6. 이미지 표시



작성한 경계를 원의 화상에 덧쓰기해 표시합니다.
cv2.waitKey()를 사용하여 일정 시간 계속 표시합니다.
일정 시간이 표시되면 자동으로 이미지가 사라지므로 시간을 조정하십시오.

python2
cv2.imshow("img_edge",img_contour)
cv2.waitKey(10000)
cv2.destroyAllWindows()

7. 이미지 저장



만든 이미지를 같은 폴더에 저장합니다.

python2
cv2.imwrite("./img_edge.jpg",img_contour)

8. 정리



0-7까지의 공정을 실시해, 고양이의 윤곽을 검출, 표시할 수 있었습니다.
그러나 배경 이미지에서도 윤곽을 검출해 버리고 있기 때문에, 필터를 거는 등의 추가 처리가 필요합니다.
이번은 여기까지입니다만, 추가로 고양이를 사각형으로 둘러싸는 처리를 9로 실시하고 있으므로 신경이 쓰이는 분은 봐 주세요.

python2
import cv2
from matplotlib import pyplot as plt


img_origin = cv2.imread('sample_000.jpg', 1)

img = cv2.bitwise_not(img_origin)

img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, img_binary = cv2.threshold(img_gray, 150, 255,cv2.THRESH_BINARY)

contours, hierarchy = cv2.findContours(img_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

img_contour = cv2.drawContours(img_origin, contours, -1, (0, 255, 0), 5)

cv2.imshow("edge",cv2.cvtColor(img_contour, cv2.COLOR_BGR2RGB))
cv2.waitKey(10000)
cv2.destroyAllWindows()

cv2.imwrite("./img_contour.jpg",img_contour)

9. 라벨이 있는 Bounding Box 만들기



다음 처리를 다음 처리로 다시 작성하십시오.
특정 일정 이상의 면적을 둘러싸는 사각형을 만들 수 있습니다.
또한 이번에는 왼쪽 상단에 neko라는 라벨을 추가하고 있습니다.

python2
img_contour = cv2.drawContours(img_origin, contours, -1, (0, 255, 0), 5)

python2
area_num = 10000
contours_filtered = list(filter(lambda x: cv2.contourArea(x) > area_num, contours))

for i in contours_filtered:
    x,y,width,height = cv2.boundingRect(i)
    cv2.rectangle(img_origin, (x,y),(x+width, y+height), color = (0,255,0), thickness =2 )
cv2.putText(img_origin,'neko',(x+10,y+10), cv2.FONT_HERSHEY_PLAIN, 1,(0,0,0),1,cv2.LINE_AA)
cv2.imwrite("./img_origin.jpg",img_origin)

좋은 웹페이지 즐겨찾기