본문 바로가기
AI/컴퓨터 비전

06. 이진화

by 사라리24 2024. 7. 18.



1. 영상의 이진화(Binarization)

- 픽셀을 검은색 또는 횐색과 같이 두 개의 값으로 나누는 작업
- 영상에서 의미있는 관심영역(ROI)과 비 관심영역 구분할 때 사용
- 배경과 객체를 나울 때도 사용
- 영상의 이진화 연산을 할 때 나누는 특정값을 임계값이라고 함

 

 

 이미지의 이진화 처리

       

      cv2.threshold(영상, 임계값, 최대값, 플래그)

      cv2.THRESH_BINARY: 픽셀값이 임계값을 넘으면 최대값으로 지정하고 넘지 못하면 0으로 지정
      cv2.THRESH_BINARY_INV: THRESH_BINARY 의 반대

 
 

 

 

 예제 : 흑백이미지 이진화 처리


       
        import cv2
        import matplotlib.pyplot as plt

        img = cv2.imread('./cells.png', cv2.IMREAD_GRAYSCALE)
        hist = cv2.calcHist([img], [0], None, [256], [0, 256])

        # cv2.THRESH_BINARY: 픽셀값이 임계값을 넘으면 최대값으로 지정하고 넘지 못하면 0으로 지정
        a, dst1 = cv2.threshold(img, 100, 255, cv2.THRESH_BINARY)
        b, dst2 = cv2.threshold(img, 210, 255, cv2.THRESH_BINARY)
        print('a:', a)

        cv2.imshow('img', img)
        cv2.imshow('dst1', dst1)
        cv2.imshow('dst2', dst2)

        plt.plot(hist)
        plt.show()
        cv2.waitKey()




 

2. 오츠의 이진화 알고리즘

- 자동 이진화
- 자동으로 임계값을 구하는 알고리즘, 임계값을 구분하는 가장 좋은 방법으로 사용

 

 Otsu's 방법을 통해 자동으로 최적의 임계값을 선택


       
         cv2.threshold(영상, 임계값, 최대값, 플래그 | cv2.THRESH_OTSU)


- 임계값을 임의로 정해 픽셀을 두 분류로 나누고 
두 분류의 명암 분포를 구하는 작업을 반복하여 모든 경우의 수 중에서 두 분류의 명암 분류가 가장 균일할 때의 임의값을 선택

 

 

 예제 : Otsu's 방법을 통해 이진화


       
        import cv2

        img = cv2.imread('./rice.png', cv2.IMREAD_GRAYSCALE)

        th, dst = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

        print('otsh: ', th)

        cv2.imshow('img', img)
        cv2.imshow('dst', dst)

        cv2.waitKey()

 

 

 

3. 지역 이진화

- 균일하지 않은 조명 환경에서 사용하는 이진화 방법
- 전체 구역에 N등분하고 각각의 디역에 이진화를 한 뒤에 이어 붙이는 방법
- 여러개의 임계값을 이용할 수 있음

 

 rice.png 이미지를 가로와 세로로 각각 4등분하여
     전역 이진화와 지역 이진화를 적용하기


       
      # rice.png 영상을 이용하여 가로 4등분, 세로 4등분하고 자동 이진화를 적용해보자.
      # 전역(자동) 이진화와 비교
      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)

      # 지역 이진화
      dst2 = np.zeros(img.shape, np.uint8)
      bw = img.shape[1] # 4
      bh = img.shape[0] # 4

      # 4x4 영역으로 나누어 지역 이진화 수행
      for x in range(4):
          for y 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()


 

 

4. 적응형 이진화

- 영상을 여러 영역으로 나눈뒤, 그 주변 픽셀 값만 활요하여 임계값을 구함
- 노이즈를 제거한 뒤에 Otsu 이잔화를 적용

 

 이미지에 적응형 임계값을 적용하기


       
         cv2.adaptiveThreshold (영상, 임계값을 만족하는 픽셀에 적용할 값, 임계값 결정 방법, Threshold 적용 방법, 블록 사이즈, 가감할 상수)


         cv2.ADAPTIVE_THRESH_MEAN_C: 이웃 픽셀의 평균으로 결정 -> 선명하지만 잡티가 많아짐

         cv2.ADAPTIVE_THRESH_GAISSIAN_C: 가우기안 분포에 따른 가중치의 합으로 결정 -> 선명도는 조금 떨어지지만 잡티가 적음


  • 영상 (src): 입력 이미지 (단일 채널, 보통 그레이스케일 이미지)
  • 임계값을 만족하는 픽셀에 적용할 값 (maxValue): 임계값을 넘는 픽셀에 적용할 최대 값 (일반적으로 255)
  • 임계값 결정 방법 (adaptiveMethod):
    • 적응형 임계값 결정 방법을 지정합니다.
    • cv2.ADAPTIVE_THRESH_MEAN_C: 이웃 픽셀의 평균을 사용하여 임계값을 결정합니다.
    • cv2.ADAPTIVE_THRESH_GAUSSIAN_C: 가우시안 윈도우의 가중치 합을 사용하여 임계값을 결정합니다.
  • Threshold 적용 방법 (thresholdType): 이진화 결과를 적용할 방법을 지정합니다.
    • cv2.THRESH_BINARY: 임계값을 넘으면 maxValue를 할당하고, 그렇지 않으면 0을 할당합니다.
    • cv2.THRESH_BINARY_INV: 임계값을 넘으면 0을 할당하고, 그렇지 않으면 maxValue를 할당합니다.
  • 블록 사이즈 (blockSize): 임계값을 계산하기 위한 블록 크기를 지정합니다. 블록 사이즈는 이웃 픽셀들의 영역 크기를 말합니다.
    • 3 이상의 값
    • 블록 사이즈가 클수록 연산 시간이 오래 걸림
  • 가감할 상수 (C):평균이나 가중치 평균에서 빼거나 더할 상수를 지정합니다. 이 값은 계산된 임계값에 더해지거나 뺄 수 있습니다.

 

 

 sudoku.jpg 이미지에 대해 전역 이진화와 적응형 이진화를 비교하여 결과를 시각화


     
          import cv2
          import matplotlib.pyplot as plt

          img = cv2.imread('./sudoku.jpg', cv2.IMREAD_GRAYSCALE)

          # 전역 이진화 (OTSU 알고리즘 사용)
          th, dst1 = cv2.threshold(img, 0 ,255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

          # 적응형 이진화 (평균 기반)
          dst2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 5)

          # 적응형 이진화 (가우시안 가중치 기반)
          dst3 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 9, 5)

          # 결과 이미지 저장
          dic = {'img': img, 'dst1': dst1, 'dst2': dst2, 'dst3': dst3}

          for i, (k, v) in enumerate(dic.items()):
              plt.subplot(2, 2, i+1) # 2x2의 subplot 중 i+1 번째에 배치
              plt.title(k) # 제목 설정
              plt.imshow(v, 'gray') # 이미지 표시 (흑백으로)

          plt.show()
 




 

'AI > 컴퓨터 비전' 카테고리의 다른 글

08. 필터링, 블러링  (0) 2024.07.22
07. 이미지 유사도, 영상의 변환  (0) 2024.07.18
05. 마스크, 관심영역  (0) 2024.07.18
04. 평활화, 색공간, CLAHE, 정규화  (1) 2024.07.17
03. 영상 화소처리  (1) 2024.07.17