어두운 색을 더 어둡게, 밝은 색을 더 밝게 대비를 주는 것을 명암비 조절이라고 한다.
간단한 명암비 조절 방법
dst(x,y)=saturate(s∗src(x,y))
소스 이미지에 특정 스케일을 곱해 전체 이미지의 intensity를 변화시켜 색감을 변화시킨다.
s=0.5 일 경우는, 변경 후 intensity의 값이 반으로 줄어들어 전반적으로 어두운 색감을 띠게 된다.
- 변경 전 intensity:
- 0≤intensity≤255
- 변경 후 intensity:
- 0≤intensity≤128
s=2 일 경우는, 변경 후 intensity의 값이 두배로 오르면서(기울기=2) 전반적으로 밝은 색감을 띠게 되며, 값이 128 이상인 intensity들은 모두 255로 saturation 된다.
- 변경 전 intensity:
- 0≤intensity≤255
- 변경 후 intensity:
- 0≤intensity[0,128)≤255
- intensity[128,255]=255
효과적인 명암비 조절 방법
dst(x,y)=saturate(src(x,y)+(src(x,y)−128)∗α)
src(x,y)=128 일 때를 전체 이미지 색감의 평균값으로 잡아 이를 원점으로 삼고, 여러 기울기 α 에 따라 색감의 대비가 달라지도록 설계된 수식이다.
α≤0 일 경우 (ex, -0.5), intensity=128을 원점으로 완만한 기울기를 가지고, 0 이하, 255 이상 일 경우는 saturation 함수 처리를 한다. (웬만해서 saturation 되지는 않을 듯)
α>0 일 경우 (ex, 1), intensity=128을 원점으로 경사진 기울기를 가지고, 0 이하, 255 이상 일 경우는 saturation 함수 처리를 한다.
이 방식은 위의 방식보다는 좋지만, 전체 이미지의 색감 평균이 intensity 128과 너무 동떨어지면, saturation 부분으로 값이 몰려 전체가 다 어두워지거나, 다 밝아지는 단점이 생길 수 있다.
이를 보완하기 위해 intensity=128 대신에 각 이미지의 색감의 평균을 집어넣으면 더 명확하게 대비를 시킬 수 있다.
m=mean(src(x,y))
dst(x,y)=saturate(src(x,y)+(src(x,y)−m)∗α)
히스토그램 구하기
OpenCV 히스토그램 계산 함수
void calcHist(const Mat* images, int nimages, const int* channels,
InputArray mask, OutputArray hist, int dims, const int* histSize,
const float** ranges, bool uniform=true, bool accumulate=false);
images
:
- 입력 영상의 배열 또는 입력 영상의 주소. 영상의 배열인 경우, 모두 크기와 깊이가 같아야 함.
nimages
:
channels
:
- 히스토그램을 구할 체널을 나타내는 정수형 배열
mask
:
- 마스크 영상. 입력 영상 전체에서 히스토그램을 구하려면
Mat()
또는 noArray()
지정.
hist
:
- (출력)히스토그램. dims-차원 배열. Mat 또는 SparseMat.
dims
:
histSize
:
ranges
:
- 히스토그램 각 차원의 최솟값과 최댓값을 원소로 갖는 배열 (uniform = true인 경우)
uniform
:
- 히스토그램 빈의 간격이 균등한지를 나타내는 플래그
accumulate
:
- 누적 플래그. 이 값이 true 이면 hist 배열을 초기화하지 않고 누적하여 히스토그램을 계산함.
calcHist() grayscale 적용 예시
Mat calcGrayHist(const Mat& img)
{
CV_Assert(img.type() == CV_8UC1);
Mat hist;
int channels[] = {0};
int dims = 1;
const int histSize[] = {256};
float graylevel[] = {0, 256};
const float* ranges[] = {graylevel};
calcHist(&img, 1, channels, Mat(), hist, dims, histSize, ranges);
return hist;
}
히스토그램 분석
- 밝은 영상: 히스토그램이 오른쪽으로 치우쳐짐
- 어두운 영상: 히스토그램이 왼쪽으로 치우쳐짐
- 명암비가 높은 영상: 히스토그램의 분산이 크며 intensity 0 ~ 255에 걸쳐 고르게 걸쳐서 나타남
- 명암비가 낮은 영상: 히스토그램의 분산이 작고 intensity가 중간값의 range에 분포함
히스토그램 스트레칭
-
기울기: Gmax−Gmin255
-
y절편: −Gmax−Gmin255×Gmin (Gmin:b=Gmax−Gmin:255)
-
dst(x,y)=Gmax−Gmin255×src(x,y)−Gmax−Gmin255×Gmin
히스토그램 평활화
-
히스토그램 함수: h(g)=Ng
-
정규화 된 히스토그램 함수: p(g)=w×hh(g)
-
누적 분포 함수(cdf): cdf(g)=∑0≤i≤gp(i)
-
dst(x,y)=round(cdf(src(x,y))×Lmax
(Lmax는 255임)
References