* 히스토그램(Histogram)
히스토그램은 각 밝기 값(0~255)에 해당하는 픽셀의 빈도수 분포를 시각적으로 표현한 그래프로, 이를 통해 이미지의 대비, 밝기 균형 등을 분석할 수 있다.
히스토그램이 왼쪽으로 치우쳐 있으면 해당 화소의 값이 전체적으로 작아서 영상의 밝기가 어두워지고, 오른쪽으로 치우쳐 있으면 영상이 밝아진다. 또한 히스토그램이 아주 좁은 범위에 분포되어 있으면 가장 어두운 명도와 가장 밝은 명도의 차이가 적기 때문에 명암 대비가 좋지 않고, 히스토그램이 넓게 분포되어 있으면 밝기의 차이가 커서 명암 대비가 좋다.
예를 들어, 픽셀 값 0이 10000번 나타났다면, 히스토그램의 0 위치에 높이가 100000인 막대가 그려진다. 이때 히스토그램의 빈도수를 전체 픽셀 수로 나눈 비율인 PDF가 사용된다. 즉, 히스토그램의 각 막대는 PDF의 값을 시각적으로 표현한 것과 같다.
- 확률 밀도 함수(PDF: Probability Destiny Function)
PDF는 데이터가 특정 값 또는 범위에 얼마나 분포되어 있는지를 나타내는 함수이다. 영상처리에서는 주로 그레이스케일 이미지에서 각 픽셀 값이 얼마나 자주 나타나는지를 확률적으로 표현하는 데 사용된다.
PDF 계산 과정은 아래와 같다.
1. 픽셀 값 개수 세기: 이미지 내에서 각 픽셀 값(0~255)이 몇 번 나타나는지 세며, 이를 히스토그램이라고 한다.
2. 화률로 변환하기: 각 픽셀 값의 개수를 전체 픽셀 수로 나누어 확률을 계산한다
어두운 레나 이미지의 히스토그램은 왼쪽으로 치우쳐 있고 밝은 레나 이미지는 오른쪽으로 치우친 형태를 띠고 있다.
어두운 레나 이미지의픽셀 값은 어두운 쪽에 분포되어 있고 밝은 영역에는 거의 존재하지 않고, 밝은 레나 이미지는 밝은 쪽에 몰려 있는 것을 확인할 수 있다.
* 히스토그램 평활화 (Histogram Equalization)
히스토그램 평활화는 이미지의 대비를 향상하기 위해 히스토그램을 평탄화하여 픽셀 값의 분포를 균등하게 만드는 이미지 처리 기법이다.
변환 함수 T(r)는 입력 강도 값을 변환하여 보다 균등하게 분포된 강도 값 s를 생성한다. r은 원본 이미지의 입력 강도를 나타내고, s는 변환된 출력 강도를 나타낸다.
이 과정에서 원본 이미지의 히스토그램이 특정 밝기 영역에 집중되어 있을 경우, 변환을 통해 분포가 평탄해지며, 명암 대비가 향상된다.
원본 히스토그램의 확률 밀도 함수 pr(r)를 기반으로 변환된 값 s=T(r)은 누적 분포 함수를 이용하여 계산된다.
이 수식을 통해 변환된 밝기 값은 이론적으로 균일한 분포를 갖게 되며, 이로 인해 이미지의 명암 대비가 개선된다.
수식적으로 s의 확률 분포 ps(s)는 평탄한 분포를 가지게 되어 모든 밝기 값에 대해 동일한 확률을 가지는 상태가 된다.
- 누적 분포 함수(CDF: Cumulative Distribution Function)
평활화 과정을 정리하면 아래와 같다.
① 히스토그램 계산: 이미지의 모든 픽셀 값을 조사하여 각 밝기 값(0~255)이 얼마나 자주 등장하는지 세어 히스토그램을 생성한다. 히스토그램은 밝기 값의 빈도 분포를 나타내며, 특정 밝기 값에 많은 픽셀이 몰려 있는 경우 이 값을 조정하기 위한 기초 데이터로 활용된다.
② 누적 분포 함수(CDF) 계산: 히스토그램의 누적 합을 계산하여 픽셀 값의 누적 확률을 구한다.
③ 변환함수 적용: CDF를 이용해 기존 픽셀 값을 새로운 픽셀 값으로 매핑하여 히스토그램을 균등하게 분포시킨다.
④ 결과 이미지 생성(픽셀 값 재매핑): 변환된 밝기 값을 기반으로 새로운 이미지가 생성된다. 원본 이미지의 픽셀 값들이 새로운 값으로 매핑되며, 히스토그램은 전체적으로 평탄하게 변한다.
* 코드
1. 히스토그램 계산
- vector<int> histogram(256, 0): 256개의 원소를 가진 벡터를 생성하고, 모든 원소를 0으로 초기화한다. 각 인덱스는 그레이스케일 값을 나타낸다.
- vector<int> cdfOfHisto(256, 0): CDF를 저장할 벡터로, 히스토그램과 동일하게 초기화한다.
- int total_pixels = X_Size * Y_Size: 이미지의 너비(X_Size)와 높이(Y_Size)를 곱하여 전체 픽셀 수를 계산한다.
- for 반복문: 이미지의 각 픽셀 값을 순회하며 각 그레이스케일 값의 빈도수를 계산하여 히스토그램을 생성한다.
2. CDF 계산
- cdfOfHisto[0] = histogram[0]: 첫 번째 CDF 값을 히스토그램의 첫 번째 값으로 초기화한다.
- for (int i = 1; i < 256; i++) cdfOfHisto[i] = cdfOfHisto[i - 1]+histogram[i];: 각 픽셀 값에 대해 누적 합을 계산하여 CDF를 생성한다.
- int cdf_min = *min_element(cdfOfHisto.begin(), cdfOfHisto.end()): CDF에서 최소 값을 찾는다.
- int range = total_pixels - cdf_min: CDF를 정규화하기 위해 CDF의 범위를 계산한다.
3. 히스토그램 평활화 수행
- vector<int> histogramEqual(256): 평활화된 히스토그램 값을 저장할 벡터를 선언한다.
- for(int i = 0; i < 256; i++) histogramEqual[i] = cvRound((double): 각 그레이스케일 값에 대해 평활화된 값을 계산한다. cvRound는소수점을 반올림하여 정수 값으로 만든다.
- (cdfOfHisto[i] - cdf_min) / range * 255): CDF 값을 정규화하여 [0,1] 범위로 만들고, 정규화된 값을 [0,255] 범위로 확장한다.
- img[i][j] = histogramEqual[img[i][j]]: 원본 픽셀 값을 평활화된 히스토그램 값을 사용하여 재매핑한다.
* 히스토그램 평활화 결과 영상
lena.512 영상을 히스토그램 평활화한 결과, CDF는 선형적으로 증가하며, 원본 이미지의 특정 밝기 값에 집중된 픽셀이 전체적으로 고르게 분포된 것을 확인할 수 있다.
'전공수업 > 영상처리(C언어)' 카테고리의 다른 글
[영상처리] Spatial Domain Filtering(공간 영역 필터링) (0) | 2024.12.09 |
---|---|
[영상처리] 히스토그램 매칭(Histogram Matching) (0) | 2024.11.18 |
[영상처리] Binary Image (OpenCV, C언어) (0) | 2024.10.07 |
[영상처리] 모자이크 처리 (OpenCV, C언어) (0) | 2024.09.30 |
[C] 2차원 배열 동적 할당 (1) | 2024.09.21 |
댓글