Computer Vision/opencv(python)

[41] 3) 지역 이진화

jwjwvison 2021. 3. 23. 14:04
  • 균일하지 않은 조명 환경에서 촬영된 영상의 이진화

 

  • 균일하지 않은 조명의 영향을 해결하려면?
    • 불균일한 조명 성분을 보상한 후 전역 이진화 수행

 

  • 픽셀 주변에 작은 윈도우를 설정하여 지역 이진화 수행
    • 윈도우의 크기는?
    • 윈도우 형태는? uniform? Gaussian?
    • 윈도우를 겹칠 것인가? Overlap? Non-overlap?
    • 윈도우 안에 배경 또는 객체만 존재한다면?

 

  • 지역 이진화 예제
import sys
import numpy as np
import cv2


# 입력 영상 불러오기
src = cv2.imread('rice.png', cv2.IMREAD_GRAYSCALE)

if src is None:
    print('Image load failed!')
    sys.exit()

#전역 이진화  by Otsu's method
_,dst1=cv2.threshold(src,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)

#지역 이진화 by Otsu's method
dst2=np.zeros(src.shape,np.uint8)

bw=src.shape[1]//4
bh=src.shape[0]//4

for y in range(4):
    for x in range(4):
        src_=src[y*bh:(y+1)*bh,x*bw:(x+1)*bw]
        dst_=dst2[y*bh:(y+1)*bh,x*bw:(x+1)*bw]

        #-,dst_=으로 받으면 dst_는 출력으로만 받게됨으로 위에서 받은 부분영상 정보를 잊어버린다
        #그러므로 입력이자 출력으로 받기위해서 dst_를 인자로 주었다 
        # 대신 이렇게 사용하려면dst_는 src_와 크기가 꼭 같아야한다 그렇지않으면 정보를 잊어버린다
        cv2.threshold(src_,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU,dst_)
        ''' 디버깅용
        cv2.imshow('dst2',dst2)
        cv2.waitKey()
        cv2.destroyAllWindows()
        '''

# 결과 출력
cv2.imshow('src', src)
cv2.imshow('dst1', dst1)   #전역 이진화의 결과
cv2.imshow('dst2', dst2)   #지역 이진화의 결과
cv2.waitKey()
cv2.destroyAllWindows()

 

  • OpenCV 적응형 이진화
cv2.adaptiveThreshold(src,maxValue,adaptiveMethod,thresholdType,blockSize,c,dst=None) -> dst

 • src: 입력 영상 . 그레이스케일 영상
 • maxValue: 임계값 함수 최댓값 . 보통 255.
 • adaptiveMethod: 블록 평균 계산 방법 지정 . cv2.ADAPTIVE_THRESH_MEAN_C 는 산술
   평균 , cv2.ADAPTIVE_THRESH_GAUSSIAN_C 는 가우시안 가중치 평균
 • thresholdType : cv2.THRESH_BINARY 또는 cv2.THRESH_BINARY_INV 지정
 • blockSize : 블록 크기 3 이상의 홀수
 • C: 블록 내 평균값 또는 블록 내 가중 평균값에서 뺄 값 .
       (x, y) 픽셀의 임계값으로 𝑇(𝑥,𝑦)=𝜇𝐵(𝑥,𝑦)−𝐶를 사용

 

  • OpenCV 적응형 이진화 예제
import sys
import numpy as np
import cv2


src = cv2.imread('sudoku.jpg', cv2.IMREAD_GRAYSCALE)

if src is None:
    print('Image load failed!')
    sys.exit()


def on_trackbar(pos):
    bsize = pos               #blcokSize는 3의배수만 가능!
    if bsize % 2 == 0:
        bsize = bsize - 1
    if bsize < 3:
        bsize = 3

    dst = cv2.adaptiveThreshold(src, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                cv2.THRESH_BINARY, bsize, 5)
    #블럭 안에 배경 혹은 객체만 있을경우 오동작을해 지저분한 형태로(점같은것) 나올수도 있다!
    #매 픽셀마다 블럭을 할당하고 결정하기 때문에 직접 구현한 지역 이진화 보다 느리다 
    cv2.imshow('dst', dst)

cv2.imshow('src', src)
cv2.namedWindow('dst')
cv2.createTrackbar('Block Size', 'dst', 0, 200, on_trackbar)
cv2.setTrackbarPos('Block Size', 'dst', 11)

cv2.waitKey()
cv2.destroyAllWindows()