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

我先粗类的介绍一下拉普拉斯算子就是沿着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);
			}
			else
			optr[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;
}

输入

输出结果

猜你喜欢

转载自blog.csdn.net/Dang_boy/article/details/75452246