喜欢拍照的朋友肯定都接触过图像滤镜,一张图加了滤镜处理之后会有很意想不到的效果,今天说说图像滤镜的简易原理。
其实图像滤镜就是对图像的像素值有规律进行操作,下面介绍10种滤镜的原理,用于测试的原图如下图所示:
1、黑白滤镜
将彩色照片变成黑白照片,实质上是一个灰度化的过程。
彩色图像的像素值有3个通道,r, g, b。灰度化的过程就是使三通道的像素值相等,即:
b = b;
g = b;
r = b;
//灰度滤镜
void fun_gray(Mat &src, Mat &dst)
{dst = src.clone();for(int i=0;i<src.rows;i++)for (int j = 0; j < src.cols; j++){dst.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j)[0];dst.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j)[0];dst.at<Vec3b>(i, j)[2] = src.at<Vec3b>(i, j)[0];}return;
}
结果图:
2、底片滤镜
将彩色照片变成底片效果,实质是对像素值取反,即:
b = 255 – b;
g = 255 – g;
r = 255 – r;
//底片滤镜
void fun_reverse(Mat &src, Mat &dst)
{dst = src.clone();for (int i = 0; i<src.rows; i++)for (int j = 0; j < src.cols; j++){dst.at<Vec3b>(i, j)[0] = 255-src.at<Vec3b>(i, j)[0];dst.at<Vec3b>(i, j)[1] = 255-src.at<Vec3b>(i, j)[1];dst.at<Vec3b>(i, j)[2] = 255-src.at<Vec3b>(i, j)[2];}return;
}
效果图:
3、换色滤镜
将彩色照片换一种主色调,实质是取三通道r,g,b像素值的最大值和最小值的平均值,然后用该平均值代替某一通道的像素值,即:
value = max(r,g,b)+min(r,g,b)
b = value/2;
//换色滤镜
void fun_changeColor(Mat &src, Mat &dst)
{dst = src.clone();for (int i = 0; i<src.rows; i++)for (int j = 0; j < src.cols; j++){int max_value = src.at<Vec3b>(i, j)[0]>src.at<Vec3b>(i, j)[1]?src.at<Vec3b>(i, j)[0]:src.at<Vec3b>(i, j)[1];max_value = max_value>src.at<Vec3b>(i, j)[2]? max_value:src.at<Vec3b>(i, j)[2];int min_value = src.at<Vec3b>(i, j)[0]<src.at<Vec3b>(i, j)[1] ? src.at<Vec3b>(i, j)[0] : src.at<Vec3b>(i, j)[1];min_value = min_value<src.at<Vec3b>(i, j)[2] ? min_value : src.at<Vec3b>(i, j)[2];int value = (max_value + min_value) / 2;dst.at<Vec3b>(i, j)[0] = value;//dst.at<Vec3b>(i, j)[1] = value;//dst.at<Vec3b>(i, j)[2] = value;}return;
}
效果图:
4、怀旧滤镜
将彩色照片的主色调换成一种怀旧的黄色,即:
b = (272 * r + 534 * g + 131 * b) / 1000;
g = (349 * r + 686 * g + 168 * b) / 1000;
r = (393 * r + 769 * g + 189 * b) / 1000;
//怀旧滤镜
void fun_old(Mat &src, Mat &dst)
{dst = src.clone();for (int i = 0; i<src.rows; i++)for (int j = 0; j < src.cols; j++){int b = src.at<Vec3b>(i, j)[0];int g = src.at<Vec3b>(i, j)[1];int r = src.at<Vec3b>(i, j)[2];int b_new = (272 * r + 534 * g + 131 * b) / 1000;int g_new = (349 * r + 686 * g + 168 * b) / 1000;int r_new = (393 * r + 769 * g + 189 * b) / 1000;if (b_new > 255) b_new = 255;if (g_new > 255) g_new = 255;if (r_new > 255) r_new = 255;dst.at<Vec3b>(i, j)[0] = b_new;dst.at<Vec3b>(i, j)[2] = g_new;dst.at<Vec3b>(i, j)[1] = r_new;}return;
}
效果图:
5、火焰滤镜
将彩色照片增加一种燃烧的效果,即:
b =b*128/(g+r+1);
g = g*128/(r+b+1);
r = r*128/(g+b+1);
//熔岩滤镜
void fun_fire(Mat &src, Mat &dst)
{dst = src.clone();for (int i = 0; i<src.rows; i++)for (int j = 0; j < src.cols; j++){int b = src.at<Vec3b>(i, j)[0];int g = src.at<Vec3b>(i, j)[1];int r = src.at<Vec3b>(i, j)[2];dst.at<Vec3b>(i, j)[0] = min(b*128/(g+r+1),255);dst.at<Vec3b>(i, j)[1] = min(g*128/(r+b+1),255);dst.at<Vec3b>(i, j)[2] = min(r*128/(g+b+1),255); }return;
}
效果图:
6、冰封滤镜
将彩色照片增加一种冰冻的效果,即:
b = (b – g – r) * 1.2;
g = (g – r – b) * 1.2;
r = (r – g – b) * 1.2;
//冰雕滤镜
void fun_ice(Mat &src, Mat &dst)
{dst = src.clone();for (int i = 0; i<src.rows; i++)for (int j = 0; j < src.cols; j++){int b = src.at<Vec3b>(i, j)[0];int g = src.at<Vec3b>(i, j)[1];int r = src.at<Vec3b>(i, j)[2];int b_new = (b - g - r) * 1.2;int g_new = (g - r - b) * 1.2;int r_new = (r - g - b) * 1.2;dst.at<Vec3b>(i, j)[0] = b_new;dst.at<Vec3b>(i, j)[1] = g_new;dst.at<Vec3b>(i, j)[2] = r_new;}return;
}
效果可能不太好,如下图:
7、卡通滤镜
将彩色照片增加一种卡通的效果,即:
b = abs(b – g + b + r) * g / 256;
g = abs(b – g + b + r) * r / 256;
r = abs(g – b + g + r) * r / 256;
//卡通滤镜
void fun_cartoon(Mat &src, Mat &dst)
{dst = src.clone();for (int i = 0; i<src.rows; i++)for (int j = 0; j < src.cols; j++){int b = src.at<Vec3b>(i, j)[0];int g = src.at<Vec3b>(i, j)[1];int r = src.at<Vec3b>(i, j)[2];int b_new = abs(b - g + b + r) * g / 256;int g_new = abs(b - g + b + r) * r / 256;int r_new = abs(g - b + g + r) * r / 256;if (b_new > 255) b_new = 255;if (g_new > 255) g_new = 255;if (r_new > 255) r_new = 255;dst.at<Vec3b>(i, j)[0] = b_new;dst.at<Vec3b>(i, j)[1] = g_new;dst.at<Vec3b>(i, j)[2] = r_new;}return;
}
效果图:
8、浮雕滤镜
将彩色照片增加一种浮雕的效果,即根据像素点灰度梯度值设置像素,即:
value = b1-b2; (b1和b2为相邻像素点的像素值)
b = value + 128;
g = value + 128;
r = value + 128; //128是为了将梯度增加,可以更改
//浮雕滤镜
void fun_floor(Mat &src, Mat &dst)
{dst = src.clone();for (int i = 1; i<src.rows; i++)for (int j = 1; j < src.cols; j++){int value1 = src.at<Vec3b>(i, j)[0]- src.at<Vec3b>(i-1, j)[0];//int value2 = src.at<Vec3b>(i, j)[1] - src.at<Vec3b>(i - 1, j)[1]; //int value3 = src.at<Vec3b>(i, j)[2] - src.at<Vec3b>(i - 1, j)[2];dst.at<Vec3b>(i, j)[0] = value1+128;dst.at<Vec3b>(i, j)[1] = value1+128;dst.at<Vec3b>(i, j)[2] = value1+128;}return;
}
效果图:
9、素描滤镜
将彩色照片增加一种素描的效果,即:
对图像求灰度图A和底片图B,将灰度图经过高斯滤波之后,和底片图叠加,然后再将像素值较小调整为0。
//素描滤镜
void fun_paint(Mat &src, Mat &dst)
{dst = src.clone();cvtColor(src, dst, CV_BGR2GRAY);Mat gray = dst.clone();for (int i = 0; i<src.rows; i++)for (int j = 0; j < src.cols; j++){dst.at<uchar>(i, j) = 255 - dst.at<uchar>(i, j);}GaussianBlur(dst, dst, Size(15, 15), 0, 0);dst = dst + gray;for (int i = 0; i<src.rows; i++){ for (int j = 0; j < src.cols; j++){if(dst.at<uchar>(i, j)<50)dst.at<uchar>(i, j) = 0;}}
}
效果图:
10、曝光滤镜
将彩色照片增加一种过度曝光的效果,实质上是一种简单的图像增强,即像素值乘以一个系数即可。
b = b+b*1.2;
g = g+g*1.2;
r = r+r*1.2; //1.2可以更改。
//曝光滤镜
void fun_exposure(Mat &src, Mat &dst)
{dst = src.clone();for (int i = 0; i<src.rows; i++)for (int j = 0; j < src.cols; j++){int b = src.at<Vec3b>(i, j)[0];int g = src.at<Vec3b>(i, j)[1];int r = src.at<Vec3b>(i, j)[2];int b_new = b + b*1.2;int g_new = g + g*1.2;int r_new = r + r*1.2;if (b_new > 255) b_new = 255;if (g_new > 255) g_new = 255;if (r_new > 255) r_new = 255;dst.at<Vec3b>(i, j)[0] = b_new;dst.at<Vec3b>(i, j)[1] = g_new;dst.at<Vec3b>(i, j)[2] = r_new;}return;
}
效果图: