上小学的时候看了很多遍七龙珠的小本连环画,也在学校旁边的借书店借到过那种合订的大本。当时一直以为作者是中国人,还很奇怪为什么有人叫鸟山明那么怪的名字。知道真相的我眼泪掉下来:(。
连环画滤镜主要算法思想:
1.用如下公式计算新的RGB值:
R = (|2*g-b+r|*r)>>8;
G = (|2*b-g+r|*r)>>8;
B = (|2*b-g+r|*r)>>8;
右移8位相当于除以256.
2.用平均值法计算灰度值:
Gray = (R+G+B)/ 3
3.设定新的RGB值:
R= Gray + 10;
G = Gray + 10;
B= Gray;
RGB的值要约束在0与255之间。
完整代码如下:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
void liHuanHuaFilter(Mat &srcImage);
int main(){
Mat srcImage = imread("longzhu.jpg");
if(!srcImage.data){
cout<<"读入图片错误!"<<endl;
return 1;
}
imshow("原图",srcImage);
liHuanHuaFilter(srcImage);
waitKey(0);
return 0;
}
void liHuanHuaFilter(Mat &srcImage){
int rowNum = srcImage.rows;
int colNum = srcImage.cols;
for(int j = 0;j<rowNum;j++){
uchar* data = srcImage.ptr<uchar>(j);
for(int i = 0;i<colNum;i++){
int b = data[i*3];
int g = data[i*3+1];
int r = data[i*3+2];
int R = (abs(2*g-b+r)*r)>>8;
int G = (abs(2*b-g+r)*r)>>8;
int B = (abs(2*b-g+r)*r)>>8;
R = max(0,min(R,255));
G = max(0,min(G,255));
B = max(0,min(B,255));
int gray = (R+G+B)/3;
R = min(255,gray + 10);
data[i*3+2] = R;
data[i*3+1] = R;
data[i*3] = gray;
}
}
imshow("连环画滤镜",srcImage);
}
来张龙珠的效果图:
参考文章:
微像素 这个网站很不错,有很多图像滤镜的算法,不过都是用C#写的,认真琢磨一下是可以用openCV实现的。