openCV中的小波变换



是否有人尝试在opencv或C++中实现DWT?我看到了关于这个主题的旧帖子,但我觉得它们对我没有用处,因为我需要一个近似系数和小波变换的细节。

我试着把它添加到我的项目中,但它没有按计划运行。

这很简单,因为作为结果,参数我需要近似系数和细节:

void haar1(float *vec, int n, int w)
{
int i=0;
float *vecp = new float[n];
for(i=0;i<n;i++)
    vecp[i] = 0;
    w/=2;
    for(i=0;i<w;i++)
    {
        vecp[i] = (vec[2*i] + vec[2*i+1])/sqrt(2.0);
        vecp[i+w] = (vec[2*i] - vec[2*i+1])/sqrt(2.0);
    }
    
    for(i=0;i<(w*2);i++)
            vec[i] = vecp[i];
        delete [] vecp;
}
void haar2(float **matrix, int rows, int cols)
{
    float *temp_row = new float[cols];
    float *temp_col = new float[rows];
    int i=0,j=0;
    int w = cols, h=rows;
while(w>1 || h>1)
{
    if(w>1)
    {
        for(i=0;i<h;i++)
        {
            for(j=0;j<cols;j++)
                temp_row[j] = matrix[i][j];
            haar1(temp_row,cols,w);
            
            for(j=0;j<cols;j++)
                matrix[i][j] = temp_row[j];
        }
    }
    if(h>1)
    {
        for(i=0;i<w;i++)
        {
            for(j=0;j<rows;j++)
                temp_col[j] = matrix[j][i];
            haar1(temp_col, rows, h);
            for(j=0;j<rows;j++)
                matrix[j][i] = temp_col[j];
        }
    }
    if(w>1)
        w/=2;
    if(h>1)
        h/=2;
}
    delete [] temp_row;
    delete [] temp_col;
}

所以有人能帮我找到用C++实现的dwt吗?或者告诉我如何从上面的代码系数中提取系数。感谢

这里是直接和反向Haar小波变换(用于滤波):

#include "opencv2/opencv.hpp"
#include <iostream>
#include <vector>
#include <stdio.h>
using namespace cv;
using namespace std;
// Filter type
#define NONE 0  // no filter
#define HARD 1  // hard shrinkage
#define SOFT 2  // soft shrinkage
#define GARROT 3  // garrot filter
//--------------------------------
// signum
//--------------------------------
float sgn(float x)
{
    float res=0;
    if(x==0)
    {
        res=0;
    }
    if(x>0)
    {
        res=1;
    }
    if(x<0)
    {
        res=-1;
    }
    return res;
}
//--------------------------------
// Soft shrinkage
//--------------------------------
float soft_shrink(float d,float T)
{
    float res;
    if(fabs(d)>T)
    {
        res=sgn(d)*(fabs(d)-T);
    }
    else
    {
        res=0;
    }
    return res;
}
//--------------------------------
// Hard shrinkage
//--------------------------------
float hard_shrink(float d,float T)
{
    float res;
    if(fabs(d)>T)
    {
        res=d;
    }
    else
    {
        res=0;
    }
    return res;
}
//--------------------------------
// Garrot shrinkage
//--------------------------------
float Garrot_shrink(float d,float T)
{
    float res;
    if(fabs(d)>T)
    {
        res=d-((T*T)/d);
    }
    else
    {
        res=0;
    }
    return res;
}
//--------------------------------
// Wavelet transform
//--------------------------------
static void cvHaarWavelet(Mat &src,Mat &dst,int NIter)
{
    float c,dh,dv,dd;
    assert( src.type() == CV_32FC1 );
    assert( dst.type() == CV_32FC1 );
    int width = src.cols;
    int height = src.rows;
    for (int k=0;k<NIter;k++) 
    {
        for (int y=0;y<(height>>(k+1));y++)
        {
            for (int x=0; x<(width>>(k+1));x++)
            {
                c=(src.at<float>(2*y,2*x)+src.at<float>(2*y,2*x+1)+src.at<float>(2*y+1,2*x)+src.at<float>(2*y+1,2*x+1))*0.5;
                dst.at<float>(y,x)=c;
                dh=(src.at<float>(2*y,2*x)+src.at<float>(2*y+1,2*x)-src.at<float>(2*y,2*x+1)-src.at<float>(2*y+1,2*x+1))*0.5;
                dst.at<float>(y,x+(width>>(k+1)))=dh;
                dv=(src.at<float>(2*y,2*x)+src.at<float>(2*y,2*x+1)-src.at<float>(2*y+1,2*x)-src.at<float>(2*y+1,2*x+1))*0.5;
                dst.at<float>(y+(height>>(k+1)),x)=dv;
                dd=(src.at<float>(2*y,2*x)-src.at<float>(2*y,2*x+1)-src.at<float>(2*y+1,2*x)+src.at<float>(2*y+1,2*x+1))*0.5;
                dst.at<float>(y+(height>>(k+1)),x+(width>>(k+1)))=dd;
            }
        }
        dst.copyTo(src);
    }   
}
//--------------------------------
//Inverse wavelet transform
//--------------------------------
static void cvInvHaarWavelet(Mat &src,Mat &dst,int NIter, int SHRINKAGE_TYPE=0, float SHRINKAGE_T=50)
{
    float c,dh,dv,dd;
    assert( src.type() == CV_32FC1 );
    assert( dst.type() == CV_32FC1 );
    int width = src.cols;
    int height = src.rows;
    //--------------------------------
    // NIter - number of iterations 
    //--------------------------------
    for (int k=NIter;k>0;k--) 
    {
        for (int y=0;y<(height>>k);y++)
        {
            for (int x=0; x<(width>>k);x++)
            {
                c=src.at<float>(y,x);
                dh=src.at<float>(y,x+(width>>k));
                dv=src.at<float>(y+(height>>k),x);
                dd=src.at<float>(y+(height>>k),x+(width>>k));
               // (shrinkage)
                switch(SHRINKAGE_TYPE)
                {
                case HARD:
                    dh=hard_shrink(dh,SHRINKAGE_T);
                    dv=hard_shrink(dv,SHRINKAGE_T);
                    dd=hard_shrink(dd,SHRINKAGE_T);
                    break;
                case SOFT:
                    dh=soft_shrink(dh,SHRINKAGE_T);
                    dv=soft_shrink(dv,SHRINKAGE_T);
                    dd=soft_shrink(dd,SHRINKAGE_T);
                    break;
                case GARROT:
                    dh=Garrot_shrink(dh,SHRINKAGE_T);
                    dv=Garrot_shrink(dv,SHRINKAGE_T);
                    dd=Garrot_shrink(dd,SHRINKAGE_T);
                    break;
                }
                //-------------------
                dst.at<float>(y*2,x*2)=0.5*(c+dh+dv+dd);
                dst.at<float>(y*2,x*2+1)=0.5*(c-dh+dv-dd);
                dst.at<float>(y*2+1,x*2)=0.5*(c+dh-dv-dd);
                dst.at<float>(y*2+1,x*2+1)=0.5*(c-dh-dv+dd);            
            }
        }
        Mat C=src(Rect(0,0,width>>(k-1),height>>(k-1)));
        Mat D=dst(Rect(0,0,width>>(k-1),height>>(k-1)));
        D.copyTo(C);
    }   
}
//--------------------------------
//
//--------------------------------
int process(VideoCapture& capture)
{
    int n = 0;
    const int NIter=4;
    char filename[200];
    string window_name = "video | q or esc to quit";
    cout << "press space to save a picture. q or esc to quit" << endl;
    namedWindow(window_name, CV_WINDOW_KEEPRATIO); //resizable window;
    Mat frame;
    capture >> frame;
    Mat GrayFrame=Mat(frame.rows, frame.cols, CV_8UC1);
    Mat Src=Mat(frame.rows, frame.cols, CV_32FC1);
    Mat Dst=Mat(frame.rows, frame.cols, CV_32FC1);
    Mat Temp=Mat(frame.rows, frame.cols, CV_32FC1);
    Mat Filtered=Mat(frame.rows, frame.cols, CV_32FC1);
    for (;;) 
    {
        Dst=0;
        capture >> frame;
        if (frame.empty()) continue;
        cvtColor(frame, GrayFrame, CV_BGR2GRAY);
        GrayFrame.convertTo(Src,CV_32FC1);
        cvHaarWavelet(Src,Dst,NIter);
        Dst.copyTo(Temp);
        cvInvHaarWavelet(Temp,Filtered,NIter,GARROT,30);
        imshow(window_name, frame);
        double M=0,m=0;
        //----------------------------------------------------
        // Normalization to 0-1 range (for visualization)
        //----------------------------------------------------
        minMaxLoc(Dst,&m,&M);
        if((M-m)>0) {Dst=Dst*(1.0/(M-m))-m/(M-m);}
        imshow("Coeff", Dst);
        minMaxLoc(Filtered,&m,&M);
        if((M-m)>0) {Filtered=Filtered*(1.0/(M-m))-m/(M-m);}        
        imshow("Filtered", Filtered);
        char key = (char)waitKey(5);
        switch (key) 
        {
        case 'q':
        case 'Q':
        case 27: //escape key
            return 0;
        case ' ': //Save an image
            sprintf(filename,"filename%.3d.jpg",n++);
            imwrite(filename,frame);
            cout << "Saved " << filename << endl;
            break;
        default:
            break;
        }
    }
    return 0;
}
int main(int ac, char** av) 
{
    VideoCapture capture(0);
    if (!capture.isOpened()) 
    {
        return 1;
    }
    return process(capture);
}

下面是Mahavir在OpenCV中实现的另一个小波变换:

            #include <opencv2highguihighgui.hpp>
            #include <opencv2corecore.hpp>
            #include <opencv2coremat.hpp>
            #include <opencv2imgprocimgproc.hpp>
            #include<iostream>
            #include<math.h>
            #include<conio.h>
            using namespace std;
            using namespace cv;
            class image
            {
            public:
                Mat im,im1,im2,im3,im4,im5,im6,temp,im11,im12,im13,im14,imi,imd,imr;
                float a,b,c,d;
                int getim();
            };
            int image::getim()
            {
                im=imread("lena.jpg",0); //Load image in Gray Scale
                imi=Mat::zeros(im.rows,im.cols,CV_8U);
                im.copyTo(imi);
                im.convertTo(im,CV_32F,1.0,0.0);
                im1=Mat::zeros(im.rows/2,im.cols,CV_32F);
                im2=Mat::zeros(im.rows/2,im.cols,CV_32F);
                im3=Mat::zeros(im.rows/2,im.cols/2,CV_32F);
                im4=Mat::zeros(im.rows/2,im.cols/2,CV_32F);
                im5=Mat::zeros(im.rows/2,im.cols/2,CV_32F);
                im6=Mat::zeros(im.rows/2,im.cols/2,CV_32F);
                //--------------Decomposition-------------------
                for(int rcnt=0;rcnt<im.rows;rcnt+=2)
                {
                    for(int ccnt=0;ccnt<im.cols;ccnt++)
                    {
                        a=im.at<float>(rcnt,ccnt);
                        b=im.at<float>(rcnt+1,ccnt);
                        c=(a+b)*0.707;
                        d=(a-b)*0.707;
                        int _rcnt=rcnt/2;
                        im1.at<float>(_rcnt,ccnt)=c;
                        im2.at<float>(_rcnt,ccnt)=d;
                    }
                }
                for(int rcnt=0;rcnt<im.rows/2;rcnt++)
                {
                    for(int ccnt=0;ccnt<im.cols;ccnt+=2)
                    {
                        a=im1.at<float>(rcnt,ccnt);
                        b=im1.at<float>(rcnt,ccnt+1);
                        c=(a+b)*0.707;
                        d=(a-b)*0.707;
                        int _ccnt=ccnt/2;
                        im3.at<float>(rcnt,_ccnt)=c;
                        im4.at<float>(rcnt,_ccnt)=d;
                    }
                }
                for(int rcnt=0;rcnt<im.rows/2;rcnt++)
                {
                    for(int ccnt=0;ccnt<im.cols;ccnt+=2)
                    {
                        a=im2.at<float>(rcnt,ccnt);
                        b=im2.at<float>(rcnt,ccnt+1);
                        c=(a+b)*0.707;
                        d=(a-b)*0.707;
                        int _ccnt=ccnt/2;
                        im5.at<float>(rcnt,_ccnt)=c;
                        im6.at<float>(rcnt,_ccnt)=d;
                    }
                }
                imr=Mat::zeros(256,256,CV_32F);
                imd=Mat::zeros(256,256,CV_32F);
                im3.copyTo(imd(Rect(0,0,128,128)));
                im4.copyTo(imd(Rect(0,127,128,128)));
                im5.copyTo(imd(Rect(127,0,128,128)));
                im6.copyTo(imd(Rect(127,127,128,128)));

                //---------------------------------Reconstruction-------------------------------------
                im11=Mat::zeros(im.rows/2,im.cols,CV_32F);
                im12=Mat::zeros(im.rows/2,im.cols,CV_32F);
                im13=Mat::zeros(im.rows/2,im.cols,CV_32F);
                im14=Mat::zeros(im.rows/2,im.cols,CV_32F);
                for(int rcnt=0;rcnt<im.rows/2;rcnt++)
                {
                    for(int ccnt=0;ccnt<im.cols/2;ccnt++)
                    {
                        int _ccnt=ccnt*2;
                        im11.at<float>(rcnt,_ccnt)=im3.at<float>(rcnt,ccnt);     //Upsampling of stage I
                        im12.at<float>(rcnt,_ccnt)=im4.at<float>(rcnt,ccnt);
                        im13.at<float>(rcnt,_ccnt)=im5.at<float>(rcnt,ccnt);
                        im14.at<float>(rcnt,_ccnt)=im6.at<float>(rcnt,ccnt);
                    }
                }

                for(int rcnt=0;rcnt<im.rows/2;rcnt++)
                {
                    for(int ccnt=0;ccnt<im.cols;ccnt+=2)
                    {
                        a=im11.at<float>(rcnt,ccnt);
                        b=im12.at<float>(rcnt,ccnt);
                        c=(a+b)*0.707;
                        im11.at<float>(rcnt,ccnt)=c;
                        d=(a-b)*0.707;                           //Filtering at Stage I
                        im11.at<float>(rcnt,ccnt+1)=d;
                        a=im13.at<float>(rcnt,ccnt);
                        b=im14.at<float>(rcnt,ccnt);
                        c=(a+b)*0.707;
                        im13.at<float>(rcnt,ccnt)=c;
                        d=(a-b)*0.707;
                        im13.at<float>(rcnt,ccnt+1)=d;
                    }
                }
                temp=Mat::zeros(im.rows,im.cols,CV_32F);
                for(int rcnt=0;rcnt<im.rows/2;rcnt++)
                {
                    for(int ccnt=0;ccnt<im.cols;ccnt++)
                    {
                        int _rcnt=rcnt*2;
                        imr.at<float>(_rcnt,ccnt)=im11.at<float>(rcnt,ccnt);     //Upsampling at stage II
                        temp.at<float>(_rcnt,ccnt)=im13.at<float>(rcnt,ccnt); 
                    }
                }
                for(int rcnt=0;rcnt<im.rows;rcnt+=2)
                {
                    for(int ccnt=0;ccnt<im.cols;ccnt++)
                    {
                        a=imr.at<float>(rcnt,ccnt);
                        b=temp.at<float>(rcnt,ccnt);
                        c=(a+b)*0.707;
                        imr.at<float>(rcnt,ccnt)=c;                                      //Filtering at Stage II
                        d=(a-b)*0.707;
                        imr.at<float>(rcnt+1,ccnt)=d;
                    }
                }
                imd.convertTo(imd,CV_8U);
                namedWindow("Input Image",1);
                imshow("Input Image",imi);
                namedWindow("Wavelet Decomposition",1);
                imshow("Wavelet Decomposition",imd);
                imr.convertTo(imr,CV_8U);
                namedWindow("Wavelet Reconstruction",1);
                imshow("Wavelet Reconstruction",imr);
                waitKey(0);
                return 0;
            }
            int main()
            {
                image my;
                my.getim();
                return 0;
            }

希望有人发现它有用!

我发现java中很少有小波的代码示例,尤其是在使用openCV的情况下。我不得不在openCV中使用java中的小波,我使用了@la-luvia中的C代码并转换为java。

翻译代码时遇到了很多麻烦,因为它在openCV方法和使用方式上有很多不同。这本书在这个过程中也帮了我很多忙。

我希望这段代码和这本书能为如何使用lib以及C和Java之间的一些差异提供一些视角。

这是代码:

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class Wavelet {
    //Imperative in java
    static{
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }
    String pathname = "C:/Users/user/img096";

    public static void main(String[] args) {
        Wavelet wavelet = new Wavelet();
        wavelet.applyHaarFoward();
        wavelet.applyHaarReverse();
        Imgcodecs.imwrite(wavelet.pathname+"imi.jpg", wavelet.imi);
        Imgcodecs.imwrite(wavelet.pathname+"imd.jpg", wavelet.imd);
        Imgcodecs.imwrite(wavelet.pathname+"imr.jpg", wavelet.imr);
    }
    Mat im,im1,im2,im3,im4,im5,im6,temp,im11,im12,im13,im14,imi,imd,imr;
    float a,b,c,d;
    private void applyHaarFoward(){
        try{
            im = Imgcodecs.imread(pathname+".jpg", 0);
            imi = new Mat(im.rows(), im.cols(), CvType.CV_8U);
            im.copyTo(imi);
            //in CvType. If the number of channels is omitted, it evaluates to 1. 
            im.convertTo(im, CvType.CV_32F, 1.0, 0.0);
            im1 = new Mat(im.rows()/2, im.cols(), CvType.CV_32F);
            im2 = new Mat(im.rows()/2, im.cols(), CvType.CV_32F);
            im3 = new Mat(im.rows()/2, im.cols()/2, CvType.CV_32F);
            im4 = new Mat(im.rows()/2, im.cols()/2, CvType.CV_32F);
            im5 = new Mat(im.rows()/2, im.cols()/2, CvType.CV_32F);
            im6 = new Mat(im.rows()/2, im.cols()/2, CvType.CV_32F);

            // ------------------- Decomposition ------------------- 
            for (int rcnt = 0; rcnt < im.rows(); rcnt+=2) {
                for (int ccnt = 0; ccnt < im.cols(); ccnt++) {
                    //even though the CvType is float with only one channel
                    //the method Mat.get() return a double array 
                    //with only one position, [0].
                    a = (float) im.get(rcnt, ccnt)[0];
                    b = (float) im.get(rcnt+1, ccnt)[0];
                    c = (float) ((a+b)*0.707);
                    d = (float) ((a-b)*0.707);
                    int _rcnt= rcnt/2;
                    im1.put(_rcnt, ccnt, c);
                    im2.put(_rcnt, ccnt, d);
                }
            }
            for (int rcnt = 0; rcnt < im.rows()/2; rcnt++) {
                for (int ccnt = 0; ccnt < im.cols() - 2; ccnt+=2) {
                    a = (float) im1.get(rcnt, ccnt)[0];
                    b = (float) im1.get(rcnt, ccnt+1)[0];
                    c = (float) ((a+b)*0.707);
                    d = (float) ((a-b)*0.707);
                    int _ccnt = ccnt/2;
                    im3.put(rcnt, _ccnt, c);
                    im4.put(rcnt, _ccnt, d);
                }
            }
            for (int rcnt = 0; rcnt < im.rows()/2; rcnt++) {
                for (int ccnt = 0; ccnt < im.cols() - 2; ccnt+=2) {
                    a = (float) im2.get(rcnt, ccnt)[0];
                    b = (float) im2.get(rcnt, ccnt+1)[0];
                    c = (float) ((a+b)*0.707);
                    d = (float) ((a-b)*0.707);
                    int _ccnt = ccnt/2;
                    im5.put(rcnt, _ccnt, c);
                    im6.put(rcnt, _ccnt, d);
                }
            }
            imr = Mat.zeros(im.rows(), im.cols(), CvType.CV_32F);//imr = Mat.zeros(512, 512, CvType.CV_32F);
            imd = Mat.zeros(512, 512, CvType.CV_32F);
            im3.copyTo(imd.adjustROI(0, 0, 256, 256));
            im4.copyTo(imd.adjustROI(0, 255, 256, 256));
            im5.copyTo(imd.adjustROI(255, 0, 256, 256));
            im6.copyTo(imd.adjustROI(255, 255, 256, 256));


        }catch(Exception ex){
            System.err.println(ex.getLocalizedMessage());
            ex.printStackTrace();
        }
    }
    private void applyHaarReverse(){
        // ------------------- Reconstruction ------------------- 
                im11 = Mat.zeros(im.rows()/2, im.cols(), CvType.CV_32F);
                im12 = Mat.zeros(im.rows()/2, im.cols(), CvType.CV_32F);
                im13 = Mat.zeros(im.rows()/2, im.cols(), CvType.CV_32F);
                im14 = Mat.zeros(im.rows()/2, im.cols(), CvType.CV_32F);
                for (int rcnt = 0; rcnt < im.rows()/2; rcnt++) {
                    for (int ccnt = 0; ccnt < im.cols()/2; ccnt++) {
                        int _ccnt  = ccnt*2;
                        im11.put(rcnt, _ccnt, im3.get(rcnt, ccnt));
                        im12.put(rcnt, _ccnt, im4.get(rcnt, ccnt));
                        im13.put(rcnt, _ccnt, im5.get(rcnt, ccnt));
                        im14.put(rcnt, _ccnt, im6.get(rcnt, ccnt));
                    }
                }
                for (int rcnt = 0; rcnt < im.rows()/2; rcnt++) {
                    for (int ccnt = 0; ccnt < im.cols() - 2; ccnt+=2) {
                        a = (float) im11.get(rcnt, ccnt)[0];
                        b = (float) im12.get(rcnt, ccnt)[0];
                        c = (float) ((a+b)*0.707);
                        im11.put(rcnt, ccnt, c);
                        d = (float) ((a-b)*0.707);
                        im11.put(rcnt, ccnt+1, d);
                        a = (float) im13.get(rcnt, ccnt)[0];
                        b = (float) im14.get(rcnt, ccnt)[0];
                        c = (float) ((a+b)*0.707);
                        im13.put(rcnt, ccnt, c);
                        d = (float) ((a-b)*0.707);
                        im13.put(rcnt, ccnt+1, d);
                    }
                }
                temp = Mat.zeros(im.rows(), im.cols(), CvType.CV_32F);
                for (int rcnt = 0; rcnt < im.rows()/2; rcnt++) {
                    for (int ccnt = 0; ccnt < im.cols(); ccnt++) {
                        int _rcnt = rcnt*2;
                        imr.put(_rcnt, ccnt, im11.get(rcnt, ccnt));
                        temp.put(_rcnt, ccnt, im13.get(rcnt, ccnt));
                    }
                }

                for (int rcnt = 0; rcnt < im.rows()-2; rcnt+=2) {
                    for (int ccnt = 0; ccnt < im.cols(); ccnt++) {
                        a = (float) imr.get(rcnt, ccnt)[0];
                        b = (float) temp.get(rcnt, ccnt)[0];
                        c = (float) ((a+b)*0.707);
                        imr.put(rcnt, ccnt, c);
                        d = (float) ((a-b)*0.707);
                        imr.put(rcnt+1, ccnt, d);
                    }
                }
    }
}

希望它有用。

建议:我不建议你从头开始实施载重吨,这很难满足你的需求。如果你在工作中真的需要它的cpp版本,我建议你尝试PyWavelets,它的dwt基本功能是用C实现的,所以你可以很容易地将它迁移到你的程序中。否则,你也可以先用python验证你的想法,而不是冒着付出无用努力的风险。


这是我的一个dwt实现,它支持多种小波滤波器,它可以工作,但不能很好地工作。随着水平的提高,重建图像越来越模糊。

如果你想改变小波滤波器,你可以使用matlab(wfilters(wname))或从PyWavelets的源代码中挑选,它还给出了从这些系数中获得total4滤波器的规则。

相关内容

  • 没有找到相关文章

最新更新