삼원색
빛의 삼원색(Primary colors of light): blue, green, red
색의 삼원색(Secondary colors of light): magenta, yellow, cyan
무채색(Achromatic color): 유채색 반대말로 색상 정보가 존재x, blue,green,red 색상 비율이 동일
왼쪽부터 Y,Cb, Cr
하늘 영역의 blue 값은 상대적으로 크기 때문에 이 영역에 대한 Y값은 이 영역의 blue값보다 작음 --> 가운데 사진을 보면 하늘에 대한 픽셀값(intensity)가 크기 때문에 Cb임을 알 수 있음
문제점
해결책
종류
Usage of HSI
원본 / change intensity value / color slicing / color conversion
color conversion
void cvtColor(Mat src, Mat dst, int code, int dstCn =0)
§ Convert an image frame one color space to another
§ Code: CV_BGR2GRAY, CV_BGR2HSV, CV_BGR2YCrCb, CV_BGR2Lab, ......)
§ dstcn: destination channel number. If 0, automatically determined by src and dst
int main() {
Mat image, image_YUV;
image = imread("lena.png");
cvtColor(image, image_YUV, CV_BGR2YUV);
}
color split/merge
§ void split(Mat src, Mat mv)
§ Splits multi-channel array into separate single-channel arrays
§ mv: output array (vector of arrays) mv[c][I] = src[I] the number of arrays must match src.channels()
§merge(InputArrayOfArray mv, OutputArray dst): reverse of split
§ mv: vector of matrices all of the matrices in mv must have same size and depth
§ dst : output array of the same size and depth as mv[0]
int main() {
Mat image, image_YUV, dst;
Mat yuv_channels[3];
image = imread("lena.png");
cvtColor(image, image_YUV, CV_BGR2YUV);
split(image_YUV, yuv_channels);
merge(yuv_channels,3,dst);
imshow("input image", image);
imshow("Y", yuv_channels[0]);
imshow("U", yuv_channels[1]);
imshow("V", yuv_channels[2]);
imshow("YUV image", dst);
waitKey(0);
return 0;
}
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 j = 0; j < rows; j++){
h = mo[0].ptr<uchar>(j);
s = mo[1].ptr<uchar>(j);
for (int i = 0; i < cols; i++) {
if (h[i] > 9 && h[i] < 23) s[i] = s[i];
else s[i] = 0;
}
}
//changing all colors
for (int j = 0; j < rows; j++) {
h = mo[0].ptr<uchar>(j);
s = mo[1].ptr<uchar>(j);
for (int i = 0; i < cols; i++) {
if (h[i] + 50 > 179) h[i] = h[i] + 50 - 179;
else h[i] += 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);
imshow("gray", gray);
imshow("image", color);
waitKey(0);
return 0;
}
white balancing
color의 intensity 전체적으로 조절 --> 자연의 빛을 제거하는 과정
방식
r', g', b': 입력된 r,g,b 값 --> 해당 값들을 일련의 작업을 통해 모두 255로 만들어줌
코드
int main() {
Mat balancing;
Mat balancing_result;
balancing = imread("balancing.jpg");
balancing_result = balancing.clone();
white_balacing(balancing_result);
imshow("image", balancing);
imshow("balancing", balancing_result);
waitKey(0);
}
void white_balacing(Mat img) {
Mat bgr_channels[3]; split(img, bgr_channels);
double avg;
int sum,temp,i, j, c;
for (c = 0; c < img.channels(); c++) {
sum = 0;
avg = 0.0f;
for (i = 0; i < img.rows; i++) {
for (j = 0; j < img.cols; j++) {
sum += bgr_channels[c].at<uchar>(i, j);
}
}
avg = sum / (img.rows * img.cols);
for (i = 0; i < img.rows; i++) {
for (j = 0; j < img.cols; j++) {
temp = (128 / avg) * bgr_channels[c].at<uchar>(i, j);
if (temp>255) bgr_channels[c].at<uchar>(i, j) = 255;
else bgr_channels[c].at<uchar>(i, j) = temp;
}
}
}
merge(bgr_channels, 3, img);
}