前言
又咕了一个学期,上学期的东西都没写完,惭愧惭愧。
实验要求
- 空域滤波
1.1 设计高斯滤波器模板函数
1.2 填充图像,将模板函数与图像进行卷积
1.3 截取图像,获得滤波后的图像 - 腐蚀/膨胀算法
2.1 读取图片
2.2 腐蚀/膨胀算法
2.3 将经过腐蚀或膨胀后的图片显示
代码实现
#include <stdlib.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
#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;
}
运行结果
有兴趣可以逛一逛我的个人博客