[Computer Vision] 영상 밝기와 명암비 조절 & 필터링

2023. 10. 11. 00:07Run/Computer Vision

영상 밝기와 명암비 조절

1. 영상 밝기 조절

  • 그레이스케일 영상
    • cvtColor(): 3채널 컬러 영상 → 그레이스케일 영상 변환. Mat 객체의 색상 정보(channel) 변경할 때 사용
    • ex. cvtColor(src, dst, COLOR_BGR2GRAY);
    • ConvertTo는 type(channel, bit) 변경, cvtColor는 channel 변경

 

가로: src 그레이스케일 값 / 세로: dst 그레이스케일 값

  • 영상 밝기 조절
    • 입력 영상의 모든 픽셀에 일정 값 더하거나 빼는 작업 수행 (더하면 밝아지고, 빼면 어두워짐)
    • dst(x, y) = src(x, y) + n
    • 한 번 밝기 조절 잘 못하면 일부 정보 날라갈 수 있음, 포화 연산 안하면 급격히 어두워질 수 있음 (ex. 200 + 100 = 300 = 44)
    • 포화(saturate): 원소 자료형이 가질 수 있는 값의 범위를 벗어나는 경우 최솟값, 최댓값으로 원소 값 설정
    • dst(x, y) = saturate(src(x, y) + n)
    • saturate_cast(): 행렬의 자료형에 맞게 포화 연산 수행하는 템플릿 함수
    • int v = src.at<uchar>(j, i) + 100;
      dst.at<uchar>(j, i) = saturate_cast<uchar>(v);
    • 밝기 조절 같은 작업 수행할 때 OpenCV에서 제공하는 연산자 재정의 사용하는 것이 빠르고 간편, CPU 최적화 및 병렬처리 수행

 

2. 영상 명암비 조절

  • 명암비 조절
    • 명암비(contrast): 영상에서 밝은 영역과 어두운 영역 사이에 드러나는 밝기 차이의 강도
    • 명암비 높다고 무조건 좋은 것은 아님
    • 곱셈 연산을 통해 구현 (포화 연산 알아서 수행됨): dst(x, y) = saturate(s * src(x, y))
    • s 값 잘 못 설정하면 일부 정보 날라감, 단순히 곱하는 방식은 잘 사용되지 않음
    • 밝은 픽셀은 더욱 밝게, 어두운 픽셀은 더욱 어둡게 → 밝고 어두움의 기준 (중간값 128, 평균 밝기, ...)
    • dst(x, y) = saturate(src(x, y) + (src(x, y) - 128) * a)

 

 

3. 히스토그램 분석

  • 히스토그램 구하기
    • 히스토그램: 영살의 픽셀 값 분포를 그래프 형태로 표현한 것
    • 컬러 영상에 대해서도 계산하여 구할 수 있음(색상별 or 다 합쳐서 밝기로), 보통 RGB → YUV 변환하여 사용
    • 히스토그램 통해 영상의 밝기, 명암비 가늠할 수 있음

 

  • 히스토그램 스트레칭

 

  • 히스토그램 평활화
    • 히스토그램이 전 범위에서 고르게 분포하도록 변환, 자주 사용함
    • equalizeHist(src, dst): CV_8UC1 타입의 그레이스케일 영상만 입력으로 받음

 

필터링

1. 영상의 필터링

  • 필터링(filtering): 영상에서 원하는 정보만 통과시키고 나머지는 걸러내는 작업
  • 잡음(noise)을 걸러내어 영상을 깔끔하게 만드는 필터, 영상 부드럽게 만드는 필터, 영상 날카롭게 만드는 필터 등

 

  • 마스크(mask) = 커널(kernel), 윈도우(window)
    • 다양한 크기, 모양으로 정의할 수 있음 (1x3, 3x1, 3x3, 5x5, ...)
    • 가운데 = 고정점(anchor point)

 

 

filter2D()가 수행하는 연산

 

  • filter2D(InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor = Point(-1, -1), double delta = 0, int borderType = BORDER_DEFAULT);
    • src 영상에 kernel 필터 이용하여 필터링 수행하고, 그 결과를 dst에 저장
    • ddepth는 결과 영상의 깊이를 지정. -1로 하면 입력 영상과 같게 설정
      • (입력) CV_8U → (출력) -1, CV_16S, CV_32F, CV_64F
      • (입력) CV_16U, CV_16S → (출력) -1, CV_32F, CV_64F
      • (입력) CV_32F → (출력) -1, CV_32F, CV_64F
      • (입력) CV_64F → (출력) -1, CV_64F

 

2. 블러링

  • 블러링(blurring): 영상 부드럽게 만드는 필터링 기법. 스무딩(smoothing)
  • 인접한 픽셀 간 픽셀 값 변화 크지 않은 경우 부드러운 느낌을 줌

 

  • 평균값 필터
    • 입력 영상에서 특정 픽셀의 주변 픽셀들의 산술 평균을 결과 영상 픽셀 값으로 설정하는 필터
    • 날카로운 에지가 무뎌지고 잡음의 영향이 크게 사라짐, but 사물 경계 흐릿해질 수 있음
    • blur(InputArray src, OutputArray dst, Size ksize, Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
    • src 영상에 ksize 크기의 평균값 필터 마스크 사용하여 dst 출력 영상 생성

 

평균 0인 가우시안 분포 그래프 (표준편차 클수록 퍼짐)
평균 0, 표준편차 1인 가우시안 필터 마스크 (원 모양과 유사)

  • 가우시안 필터
    • 가우시안 분포: 평균을 중심으로 좌우 대칭의 종 모양을 갖는 확률 분포. 정규 분포(normal distribution)
    • GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT);
    • sigma는 보통 1보다 작게 설정

 

3. 샤프닝

  • 샤프닝(sharpening): 영상을 날카로운 느낌이 나도록 변경하는 필터링 기법
  • 영상 에지 근방에서 픽셀 값의 명암비 커지도록 수정
  • 언샤프 마스크 필터(unsharp mask filter): 블러링이 적용되어 부드러워진 영상(unsharp)을 활용하여 날카로운 영상을 생성

 

언샤프 마스크 필터 동작 방식 (가로: 픽셀 좌표 이동 / 세로: 픽셀 값)

  • g(x, y) = (입력 영상) - (블러링된 영상) = 오직 날카로운 성분만 가지고 있는 함수
  • h(x, y) = f(x, y) + g(x, y) = 날카로운 성분이 강조된 최종 영상
  • f(x, y)에 g(x, y) 단순히 더하는 게 아니라 가중치 곱한 후 더해 날카로운 정도 조절: f(x, y) + a * g(x, y)

 

식 풀어쓴 것

  • OpenCV 언샤프 마스크 필터 함수 따로 제공하지 않음
  • 위 수식을 코드로 작성하면 됨 (블러링 영상은 평균값 필터, 가우시안 필터 등 사용)