1. 程式人生 > >形態Haar小波的OpenCV程式碼

形態Haar小波的OpenCV程式碼

////////////////////////////////////////////////////////////////////////

//-正變換,放在標頭檔案中

#pragma once

#include "cv.h"
#include "highgui.h"

using namespace cv;

Mat MWT(Mat img,int nlevs)
{
 int halfH = img.rows/2;
 int halfW = img.cols/2;

 Mat img64f;
 img.convertTo(img64f,CV_64F);

 Mat temp = Mat(img.rows,img.cols,CV_64F,Scalar::all(0));

 for(int n=nlevs;n>0;n--)
 {
  for(int i=0;i<halfH;i++)
  {
   for(int j=0;j<halfW;j++)
   {
    //結構元素B
    double b11 = img64f.at<double>(2*i,2*j);
    double b12 = img64f.at<double>(2*i,2*j+1);
    double b21 = img64f.at<double>(2*i+1,2*j);
    double b22 = img64f.at<double>(2*i+1,2*j+1);
    
    double M = min(min(min(b11,b12),b21),b22);
    double Yh = (b11-b21+b12-b22)/2;
    double Yv = (b11-b12+b21-b22)/2;    
    double Yd = (b11-b12-b21+b22)/2;
    
    temp.at<double>(i,j) = M;
    temp.at<double>(i,j+halfW) = Yh;
    temp.at<double>(i+halfH,j) = Yv;    
    temp.at<double>(i+halfH,j+halfW) = Yd;
   }
  }
  img64f = temp.clone();
  halfW = halfW/2;
  halfH = halfH/2;
 } 
 return temp;
}
////////////////////////////////////////////////////////////////////////////////////////////

//反變換,放在標頭檔案中

#ifndef _IMWT_H_
#define _IMWT_H_

#include "cv.h"
#include "highgui.h"

using namespace cv;

// 功能計演算法x的n次方
template <class T>
T power( T x, int m)
{
 int i;       //迴圈次數
 T p=1;   //存放結果
 for (i=1;i<=m;i++)
  p=p*x;
 return p;
}

Mat IMWT(Mat img,int nlevs)
{
 // 臨時矩陣,用於儲存矩陣資料
 Mat temp = Mat(img.rows,img.cols,CV_64F,Scalar::all(0));
 
 int p = power(2,nlevs);
 int iw = img.cols/p;
 int ih = img.rows/p;

 for(int n= nlevs;n>0;n--)
 {
  // 獲得尺度訊號的寬和高
  for(int i=0;i<ih;i++)
  {
   for(int j=0;j<iw;j++)
   {
    double m = img.at<double >(i,j);
    double h = img.at<double >(i,j+iw);
    double v = img.at<double >(i+ih,j);
    double d = img.at<double >(i+ih,j+iw);

    double  rm  = max(max(max(v+h,v+d),h+d),0.0);
    double  rh =  max(max(max(h-v,-v-d),h-d),0.0);
    double  rv =  max(max(max(v-h,v-d),-h-d),0.0);
    double  rd =  max(max(max(-v-h,d-v),d-h),0.0);

       temp.at<double>(2*i,2*j) = m+rm;
    temp.at<double>(2*i,2*j+1) = m+rh;
    temp.at<double>(2*i+1,2*j) = m+rv;
       temp.at<double>(2*i+1,2*j+1) = m+rd;
   }
  }
  iw = iw*2;
  ih = ih*2;
  for(int i=0;i<iw;i++)
  {
   for(int j=0;j<ih;j++)
   {
    img.at<double>(i,j) = temp.at<double>(i,j);
   }
  }
 }
 temp.convertTo(temp,CV_8U,1.0,0.0);
 return temp;
}
#endif

/////////////////////////////////////////

// -主程式

#include "cv.h"
#include "highgui.h"
#include "MWT.h"
#include "IMWT.h"

#include <iostream>
using namespace cv;
using namespace std;

int main()
{
 Mat img1 = imread("zoneplate.png",0);  //單通道
 int nlev;
 cout<<"Please input nlev:";
 cin>>nlev;

 Mat imgdec = Mat(img1.rows,img1.cols,CV_64F);
 imgdec = MWT(img1,nlev);

 Mat imgdec8u;
 imgdec.convertTo(imgdec8u,CV_8U);

 Mat imgrec = Mat(img1.rows,img1.cols,CV_8U,Scalar::all(0));
 imgrec = IMWT(imgdec,nlev);

 namedWindow("img",1);
 imshow("img",img1);

 namedWindow("imgdec",1);
 imshow("imgdec",imgdec8u);

 namedWindow("imgrec",1);
 imshow("imgrec",imgrec);

 subtract(img1,imgrec,imgrec);
 namedWindow("deta",1);
 imshow("deta",imgrec);

 Scalar m = mean(imgrec);

 cout<<"原圖-重建影象的均值:"<<m.val[0]<<endl;
 cout<<"完美重建";

 waitKey();
 return 0;

}