网上看到了一篇论文《彩色图像的亮度色度非线性重组》http://www.docin.com/p-395819289.html,主要介绍了彩图图像增强的算法。中心思想是:对三通道彩图的R,G,B三个通道分别进行某种变换(文中为直方图均衡化),得到R1,G1,B1。再将原图(R,G,B)空间转为色度亮度彩色空间(Y,U,V),同时将(R1,G1,B1)空间也转化为色度亮度空间(Y1,U1,V1),然后将(Y1,U,V)结合起来,转化到RGB空间中去,就得到改善后的图像。
这里用opencv来验证此论文。
代码大致如下,头文件自行添加,效果见下图:
void main()
{
cv::Mat src = imread("F:/sample.bmp");//源图像
cv::Mat dst;
dst.create(src.cols, src.rows, CV_8UC3);//创建目标图像
// 通道分离用
std::vector<cv::Mat> Src_bgr(src.channels());
std::vector<cv::Mat> Dst_bgr(src.channels());
// 通道合成用
std::vector<cv::Mat> mbgr(src.channels());
// 分离
split(src,Src_bgr); //将src分裂成三个通道,并且保存在Src_bgr中
//每个通道分别进行直方图均衡化
for(int i=0;i<src.channels();++i)
{
cv::equalizeHist(Src_bgr[i],Dst_bgr[i]);
}
//将均衡化后的三个通道合并到一起
merge(Dst_bgr,dst);
int R,G,B,R1,G1,B1;
int Y,U,V,Y1,U1,V1;
for ( int j = 0; j < src.rows; j++)//rows是行数相当于height ,cols是列数相当于width;
{
for (int i = 0; i < src.cols; i++)
{
B = src.at<cv::Vec3b>(j,i)[0];//Mat 里面数据是BGR顺序存储
G = src.at<cv::Vec3b>(j,i)[1];
R = src.at<cv::Vec3b>(j,i)[2];
B1 = dst.at<cv::Vec3b>(j,i)[0];
G1 = dst.at<cv::Vec3b>(j,i)[1];
R1 = dst.at<cv::Vec3b>(j,i)[2];
Y = 0.299 * R + 0.587 * G + 0.1148 * B;
U = -0.147 * R - 0.289 * G + 0.436 * B;
V = 0.615 * R - 0.515 * G - 0.100 * B;
Y1 = 0.299 * R1 + 0.587 * G1 + 0.1148 * B1;
U1 = -0.147 * R1 - 0.289 * G1 + 0.436 * B1;
V1 = 0.615 * R1 - 0.515 * G1 - 0.100 * B1;
R = Y1 + 1.14 * V;
G = Y1 - 0.39 * U - 0.58 * V;
B = Y1 + 2.03 * U;
src.at<cv::Vec3b>(j,i)[0] = B;
src.at<cv::Vec3b>(j,i)[1] = G;
src.at<cv::Vec3b>(j,i)[2] = R;
}
}
imshow("Src",src);
imshow("Dst",dst);
}
效果:
可见效果根本不像作者所说的不会失真。但是这种思路值得借鉴。