getSturucturingElement - 첫 번쨰 파라미터는 배열의 모양을 뜻한다 - RECT의 경우 배열에서 1을 사각형 모양으로 채운다 - CROSS의 경우 배열에서 1을 십자 모양으로 채운다 - ELLIPSE의 경우 배열에서 1을 타원 모양으로 채운다( 육각형에 가깝다 ) - 두 번째 파라미터는 배열의 크기를 뜻한다 아래 그림을 보다시피 RECT (11,11)의 경우 배열의 크기가 각각 가로 세로 11, 11 인것을 볼 수 있다
다음에는 이번 장에서 학습한 내용을 가지고 배경추출에 대해서 알아보겠다
기존 1D Histogram을 그릴 때와 변경된 부분은 4번째 파라미터인 x축 간격이 2개의 값을 넘겨 x와 y축으로 변경되었고 5번째 파라미터인 축의 범위또한 x, y 각각 0~360 , 0~256의 범위로 설정되었다
1D 일 때는 ply.plot으로 그래프를 그렸지만 2D에서는 imshow를 통해 보였다 그 이유는 1D에서는 각 그 값에 해당하는 픽셀의 개수를 표현했지만 2D에서는 H일 때 S 픽셀이 있나 를 표현해서 0, 1 의값이 리턴된다 그렇기 때문에 plot으로 2D를 그리면 0과 1만 표현된다
hist의 결과값은 H, S 2개의 값이 리턴되기 때문에 shape이 (360,256)이 된다 위에 가운데 사진에 보다시피 imshow로 보였을 때 잘 구분이 되지 않는다
좀더 보기 쉽게 np.stack을 통해 RGB 같은 (360,256,3)의 shape으로 변경하였다
여기서 의문이 생긴다 각 값이 0과 1로 표현됐는데 왜 결괏값으로 보이는 이미지는 왜 검은색과 하얀색으로 표현되나 하얀색은 255가 아닌가? matplotlib.pyplot에서 0과 1로 되어있는 데이터는 자동으로 0,255로 변경해준다
자 이제 나온 결과값을 해석해 보자
세로의 값은 Hue를 뜻한다 (100,110) 정도에 점이 찍혀있다 그 뜻은 Hue:110, Saturation:100이란 뜻이므로 약간 어두운 초록색 부분이 많다는 뜻이다 사진에서 숲의 영역을 뜻한다
또한 H:160~250 S:150~200 까지의 부분에 점이 몰려있다 그 뜻은 밝은 하늘색이 다양한 밝기와 색상으로 존재한다는 뜻이다 사진에서 바다와 하늘을 뜻한다
위의 코드에서 주석처리된 부분에 cvt color 부분을 주석 처리한 이유는 opencv는 기본적으로 모든 색상 순서가 BGR로 되어있다. 그래서 변환 없이 바로 imshow로 보여주면 bgr을 bgr로 보여주기 때문에 cv2.imshow를 할 때는 ctvCOLOR를 이용할 이유가 없다. 하지만 plt.imshow()의 경우는 ctvCOLOR를 이용하여 보여줘야 원래 이미지대로 볼 수 있다.
같은 이미지이지만 왼쪽은 cv2.imshow()이고 오른쪽은 plt.imshow()이다
왼쪽은 cv2.imshow()를 한 이미지, 오른쪽은 plt.imshow()를 한 이미지
cv2.imshow는 BGR로 불러와 내보낼 때도 BGR로 내보내지만 cv2로 읽어온 객체를 plt로 내보내면 RGB 순서로 돼있
다는 가정하에 읽어오기 때문에 파란 이미지가 빨간색으로 표현된다
BGR과 RGB가 햇갈려서 테스트를 통해 확인하였다
cv2.calcHist의 2번째 파라미터는 0: blue, 1:green, 2:red 이다
각각 히스토그램의 shape를 찍어본 이유는 cv2.calcHist의 return value를 확인하기 위해서다. 각 1차원의 결괏값을 가진다
다음과 같이 hist의 return 값은 x와 y 축의 2차원 배열이다 shape은 (256,1) 로써 첫 차원에는 0~ 255까지의 pixel의 개수가 포함되어 있다
왼쪽 사진은 위의 파란 이미지의 BGR 히스토그램 return값을 print 한것이다 Blue는 255 색상뿐이여서 0, 0, 0이라 나왔고 green과 red는 0 색상뿐이여서 배열의 첫 번째인 0 값이 해당 이미지의 넓이만큼 나왔다 ( 512x 512 = 262144 ) = blue는 모두 255이고 green, red는 모두 0이다라는 뜻
cv2.threshold( image, min_value, max_value, TYPE )
2차원 이미지만 입력으로 넣을 수 있기 떄문에 grayscale로 변환헀다
threshold를 해주는 이유는 외곽선을 찾을 때 색상정보를 단순하게 변경하여 (0과 255로) 외곽선을 더 찾기 쉽게 할 수 있다.
threshold의 파라미터는 (image_source, min_value, max_value, TYPE)이다 TYPE의 종류 cv2.THRESH_BINARY cv2.THRESH_BINARY_INV cv2.THRESH_TRUNC cv2.THRESH_TOZERO cv2.THRESH_TOZERO_INV cv2. THRESH_OTSU : 이진화를 할 때 히스토그램 분석을 통해 자동으로 임계값을 찾아준다
mode 의 종류 cv2.RETR_EXTERNAL : 외곽선중 가장 바깥쪽 선만 리턴한다 cv2.RETR_LIST : 모든 외곽선을 찾지만 계층관계는 구성하지 않는다 cv2.RETR_CCOMP : 모든 외곽선을 찾으며 2단계의 계층관계를 구성한다 cv2.RETR_TREE : 모든 외곽선을 찾으며 모든 계층관계를 구성한다 여기서 계층이란 검출된 외곽선 안에 있는 또다른 외곽선을 뜻한다
method 의 종류 cv2.CHAIN_APPROX_NONE : 모든 point를 저장 cv2.CHAIN_APPROX_SIMPLE : 4개의 point만을 저장하여 메모리를 절약 cv2.CHAIN_APPROX_TC89_L1 : Teh_Chin 연결 근사 알고리즘 L1버전을 적용하여 point 개수를 줄임 cv2.CHAIN_APPROX_TC89_KCOS : Teh_Chin 연결 근사 알고리즘 KCOS 버전을 적용하여 point 개수를 줄임 return 값으로 오는 contours의 shape를 찍어보면 각각 method마다 shape이 다른것을 볼 수 있다. 각각 method마다의 contours[-1]의 draw 와 shape
첫 파라미터로 띄어질 윈도우의 이름을 설정하고 두 번째 파라미터로 어떤 이미지를 띄울것인지 입력한다
waitKey와 destroyAllWindows 는 함께 쌍으로 자주 쓰이는 함수이다. waitKey는 사용자의 키보드 입력이 올때까지 대기하고 destroyAllWindows는 Opencv에서 띄운 모든 윈도우를 종료한다
위의 코드를 보면 imshow 이후 cv2.waitKey(0)에 의해서 그 다음 문단으로 가지않고 sleep()처럼 대기된다. 여기서 waitKey의 함수안에 파라미터로 0이 있는데 이것은 무한대로 기다린다는 의미이다. 만약 사용자의 키보드 입력이 들어오면 waitKey 함수는 끝나게되고 뒤에있는 destroyAllWindows 함수에 의해 띄어졌던 이미지가 종료된다
3. imwrite
cv2.imwrite("test.jpg", image)
imwrite = image write 이미지를 저장하는 함수이다.
첫 파라미터로 파일이 저장될 경로(test.jpg)를 설정한다 두 번째 파라미터로 저장할 이미지변수를 입력한다.