📄 wavelet.cpp
字号:
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include "global.h"
#include "image.h"
#include "wavelet.h"
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
#include <iostream.h>
Wavelet::Wavelet (FilterSet *filterset)
{
analysisLow = filterset->analysisLow;
analysisHigh = filterset->analysisHigh;
synthesisLow = filterset->synthesisLow;
synthesisHigh = filterset->synthesisHigh;
symmetric = filterset->symmetric;
// amount of space to leave for padding vectors for symmetric extensions
npad = max(analysisLow->size, analysisHigh->size);
}
/*---------------------------------------------------------------------------*/
Wavelet::~Wavelet ()
{
}
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
void Wavelet::transform1d (Real *input, Real *output, int size,
int nsteps, int sym_ext)
{
int i;
int currentIndex = 0;
Real *data[2];
int lowSize = size, highSize;
// If form of extension unspecified, default to symmetric
// extensions for symmetrical filters and periodic extensions for
// asymmetrical filters
if (sym_ext == -1)
sym_ext = symmetric;
// data[0] and data[1] are padded with npad entries on each end
data [0] = new Real [2*npad+size];
data [1] = new Real [2*npad+size];
for (i = 0; i < size; i++)
data[currentIndex][npad+i] = input[i];
while (nsteps--) {
if (lowSize <= 2 && symmetric == 1) {
warning ("Reduce # of transform steps or increase signal size");
warning (" or switch to periodic extension");
error ("Low pass subband is too small");
}
// Transform
printf ("transforming, size = %d\n", lowSize);
transform_step (data[currentIndex], data[1-currentIndex],
lowSize, sym_ext);
highSize = lowSize/2;
lowSize = (lowSize+1)/2;
// Copy high-pass data to output signal
copy (data[1-currentIndex] + npad + lowSize, output +
lowSize, highSize);
for (i = 0; i < lowSize+highSize; i++)
printf ("%5.2f ", data[1-currentIndex][npad+i]);
printf ("\n\n");
// Now pass low-pass data (first 1/2 of signal) back to
// transform routine
currentIndex = 1 - currentIndex;
}
// Copy low-pass data to output signal
copy (data[currentIndex] + npad, output, lowSize);
delete [] data [1];
delete [] data [0];
}
/*---------------------------------------------------------------------------*/
void Wavelet::invert1d (Real *input, Real *output, int size,
int nsteps, int sym_ext)
{
int i;
int currentIndex = 0;
Real *data[2];
// If form of extension unspecified, default to symmetric
// extensions for symmetrical filters and periodic extensions for
// asymmetrical filters
if (sym_ext == -1)
sym_ext = symmetric;
int *lowSize = new int [nsteps];
int *highSize = new int [nsteps];
lowSize[0] = (size+1)/2;
highSize[0] = size/2;
for (i = 1; i < nsteps; i++) {
lowSize[i] = (lowSize[i-1]+1)/2;
highSize[i] = lowSize[i-1]/2;
}
data [0] = new Real [2*npad+size];
data [1] = new Real [2*npad+size];
copy (input, data[currentIndex]+npad, lowSize[nsteps-1]);
while (nsteps--) {
// grab the next high-pass component
copy (input + lowSize[nsteps],
data[currentIndex]+npad+lowSize[nsteps], highSize[nsteps]);
// Combine low-pass data (first 1/2^n of signal) with high-pass
// data (next 1/2^n of signal) to get higher resolution low-pass data
invert_step (data[currentIndex], data[1-currentIndex],
lowSize[nsteps]+highSize[nsteps], sym_ext);
// Now pass low-pass data (first 1/2 of signal) back to
// transform routine
currentIndex = 1 - currentIndex;
}
// Copy inverted signal to output signal
copy (data[currentIndex]+npad, output, size);
delete [] highSize;
delete [] lowSize;
delete [] data [1];
delete [] data [0];
}
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
void Wavelet::transform2d (Real *input, Real *output, int hsize, int vsize,
int nsteps, int sym_ext)
{
long j;
int hLowSize = hsize, hHighSize;
int vLowSize = vsize, vHighSize;
// If form of extension unspecified, default to symmetric
// extensions for symmetrical filters and periodic extensions for
// asymmetrical filters
if (sym_ext == -1)
sym_ext = symmetric;
Real *temp_in = new Real [2*npad+max(hsize,vsize)];
Real *temp_out = new Real [2*npad+max(hsize,vsize)];
copy (input, output, ((long)hsize)*vsize);
while (nsteps--) {
if ((hLowSize <= 2 || vLowSize <= 2) && sym_ext == 1) {
warning ("Reduce # of transform steps or increase signal size");
warning (" or switch to periodic extension");
error ("Low pass subband is too small");
}
// Do a convolution on the low pass portion of each row
for (j = 0; j < vLowSize; j++) {
// 暑镨痼屐 耱痤牦 j
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -