본문 바로가기
IT 프로그래밍 관련/OpenCV

OpenCV threshold, 이미지형태 변환(dilate,erode, opening, closing)

by 지나는행인 2021. 4. 22.
728x90

threshold 함수는 이미지를 이진화할 때 사용한다.

 

이미지의 이진화란, 이미지를 흑과백으로 나누는것을 뜻하고, 

 

흑과백으로 나눌때 우리가 원하는 기준치(임계값)을 설정해서, 

 

임계값보다 크면 백으로, 임계값보다 작으면 , 흑으로 바꾸고 그 결과값을 보여주는 것이 

 

threshold 함수이다.

 

( 이미지를 불러올때 Gray Scale 로 불러와야 한다 )

 

threshold 코드 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import cv2
 
src = cv2.imread('data/images/threshold.png'0 )
 
#구분하기 위한 값 설정 ( 임계값 )
threshold = 0       # 0 은 검정색
 
maxValue = 255
 
cv2.imshow('original',src) #원본이미지 보기
 
ret, dst = cv2.threshold(src, threshold, maxValue, cv2.THRESH_BINARY ) 
#ret은 사용된 임계값을 받음 ,  dst는 함수가 적용된 이미지(numpy)
cv2.imshow('Thresholded Image', dst)
 
cv2.waitKey(0)
cv2.destroyAllWindows()
 
 
cs

* cv2.threshold( src, thresh, maxval, type ) 

- src : 변환할 이미지 ( 그레이스케일 적용 이미지 )

- thresh : 임계값( 기준값 ) ( 0~255 )

- maxval : 임계값을 넘었을때 적용할 값 ( 0~255, 보통 255설정)

- type : thresholing type

       -cv2.THRESH_BINARY

       -cv2.THRESH_BINARY_INV

       -cv2.THRESH_TRUNC

       -cv2.THRESH_TOZERO

       -cv2.THRESH_TOZERO_INV

* 원본과 threshold함수 적용 후 비교

 

 

 

이미지 형태 변환 역시 기본적으로 바이너리 이미지 상에서 이루어 진다.

이미지 형태 변환 함수는 dilate ,  erode 가 있는데 ,

dilate 는 이미지의 경계부분을 팽창시키고  , 

erode 는 이미지의 경계부분을 침식시킨다.

dilate 는 경계가 부드러워지고, 구밍이 메워지는 효과가 있고,

erode 는 작은 object를 지우는 효과가 있다.

 

 

dilate 코드 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import cv2
 
imageName = 'data/images/truth.png'
 
image =cv2.imread(imageName, 0)
 
cv2.imshow('original', image)
 
dilationSize = 10
 
# cv2.getStructuringElement  커널 만들기.
# 십자가모양
element = cv2.getStructuringElement( cv2.MORPH_CROSS, (2*dilationSize + 12*dilationSize + 1), (dilationSize,dilationSize)  )
 
imageDilate = cv2.dilate(image,element)
 
cv2.imshow('Dilation', imageDilate)
 
 
 
#사각형모양
element1 = cv2.getStructuringElement( cv2.MORPH_RECT, (2*dilationSize + 12*dilationSize + 1) )
 
imageDilate1 = cv2.dilate(image,element1)
 
cv2.imshow('Dilation1', imageDilate1)
 
 
cv2.waitKey()
cv2.destroyAllWindows()
 
cs

사각형 모양의 커널은 numpy를 통해 만들 수 있지만, 원이나 타원형의 커널은 만들지 못한다.

그럴때 OpenCV에서 제공하는 cv2.getStructuringElement 함수를 통해 만들 수 있다.

* cv2.getStructuringElement(shape, ksize, anchor)

- shape : 커널의 모양.

     - MORPH_RET : 사각형 모양

     - MORPH_ELLIPSE : 타원형 모양

     - MORPH_CROSS : 십자 모양

 

- ksize – 커널 사이즈

- anchor - 커널의 중심

 

* cv2.dilate( src, kernel , iterations )

- src : 적용할 이미지 파일

- kernel : 적용할 커널,  모양, 크기 ( 직접입력 가능 )

           (cv2.getStructuringElement로 만들기 가능 )

- iterations : 반복 횟수 ( default 1 )

* 원본이미지 , 십자가모양 , 사각형모양

 

 

 

erode 코드예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import cv2
 
imageName = 'data/images/truth.png'
 
image =cv2.imread(imageName, 0)
 
cv2.imshow('original', image)
 
 
dilationSize = 8
 
 
# 십자가모양
element = cv2.getStructuringElement( cv2.MORPH_CROSS, (2*dilationSize + 12*dilationSize + 1), (dilationSize,dilationSize)  )
 
imageEroded = cv2.erode(image, element )
 
cv2.imshow('erosion', imageEroded)
 
#사각형모양
element1 = cv2.getStructuringElement( cv2.MORPH_RECT, (2*dilationSize + 12*dilationSize + 1) )
 
imageEroded1 = cv2.erode(image,element1)
 
cv2.imshow('erosion1', imageEroded1)
 
 
cv2.waitKey()
cv2.destroyAllWindows()
cs

* cv2.erode(src, kernel, iterations )

- src : 적용할 이미지 파일

- kernel : 적용할 커널,  모양, 크기 ( 직접입력 가능 )

             (cv2.getStructuringElement로 만들기 가능 )

- iterations :  반복 횟수

* 원본 , 십자가모양, 사각형모양

 

 

 

Opening 과 Closing은 Dilate 와 Erode 의 조합 결과이다.

 

차이는 Dilate 와 Erode 중 어느것을 먼저 적용하느냐의 차이이다.

 

★Opening : Erosion적용 후 Dilation 적용. 작은 Object나 돌기 제거에 적합

             (이미지를 침식 후 다시 팽창 시킴)

★Closing : Dilation적용 후 Erosion 적용. 전체적인 윤곽 파악에 적합

             (이미지를 팽창 후 다시 침식 시킴)

 

Opening 과 Closing 은 cv2.morphologyEx 함수를 이용하고 옵션에 따라 Opening과 Closing 이 나뉜다.

 

 

 

 

Opening 코드 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import cv2
 
 
imageName = "data/images/opening.png"
 
image = cv2.imread(imageName, 0 )
 
 
cv2.imshow('original', image)
 
 
## opening    (이미지를 침식 후 다시 확장시킴)
 
openingSize = 3
 
# 커널 만들기                           #타원형               #커널사이즈
element = cv2.getStructuringElement( cv2.MORPH_ELLIPSE, (2*openingSize, 2*openingSize))  
 
imageOpened = cv2.morphologyEx( image, cv2.MORPH_OPEN, element, iterations=3  )
 
cv2.imshow('opened', imageOpened)
 
 
 
 
 
cv2.waitKey()
cv2.destroyAllWindows()
 
cs

* cv2.morphologyEx ( src , op , kernel , interations )

 

- src : 적용할 이미지 파일

- op : 여러가지 옵션이 있음  , MORPH_OPEN은 Opening 시 옵션

- kernel : 적용할 커널 ( 커널모양, 사이즈 직접 입력 가능)

            (cv2.getStructuringElement 함수 이용해 만들 수 있음)

- iterations : 반복횟수

* 원본 , Opening 한 이미지

 

 

 

 

Closing 코드 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import cv2
 
imageName = "data/images/closing.png"
 
image = cv2.imread(imageName, 0 )
 
 
cv2.imshow('original', image)
 
## closing  (이미지를 확장 다시 침식시킴)
 
 
closingSize = 4
 
#커널 만들기                            #타원형              #커널 사이즈
element = cv2.getStructuringElement( cv2.MORPH_ELLIPSE, (2*closingSize, 2*closingSize))  
 
imageClosed = cv2.morphologyEx( image, cv2.MORPH_CLOSE, element, iterations=3  )
 
cv2.imshow('Closed', imageClosed)
 
 
 
cv2.waitKey()
cv2.destroyAllWindows()
cs

* cv2.morphologyEx ( src , op , kernel , interations )

 

- src : 적용할 이미지 파일

- op : 여러가지 옵션이 있음  , MORPH_CLOSE는 Closing시 옵션

- kernel : 적용할 커널 ( 커널모양, 사이즈 직접 입력 가능)

            (cv2.getStructuringElement 함수 이용해 만들 수 있음)

- iterations : 반복횟수

* 원본 , Closing 한 이미지

 

 

 

댓글