这是OpenCV图像处理专栏的第七篇文章,这篇文章是在之前的推文 OpenCV图像处理专栏二 |《Local Color Correction 》论文阅读及C++复现基础上进行了改进,仍然针对数字图像的光照不均衡现象进行校正。
首先在《Local Color Correction》中有 O ( i , j ) = 255 [ I ( i , j ) 255 ] γ O(i,j)=255[\frac{I(i,j)}{255}]^{\gamma} O(i,j)=255[255I(i,j)]γ指数部分为 γ [ i , j , N ( i , j ) ] = 2 [ 128 − B F m a s k ( i , j ) / 128 ] \gamma[i,j,N(i,j)]=2^{[128-BFmask(i,j)/128]} γ[i,j,N(i,j)]=2[128−BFmask(i,j)/128],具体去看上篇文章,这篇论文优化了2个地方:
2
使用 α \alpha α来代替,并且是和图像内容相关的,当图像的整体平均值小于128时,使用: α = l n ( I a v e / 255 ) l n ( 0.5 ) \alpha=\frac{ln(I_{ave}/255)}{ln(0.5)} α=ln(0.5)ln(Iave/255)计算,当平均值大于128时,使用 α = l n ( 0.5 ) l n ( I a v e / 255 ) \alpha=\frac{ln(0.5)}{ln(I_{ave}/255)} α=ln(Iave/255)ln(0.5),意思就是说对于低对比度的图像,应该需要比较强的矫正幅度,所以 α \alpha α应该偏大,反之对于高对比度的图像,只需要较弱的校正幅度。接下来我们实现算法需要对RGB图像进行处理,我们可以像我之前那篇推文那样对RGB通道分别处理,但是可能会存在色偏,所以可以在YUV或者CIELAB等等空间只对亮度的通道进行处理,最后再转回RGB,并且作者提出在对Y分量做处理后,再转换到RGB空间,图像会出现饱和度一定程度丢失的现象,看上去图像似乎色彩不足。所以论文提出了一个修正的公式为:
Mat ContrastImageCorrection(Mat src){
int rows = src.rows;
int cols = src.cols;
Mat yuvImg;
cvtColor(src, yuvImg, CV_BGR2YUV_I420);
vector mv;
split(yuvImg, mv);
Mat OldY = mv[0].clone();
// for(int i = 0; i < rows; i++){
// for(int j = 0; j < cols; j++){
// mv[0].at(i, j) = 255 - mv[0].at(i, j);
// }
// }
Mat temp;
bilateralFilter(mv[0], temp, 9, 50, 50);
//GaussianBlur(mv[0], temp, Size(41, 41), BORDER_DEFAULT);
for(int i = 0; i < rows; i++){
for(int j = 0; j < cols; j++){
float Exp = pow(2, (128 - (255 - temp.at(i, j))) / 128.0);
int value = int(255 * pow(OldY.at(i, j) / 255.0, Exp));
temp.at(i, j) = value;
}
}
Mat dst(rows, cols, CV_8UC3);
// mv[0] = temp;
// merge(mv, dst);
// cvtColor(dst, dst, CV_YUV2BGRA_I420);
for(int i = 0; i < rows; i++){
for(int j = 0; j < cols; j++) {
if (OldY.at(i, j) == 0) {
for (int k = 0; k < 3; k++) dst.at(i, j)[k] = 0;
} else {
//channel B
dst.at(i, j)[0] =
(temp.at(i, j) * (src.at(i, j)[0] + OldY.at(i, j)) / OldY.at(i, j) +
src.at(i, j)[0] - OldY.at(i, j)) >> 1;
//channel G
dst.at(i, j)[1] =
(temp.at(i, j) * (src.at(i, j)[1] + OldY.at(i, j)) / OldY.at(i, j) +
src.at(i, j)[1] - OldY.at(i, j)) >> 1;
//channel R
dst.at(i, j)[2] =
(temp.at(i, j) * (src.at(i, j)[2] + OldY.at(i, j)) / OldY.at(i, j) +
src.at(i, j)[2] - OldY.at(i, j)) >> 1;
}
}
}
// for(int i = 0; i < rows; i++){
// for(int j = 0; j < cols; j++){
// for(int k = 0; k < 3; k++){
// if(dst.at(i, j)[k] < 0){
// dst.at(i, j)[k] = 0;
// }else if(dst.at(i, j)[k] > 255){
// dst.at(i, j)[k] = 255;
// }
// }
// }
// }
return dst;
}
int main(){
Mat src = imread(../1.jpg");
Rect rect(0, 0, (src.cols-1)/2*2, (src.rows-1)/2*2); //保证长宽都是偶数
Mat newsrc = src(rect);
Mat dst = ContrastImageCorrection(newsrc);
imshow("origin", newsrc);
imshow("result", dst);
waitKey(0);
return 0;
}
论文原文:https://www.researchgate.net/publication/220051147_Contrast_image_correction_method
今天就讲到这里了,希望《Contrast image correction method》 这篇论文可以帮助到大家。
欢迎关注我的微信公众号GiantPandaCV,期待和你一起交流机器学习,深度学习,图像算法,优化技术,比赛及日常生活等。