이번 장에서는 몇개의 opencv-python 모듈을 이용하여 이미지의 특정 부분만 남기는 작업을 진행해 보겠다.

이번 장은 왜 하는지 이해가 안갈 수 있지만 다음에 진행될 배경 추출에서 유용하게 사용되는 모듈로써 배워두면 좋다

 

1. 이미지의 영역 확장과 침식 

각 순서대로 이미지의 특정 영역에 대한 변환이 어떻게 작용하는지 imshow를 통해 띄어 보았다

import numpy as np
import cv2

image_path = './test.JPG'

image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
image = cv2.resize(image,(300,300))
return_value, image = cv2.threshold(image, 127,255,cv2.THRESH_BINARY)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))

erosion = cv2.erode(image,kernel,iterations=1)
dilate = cv2.dilate(image,kernel,iterations=1)
opening = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel)
blackhat = cv2.morphologyEx(image,cv2.MORPH_BLACKHAT, kernel)
tophat = cv2.morphologyEx(image,cv2.MORPH_TOPHAT, kernel)
gradient = cv2.morphologyEx(image,cv2.MORPH_GRADIENT, kernel)


image = cv2.putText(image,'origin',(30,30),1,2,255,2)
erosion = cv2.putText(erosion,'Erosion',(30,30),1,2,255,2)
dilate = cv2.putText(dilate,'dilate',(30,30),1,2,255,2)
opening = cv2.putText(opening,'opening',(30,30),1,2,255,2)
closing = cv2.putText(closing,'closing',(30,30),1,2,255,2)
blackhat = cv2.putText(blackhat,'blackhat',(30,30),1,2,255,2)
tophat = cv2.putText(tophat,'tophat',(30,30),1,2,255,2)
gradient = cv2.putText(gradient,'gradient',(30,30),1,2,255,2)


concat_image1 = np.concatenate((erosion,dilate,blackhat,image),axis=1)
concat_image2 = np.concatenate((opening,closing,tophat,gradient),axis=1)
concat_image = np.concatenate((concat_image1,concat_image2),axis=0)

cv2.imshow('concat_image',concat_image)
cv2.moveWindow('concat_image',10,10)
cv2.waitKey(0)

 

  • cv2.threshold
    - grayscale 이미지를 0 or 1 의 BINARY 이미지로 변경한다 - 이유는 침식과 확장에 간편하게 목표하는 값을 설정하기 위해서다 ( 0~255의 이미지는 너무 다양해서 특정 값을 변경해도 눈에 띄는 효과가 없다)
  • cv2.getStructuringElement
    - 확장과 침식의 범위를 정해줄 kernel을 정의한다 - 아래에 자세히 설명하겠다 
  • cv2.erode
    - 이미지에서 침식을 담당한다 binary 이미지의 경우 검정색인 0의 부분을 확장하여 원본 이미지에서 검은색이 많아진다 
  • cv2.dilate
    - 이미지에서 확장을 담당한다. binary 이미지의 경우 흰색인 1의 부분을 확장하여 원본 이미지에서 흰색이 많아진다 
  • cv2.MORPH_OPEN
    - 이미지에서 침식을 한 후 확장을 한다. 위의 사진과 같이 원본에 있던 작은 noise라고 할 수 있는 부분이 없어진것을 볼 수 있다
  • cv2.MORPH_CLOSE
    - 이미지에서 확장을 한 후 침식을 한다.
  • cv2.MORPH_BLACKHAT
    - CLOSE와 원본 이미지의 차이를 보여준다
  • cv2.MORPH_TOPHAT
    - OPEN과 원본 이미지의 차이를 보여준다 
  • cv2.MORPH_GRADIENT
    - dilate와 erode의 차이를 보여준다

 

2. cv2.getStructuringElement

위의 코드에서 kernel의 설정에 따라 어떻게 변하는지 보여주겠다 

import numpy as np
import cv2

image_path = './test.JPG'

image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
image = cv2.resize(image,(300,300))
return_value, image = cv2.threshold(image, 127,255,cv2.THRESH_BINARY)

kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT,(11,11))
kernel3 = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
kernel4 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))

kernel_list = [kernel1,kernel2,kernel3,kernel4]

kernel1 = cv2.dilate(image,kernel1,iterations=1)
kernel2 = cv2.dilate(image,kernel2,iterations=1)
kernel3 = cv2.dilate(image,kernel3,iterations=1)
kernel4 = cv2.dilate(image,kernel4,iterations=1)

image = cv2.putText(image,'origin',(30,30),1,2,255,2)
kernel1 = cv2.putText(kernel1,'RECT 5x5',(30,30),1,2,255,2)
kernel2 = cv2.putText(kernel2,'RECT 11x11',(30,30),1,2,255,2)
kernel3 = cv2.putText(kernel3,'CROSS 5x5',(30,30),1,2,255,2)
kernel4 = cv2.putText(kernel4,'ELLIPSE 5x5',(30,30),1,2,255,2)

concat_image = np.concatenate((image,kernel1,kernel2,kernel3,kernel4),axis=1)

cv2.imshow('concat_image',concat_image)
cv2.moveWindow('concat_image',10,10)
cv2.waitKey(0)
  • getSturucturingElement
    - 첫 번쨰 파라미터는 배열의 모양을 뜻한다 
    - RECT의 경우 배열에서 1을 사각형 모양으로 채운다
    - CROSS의 경우 배열에서 1을 십자 모양으로 채운다
    - ELLIPSE의 경우 배열에서 1을 타원 모양으로 채운다( 육각형에 가깝다 ) 
    - 두 번째 파라미터는 배열의 크기를 뜻한다 아래 그림을 보다시피 RECT (11,11)의 경우 배열의 크기가 각각 가로 세로 11, 11 인것을 볼 수 있다
    다음에는 이번 장에서 학습한 내용을 가지고 배경추출에 대해서 알아보겠다

+ Recent posts