ygreenb
yellowgreenblue
ygreenb
전체 방문자
오늘
어제
  • TIL (130)
    • Algorithm & Data Structure (70)
      • 이론 (4)
      • 프로그래머스 (54)
      • 백준 (12)
    • JAVA (4)
    • Android Studio (9)
    • Database (1)
    • WEB (25)
      • HTML+CSS (7)
      • Javascript (5)
      • React (11)
      • Django (1)
      • Node.js (1)
    • Computer Vision (13)
    • Git (8)

블로그 메뉴

  • HOME
  • TAG
  • GITHUB

공지사항

인기 글

태그

  • getOrDefault
  • 깃허브
  • entrySet
  • greedy
  • 프로그래머스 Lv.2
  • git
  • sort
  • HashMap
  • 코틀린
  • Queue
  • Arrays.sort()
  • java
  • Comparator
  • PriorityQueue
  • stack
  • 프로그래머스
  • kotiln
  • 해시
  • 스택/큐
  • DP
  • 안드로이드
  • compareTo()
  • git bash
  • BFS
  • reactjs
  • Android
  • 깃
  • 백준
  • dfs
  • React

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
ygreenb

yellowgreenblue

[OpenCV] 히스토그램 평활화(Histogram Equalization)
Computer Vision

[OpenCV] 히스토그램 평활화(Histogram Equalization)

2020. 1. 19. 02:29

히스토그램(=도수분포도)

intensity levels의 범위가 [0, L-1]인 영상의 히스토그램에서

- ℎ (𝑟𝑘) = 𝑛𝑘 

- 𝑟𝑘: 𝑘^𝑡ℎ intensity value(k번째 인텐시브 값), 𝑛𝑘 : the number of pixels with intensity 𝑟𝑘 (인텐시브 rk의 픽셀 수)

- 이 경우 bin의 개수는 L이다.

히스토그램과 누적히스토그램. (x축이 bin)

히스토그램의 bin의 개수가 256개, 이미 픽셀 값도 0~255라고 할때, 제일 첫번째 bin에 해당하는 값은 intensity 값(픽셀 값)이 0인 픽셀의 개수로 결정된다.

 

Histogram normalization(히스토그램 정규화)

- 각 구성 요소를 총 픽셀 수로 나눔. 즉, 각각의 bin에 있는 값을 영상을 포함하고 있는 전체 픽셀 값으로 나눠준다. 영상 내의 특정한 값을 가진 픽셀이 존재할 확률이, 이 정규화된 히스토그램으로 표현된다.

- 그렇기 때문에 확률 함수로 간주 될 수 있습니다

히스토그램은 수많은 공간 영역 처리 기술의 기초로, 적절한 bin 수를 설정하는 것이 중요하다.

 

왼쪽부터 차례대로 bin의 개수가 많은경우와 bin의 개수가 적은(3개) 경우

bin의 개수가 너무 많으면, 대부분의 bin에서 유사한 값이 나타나는 것을 볼 수 있고,

bin의 개수가 너무 적으면, 영상의 특성을 반영하기 어렵다.

 

 

Histogram equalization(히스토그램 평준화)

- 히스토그램 평준화는 일종의 전처리 방식으로, 이미지의 대비(contrast)를 조정하는 방법이다.

이 때 대비(contrast)란, 개체를 구별 할 수있는 밝기 또는 색상의 차이로 대비가 클수록 이미지가 선명해보여서 물체의 식별이 용이해진다.

이미지와 히스토그램.

히스토그램이 상대적으로 균일하게 분포되어있는 가장 오른쪽 영상의 대비가 가장 높은 걸 알 수 있다.

 

히스토그램 평준화를 하는 방법을 간단하게 설명하자면

1. 입력 영상의 히스토그램을 계산하고

2. 히스토그램을 최대한 평평히 만들 수 있는, 즉 평활화 할 수 있는 함수를 구한다.

3. 이렇게 구한 함수를 매핑함수로 사용해 입력 영상에 적용한다.

 

ex code

#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp> // equlizeHist, calcHist 사용하기위해 추가
#include <iostream>
#include <stdio.h>

using namespace cv;
using namespace std;


Mat drawHistogram(Mat src) {
	Mat hist, histImage;

	// establish the number of bins 
	int i, hist_w, hist_h, bin_w, histSize;
	float range[] = { 0, 256 }; // 입력값의 범위를 정해주는 부분 
	const float* histRange = { range };

	// 히스토그램을 그릴 캔버스 사이즈
	hist_w = 512;
	hist_h = 400;
	histSize = 256; 
	bin_w = cvRound((double)hist_w / histSize); // 캔버스 크기 대비 bin의 개수로 나눠주면 하나의 bin의 width 알 수 있다.

	// compute the histograms 
	// &src: input image, 1: #of src image, 0: #of channels numerated from 0 ~ channels()-1, Mat(): optional mask 
	// hist: output histogram, 1: histogram dimension, &histSize: array of histogram size,  &histRange: array of histogram’s boundaries 
	calcHist(&src, 1, 0, Mat(), hist, 1, &histSize, &histRange); // 히스토그램을 계산하는 부분

	//draw the histogram 
	histImage = Mat(hist_h, hist_w, CV_8UC3, Scalar(255, 255, 255)); // 히스토그램을 글기 위한 캔버스 설정. 초기색상은 흰색

	// normalize the result to [0, histImage.rows] 
	// hist: input Mat, hist: output Mat, 0: lower range boundary of range normalization, histImage.rows: upper range boundary 
	// NORM_MINMAX: normalization type, -1: when negative, the ouput array has the same type as src, Mat(): optional mask 
	normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, -1, Mat()); // 캔버스 높이를 이용해서 계산한 히스토그램을 정규화 시킴.


	for (i = 1; i < histSize; i++) {
		rectangle(histImage, Point(bin_w*i, hist_h), Point(bin_w*i, hist_h - cvRound(hist.at<float>(i))), Scalar(0, 0, 0), 2, 8, 0);
	}
	return histImage;
}

int main() {
	Mat image;
	Mat hist_equalized_image;
	Mat hist_graph;
	Mat hist_equalized_graph;

	image = imread("lena.png", 0);
	if (!image.data) exit(1); // check image

	equalizeHist(image, hist_equalized_image); //histogram equlization

	hist_graph = drawHistogram(image);
	hist_equalized_graph = drawHistogram(hist_equalized_image);

	imshow("Input image", image);
	imshow("Hist Equalizd Image", hist_equalized_image);
	imshow("Hist Graph", hist_graph);
	imshow("Hist qualized Graph", hist_equalized_graph);

	waitKey(0);
	return 0;
}

calcHist() 의 파라미터를 순서대로 설명하면,

  • 입력영상
  • 입력영상의 개수(여러개의 영상에 대해서 동시에 히스토그램 그릴수 있기때문)
  • 영상 채널수(0=채널1개, 1=2개..)
  • 히스토그램을 특정한 부분에서 그리고싶을 때 옵션mat 사용
  • 그려지게될(계산되게 될)히스토그램
  • 히스토그램의 디맨져? 1이면 1차원적인 히스토그램
  • bin의 개수
  • 히스토그램을 그리기위해 사용되는 입력값의 범위를 설정해줌

normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, -1, Mat()); 

히스토그램을 그릴 캔버스의 높이를 이용해서 히스토그램을 정규화시키는 이유는, hist_h(높이)보다 bin의 값이 클 경우엔, 캔버스를 넘어가버려 표현이 불가능해지기 때문이다.

 

히스토그램 평준화는 무조건 모든 영상에 사용가능한 것이 아니라, 영상 내의 픽셀들이 균등하게 분포하는 것이 타당한 경우에만 사용가능하다!

 

이 게시물은 한동대학교 황성수 교수님의 컴퓨터비전 강의를 공부하며 정리한 내용입니다.

'Computer Vision' 카테고리의 다른 글

[OpenCV] 컬러영상처리(Color Processing)  (0) 2020.01.19
[OpenCV] 공간 도메인 필터링(Spatial Filtering)  (0) 2020.01.19
[OpenCV] 밝기값 변환(Intensity Transformation)  (0) 2020.01.18
[OpenCV] 메모리 관리 및 픽셀 액세스(Memory Management/Pixel Access)  (0) 2020.01.11
[OpenCV] Drawing 함수(Drawing Function)  (0) 2020.01.11
    'Computer Vision' 카테고리의 다른 글
    • [OpenCV] 컬러영상처리(Color Processing)
    • [OpenCV] 공간 도메인 필터링(Spatial Filtering)
    • [OpenCV] 밝기값 변환(Intensity Transformation)
    • [OpenCV] 메모리 관리 및 픽셀 액세스(Memory Management/Pixel Access)
    ygreenb
    ygreenb
    개발공부기록장

    티스토리툴바