1. 程式人生 > >opencv實現拉普拉斯銳化的總結

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;
}

輸入

 

輸出結果