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

04. 평활화, 색공간, CLAHE, 정규화

by 사라리24 2024. 7. 17.



1. 균등화, 평탄화(Equalization)

- 히스토그램을 활용하여 이미지의 품질을 개선하기 위한 방법
- 화소값을 0 ~ 255555 사이에 고루게 분표하도록 개선

 

평활화


       
            cv2. equalizeHist(영상)
 
 
 

 

히스토그램 계산


       
            cv2. clacHist( images , channels , mask , histSize , ranges )

 
  • images: 히스토그램을 계산할 이미지 목록입니다. 여기서는 img와 dst 두 이미지의 히스토그램을 계산하기 위해 두 번 호출하고 있습니다.
  • channels: 히스토그램을 계산할 채널 목록입니다. [0]은 그레이스케일 이미지의 경우 채널 0을 의미합니다. 만약 컬러 이미지라면 [0], [1], [2]을 사용하여 B, G, R 채널별로 히스토그램을 계산할 수 있습니다.
  • mask: 이미지의 특정 영역에 대해 히스토그램을 계산할 때 사용할 마스크입니다. 여기서는 None으로 설정되어 있어 전체 이미지에 대해 히스토그램을 계산합니다.
  • histSize: 히스토그램 빈(bin)의 개수를 나타냅니다. [256]은 256개의 빈을 사용하겠다는 의미입니다. 즉, 각 픽셀 값(0~255)에 대해 히스토그램을 계산합니다.
  • ranges: 픽셀 값의 범위를 나타냅니다. [0, 255]는 픽셀 값이 0에서 255 사이임을 의미합니다.
히스토그램을 사용하여 두 이미지 간의 유사성을 비교하거나 이미지의 특성을 분석할 수 있습니다.
예를 들어, 히스토그램 비교를 통해 두 이미지가 얼마나 비슷한지 알 수 있으며, 특정 영역의 히스토그램을 분석하여 이미지의 특정 부분의 특징을 파악할 수 있습니다.

 

 

예제1 : 흑백 이미지 히스토그램 평활화 적용


       
        import cv2
        import matplotlib.pyplot as plt
       
        img = cv2.imread('./Hawkes.jpg', cv2.IMREAD_GRAYSCALE)
        dst = cv2.equalizeHist(img)
       
        cv2.imshow('img', img)
        cv2.imshow('dst', dst)
        cv2.waitKey()

 

 

 

 

 화질차이


       
        import cv2
        import matplotlib.pyplot as plt

        img = cv2.imread('./Hawkes.jpg', cv2.IMREAD_GRAYSCALE)
        dst = cv2.equalizeHist(img)

        hist1 = cv2.calcHist([img], [0], None, [256], [0, 255])
        hist2 = cv2.calcHist([dst], [0], None, [256], [0, 255])

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

        hists = {'hist1': hist1, 'hist2': hist2}

        plt.figure(figsize=(12, 8))
        for i, (k, v) in enumerate(hists.items()):
            plt.subplot(1, 2, i+1)
            plt.title(k)
            plt.plot(v)

        plt.show()

 



 



2. 색공간

 

 

YCbCr
- 색공간을 밝기 정보로 표현하는 방식
- Y: 밝기 정보
- YCbCr을 줄여서 YCC라고 부르기도 함
HCV
- 색을 표현한는 방법이자 색을 배치하는 방식
- H(색상 / 빨강녹색파랑), S (채도 / 선명도), V(명도 / 빛의 밝기)의 좌표를 써서 특정한 색을 지정

 

 

BGR 이미지YCrCb 색공간으로 변환,
Y (밝기) 채널에 히스토그램 평활화를 적용한 후
다시 BGR 색공간으로 변환


     
          import cv2
           
          img = cv2.imread('./field.bmp')
           
          ycrcb = []
          # YCrCb 채널 병합
          dst = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
          ycrcb = cv2.split(dst)
          ycrcb = list(ycrcb)
          print(ycrcb)

          # Y 채널에 히스토그램 평활화 적용
          ycrcb[0] = cv2.equalizeHist(ycrcb[0])
          # YCrCb 채널 병합
          dst = cv2.merge(ycrcb)
          # 다시 BGR 색공간으로 변환
          dst = cv2.cvtColor(dst, cv2.COLOR_YCrCb2BGR)
           
            cv2.imshow('img', img)
            cv2.imshow('dst', dst)
            cv2.waitKey()
 

 

 

슬라이싱과 인덱싱을 이용하는 방법


       

        # 문제
        # split(), merge()를 사용하지 않고 슬라이싱과 인덱싱을 이용하여 위 예제와 동일하게 결과영상 만들기
        dst = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
        dst[: , :, 0] = cv2.equalizeHist(dst[:,:,0])
        dst = cv2.cvtColor(dst, cv2.COLOR_YCrCb2BGR)

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


 



3. CLAHE 
(Contrast Limited Adaptive Histogram Equlization)

- 평탄화를 하면 이미지의 밝은 부분이 날라가는 현상을 보정하기 위해 사용 
- 이미지의 일정한 영역으로 나누어 평탄화를 적용 

 

CLAHE 객체를 생성

z
xxcc
       
          변수 = cv2.createCLAHE(대비, 영영크기)
          변수.apply(영상)

 
 

 

 

YCrCb 색 공간으로 변환하고,
밝기(Y) 채널에 히스토그램 평활화(equalizeHist)와 CLAHE를 각각 적용한 후,
다시 BGR 색 공간으로 변환하여 결과


       
        import cv2

        img = cv2.imread('./field.bmp')
        dst = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)

        # 히스토그램 평활화를 위한 이미지 복사
        img_eq = dst.copy()
        # CLAHE를 위한 이미지 복사
        img_clahe = dst.copy()

        img_eq[:, :, 0] = cv2.equalizeHist(img_eq[:, :, 0]) # 평활화
        img_eq = cv2.cvtColor(img_eq, cv2.COLOR_YCrCb2BGR) # 원상태

        # CLAHE 객체 생성 (대비 제한과 타일 그리드 크기 설정)
        clahe = cv2.createCLAHE(clipLimit = 4, tileGridSize=(4, 4))
        img_clahe[: ,:, 0] = clahe.apply(img_clahe[:, :, 0]) # CLAHE 적용
        img_clahe = cv2.cvtColor(img_clahe, cv2.COLOR_YCrCb2BGR) # 원상태

        cv2.imshow('img', img)
        cv2.imshow('img_eq', img_eq)
        cv2.imshow('img_clahe', img_clahe)

        cv2.waitKey()


 

 

4. 정규화(Normalization)


특정영역에 값이 물어 있는 경우 화질을 개선하고, 이미지 간의 연산 시 서로 조건이 다른 경우 같은 조건으로 변경

 

정규화 알고리즘


       
           cv2.normalize(정규화 이전 영상, 정규화 이후 영상, 정규화 구간1, 정규화 구간2, 정규화 알고리즘)
           cv2
.NORM_MINMAX: 정구화 구간1 ~ 정규화 구간2
           cv2
.NROM_L1: 전체 합으로 나눔
           cv2
.NORM_L2: 단위 백터로 정규화
           cv2
.NORM_INF: 최대값으로 나눔
 
 

매개변수

  • 정규화 이전 영상: 입력 이미지 또는 배열입니다.
  • 정규화 이후 영상: 출력 이미지 또는 배열입니다. 입력 이미지와 같은 크기와 타입이어야 합니다.
  • 정규화 구간1: 정규화된 값의 최소값입니다.
  • 정규화 구간2: 정규화된 값의 최대값입니다.
  • 정규화 알고리즘: 정규화에 사용할 방법을 지정합니다.

정규화 알고리즘

  1. cv2.NORM_MINMAX:
    • 설명: 이 방법은 입력 이미지의 최소값을 정규화 구간1에, 최대값을 정규화 구간2에 맵핑하여
      모든 값을 이 범위로 스케일링합니다.
    • 사용 예: cv2.normalize(src, dst, 0, 255, cv2.NORM_MINMAX)
  2. cv2.NORM_L1:
    • 설명: 이 방법은 입력 이미지의 모든 픽셀 값을 더한 값으로 각 픽셀 값을 나눕니다.
      이 결과로 모든 픽셀 값의 합이 1이 되도록 정규화됩니다.
    • 사용 예: cv2.normalize(src, dst, alpha, beta, cv2.NORM_L1)
  3. cv2.NORM_L2:
    • 설명: 이 방법은 단위 벡터로 정규화하는 방법으로, 각 픽셀 값을 모든 픽셀 값의 제곱 합의 제곱근으로 나눕니다.
      이 결과로 모든 픽셀 값의 제곱 합이 1이 되도록 정규화됩니다.
    • 사용 예: cv2.normalize(src, dst, alpha, beta, cv2.NORM_L2)
  4. cv2.NORM_INF:
    • 설명: 이 방법은 입력 이미지의 최대값으로 모든 픽셀 값을 나눕니다.
      이 결과로 가장 큰 픽셀 값이 1이 되도록 정규화됩니다.
    • 사용 예: cv2.normalize(src, dst, alpha, beta, cv2.NORM_INF)

 

예제 : 이미지를 정규화하고, 정규화된 이미지들과 그 히스토그램을 비교하여 시각화


     
            import cv2
            import numpy as np
            import matplotlib.pyplot as plt
           
            img = cv2.imread('./Hawkes.jpg', cv2.IMREAD_GRAYSCALE)
           
            img_norm1 = img.astype(np.float32)
            img_norm1 = ((img_norm1 - img_norm1.min()) * 255 / (img_norm1.max() - img_norm1.min()))
            img_norm1 = img_norm1.astype(np.uint8)
           
            img_norm2 = cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX)
           
            hist = cv2.calcHist([img], [0], None, [256], [0, 255])
            hist_norm1 = cv2.calcHist([img_norm1], [0], None, [256], [0, 255])
            hist_norm2 = cv2.calcHist([img_norm2], [0], None, [256], [0, 255])
           
            cv2.imshow('img', img)
            cv2.imshow('img_norm1', img_norm1)
            cv2.imshow('img_norm2', img_norm2)
           
            hist = {'hist': hist, 'hist_norm1': hist_norm1, 'hist_norm2': hist_norm2}
           
            for i, (k, v) in enumerate(hist.items()):
                plt.subplot(1, 3, i+1)
                plt.title(k)
                plt.plot(v)
            plt.show()
            cv2.waitKey()


 

 

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

06. 이진화  (0) 2024.07.18
05. 마스크, 관심영역  (0) 2024.07.18
03. 영상 화소처리  (1) 2024.07.17
02. OpenCV 라이브러리  (3) 2024.07.16
01. 컴퓨터 비전  (3) 2024.07.16