数字图像处理之图像滤波与形态学

前言

又咕了一个学期,上学期的东西都没写完,惭愧惭愧。

实验要求

  1. 空域滤波
    1.1 设计高斯滤波器模板函数
    1.2 填充图像,将模板函数与图像进行卷积
    1.3 截取图像,获得滤波后的图像
  2. 腐蚀/膨胀算法
    2.1 读取图片
    2.2 腐蚀/膨胀算法
    2.3 将经过腐蚀或膨胀后的图片显示

代码实现

#include 
#include 
#include 
#include 
#define LINEAR_X 0
#define SIZE 5
#define PI 3.1415926
using namespace cv;
void threshold(Mat input,Mat &output,int var)
{
	int rows = output.rows;
	int cols = output.cols;
	for(int i=0;i<rows;i++)
	{
		for(int j=0;j<cols;j++)
		{
			int p=input.at<uchar>(i,j);
			if(p>var)
				output.at<uchar>(i,j)=255;
			else output.at<uchar>(i,j)=0;
		}
	}
}
//滤波//
// 空域高斯滤波器函数
void Gaussian(Mat input, Mat &output, double sigma){
	double weight;//权重
	double sum = 0; 
	double Gaussian_Temp[SIZE][SIZE] = {0};//模板
	weight = (2*PI*sigma*sigma);  
	for(int i =0;i <SIZE;i++)  
	{  
		for(int j = 0;j < SIZE;j++)  
		{  
			int x = i - SIZE/2;
			int y = j - SIZE/2;
		    Gaussian_Temp[i][j] =exp(-(x*x+y*y)/(2.0*sigma*sigma))/weight;  
		    sum += Gaussian_Temp[i][j];  
		}  
	}  

	for(int i = 0; i < SIZE;i++)  
	{  
		for(int j = 0;j < SIZE;j++)  
		{  
		    Gaussian_Temp[i][j] = Gaussian_Temp[i][j]/sum;//归一化处理
		}  
	}
	//卷积
	int rows = output.rows;
	int cols = output.cols;
	for(int i=0;i<rows;i++)
	{
		for(int j=0;j<cols;j++)
		{
			for(int k=0;k<SIZE;k++)
				for(int t=0;t<SIZE;t++)
				{
					int x=i+k-SIZE/2;
					int y=j+t-SIZE/2;
					if(x<0||y<0||x>=rows||y>=cols)continue;
					int p=input.at<uchar>(x,y);
					output.at<uchar>(i,j)+=p*Gaussian_Temp[k][t];
				}
			if(output.at<uchar>(i,j)>255)output.at<uchar>(i,j)=255;
			if(output.at<uchar>(i,j)<0)output.at<uchar>(i,j)=0;
		}
	}

}
// 膨胀函数
void Dilate(Mat Src, Mat Tem, Mat Dst){
	int rows = Dst.rows;
	int cols = Dst.cols;
	int t_rows = Tem.rows;
	int t_cols = Tem.cols;
	for(int i=0;i<rows;i++)
	{
		for(int j=0;j<cols;j++)
		{
			int p = Src.at<uchar>(i,j);
			if(p == 0)continue;
			for(int k=0;k<t_rows;k++)
				for(int t=0;t<t_cols;t++)
				{
					int x=i+k;
					int y=j+t;
					if(x<0||y<0||x>=rows||y>=cols)continue;
					if(Tem.at<uchar>(k,t) == 1)
						Dst.at<uchar>(x,y)=255;
				}
		}
	}
}
// 腐蚀函数
void Erode(Mat Src, Mat Tem, Mat Dst){
	int rows = Dst.rows;
	int cols = Dst.cols;
	int t_rows = Tem.rows;
	int t_cols = Tem.cols;
	for(int i=0;i<rows;i++)
	{
		for(int j=0;j<cols;j++)
		{
			int sum = 0;
			for(int k=0;k<t_rows;k++)
				for(int t=0;t<t_cols;t++)
				{
					int x=i+k-t_rows/2;
					int y=j+t-t_cols/2;
					if(x<0||y<0||x>=rows||y>=cols)continue;
					sum +=Tem.at<uchar>(k,t)*Src.at<uchar>(x,y);
				}
			if(sum == 13*255)Dst.at<uchar>(i,j)=255;
		}
	}
}
int main(int argc,char **argv){
	//读取原始图像
	Mat src=imread(argv[1],IMREAD_UNCHANGED);
	//检查是否读取图像
	if(src.empty()){
		std::cout<<"Error! Input image cannot be read...\n";
		return -1;
	}
	
	imshow("src",src);
	cvtColor(src,src,COLOR_BGR2GRAY);

	Mat dst1=Mat::zeros(src.size(),CV_8UC1);
	Mat dst2=Mat::zeros(src.size(),CV_8UC1);
	Mat dst3=Mat::zeros(src.size(),CV_8UC1);
	Mat Thimg=Mat::zeros(src.size(),CV_8UC1);
	threshold(src,Thimg,255/2);

	Mat dstOut;
	//GaussianBlur(img_out,dstOut,Size(3,3),1,1);
	// 空域滤波函数
	Gaussian(src,dst1,0.8);
	
	// 膨胀函数
	uchar matrix1[5][5] = {{1,1,1,1,1},{1,1,1,1,0}, {1,1,1,0,0}, {1,1,0,0,0}, {1,0,0,0,0}};
	Mat Tem1(Size(5,5), CV_8UC1, matrix1);//注意:opencv里的行列顺序是和maltab相反的
										//由于Mat矩阵默认的是uchar类型,所以前后一致,定义矩阵时也要定义uchar类型
	Dilate(Thimg,Tem1,dst2);

	// 腐蚀函数
	uchar matrix2[5][5] = {{0,0,1,0,0}, {0,1,1,1,0},{1,1,1,1,1},{0,1,1,1,0},{0,0,1,0,0}};
	Mat Tem2(Size(5,5), CV_8UC1, matrix2);//注意:opencv里的行列顺序是和maltab相反的
										//由于Mat矩阵默认的是uchar类型,所以前后一致,定义矩阵时也要定义uchar类型
	Erode(Thimg,Tem2,dst3);
	imshow("高斯滤波",dst1);
	imshow("膨胀",dst2);
	imshow("腐蚀",dst3);
	std::cout << "Press any key to exit...\n";
    waitKey(); // Wait for key press
	return 0;
}

运行结果

数字图像处理之图像滤波与形态学_第1张图片
数字图像处理之图像滤波与形态学_第2张图片
数字图像处理之图像滤波与形态学_第3张图片
数字图像处理之图像滤波与形态学_第4张图片
有兴趣可以逛一逛我的个人博客

你可能感兴趣的:(数字图像处理,opencv)