天天看點

基于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)

繼續閱讀