文章目录
前言1. 灰度世界算法介绍2. 灰度世界算法C++ Opencv实现3. 结果总结参考前言
最近在研究ISP中图像处理算法,刚好学习到3A算法中实现自动白平衡(Auto White Balance)的算法:灰度世界算法,这里分享给大家
1. 灰度世界算法介绍
白平衡就是将原本白色的事物矫正为白色的过程,这可能听起来有点拗口,通俗点说,由于环境(不同色温的光源)不同相机拍出的图像中原本白色的事物反而不是白色, 比如,在暖色温环境下拍出白色的事物呈现偏黄色,在冷色温环境下拍出白色事物呈现偏蓝色。
灰度世界法是一种简单的实现自动白平衡的算法,它基于这样一个假设:图像中色彩复杂丰富,R/G/B三通道图像的灰度均值相等。
算法实现的步骤如下:
分别计算彩色图像三通道均值, R m e a n , B m e a n , G m e a n R_{mean}, B_{mean}, G_{mean} Rmean,Bmean,Gmean;计算图像图像均值, K = R m e a n + B m e a n , G m e a n 3 K=\frac{R_{mean} + B_{mean}, G_{mean}}{3} K=3Rmean+Bmean,Gmean;计算各通道增益值, K R = K R m e a n , K G = K G m e a n , K B = K B m e a n K_{R}=\frac{K}{R_{mean}}, K_{G}=\frac{K}{G_{mean}}, K_{B}=\frac{K}{B_{mean}} KR=RmeanK,KG=GmeanK,KB=BmeanK根据各通道增益值更新通道图像, I R ( i , j ) = K R ∗ I R ( i , j ) , I G ( i , j ) = K G ∗ I G ( i , j ) , I B ( i , j ) = K B ∗ I B ( i , j ) I_{R}(i,j)=K_{R}*I_{R}(i,j), I_{G}(i,j)=K_{G}*I_{G}(i,j), I_{B}(i,j)=K_{B}*I_{B}(i,j) IR(i,j)=KR∗IR(i,j),IG(i,j)=KG∗IG(i,j),IB(i,j)=KB∗IB(i,j)
2. 灰度世界算法C++ Opencv实现
#include <iostream>#include <opencv2\imgcodecs.hpp>#include <opencv2\imgproc.hpp>#include <opencv2\core.hpp>#include <opencv2\highgui.hpp>#include <vector>using namespace cv;// Auto White Balance - Gray World Algorithmint AWB_GrayWorld(InputArray src, OutputArray dst){CV_Assert(src.channels() == 3, "AWB_GrayWorld() input image must be 3 channels!");Mat mSrc = src.getMat();if (mSrc.empty()){std::cout << "AWB_GrayWorld() input image is empty!" << std::endl;return -1;}dst.create(mSrc.size(), mSrc.type());Mat mDst = dst.getMat();if (mDst.empty()){std::cout << "AWB_GrayWorld() create dst image failed!" << std::endl;return -1;}//对输入src图像进行RGB分离std::vector<Mat> splitedBGR;splitedBGR.reserve(3);split(mSrc, splitedBGR);//分别计算R/G/B图像像素值均值double meanR = 0, meanG = 0, meanB = 0;meanB = mean(splitedBGR[0])[0];meanG = mean(splitedBGR[1])[0];meanR = mean(splitedBGR[2])[0];//计算R/G/B图像的增益double gainR = 0, gainG = 0, gainB = 0;gainR = (meanR + meanG + meanB) / (3 * meanR);gainG = (meanR + meanG + meanB) / (3 * meanG);gainB = (meanR + meanG + meanB) / (3 * meanB);//计算增益后R/G/B图像splitedBGR[0] = splitedBGR[0] * gainB;splitedBGR[1] = splitedBGR[1] * gainG;splitedBGR[2] = splitedBGR[2] * gainR;//将三个单通道图像合成一个三通道图像merge(splitedBGR, mDst);return 0;}int main(){std::string imgPath = "C:\\Temp\\common\\Workspace\\Opencv\\images\\awb_grayworld.jpg";Mat src = imread(imgPath);Mat dst;int status = AWB_GrayWorld(src, dst);if (status != 0)goto EXIT;imshow("src", src);imshow("AWB GrayWorld", dst);waitKey(0);EXIT:system("pause");destroyAllWindows();return 0;}
3. 结果
原图像:
灰度世界-白平衡后图像:
总结
从结果来看,效果还不错,但是灰度世界算法必须满足假设才可以,如果图像色彩单一,那么该算法效果就可能很差!
参考
/Imageshop/archive//04/20/3032062.html