#include
using namespace cv;
using namespace std;
Mat meibai(Mat &img);
Mat wImg(Mat &img1, Mat &img2);
void lbImg(Mat &img1, Mat &img2, Mat &result, int rad, int e);
void dealImg(Mat &img);
int main() {
Mat img = imread("E://图片//色斑.jpg");
if (img.empty()) {
return -1;
}
imshow("img_org", img);
dealImg(img);
waitKey(0);
destroyAllWindows;
return 0;
}
void dealImg(Mat &img) {
Mat tem = img.clone();
Mat result = img.clone();
Mat gray;
cvtColor(img, gray, CV_BGR2GRAY);
vector channelsone, channelstwo;
split(tem, channelsone);
split(result, channelstwo);
for (int i = 0; i < 3; i++) {
lbImg(channelsone[i], gray, channelstwo[i], 18, 500);
}
merge(channelstwo, result);
result = wImg(result, img);
imshow("result", result);
}
void lbImg(Mat &img1, Mat &img2, Mat &result, int rad, int e) {
img1.convertTo(img1, CV_32F);
img2.convertTo(img2, CV_32F);
result.convertTo(result, CV_32F);
Mat tem_img1, tem_img2;
multiply(img1, img2, tem_img1);
multiply(img2, img2, tem_img2); //求方差用
Size dealSize(rad, rad);
Mat box1, box2, box3, box4;
boxFilter(tem_img1, box1, CV_32F, dealSize); //两图像的均值乘积
boxFilter(tem_img2, box2, CV_32F, dealSize); //平方的均值
boxFilter(img1, box3, CV_32F, dealSize); //图片1的均值
boxFilter(img2, box4, CV_32F, dealSize); //图片2的均值
Mat one, two, a, b;
one = box1 - box4.mul(box3); //分子
two = box2 - box4.mul(box4) + e;
divide(one, two, a); //得到系数
b = box3 - a.mul(box4); //得到常数
Mat box_r1, box_r2;
boxFilter(a, box_r1, CV_32F, dealSize);
boxFilter(b, box_r2, CV_32F, dealSize);
result = box_r1.mul(img2) + box_r2;
result.convertTo(result, CV_8U);
}
Mat wImg(Mat &img1, Mat &img2) {
Mat y = img1.clone();
int alpha = 30;
//img1 = (y*(100 - alpha) + (y + 2 * img1 - 256)*alpha) / 100; //与原图混合
for (int i = 0; i < img1.rows; i++) { //羽化融合,也可锐化操作增加纹理
uchar * p1 = img1.ptr(i);
uchar * p2 = img2.ptr(i);
for (int j = 0; j < img1.cols; j++) {
p1[j * 3 + 0] = (p2[j * 3 + 0] * alpha + (255 - alpha) * p1[j * 3 + 0]) >> 8;
p1[j * 3 + 1] = (p2[j * 3 + 1] * alpha + (255 - alpha) * p1[j * 3 + 1]) >> 8;
p1[j * 3 + 2] = (p2[j * 3 + 2] * alpha + (255 - alpha) * p1[j * 3 + 2]) >> 8;
}
}
img1 = meibai(img1); //美白
return img1;
}
Mat meibai(Mat &img) {
Mat tem = img.clone();
tem.convertTo(tem, CV_32F, 1/255.0);
Mat result(tem.size(), tem.type());
float beta = 4.0;
for (int i = 0; i < img.rows; i++) {
float *p1 = tem.ptr(i);
float *p2 = result.ptr(i);
for (int j = 0; j < img.cols; j++) {
float Bt = log(p1[j * 3 + 0] * (beta - 1) + 1);
float Gt = log(p1[j * 3 + 1] * (beta - 1) + 1);
float Rt = log(p1[j * 3 + 2] * (beta - 1) + 1);
p2[j * 3 + 0] = Bt / log(beta);
p2[j * 3 + 1] = Gt / log(beta);
p2[j * 3 + 2] = Rt / log(beta);
}
}
result.convertTo(result, CV_8U, 255);
return result;
}
效果:
笔记: