赞
踩
木刻滤镜
木刻滤镜其实就是图像的二值化处理。图像的二值化处理就是将每个像素点的RGB分量值设成0或255。进行图像二值化之前,先将图像做灰度化处理,灰度化就是把每个像素点的RGB分量值设成一样大。图像的灰度化处理有三种方法:最大值法,平均法或权值法。
最大值法:顾名思义就是取RGB三个分量的最大值作为灰度值,即:gray=max(R,G,B),这种方法转化的灰度图亮度很高。
平均值法:就是取RGB三个分量的平均值作为灰度值,即:gray=(R+G+B)/ 3。这种方法产生的灰度图比较柔和。
权值法:对RGB三个分量按不同的比率取值的和作为灰度值。由于人眼对绿色最为敏感,红色次之,对蓝色的敏感性最低,因此将得到较易识别的灰度图像。一般得到的灰度图像效果最好。公式如下:
Gray = 0.30R + 0.59G + 0.11B 。
二值化就是在灰度图像的基础上,所有灰度值大于或等于阀值的像素被判定为属于特定物体,其灰度值为255表示,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。公式如下:
gray = gray > 阀值 ? 255 : 0。为了实现木刻滤镜,阀值设成127.
openCV有专门的图像灰度化处理函数:cvtColor()
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 )
参数说明:
这个函数可以将图像在RGB,HSV ,HLS,Gray等多种模式间互相转换,第三个参数决定以哪种模式转换。
用该函数对彩色图像灰度化以后,图像会由三通道变成一通道。
完整版代码如下:
void muKeFilter(Mat &srcImage){
Mat dstImage = srcImage;
cvtColor(dstImage,dstImage,CV_BGR2GRAY);
int rowNum = dstImage.rows;//要处理的行数
int colNum = dstImage.cols ;//要处理的列数
for(int j = 0;j<rowNum;j++){
uchar * row = dstImage.ptr<uchar>(j);
for(int i = 0;i<colNum ;i++){
row[i] = row[i] > 127 ? 255:0;
}
}
}
如果不用cvtColor()函数对彩色图像做灰度化预处理,直接用自己的代码对图像灰度化处理,像下面的代码:
int rowNum = srcImage.rows;//要处理的行数
int colNum = srcImage.cols ;//要处理的列数
for(int j = 0;j<rowNum;j++){
uchar * row = srcImage.ptr<uchar>(j);
for(int i = 0;i<colNum ;i++){
int gray = (row[i*3] + row[i*3+1] + row[i*3+2])/3 > 127 ? 255:0;//二值化
row[i*3] = gray;
row[i*3+1] = gray;
row[i*3+2] = gray;
}
}
这时候,图像还是三通道的。
openCV里有一个专门的二值化函数
double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type)
参数说明:
type: 设定值的方法,有五种,如下图
所以这个滤镜用最简单的方法写的话,代码很少,如下:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
void muKeFilter(Mat &srcImage);
int main(){
Mat srcImage = imread("lena.jpg");
if(!srcImage.data || srcImage.empty()){
cout<<"读入图片错误!"<<endl;
return -1;
}
imshow("原图",srcImage);
muKeFilter(srcImage);
waitKey(0);
return 0;
}
void muKeFilter(Mat &srcImage){
Mat dstImage = srcImage;
cvtColor(dstImage,dstImage,CV_BGR2GRAY);
threshold(dstImage,dstImage,127,255,THRESH_BINARY);
imshow("木刻滤镜",srcImage);
}
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
效果图:
下面这篇文章介绍了四种二值化方法:
图像二值化
怀旧滤镜
怀旧滤镜就是让照片有种发黄的效果。主要算法思想:
按以下公式计算新的RGB值:
int R = 0.393*r + 0.769*g + 0.189*b;
int G = 0.349*r + 0.686*g + 0.168*b;
int B = 0.272*r + 0.534*g + 0.131*b;
RGB的值要约束在0与255之间。
主要代码如下:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
void huaiJiuFilter(Mat &srcImage);
int main(){
Mat srcImage = imread("lena.jpg");
if(!srcImage.data || srcImage.empty()){
cout<<"读入图片错误!"<<endl;
return -1;
}
imshow("原图",srcImage);
huaiJiuFilter(srcImage);
waitKey(0);
return 0;
}
void huaiJiuFilter(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 = static_cast<int>(0.393*r + 0.769*g + 0.189*b);
int G = static_cast<int>(0.349*r + 0.686*g + 0.168*b);
int B = static_cast<int>(0.272*r + 0.534*g + 0.131*b);
data[i*3+2] = max(0,min(R,255));
data[i*3+1] = max(0,min(G,255));
data[i*3] = max(0,min(B,255));
}
}
imshow("怀旧滤镜",srcImage);
}
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
效果图:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。