Threshold에 대해서 이미 OpenCV 5.임계처리에서 설명을 하였는데 자료를 정리 하다가 조금 다른 방법으로 다시 정리해 보았습니다.

 

cv2.threshold(src, thresh, maxval, type[, dst]) → retval, dst

Parameter

설명

src

입력 이미지 : single-channel, 8-bit or 32-bit floating point(input array)

thresh

threshold value(임계 값)

maxval

임계값을

type

thresholding type

- cv2.THRESH_BINARY : 픽셀이 thresh 보다 크면 maxval, 작으면 0

- cv2.THRESH_BINARY_INV : 픽셀이 thresh 보다 작으면 0, 크면 maxval

- cv2.THRESH_TRUNC : 픽셀이 thresh 보다 크면 maxval, 작으면 변경 없음

- cv2.THRESH_TOZERO : 픽셀이 thresh 보다 크면 변경 없음, 작으면 0

- cv2.THRESH_TOZERO_INV : 픽셀이 thresh 보다 크면 0, 작으면 변경 없음

dst

output array : src와 동일 size

 

threshold는 이미지를 grayscale로 불러와 픽셀 하나하나를 기준 값과 비교하여 기준 값을 초과하는 경우와 미달하는 경우로 나누어 새로운 값으로 설정 합니다예를 들어 커트라인을 90으로 설정 했다고 하면 하나의 픽셀 값을 가져와 90하고 비교해서 크면 A , 작으면 B 값으로 다시 설정하는 이분법적 방법으로 색상을 새로 설정 하게 됩니다이렇게 하면 특정 값 이하를 제거 하거나 특정 값 이상을 제거할 수 있겠죠.

 

import cv2

import numpy as np

from matplotlib import pyplot as plt

 

img = cv2.imread('D:/tensorflow/images/mickey.jpg', cv2.IMREAD_GRAYSCALE)

 

ret, thresh1 = cv2.threshold(img,99,255, cv2.THRESH_TRUNC)

ret, thresh2 = cv2.threshold(thresh1, 49,255, cv2.THRESH_TRUNC)

 

titles =['Original','TRUNC 99','TRUNC 49']

images = [img,thresh1,thresh2]

 

for i in range(3):

    plt.imshow(images[i], 'gray')

    plt.title(titles[i])

    plt.show()

 

opencv threshold


이 프로그램은 이미지를 하나 가져와 픽셀이 99보다 크면 255(흰색)으로 설정하고 설정된 그림을 다시 45보다 큰 값을 가지면 255(흰색)로 설정하는 프로그램 입니다.  실제 적용한 이미지를 가지고 설명을 하면


opencv threshold


미키마우스 이미지에 바탕색을 100인 옅은 회색으로 칠하고 거기에 50인 네모를 추가하여 이미지를 하나 만든 후 추가된 색상을 제거해 나가는 방식으로 원본 이미지를 복원하는 작업을 해보았습니다이미지에 따라 어떤 thresholding type을 사용할지 선택을 하고 어떤 값을 가진 부분부터 제거해 나갈지 설정을 하여 작업을 해나가면 원하는 이미지를 찾을 수 있습니다


- copy coding -



5. 임계처리 (이진화)

 

임계처리는 한 픽셀에 대해 임계 값을 정해 놓고 판별을 진행 하기 때문에 사용 하려면 일단 이미지가 컬러라면 gray로 변경시켜야 합니다.  gray로 변경되면 하나의 픽셀이 0에서 255까지의 값 중 하나를 갖게 되고 그 값이 설정한 임계 값을 넘는가 넘지 않는가에 따라 작업을 진행 합니다.

 

5.1 Global Threshold

 

Global Threshold0에서 255의 값을 2개의 영역으로 분할 하여 작업을 하기 때문에 너무 극단적인 결과가 나타날 수 있습니다.


cv2.threshold(src, thresh, maxval, type[, dst]) → retval, dst


parameter

내용

src

이미지 파일. single-channel (gray 이미지)

thresh

임계 값

maxval

임계 값 이상인 경우 적용할 값.  임계

type

cv2.THRESH_BINARY

cv2.THRESH_BINARY_INV

cv2.THRESH_TRUNC

cv2.THRESH_TOZERO

cv2.THRESH_TOZERO_INV

dst

결과 이미지

 

threshold() 함수는 픽셀 값이 thresh 값을 기준으로 큰가 작은가에 따라 픽셀의 값을 수정해서 보여주는 기능을 합니다.

아래 표를 보면 type에 따라 픽셀(x, y) 값이 thresh 보다 크면 maxval로 치환 하거나 0으로 치환 하거나 thresh로 치환 하거나 원래 값을 유지 하거나 하고 아니면 표에 있는 데로 값을 수정하게 됩니다.


type

src(x, y) > thresh

otherwise

cv2.THRESH_BINARY

maxval

0

cv2.THRESH_BINARY_INV

0

maxval

cv2.THRESH_TRUNC

thresh

src(x, y)

cv2.THRESH_TOZERO

src(x, y)

0

cv2.THRESH_TOZERO_INV

0

src(x, y)


- 원본 이미지

opencv_threshold


import numpy as np

import cv2

 

imgFile1 = 'C:/opencv/threshold01.png'

 

img1 = cv2.imread(imgFile1, cv2.IMREAD_GRAYSCALE)

 

ret1, addWeight1 = cv2.threshold(img1, 127, 255, cv2.THRESH_BINARY)

ret2, addWeight2 = cv2.threshold(img1, 127, 255, cv2.THRESH_BINARY_INV)

ret3, addWeight3 = cv2.threshold(img1, 127, 255, cv2.THRESH_TRUNC)

ret4, addWeight4 = cv2.threshold(img1, 127, 255, cv2.THRESH_TOZERO)

ret5, addWeight5 = cv2.threshold(img1, 127, 255, cv2.THRESH_TOZERO_INV)

 

cv2.imshow('THRESH_BINARY', addWeight1)

cv2.imshow('THRESH_BINARY_INV', addWeight2)

cv2.imshow('THRESH_TRUNC', addWeight3)

cv2.imshow('THRESH_TOZERO', addWeight4)

cv2.imshow('THRESH_TOZERO_INV', addWeight5)

   

cv2.waitKey(0)

cv2.destroyAllWindows()


- 상단 원본과 결과 모음 입니다.

하나의 값에 의하여 양분되는걸 볼 수 있습니다.


opencv_threshold



다른 예로 global threshold를 이미지에 사용해 보겠습니다.

하나의 하트를 배경이 다른 두 곳에서 사진을 찍고 THRESH_BINARY를 적용해 보았습니다.

 

- 장판 위 하트


opencv_threshold


- 회색 바탕 하트


opencv_threshold


thresh82로 하니 장판에 있는 하트는 윤곽선을 확인할 수 있지만 회색에 있는 하트는 이제 뭔가 보이려고 합니다.


- 장판 위 하트


opencv_threshold


- 회색 바탕 하트


opencv_threshold



이제 thresh 값이 180이 되었습니다장판에 있는 하트는 윤곽선을 찾으려면 좀 어려울 것 같은데 회색에 있던 하트는 선명하게 윤곽선을 구할 수 있습니다.


- 장판 위 하트


opencv_threshold


- 회색 바탕 하트


opencv_threshold


이처럼 물체의 경계가 어느 정도의 기준 값으로 확실히 구분이 되는 경우에 사용하면 그 물체만 뽑아 내는데 사용할 수 있습니다.

 

 

5.2 Adaptive Threshold

 

Global Threshold는 물체가 주위와 구분이 되는 경우에 사용이 가능하지만 경계가 애매한 경우에는 사용하기가 어렵습니다그래서 이미지를 작은 단위로 나누어 비교하는 방식으로 adaptiveThreshold를 사용면 좀더 세밀한 값을 도출 할 수 있습니다


cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst]) → dst


parameter

내용

src

이미지 파일. single-channel (gray 이미지)

maxValue

임계 값 이상인 경우 적용할 값.  임계

adaptiveMethod

적용할 thresholding algorithm

ADAPTIVE_THRESH_MEAN_C

ADAPTIVE_THRESH_GAUSSIAN_C

thresholdType

cv2.THRESH_BINARY

cv2.THRESH_BINARY_INV

cv2.THRESH_TRUNC

cv2.THRESH_TOZERO

cv2.THRESH_TOZERO_INV

blockSize

threshold 계산을 위한 주변 pixel size

C

평균 또는 가중 평균에서 차감할 값.

dst

결과 이미지

 

 

알고리즘

src(x, yO > T(x, y)

otherwise

ADAPTIVE_THRESH_MEAN_C

maxValue

0

ADAPTIVE_THRESH_GAUSSIAN_C

0

maxValue

 

어느덧 짐을 싸야 하는 시간이 되었군요. 잠시 예전 계약서를 보면서


opencv_threshold


- cv2.ADAPTIVE_THRESH_GAUSSIAN_C


opencv_threshold


- cv2.ADAPTIVE_THRESH_MEAN_C


opencv_threshold


이렇게 상황에 적합한 함수를 사용하면 됩니다.



1

+ Recent posts