이번에는 오츠의 이진화를 통해서 쓰레숄드값을 자동으로 잡아주려고합니다.
이전예제인 이진화에서는 직접 100,150,200 등 찾아주었는데 이번같은경우는 오츠의 이진화를 통해서
자동으로 임계값을 구하게 만들어주려고합니다.
사용할 이미지는 위와 같습니다(rice)쌀.
## otus
3. 오츠의 이진화 알고리즘( 오츠의이진화 = 자동 이진화를 하고싶을 때 사용하는 알고리즘)
- 자동 이진화 알고리즘
- 자동으로 임계값을 구해줌 (임계값을 구분하는 가장 좋은 방법으로 찾아줌)
- cv2.threshold(영상, 임계값(암거나 넣어도 됨 0넣어도됨), 최대값, 플래그|cv2.THRESH_OTSH)
- 임계값을 임의로 정해 픽셀을 두 부류로 나누고 두 부류의 명암 분포를 구하는 작업을 반복하여
모든 경우의 수 중에서 두 부류의 명암 분류가 가장 균일할 때의 임계값을 선택해줌
import cv2
img = cv2.imread('./rice.png',cv2.IMREAD_GRAYSCALE)
th, dst = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)
print(f'otsu: ', th)
th, dst1 = cv2.threshold(img, 131, 255, cv2.THRESH_BINARY)
cv2.imshow('img', img)
cv2.imshow('dst', dst)
cv2.imshow('dst1', dst1)
cv2.waitKey()
원래는 thresh값에 임계값을 직접 넣어줘야하는데 이번에는 0을 넣었습니다.
이렇게되어도 상관이없는것이 오츠알고리즘을 사용하면 자동으로 임계값(스레숄드)를 잡아줍니다
그렇기때문에 thresh값에 0(아무숫자잡아도 상관없음)을 넣습니다.
그리고 잡아보면 otsh : 131값이 나오게 되는데 그 값을 가지고 다시 살행을 해보면
이렇게 나오게됩니다. 그런데 오른쪽을 보면 쌀 뿐만 아니라 다른것도 잡은것같아요
그리고 원본 밑에를 보면 아래쪽은 좀 더 어두운데이런 곳에서 오브젝트는 잘 못잡는것같습니다.
실제로 쓰레숄드값을 131로 했었을때는 어떨지 궁금해서 dst1변수로 잡고 진행해봤는데
결과는 역시 똑같이 나옵니다!
만약 특정부위를 뽑고싶다면 빛의밝기, 어두운부분이 좀 나뉘어져있기때문에 이부분에 대한
전처리를 잘 해야하는데 하는 방법이 지역이진화 입니다.
#이진화
4. 지역 이진화
- 균일하지 않은 조명 환경에서 사용하는 이진화 방법
- 전체구역을 n등분하고 각각의 구역에 이진화를 한 뒤에 이어 붙이는 방법을 사용
- 여러개의 임계값을 이용할 수 있다는장점이 생김
- 오츠처럼 자동으로 계산해줍니다.
import cv2
import numpy as np
img = cv2.imread('./rice.png', cv2.IMREAD_GRAYSCALE)
#전역 자동 이진화
_, dst1 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)
#지역 자동 이진화(4*4)
#가로세로 크기 확인하기
#zeros로 만들었기 때문에 검정색 도화지가 됨
dst2 = np.zeros(img.shape, np.uint8)
#세로를 4로 나눈 정수값을 취함
bw = img.shape[1] // 4
#가로를 4로 나눈 정수값을 취함
bh = img.shape[0] // 4
for y in range(4):
for x in range(4):
# 한 칸씩 옆으로 가는것
img_ = img[y*bh: (y+1)*bh, x*bw: (x+1)*bw]
dst_ = dst2[y*bh: (y+1)*bh, x*bw: (x+1)*bw]
#빛 자동 이진화시키기
cv2.threshold(img_, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU, dst_)
cv2.imshow('img', img)
cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.waitKey()
#전역 자동 이진화
_, = 스레숄드값은 받지 않도록 합니다. 그리고 자동이진화를 합니다.
지역이진화를 하려면 일단 크기를 알아야합니다.
bw, bh를 하는 이유는 전체적인 크기를 맞춰주기 위해서 입니다.
for 구문에서는 16바퀴를 돌면서 이미지에서 이진화 해서 dst(검정)영상으로 넣습니다.
그 구문이 cv2.threshold절 입니다.
이렇게 빛때문에 잘 안되는 부분을 지역으로 해서 나눠서 처리를 해주면됩니다.
'AI 컴퓨터 비전프로젝트' 카테고리의 다른 글
[DL] 영상의 변환(이동), resize (0) | 2024.10.05 |
---|---|
[DL] 적응형이진화(cv2.adaptiveThreshold())+자동이진화 적응형, 가우시안 비교 (0) | 2024.10.04 |
[DL]영상의 이진화(Binarization) (0) | 2024.10.02 |
[DL] 마스크 연산_cv2.copyTo(), 동영상 합성 (0) | 2024.10.01 |
[DL] cv2.inRange_hsv 색상추출 (0) | 2024.09.30 |