영상의 명암비, 히스토그램에 대한 이해

Lily·2023년 10월 19일
0

TIL

목록 보기
7/21

어두운 색을 더 어둡게, 밝은 색을 더 밝게 대비를 주는 것을 명암비 조절이라고 한다.

간단한 명암비 조절 방법

dst(x,y)=saturate(ssrc(x,y))dst(x, y) = saturate(s * src(x,y))

소스 이미지에 특정 스케일을 곱해 전체 이미지의 intensity를 변화시켜 색감을 변화시킨다.
s=0.5s=0.5 일 경우는, 변경 후 intensity의 값이 반으로 줄어들어 전반적으로 어두운 색감을 띠게 된다.

  • 변경 전 intensity:
    • 0intensity2550 \le intensity \le 255
  • 변경 후 intensity:
    • 0intensity1280 \le intensity \le 128

s=2s=2 일 경우는, 변경 후 intensity의 값이 두배로 오르면서(기울기=2) 전반적으로 밝은 색감을 띠게 되며, 값이 128 이상인 intensity들은 모두 255로 saturation 된다.

  • 변경 전 intensity:
    • 0intensity2550 \le intensity \le 255
  • 변경 후 intensity:
    • 0intensity[0,128)2550 \le intensity [0,128) \le 255
    • intensity[128,255]=255intensity [128, 255] = 255

\\
\\

효과적인 명암비 조절 방법

dst(x,y)=saturate(src(x,y)+(src(x,y)128)α)dst(x,y) = saturate(src(x,y) + (src(x,y)-128)*\alpha)

src(x,y)=128src(x,y)=128 일 때를 전체 이미지 색감의 평균값으로 잡아 이를 원점으로 삼고, 여러 기울기 α\alpha 에 따라 색감의 대비가 달라지도록 설계된 수식이다.

α0\alpha \le 0 일 경우 (ex, -0.5), intensity=128을 원점으로 완만한 기울기를 가지고, 0 이하, 255 이상 일 경우는 saturation 함수 처리를 한다. (웬만해서 saturation 되지는 않을 듯)

α>0\alpha> 0 일 경우 (ex, 1), intensity=128을 원점으로 경사진 기울기를 가지고, 0 이하, 255 이상 일 경우는 saturation 함수 처리를 한다.

이 방식은 위의 방식보다는 좋지만, 전체 이미지의 색감 평균이 intensity 128과 너무 동떨어지면, saturation 부분으로 값이 몰려 전체가 다 어두워지거나, 다 밝아지는 단점이 생길 수 있다.

이를 보완하기 위해 intensity=128 대신에 각 이미지의 색감의 평균을 집어넣으면 더 명확하게 대비를 시킬 수 있다.

m=mean(src(x,y))m = mean(src(x,y))
dst(x,y)=saturate(src(x,y)+(src(x,y)m)α)dst(x,y) = saturate(src(x,y) + (src(x,y)-m)*\alpha)

\\
\\

히스토그램 구하기

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에 분포함

\\
\\

히스토그램 스트레칭

  • 기울기: 255GmaxGmin\frac{255} {G_{max} - G_{min}}

  • y절편: 255×GminGmaxGmin-\frac{255 \times G_{min}} {G_{max} - G_{min}} (Gmin:b=GmaxGmin:255G_{min}:b = G_{max}-G_{min}:255)

  • dst(x,y)=255GmaxGmin×src(x,y)255×GminGmaxGmindst(x,y)=\frac{255} {G_{max} - G_{min}}\times src(x,y) - \frac{255 \times G_{min}} {G_{max} - G_{min}}

\\
\\

히스토그램 평활화

  • 히스토그램 함수: h(g)=Ngh(g)=N_{g}

  • 정규화 된 히스토그램 함수: p(g)=h(g)w×hp(g)=\frac{h(g)}{w \times h}

  • 누적 분포 함수(cdf): cdf(g)=0igp(i)cdf(g)=\sum_{0 \le i \le g}{p{(i)}}

  • dst(x,y)=round(cdf(src(x,y))×Lmaxdst(x,y)=round(cdf(src(x,y)) \times L_{max}
    (LmaxL_{max}는 255임)

\\
\\

References

profile
First Attempt In Learning

0개의 댓글