天天看点

基于opencv的高斯滤波实现的VC++代码

一、设计思路

  • 新建CZQLImgPro类

私有数据成员:高斯滤波器的大小(nwindowsize),高斯滤波器方差(sigma),高斯滤波器(Mat Gauss),二值化阈值(binaryT)。

私有成员函数:生成高斯滤波器函数。

共有成员函数:设置高斯滤波参数;设置二值化阈值函数;阈值分割函数;高斯滤波函数。

重载两个构造函数:初始化高斯滤波参数;初始化阈值分割参数。

  • 阈值分割算法过程

设置一个二值化阈;

判断每一个像素的灰度值:灰度值大于阈值的赋值为255,灰度值小于阈值的赋值为0。

  • 高斯滤波算法过程

由高斯滤波器窗口大小nwindowsize计算gauss滤波器空间;

计算高斯滤波器:利用高斯函数求出每一个像素的值后,进行归一化处理。

利用高斯滤波器进行卷积。

  • 对话框类接口

二值化按钮:判断是否读入原始影像并且输入的二值化阈值为[0,255]的数,如果是则调用阈值分割函数。

高斯滤波按钮:判断是否读入元使用想并且输入额高斯滤波器大小nwindowsize为正奇数,如果是则调用高斯滤波函数。

二、主要代码

//ZLImgPro.h 头文件
#pragmaonce
#include"opencv2\core\core.hpp"
usingnamespace cv;
classCZQLImgPro
{
public:
   CZQLImgPro(void);
   ~CZQLImgPro(void);
   CZQLImgPro(int n_windowsize,floatd_sigma);//构造函数重载(设置高斯滤波参数)
   CZQLImgPro(int i_binaryT);                //构造函数重载(设置阈值分割参数)
private:
   int nwindowsize; //高斯滤波器的大小
   float sigma;     //高斯滤波器方差
   MatGauss;       //高斯滤波器
   int binaryT;     //二值化阈值
private:
   void CreatGauss();                               //生成高斯滤波器
public:
   void setGauss(intn_windowsize,float d_sigma);   //设置高斯滤波参数
   void setBinaryT(inti_binaryT);                  //设置二值化阈值
   void BinaryImg(constMat srcimg,Mat &result);    //阈值分割函数
   void Gaussianfilter(constMat srcimg,Mat &result);//高斯滤波
};
           
//ZLImgPro.cpp 实现文件
 
#include"StdAfx.h"
#include"ZQLImgPro.h"
#include"math.h"
constfloat PI=4.0*atan(1.0);
 
//默认构造函数
CZQLImgPro::CZQLImgPro(void)
{
   nwindowsize=0;
   sigma=0;
   Gauss.create(nwindowsize,nwindowsize,CV_32F);
}
//析构函数
CZQLImgPro::~CZQLImgPro(void)
{
}
//构造函数重载(设置高斯滤波参数)
CZQLImgPro::CZQLImgPro(intn_windowsize,float d_sigma)
{
   nwindowsize=n_windowsize;
   sigma=d_sigma;
   Gauss.create(nwindowsize,nwindowsize,CV_32F);
}
//构造函数重载(设置阈值分割参数)
CZQLImgPro::CZQLImgPro(intiBinaryT)
{
   binaryT=iBinaryT;
}
//设置高斯滤波参数
voidCZQLImgPro::setGauss(int n_windowsize,float d_sigma)
{
   nwindowsize=n_windowsize;
   sigma=d_sigma;
   Gauss.create(nwindowsize,nwindowsize,CV_32F);
}
//设置二值化阈值
voidCZQLImgPro::setBinaryT(int iBinaryT)
{
   binaryT=iBinaryT;
}
//阈值分割函数
voidCZQLImgPro::BinaryImg(const Mat srcimg,Mat&result)
{
   //给目标影像分配内存
   result.create(srcimg.rows,srcimg.cols,srcimg.type());
   for (inti=0;i<srcimg.rows;i++)
   {
       for (intj=0;j<srcimg.cols;j++)
       {
           int graytmp=srcimg.at<uchar>(i,j);
           if (graytmp>binaryT) //大于阈值赋予255否则赋予0
               result.at<uchar>(i,j)=255;
           else
               result.at<uchar>(i,j)=0;
       }
   }
}
//生成高斯滤波器
voidCZQLImgPro::CreatGauss()
{
   floatsum=0;
   for(inti=0;i<nwindowsize;i++)
   {
       for(intj=0;j<nwindowsize;j++)
       {
           int x=i-(nwindowsize-1)/2;
           int y=j-(nwindowsize-1)/2;
           Gauss.at<float>(i,j)=exp(-(x*x+y*y)/(2*sigma*sigma))
               /(2*PI*sigma*sigma);//利用高斯公式计算计算滤波器
 
           //float m=exp(-(x*x+y*y)/(2*sigma*sigma));
           //float q=Gauss.at<float>(i,j);
           sum+=Gauss.at<float>(i,j);
       }
   }
 
   //进行归一化处理
   for(inti=0;i<nwindowsize;i++)
   {
       for (int j=0;j<nwindowsize;j++)
       {
           Gauss.at<float>(i,j)/=sum;
       }
   }
}
 
//高斯滤波
voidCZQLImgPro::Gaussianfilter(const Mat srcimg,Mat&result)
{
CreatGauss();//计算高斯滤波器
   //给目标影像分配内存
   result.create(srcimg.rows,srcimg.cols,srcimg.type());
   int rows=srcimg.rows;
   int cols=srcimg.cols;
   for (inti=0;i<rows;i++)
   {
       for (intj=0;j<cols;j++)
       {
           result.at<uchar>(i,j)=0;
           //将结果矩阵初始化为零矩阵
       }
   }
   int nhalfw=nwindowsize/2;
   int sum=0;
   for (inti=nhalfw;i<rows-nhalfw;i++)
   {
       for (intj=nhalfw;j<cols-nhalfw;j++)
       {
          sum=0;
           for (intm=-nhalfw;m<nwindowsize-nhalfw;m++)
           {
               for (intn=-nhalfw;n<nwindowsize-nhalfw;n++)
               {
                  sum+=Gauss.at<float>(m+nhalfw,n+nhalfw)*srcimg.at<uchar>(i+m,j+n);
                  //利用高斯滤波器进行卷积
               }
           }
           result.at<uchar>(i,j)=sum;
       }
   }
}
           
// ZQL_0107150120_1Dlg.h :头文件
#pragmaonce
#include"opencv2/core/core.hpp"
usingnamespace cv;
#include<vector>
usingnamespace std;
// CZQL_0107150120_1Dlg对话框
classCZQL_0107150120_1Dlg :public CDialogEx
{
public:
   Matm_srcimg;                //原始影像灰度矩阵
   Matresult;                  //结果影像灰度矩阵
   CStringstrResultImgName;    //结果影像名称
   int m_binaryT;               //二值化阈值
   CStringm_strImgName;        //原始影像名称
   float fSigma;                //高斯滤波器方差sigma
   int nwindowsize;             //高斯滤波器大小
   bool bRead;                  //判断是否读入影像
 
   afx_msgvoid OnBnClickedBtnOpen();        //打开影像
   afx_msgvoid OnBnClickedBtnSave();        //保存影像
   afx_msgvoid OnBnClickedBtnGauss();       //高斯滤波
   afx_msgvoid OnBnClickedBtnBinarization();//进行图像二值化
};
           
// ZQL_0107150120_1Dlg.cpp :实现文件
#include"opencv2/highgui/highgui.hpp"
usingnamespace std;
CZQL_0107150120_1Dlg::CZQL_0107150120_1Dlg(CWnd*pParent/*=NULL*/)
   :CDialogEx(CZQL_0107150120_1Dlg::IDD, pParent)
   ,m_binaryT(0)
   ,m_strImgName(_T(""))
   , fSigma(0)
   ,strResultImgName(_T(""))
   ,nwindowsize(0)
   ,bRead(FALSE)
{
   m_hIcon =AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
voidCZQL_0107150120_1Dlg::OnBnClickedBtnOpen()
{
   // TODO:在此添加控件通知处理程序代码
   UpdateData(TRUE);
   CFileDialogFileDlg(TRUE,"*.jpg;*.bmp","*.jpg;*.bmp",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"影像文件()");
   if (FileDlg.DoModal()!=IDOK)
   {
       return;
   }
   m_strImgName=FileDlg.GetPathName();
   bRead=TRUE;        //标记已经读入影像
   UpdateData(FALSE); //将影像名字显示到对话框中
   m_srcimg=imread(m_strImgName.GetBuffer(),CV_LOAD_IMAGE_GRAYSCALE);//打开影像
   imshow("原始影像",m_srcimg);//图像显示
   cvWaitKey();                //等待鼠标响应
}
 
voidCZQL_0107150120_1Dlg::OnBnClickedBtnBinarization()
{
   // TODO:在此添加控件通知处理程序代码
   UpdateData(TRUE);
   if (bRead!=TRUE)
   {
       MessageBox("请读入影像文件");
       return;
   }
   if (m_binaryT<0||m_binaryT>255)
   {
       MessageBox("二值化阈值应为一个在区间[0,255]的正数");
       return;
   }
   CZQLImgProimp(m_binaryT);//定义CZQLImgPro对象
   imp.BinaryImg(m_srcimg,result);
   //图像显示
   imshow("二值化影像",result); 
   cvWaitKey(0);     //等待鼠标响应
}
 
voidCZQL_0107150120_1Dlg::OnBnClickedBtnSave()
{
   // TODO:在此添加控件通知处理程序代码
   CFileDialogFileDlg(FALSE,_T("jpg"));//创建保存图像对话框
   if (FileDlg.DoModal()!=IDOK)
   {
       return;
   }
   strResultImgName=FileDlg.GetPathName();  //用于保存结果
   if (strResultImgName!="")
   {
      imwrite(strResultImgName.GetBuffer(),result);//将结果影像写入文件
   }
   UpdateData(FALSE);
}
 
voidCZQL_0107150120_1Dlg::OnBnClickedBtnGauss()
{
   // TODO:在此添加控件通知处理程序代码
   UpdateData(TRUE);
   if (bRead!=TRUE)
   {
       MessageBox("请读入影像文件");
       return;
   }
   
   if (nwindowsize%2!=1)
   {
       MessageBox("nwindowsize应为一个正奇数");
       return;
   }
 
   if (fSigma<=0)
   {
       MessageBox("sigma应为一个正数");
       return;
   }
   CZQLImgProimp(nwindowsize,fSigma);//定义CZQLImgPro对象
   imp.Gaussianfilter(m_srcimg,result);//进行高斯滤波
   imshow("高斯平滑影像",result);
   cvWaitKey(0);     //等待鼠标响应
}
           

三、运行结果

基于opencv的高斯滤波实现的VC++代码

原始影像

基于opencv的高斯滤波实现的VC++代码

二值化影像(阈值为100)

基于opencv的高斯滤波实现的VC++代码

高斯平滑影像(滤波器大小3X3,σ=1.5)

继续阅读