본문 바로가기
openCV

[openCV] 컬러영상 처리

by _eunji_ 2020. 1. 18.

Color Processing

컬러 영상을 preprocessing 하는 것

 

Usage of HSI (or YCbCr 색공간으로 변환)

  • 특정한 축이 intensity 값이 아니라 rgb 각 채널들이 합쳐져서 intensity 값을 표현하는 것이다.
  • HSI or YCbCr 경우는 특정한 채널 값이 intensity 값을 의미한다. 
  • 따라서 HSI or YCbCr로 변환시킨 후 I값이나 Y값을 건드리는 방식으로 color processing을 수행한다.
  • (HSI로 변환한 후에는 밝기값 변환이나 히스토그램 평활화, 평균값 필터 등을 수행할 수 있다.)
  • Color Slicing : 특정한 hue 값을 제외하고 나머지 값들을 0으로 변환
  • Color Conversion : hue 값을 조정

Pseudo Coloring

  • 우리 눈이 그레이스케일 영상에서 색상을 구별할 수 있는 범위가 30~50개 사이이다. 즉, 픽셀의 개수가 256개라 할지라도 사람의 눈은 30~50개의 경우의 수만 인지 가능하다는 것이다.
  • 하지만 컬러의 경우 100k ~ 10m 가지의 색을 구별 가능하다. 따라서 Pseudo Coloring을 사용하는 것이다.
  • 각각의 컬러가 어떠한 의미를 가지는지 표시해야 한다.
  • Intensity Slicing : 각각의 Intensity 값에 대해 특정한 값을 할당시키는 것이다.

Color Balancing

  • 특정한 색채의 영향을 빼주는 것

원래 rgb공간에서 흰색은 [255,255,255], 하지만 흰색을 띄지 않는데 우리는 흰색이라고 알고 있는 영역의 값을 Rw,Gw,Bw라고 하고 영상에서는 흰색을 나타내지 않으므로 Rw,Gw,Bw값들로 나눠준다.

color balancing 방법

1. color checker 이용

2. 두 가지 가정 이용

  • gray world assuption : 사진을 찍으면 사진의 픽셀 값의 평균은 회색에 가깝다 [128,128,128]
  • 원래 흰색 값이 영상 내에서 가장 밝다. -> 영상 내 가장 밝은 값을 흰색이었다고 가정

Color Processing - Usage of HSI

int main() {
Mat image = imread("colorful.jpg");
Mat HSV, intensity_change, mask_out, change_color;
vector<Mat> ic(3);
vector<Mat> mo(3);
vector<Mat> cc(3);

int rows = image.rows;
int cols = image.cols;
uchar* h;
uchar* s;
uchar* v;

cvtColor(image, HSV, CV_BGR2HSV);
split(HSV, ic);
split(HSV, mo);
split(HSV, cc);

//eqaulizing the histogram of I mat
equalizeHist(ic[2], ic[2]);

//masking out except orange
for (int i = 0; i < rows; i++) {
h = mo[0].ptr<uchar>(i);
s = mo[1].ptr<uchar>(i);
for (int j = 0; j < cols; j++) {
if (h[j] > 9 && h[j] < 23) s[j] = s[j];
else s[j] = 0;
}
}

//changing all colors
for (int i = 0; i < rows; i++) {
h = cc[0].ptr<uchar>(i);
s = cc[1].ptr<uchar>(i);
for (int j = 0; j < cols; j++) {
if (h[j] + 50 > 255) h[j] = h[j] + 50 - 255;
else h[j] += 50;
}
}

merge(ic, intensity_change);
merge(mo, mask_out);
merge(cc, change_color);
cvtColor(intensity_change, intensity_change, CV_HSV2BGR);
cvtColor(mask_out, mask_out, CV_HSV2BGR);
cvtColor(change_color, change_color, CV_HSV2BGR);

imshow("image", image);
imshow("intensity change", intensity_change);
imshow("mask out", mask_out);
imshow("change color", change_color);

waitKey(0);
return 0;
}

Pseudo coloring

int main() {
Mat gray = imread("xray.jpg", 0);
Mat color;
// Applies a colormap on a given image
// gray: src, color: dst, COLORMAP_JET: the color map to apply
applyColorMap(gray, color, COLORMAP_JET); /(입력, 결과, colormap)
imshow("gray", gray);
imshow("image", color);
waitKey(0);
return 0;
}

Color Balancing

int main() {
Mat image = imread("lena.png");
Mat result;
vector<Mat> ch(3);
int b_sum = 0, g_sum = 0, r_sum = 0;
int b_avg, g_avg, r_avg, b_tmp, g_tmp, r_tmp;
if (image.empty()) {
cerr << "read fail" << endl;
exit(-1);
}
int rows = image.rows;
int cols = image.cols;
int pixno = rows * cols;

// split by B, G, R channel
split(image, ch);
uchar* b;
uchar* g;
uchar* r;

// 각 컬러 채널에 대해 평균 계산
for (int i = 0; i < rows; i++) {
b = ch[0].ptr<uchar>(i);
g = ch[1].ptr<uchar>(i);
r = ch[2].ptr<uchar>(i);
for (int j = 0; j < cols; j++) {
b_sum += b[j];
g_sum += g[j];
r_sum += r[j];
}
}
b_avg = b_sum / pixno;
g_avg = g_sum / pixno;
r_avg = r_sum / pixno;

// color balancing using gray world assumsption
// 원래 평균값이 [128,128,128]이어야 하는데 그렇지 않은 값들에 대해 128로 만들기 위한 처리
for (int i = 0; i < rows; i++) {
b = ch[0].ptr<uchar>(i);
g = ch[1].ptr<uchar>(i);
r = ch[2].ptr<uchar>(i);
for (int j = 0; j < cols; j++) {
// to prevent overflow
b_tmp = (128 * b[j]) / b_avg;
if (b_tmp > 255) {
b[j] = 255;
}
else {
b[j] = b_tmp;
}
g_tmp = (128 * g[j]) / g_avg;
if (g_tmp > 255) {
g[j] = 255;
}
else {
g[j] = g_tmp;
}

r_tmp = (128 * r[j]) / r_avg;
if (r_tmp > 255) {
r[j] = 255;
}
else {
r[j] = r_tmp;
}
}
}

// merge 3 channel's image
merge(ch, result);
imshow("image", image);
imshow("result", result);
waitKey(0);
return 0;
}

 

 

출처 - 컴퓨터 비전 한동대학교 황성수

 http://www.kocw.net/home/cview.do?cid=1b1f5b73413060b5

'openCV' 카테고리의 다른 글

[openCV] 동영상 분할  (0) 2020.01.18
[openCV] 영상 분할  (0) 2020.01.18
[openCV] 공간 도메인 필터링  (0) 2020.01.18
[openCV] 히스토그램 평활화  (0) 2020.01.18
[openCV] 밝기 값 변환  (1) 2020.01.18

댓글