高斯滤波的实现-C++(vs2022)

本文介绍了如何使用VS2022开发基于MFC的图像处理应用程序,实现图像的二值化和高斯滤波功能。通过对话框界面,用户可以加载图像,然后点击按钮进行二值化或高斯滤波操作。二值化代码将图像按阈值分割成黑白两部分,高斯滤波则利用自定义高斯模板进行卷积处理,平滑图像。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、打开VS2022软件,创建一个基于对话框(MFC)的应用程序;

2、编辑对话框界面如下:

3、为编辑框设置变量,获取界面输入的数值。

4、为按钮控件设置点击事件代码。如下:OnBnClickedButton1()对应二值化按钮,OnBnClickedButtoncalgauss()对应高斯滤波按钮。

void CxxxxDlg::OnBnClickedButton1()
{
    // TODO: 在此添加控件通知处理程序代码
    CFileDialog FileDlg(TRUE, "*.jpg;*.bmp", "*.jpg;*.bmp", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "影像文件()");
    if (FileDlg.DoModal() != IDOK)
    {
        return;
    }
    CString strImgName = FileDlg.GetPathName();

    Cxxxx_ImgPro img;
    Mat m_srcimg = imread(strImgName.GetBuffer(), IMREAD_GRAYSCALE);
    imshow("src image", m_srcimg); //显示
    waitKey(); //等待操作,将窗口关闭\回车\ESC等操作会运行以下的程序

    Mat binaeryImg;
    img.BinaryImg(m_srcimg,100, binaeryImg);
    imshow("binaeryImg", binaeryImg); //显示
    waitKey();
}


void CxxxxDlg::OnBnClickedButtoncalgauss()
{
    // TODO: 在此添加控件通知处理程序代码
    UpdateData(TRUE);
    UpdateData(FALSE);
    CFileDialog FileDlg(TRUE, "*.jpg;*.bmp", "*.jpg;*.bmp", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "影像文件()");
    if (FileDlg.DoModal() != IDOK)
    {
        return;
    }
    CString strImgName = FileDlg.GetPathName();

    Cxxxx_ImgPro img;

    Mat m_srcimg = imread(strImgName.GetBuffer(), IMREAD_GRAYSCALE);
    imshow("src image", m_srcimg); //显示
    


    int nwiddowsize = 3;
    nwiddowsize = m_windowsH;
    Mat Gauss;

    img.CreatGauss(nwiddowsize,m_sigma,Gauss);
    img.Gaussianfilter(m_srcimg, nwiddowsize,m_sigma,Gauss);

    imshow("高斯滤波结果",m_srcimg);
    waitKey(); //等待操作,将窗口关闭\回车\ESC等操作会运行以下的程序
}

5、处理结果。

 

 

二值化的结果

 高斯滤波结果

 6、高斯滤波代码展示

//二值分割函数
void CWGY_ImgPro::BinaryImg(const Mat srcimg, const int binaryT, Mat &dstimg)
{
    dstimg.create(srcimg.rows, srcimg.cols, srcimg.type());

    //访问图像是一行行访问,从上到下,
    for (int i = 0; i < srcimg.rows; i++)
    {
        //每一行 是从左到右
        for (int j = 0; j < srcimg.cols; j++)
        {
            //访问位置 (i,j) 注意 y在前,x 在后
            //返回 uchar (unsigned char 的 代名词)
            int graytmp = srcimg.at<uchar>(i, j);
            if (graytmp > binaryT)  //大于阈值赋予 255
            {
                dstimg.at<uchar>(i, j) = 255;
            }
            else
            {
                dstimg.at<uchar>(i, j) = 0;
            }
        }
    }
}

//高斯模板计算函数,得到卷积核
void CWGY_ImgPro::CreatGauss(const int nwiddowsize, float sigma, Mat &Gauss)
{
    Gauss.create(nwiddowsize, nwiddowsize,CV_32FC1);   //窗口大小

    float a = 1 / (2 * PI*sigma*sigma);
    float b; 

    double dSum=0;

    //计算高斯模板,并得到卷积核
    for (int i = 0; i < nwiddowsize; i++)
    {
        for (int j = 0; j < nwiddowsize; j++)
        {
            int c;
            c = i - 1;
            int d;
            d = j - 1;

            b = exp(-(c*c + d * d) / (2 * sigma*sigma));
            Gauss.at<float>(i, j) = a * b;
            dSum += Gauss.at<float>(i, j);
        }
    }

    //归一化
    for (int i = 0; i < nwiddowsize; i++)
    {
        for (int j = 0; j < nwiddowsize; j++)
        {
            Gauss.at<float>(i, j) = Gauss.at<float>(i,j) / dSum;
        }
    }

}

//高斯滤波函数,对图像进行卷积
void CWGY_ImgPro::Gaussianfilter(Mat srcImg, const int nwiddowsize, const float sigma, Mat &Gauss)
{
    int k;
    k = (nwiddowsize / 2);           //计算图像开始卷积像素点坐标

    Mat tux;             //存放图像卷积结果
    tux.create(srcImg.rows, srcImg.cols, CV_32FC1);

    double dSum = 0;        //用于存储被处理图像的单个像素的卷积结果

    for (int m = k; m < srcImg.rows-k; m++)
    {
        for (int n = k; n <srcImg.cols-k; n++)
        {
            dSum = 0;
            for (int i = 0; i < nwiddowsize; i++)
            {
                for (int j = 0; j < nwiddowsize; j++)
                {
                    double a;
                    a = float(srcImg.at<uchar>(m-k+i, n-k+j))*Gauss.at<float>(i, j);       //对每个像素进行卷积运算
                    dSum += a;
                }
            }
            tux.at<float>(m, n) = dSum;     //结果图像矩阵
        }
    }

    for (int i = 0; i < srcImg.rows - k; i++)
    {
        for (int j = 0; j < srcImg.rows - k; j++)
        {
            srcImg.at<uchar>(i, j) = tux.at<float>(i, j);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值