opencv实现拉普拉斯锐化的总结

来源:互联网 发布:剑网三不合法的脸数据 编辑:程序博客网 时间:2024/05/23 20:17

我先粗类的介绍一下拉普拉斯算子就是沿着x方向的二阶导数和沿着y方向的二阶导数之和。

由于图像都是离散的值,所以结果是得到一个简单的线性表达式,如下图所示

http://images2015.cnblogs.com/blog/810956/201509/810956-20150926131130740-1169908475.gif

http://images2015.cnblogs.com/blog/810956/201509/810956-20150926131131569-686565695.gif

拉普拉斯算子http://images2015.cnblogs.com/blog/810956/201509/810956-20150926131132537-544113466.gif

写成滤波器则是{0,1,0,

                             1,-4,1,

                               0,1,0}

其他还有几个常用的滤波器{1,1,1,1,-8,1,1,1,1}

以及对他们的取相反数。

拉普拉斯处理结果是得到图片的细节部分,这里我介绍一下我理解的为什么?

因为一阶导数便是数据的变化情况,二阶导数便是数据变化的速度。变化速度越快就会得到数值上越大的滤波结果。所以该滤波结果是得到了图片的细节,再将图片的细节加到原图上,那么结果就是细节部分增强,其余部分基本不变,也就是达到了锐化的效果。

接下来介绍一下实现的具体步骤。

下面是代码

#include<opencv2/opencv.hpp>#include<iostream>using namespace std;using namespace cv;void toBeOne(Mat&input,Mat&output,int index=0){float max=0,min=0;output=Mat::zeros(input.rows,input.cols,CV_8UC3);for(int i=0;i<input.rows;i++){float *ptr=input.ptr<float>(i);for(int j=0;j<input.cols*3;j++)//图像为3通道{if(max<ptr[j])max=ptr[j];if(min>ptr[j])min=ptr[j];}}//取出图像中的上下限for(int i=0;i<input.rows;i++){float *ptr=input.ptr<float>(i);uchar *optr=output.ptr<uchar>(i);for(int j=0;j<input.cols*3;j++){if(index){if(ptr[j]>1){optr[j]=255;continue;}else if(ptr[j]<0){optr[j]=0;continue;}else optr[j]=(uchar)(ptr[j]*255);}elseoptr[j]=(uchar)((ptr[j]-min)/(max-min)*255);}}}int main(int a,char**p){Mat iinput=imread(p[1]),input,Tlaplas;iinput.convertTo(input,CV_32F,1.0/255,0);//把图片转化为float类型,这样子可以直接进行加减而不会溢出Mat kern=(Mat_<char>(3,3)<<1,1,1,1,-8,1,1,1,1);//滤波器Mat laplas;Mat output;filter2D(input,laplas,input.depth(),kern);//使用滤波器kern对input进行相关操作,结果存储在laplas中toBeOne(laplas,Tlaplas);//自己定义的归一函数,把float类型的laplas拉伸到类型为uchar的Tlaplas中output=input-laplas;//如果中间的值是正的则是加号,负值则是减号toBeOne(output,iinput,1);//把float类型的结果转化为uchar类型,把超出范围的直接裁剪imshow("output_float",output);imshow("input",input);imshow("laplas",laplas);imshow("Tlaplas",Tlaplas);imshow("output_uchar",iinput);waitKey();return 0;}
输入


输出结果


原创粉丝点击