1. 컬러영상의 히스토그램 평활화

 

1)

void equalizeHist(InputArray src, OutputArray dst);

src: 8비트 1채널.

dst: src와 같은 크기 , 같은 타입

단, 그레이스케일 영상에서만 지원됨.

 

이에, 컬러영상 히스토그램 평활화를 직접 구현해야한다.

직관적으로 R,G,B 를 Split 해서 각각  히스토그램 평활화(1채널이기에)를 수행한 후 이를 다시 컬러영상으로 바꿈으로써 출력하면 되는 줄 알지만, 컬러 색감이 변형되는 문제가 있다.

R, G, B 각 영상에서 히스토그램 평활화 변환함수 형태가 세개의 색상형태에서 서로 다른 형태로 적용되기 떄문에 색감이 변경된다.

 

2) 정상적인 컬러 영상의 히스토그램 평활화 수행법

  - 밝기 성분에 대해서만 히스토그램 평활화 수행(색상 성분은 그대로 유지)

   1) 밝기성분과 색상 성분을 구분하는 색상으로 변환      예) BGR  -> yCrCb 로

   2) Y 만 히스토그램 평활화

   3) 그 이후 Y와 Cr , Cb  3개를  merge해 컬러영상으로 출력 시 색감유지 되면서 명암비가 높아지게 된다.

 

#include <iostream>
#include "opencv2/opencv.hpp"

using namespace std;
using namespace cv;

void histogram_color() {
	Mat src = imread("mandrill.bmp");

	if (src.empty()) {
		cerr << "Image laod failed!" << endl;
		return;
	}
	Mat src_ycrcb;
	cvtColor(src, src_ycrcb, COLOR_BGR2YCrCb);  // src_ycrcb : CV_8UC3
	
	vector<Mat> ycrcb_planes;  
	split(src_ycrcb, ycrcb_planes); // ycrcb_planes 에 3개 채널 생김
	
	// Y만 히스토그램 평활화 수행해서 그걸 자기 자신에 저장.
	equalizeHist(ycrcb_planes[0], ycrcb_planes[0]);  //밝기 성분만 명암비 조절
	//planes[1], [2]는 그대로 인 상태.
	Mat dst_ycrcb, dst;
	merge(ycrcb_planes, dst_ycrcb); 
	cvtColor(dst_ycrcb, dst, COLOR_YCrCb2BGR); //반드시 BGR로 변환해야 정상적으로 출력됨

	imshow("src", src);
	imshow("dst_ycrcb", dst_ycrcb);
	imshow("dst", dst);
	waitKey();
}
int main()
{
	histogram_color();
}

 

2. 컬러영상의 색감 바꾸기

1) R, G, B 각 색상 채널의 커브를 변경해 컬러 톤(색감) 변경

2) HSV 변환해서 Hue 값 변경하여 색감 변경

 

 

1)

gimp 이용해서 색감 변경해보기

 

원본

빨강을 높이고 파랑을 낮추면, 저녁 노을에 찍은 듯한, 따뜻한느낌

 

파랑 올리고 빨강 낮추니, 차가운 느낌

 


#include <iostream>
#include "opencv2/opencv.hpp"

using namespace std;
using namespace cv;

//인덱스보다 크게 증가함.  색감 높이는 역할
uchar curve1[256] = {
	0, 2, 3, 4, 7, 8, 9, 11,
	12, 14, 15, 16, 18, 19, 21, 22,
	24, 25, 27, 28, 30, 31, 33, 34,
	36, 37, 39, 40, 42, 43, 45, 46,
	47, 49, 50, 52, 53, 55, 56, 58,
	59, 61, 62, 63, 65, 66, 68, 69,
	71, 72, 73, 75, 76, 78, 79, 80,
	82, 83, 85, 86, 87, 89, 90, 91,
	93, 94, 95, 97, 98, 100, 101, 102,
	104, 105, 106, 107, 109, 110, 111, 113,
	114, 115, 117, 118, 119, 120, 122, 123,
	124, 125, 127, 128, 129, 130, 131, 133,
	134, 135, 136, 137, 139, 140, 141, 142,
	143, 144, 145, 146, 148, 149, 150, 151,
	152, 153, 154, 155, 156, 157, 158, 159,
	160, 161, 162, 164, 165, 165, 166, 167,
	168, 169, 170, 171, 172, 173, 174, 175,
	176, 177, 178, 179, 180, 180, 181, 182,
	183, 184, 185, 186, 186, 187, 188, 189,
	190, 191, 191, 192, 193, 194, 195, 195,
	196, 197, 198, 198, 199, 200, 201, 201,
	202, 203, 204, 204, 205, 206, 207, 207,
	208, 209, 209, 210, 211, 211, 212, 213,
	213, 214, 215, 215, 216, 217, 217, 218,
	219, 219, 220, 221, 221, 222, 222, 223,
	224, 224, 225, 226, 226, 227, 227, 228,
	229, 229, 230, 230, 231, 231, 232, 233,
	233, 234, 234, 235, 235, 236, 237, 237,
	238, 238, 239, 239, 240, 241, 241, 242,
	242, 243, 243, 244, 244, 245, 246, 246,
	247, 247, 248, 248, 249, 249, 250, 250,
	251, 252, 252, 253, 254, 254, 255, 255
};

//인덱스보다 낮게 증가함.  색감 낮추는 역할
uchar curve2[256] = {
	0, 0, 1, 1, 1, 2, 3, 3,
	4, 4, 5, 6, 6, 7, 7, 8,
	8, 9, 9, 10, 10, 11, 11, 12,
	12, 13, 13, 14, 14, 15, 15, 16,
	17, 17, 18, 18, 19, 19, 20, 20,
	21, 21, 22, 23, 23, 24, 24, 25,
	25, 26, 27, 27, 28, 28, 29, 30,
	30, 31, 31, 32, 33, 33, 34, 35,
	35, 36, 37, 37, 38, 38, 39, 40,
	40, 41, 42, 43, 43, 44, 45, 45,
	46, 47, 47, 48, 49, 50, 50, 51,
	52, 53, 53, 54, 55, 56, 57, 57,
	58, 59, 60, 61, 61, 62, 63, 64,
	65, 66, 67, 68, 68, 69, 70, 71,
	72, 73, 74, 75, 76, 77, 78, 79,
	80, 81, 82, 82, 83, 85, 86, 87,
	88, 89, 90, 91, 92, 93, 94, 95,
	96, 97, 98, 99, 100, 102, 103, 104,
	105, 106, 107, 108, 110, 111, 112, 113,
	114, 115, 117, 118, 119, 120, 121, 123,
	124, 125, 126, 128, 129, 130, 131, 133,
	134, 135, 136, 138, 139, 140, 141, 143,
	144, 145, 147, 148, 149, 151, 152, 153,
	155, 156, 157, 159, 160, 161, 163, 164,
	165, 167, 168, 169, 171, 172, 174, 175,
	176, 178, 179, 180, 182, 183, 185, 186,
	187, 189, 190, 192, 193, 195, 196, 197,
	199, 200, 202, 203, 205, 206, 207, 209,
	210, 212, 213, 215, 216, 217, 219, 220,
	222, 223, 225, 226, 228, 229, 230, 232,
	233, 235, 236, 238, 239, 241, 242, 244,
	245, 246, 248, 249, 250, 252, 253, 255
};

int main()
{
	Mat src = imread("girl.jpg", IMREAD_COLOR);

	if (src.empty()) {
		cerr << "Image load failed!" << endl;
		return -1;
	}

	vector<Mat> channels_r;
	vector<Mat> channels_b;
	split(src, channels_r);
	split(src, channels_b);
	for (int y = 0; y < src.rows; y++) {
		for (int x = 0; x < src.cols; x++) {
			channels_r[2].at<uchar>(y, x) = curve1[channels_r[2].at<uchar>(y, x)];  // RED 강조
			channels_r[0].at<uchar>(y, x) = curve2[channels_r[0].at<uchar>(y, x)];  //BLUE 미강조.
		}
	}
	for (int y = 0; y < src.rows; y++) {
		for (int x = 0; x < src.cols; x++) {
			channels_b[0].at<uchar>(y, x) = curve1[channels_b[0].at<uchar>(y, x)];  // blue 강조
			channels_b[2].at<uchar>(y, x) = curve2[channels_b[2].at<uchar>(y, x)];  //red 미강조.
		}
	}
	Mat dst_r,dst_b;
	merge(channels_r, dst_r);
	merge(channels_b, dst_b);
	resize(src, src, Size(400, 400));
	resize(dst_r, dst_r, Size(400, 400));
	resize(dst_b, dst_b, Size(400, 400));
	imshow("src", src);
	imshow("dst_red", dst_r);
	imshow("dst_blue", dst_b);
	waitKey();
}

 

 

 

'프로그래머스 > OPENCV' 카테고리의 다른 글

색상범위 관련  (0) 2022.12.07
특정 색상 영역 추출 하기 [다시]  (0) 2022.12.07
색 공간  (0) 2022.12.06
리매핑(remapping)  (0) 2022.12.05
어파인 변환과 투시 변환 ( with bird eyeview)  (0) 2022.12.05

+ Recent posts