实验三 空域滤波

一、实验目的:

掌握利用模板对图像进行空域滤波操作,熟练掌握常用空域模板的使用。 1、掌握图像平滑的空域方法,熟练掌握均值模板和高斯模板平滑图像 2、掌握图像锐化的空域方法,熟练掌握 Laplacian、Robert、Sobel 模板锐化
图像 3、掌握利用高提升滤波算法对图像进行增强

二、实验内容:

1、利用均值模板平滑灰度图像。
具体内容:利用 OpenCV 对图像像素进行操作,分别利用 3*3、5*5 和 9*9尺寸的均值模板平滑灰度图像
2、利用高斯模板平滑灰度图像。
具体内容:利用 OpenCV 对图像像素进行操作,分别利用 3*3、5*5 和 9*9尺寸的高斯模板平滑灰度图像
3、利用 Laplacian、Robert、Sobel 模板锐化灰度图像。
具体内容:利用 OpenCV 对图像像素进行操作,分别利用 Laplacian、Robert、Sobel 模板锐化灰度图像
4、利用高提升滤波算法增强灰度图像。
具体内容:利用 OpenCV 对图像像素进行操作,设计高提升滤波算法增强图像
5、利用均值模板平滑彩色图像。
具体内容:利用 OpenCV 分别对图像像素的 RGB 三个通道进行操作,利用 3*3、5*5 和 9*9 尺寸的均值模板平滑彩色图像
6、利用高斯模板平滑彩色图像。
具体内容:利用 OpenCV 分别对图像像素的 RGB 三个通道进行操作,分别利用 3*3、5*5 和 9*9 尺寸的高斯模板平滑彩色图像
7、利用 Laplacian、Robert、Sobel 模板锐化彩色图像。
具体内容:利用 OpenCV 分别对图像像素的 RGB 三个通道进行操作,分别利用 Laplacian、Robert、Sobel 模板锐化彩色图像

三.实验过程

对实验内容进行分析,实验利用均值和高斯模版时只是模版内容不同,但通过模版样式平滑图片的过程相同。
所以首先写出一个通用的滤波器。这个滤波器可以处理灰度和彩色的传入图像。

//利用模版进行平滑处理
Mat Filter(const Mat &src,Mat &dst,int ksize,double **templateMatrix){
   
    assert(src.channels()||src.channels()==3);
    //建立滤波器模版
    cout <<ksize<<"*"<<ksize<<"模版为:"<<endl;
    for(int i=0;i<ksize;i++){
   
        for (int j=0; j<ksize; j++) {
   
            cout<<templateMatrix[i][j]<<"";
        }
        cout<<endl;
    }
    int border=ksize/2;
    //边界处理,这里直接调用函数进行
    copyMakeBorder(src, dst, border, border, border, border, BorderTypes::BORDER_REFLECT);
    int channels=src.channels();
    int cols=dst.cols-border;
    int rows=dst.rows-border;
    //开始利用模版进行平滑处理
    for(int i=border;i<rows;i++){
   
        for(int j=border;j<cols;j++){
   
            double sum[3]={
   0};
            for (int k=-border;k<=border;k++){
   
                for(int m=-border;m<=border;m++){
   
                    //灰度
                    if(channels==1){
   
                        sum[0] += (double)templateMatrix[k + border][m + border] * src.at<uchar>(i + k, j + m);
                    }
                    //彩色
                    else if (channels == 3)
                    {
   
                    Vec3b rgb = src.at<Vec3b>(i + k,j + m);
                    auto tmp = templateMatrix[border + k][border + m];
                    sum[0] += tmp*rgb[0];
                    sum[1] += tmp*rgb[1];
                    sum[2] += tmp*rgb[2];
                    }
                }
            }
            //限定像素值在0-255之间
            for (int i = 0; i < channels; i++) {
   
                if (sum[i] < 0)
                    sum[i] = 0;
                else if (sum[i] > 255)
                    sum[i] = 255;
            }
            if (channels == 1) {
   
                dst.at<uchar>(i, j) = static_cast<uchar>(sum[0]);
            }
            else if (channels == 3) {
   
                Vec3b rgb;
                rgb[0] = static_cast<uchar>(sum[0]);
                rgb[1] = static_cast<uchar>(sum[1]);
                rgb[2] = static_cast<uchar>(sum[2]);

                dst.at<Vec3b>(i, j) = rgb;
            }
        }
    }
    return dst;
}

实验

(1)实验1、利用均值模板平滑灰度图像 实验5、利用均值模板平滑彩色图像。

两个实验用的均值处理的模版相同。

//实验一:
void MeanFilter(const Mat &src,Mat &dst,int ksize){
   
    //建立一个二维数组
    double **templateMatrix=new double *[ksize];
    for(int i=0;i<ksize;i++){
   
        templateMatrix[i]=new double [ksize];
    }
    int tmp=ksize*ksize;
    int origin=ksize/2;
    for(int i=0;i<ksize;i++){
   
        for(int j=0;j<ksize;j++){
   
            //每个位置上直接算出来平均值
            templateMatrix[i][j]=1.0/tmp;
        }
    }
    dst=Filter(src,dst,ksize,templateMatrix);
    imshow("lab1", dst);
    waitKey(1000);
}

处理结果:
实验1:利用均值模板平滑灰度图像。
在这里插入图片描述
在这里插入图片描述
实验五:利用均值模板平滑彩色图像。
在这里插入图片描述
在这里插入图片描述

(2)实验2、利用高斯模板平滑灰度图像。实验6、利用高斯模板平滑彩色图像。

高斯公式:
在这里插入图片描述

//实验二:利用高斯模板平滑灰度图像。
void GaussianFilter(const Mat &src,Mat &dst,int ksize,double sigma){
   
    const static double pi=3.1415926;
    //根据窗口大小和sigma生成高斯滤波模版,并申请一个二维数组,存放生成的高斯模版矩阵
    double **templateMatrix=new double *[ksize];
    for(int i=0;i<ksize;i++)
        templateMatrix[i]=new double[ksize];
    int origin=ksize/2; //以模版中心为原点
    double x2,y2;
    double sum=0;
    for(int i=0;i<ksize;i++){
   
        x2=pow(i-origin, 2);
        for(int j=0;j<ksize;j++){
   
            y2=pow(double(j-origin), 2);
            //高斯函数前的常数可以不用计算,会在归一化的过程中消去
            double g=exp(-(x2+y2)/(2*sigma*sigma));
            sum+=g;
            templateMatrix[i][j]=g;
        }
    }
    double k=1/sum;
    for(int i=0;i<ksize;i++){
   
        for(int j=0;j<ksize;j++){
   
            templateMatrix[i][j]*=k;
        }
    }
    dst=Filter(src,dst,ksize,templateMatrix);
    imshow("lab2", dst);
    waitKey(1000);
}

实验结果:
实验2、利用高斯模板平滑灰度图像。
在这里插入图片描述
在这里插入图片描述
实验6、利用高斯模板平滑彩色图像。
在这里插入图片描述
在这里插入图片描述

(3)实验3、利用 Laplacian模板锐化灰度图像。实验 7、利用 Laplacian、模板锐化彩色图像。

这三个锐化模板与之前的平滑模板不同,会出现超过[0,255]范围的结果。对于结算得到的边缘图像,需要标定一下。
首先利用Laplacian:
拉普拉斯经过公式变换后得到几个模版:
在这里插入图片描述
灰度图像下算法过程:

//实验三:使用拉普拉斯进行锐化
int FilterProcessing(Mat src, Mat dst, Mat filter,double ProcessingMethod(Mat filterArea, Mat filter))
{
   
    Mat src_padding=src.clone();
    Mat filterArea;
    int padding = (filter.rows - 1) / 2;
    //padding the border
    copyMakeBorder(src, src_padding, padding, padding, padding, padding, BORDER_REPLICATE);

    if (dst.type() == CV_8U)
    {
   
        for (int y = padding; y < src_padding.rows - padding; y++)
        {
   
            for (int x = padding; x < src_padding.cols - padding; x++)
            {
   
                filterArea = src_padding(Range(y - padding, y + padding + 1), Range(x - padding, x + padding + 1));
                dst.at<uchar>(y - padding, x - padding) = cvRound(ProcessingMethod(filterArea, filter));
            }
        }
    }
    else if (dst.type() == CV_64F)
    {
   
        for (int y = padding; y < src_padding.rows - padding; y++)
        {
   
            for (int x = padding; x < src_padding.cols - padding; x++)
            {
   
                filterArea = src_padding(Range(y - padding, y + padding + 1), Range(x - padding, x + padding + 1));
                dst.at<double>(y - padding, x - padding) = ProcessingMethod(filterArea, filter);
            }
        }
    }
    else
    {
   
        cout << "type error" << endl;
    }

    return 0;
}
double LinearFilterCalc(Mat filterArea, Mat linearFilter)
{
   
    double result = 0;
    for (int y = 0; y < filterArea.rows; y++)
    {
   
        for (int x = 0; x < filterArea.cols; x++)
        {
   
            result += (double(filterArea.at<uchar>(y, x)))*(linearFilter.at<double>(y, x));
        }
    }
    return result;
}
int LaplacianFilterProcessing(Mat src, Mat dst, Mat laplacianFilter, Mat laplacianFilterImg, double c)
{
   

    FilterProcessing(src, laplacianFilterImg, laplacianFilter, LinearFilterCalc);
        
    //计算并标定锐化结果,直接saturate_cast<uchar>
    for (int y = 0; y < src.rows; y++)
    {
   
        for (int x = 0; x < src.cols; x++)
        {
   
            dst.at<uchar>(y, x) = saturate_cast<uchar>(src.at<uchar>(y, x) + cvRound(c*laplacianFilterImg.at<double>(y, x)));
        }
    }

    return 0;
}
int LaplacianSharpen(Mat src, Mat dst, string title, double c, int filterNum)//dst是锐化后的结果图像
{
   
    Mat laplacianFilter_n4 = (Mat_<double>(3, 3) <<
        0, 1, 0,
        1, -4, 1,
        0, 1, 0);
    /*Mat laplacianFilter_n8 = (Mat_<double>(3, 3) <<
        1, 1, 1,
        1, -8, 1,
        1, 1, 1);*/
    Mat laplacianFilter;
    string filterTitle;
    laplacianFilter = laplacianFilter_n4;
    filterTitle = "1 -4 1";

    Mat laplacianFilterImg = Mat::zeros(src.size(), CV_64F);//滤波后得到的边缘图像

    LaplacianFilterProcessing(src, dst, laplacianFilter, laplacianFilterImg, c);

    /*标定Laplacian滤波得到的边缘结果*/
    double maxLap, minLap;
    minMaxLoc(laplacianFilterImg, &minLap, &maxLap, <
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值