⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wavelet.c

📁 该程序把数字图像处理与小波变换结合起来
💻 C
📖 第 1 页 / 共 2 页
字号:
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Port to C from C++
 *
 * Mow-Song, Ng 2/9/2002
 * msng@mmu.edu.my
 * http://www.pesona.mmu.edu.my/~msng
 *
 * I do not claim copyright to the code, but if you use them or modify them,
 * please drop me a mail.
 *
 */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Original copyright info */
/*---------------------------------------------------------------------------*/
// Baseline Wavelet Transform Coder Construction Kit
//
// Geoff Davis
// gdavis@cs.dartmouth.edu
// http://www.cs.dartmouth.edu/~gdavis
//
// Copyright 1996 Geoff Davis 9/11/96
//
// Permission is granted to use this software for research purposes as
// long as this notice stays attached to this software.
//
/*---------------------------------------------------------------------------*/
#include "wavelet.h"

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
WAVELET *WaveletAlloc(FILTERSET *filterset)
{
	WAVELET *wavelet;

	if((wavelet=(WAVELET *)malloc(sizeof(WAVELET)))==NULL){
		return NULL;
	}

	wavelet->analysisLow=filterset->analysisLow;
	wavelet->analysisHigh=filterset->analysisHigh;
	wavelet->synthesisLow=filterset->synthesisLow;
	wavelet->synthesisHigh=filterset->synthesisHigh;
	wavelet->symmetric=filterset->symmetric;

	// amount of space to leave for padding vectors for symmetric extensions
	wavelet->npad = max(wavelet->analysisLow->size, wavelet->analysisHigh->size);

	return wavelet;
}


/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
void WaveletDealloc(WAVELET *wavelet)
{
	free(wavelet);
}


/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
void WaveletTransform1D(WAVELET *wavelet, Real *input, Real *output, int size,
								int nsteps, int symExt)
{
	int i, 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
	
	//- Explicitly set symExt = -1
   if (symExt == -1){
		symExt = wavelet->symmetric;
	}
	
	// data[0] and data[1] are padded with npad entries on each end
   data [0] = (Real *)calloc(2*wavelet->npad+size, sizeof(Real));
   data [1] = (Real *)calloc(2*wavelet->npad+size, sizeof(Real));
	
	
   for (i = 0; i < size; i++){
		data[currentIndex][wavelet->npad+i] = input[i];
	}
	
	while(nsteps--){
		if (lowSize<=2 && wavelet->symmetric == 1){
			WaveletWarning("Reduce # of transform steps or increase signal size.\n");
			WaveletWarning("or switch to periodic extension.\n");
			WaveletError("Low pass subband is too small\n");
		}
		
		// Transform
		WaveletTransformStep(wavelet, data[currentIndex], data[1-currentIndex], 
			lowSize, symExt);
		
		highSize = lowSize/2;
		lowSize = (lowSize+1)/2;
		
		// Copy high-pass data to output signal
		copy (data[1-currentIndex] + wavelet->npad + lowSize, 
			output+lowSize, highSize);
		
		// 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] + wavelet->npad, output, lowSize);
   
   free(data[1]);
   free(data[0]);
}


/*----------------------------------------------------------------------------*/	
/*----------------------------------------------------------------------------*/
void WaveletInvert1D(WAVELET *wavelet, Real *input, Real *output, int size,
							int nsteps, int symExt)
{
   int i;
   int currentIndex = 0;
   Real *data[2];
	int *lowSize, *highSize;
	
   // If form of extension unspecified, default to symmetric
   // extensions for symmetrical filters and periodic extensions for
   // asymmetrical filters
   if (symExt == -1){
		symExt = wavelet->symmetric;
	}
	
	lowSize = (int *)calloc(nsteps, sizeof(int));
   highSize = (int *)calloc(nsteps, sizeof(int));
	
   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] = (Real*)calloc(2*wavelet->npad+size, sizeof(Real));
   data [1] = (Real*)calloc(2*wavelet->npad+size, sizeof(Real));
		
		copy (input, data[currentIndex]+wavelet->npad, lowSize[nsteps-1]);
	
   while (nsteps--)  {
		
		// grab the next high-pass component
		copy (input + lowSize[nsteps], data[currentIndex]+wavelet->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
		WaveletInvertStep(wavelet, data[currentIndex], data[1-currentIndex], 
			lowSize[nsteps]+highSize[nsteps], symExt);
		
		// 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]+wavelet->npad, output, size);
	
   free(highSize);
   free(lowSize);
	
   free(data[1]);
   free(data[0]);
}


/*----------------------------------------------------------------------------*/	
/*----------------------------------------------------------------------------*/
void WaveletTransform2D(WAVELET *wavelet, Real *input, Real *output, int hsize, int vsize,
								int nsteps, int symExt)
{
   int j;
   int hLowSize = hsize, hHighSize;
   int vLowSize = vsize, vHighSize;
	Real *temp_in, *temp_out;
	
   // If form of extension unspecified, default to symmetric
   // extensions for symmetrical filters and periodic extensions for
   // asymmetrical filters
   if (symExt == -1)
		symExt = wavelet->symmetric;
	
   temp_in = (Real*)calloc(2*wavelet->npad+MAX(hsize,vsize), sizeof(Real));
   temp_out = (Real*)calloc(2*wavelet->npad+MAX(hsize,vsize), sizeof(Real));
	
   copy (input, output, hsize*vsize);
	
   while (nsteps--){
		if ((hLowSize <= 2 || vLowSize <= 2) && symExt == 1) {
			WaveletWarning ("Reduce # of transform steps or increase signal size.\n");
			WaveletWarning ("or switch to periodic extension\n");
			WaveletError ("Low pass subband is too small\n");
      }
		
      // Do a convolution on the low pass portion of each row
      for (j = 0; j < vLowSize; j++)  {
			// Copy row j to data array
			copy (output+(j*hsize), temp_in+wavelet->npad, hLowSize);
			
			// Convolve with low and high pass filters
			WaveletTransformStep (wavelet, temp_in, temp_out, hLowSize, symExt);
			
			// Copy back to image
			copy (temp_out+wavelet->npad, output+(j*hsize), hLowSize);
      }
		
      // Now do a convolution on the low pass portion of  each column
      for (j = 0; j < hLowSize; j++)  {
			// Copy column j to data array
			copy_p1_skip (output+j, hsize, temp_in+wavelet->npad, vLowSize);
			
			// Convolve with low and high pass filters
			WaveletTransformStep (wavelet, temp_in, temp_out, vLowSize, symExt);
			
			// Copy back to image
			copy_p2_skip (temp_out+wavelet->npad, output+j, hsize, vLowSize);
      }
		
      // Now convolve low-pass portion again
      hHighSize = hLowSize/2;
      hLowSize = (hLowSize+1)/2;
      vHighSize = vLowSize/2;
      vLowSize = (vLowSize+1)/2;
   }
	
   free(temp_out);
   free(temp_in);
	
}


/*----------------------------------------------------------------------------*/	
/*----------------------------------------------------------------------------*/
void WaveletInvert2D(WAVELET *wavelet, Real *input, Real *output, int hsize, int vsize,
							int nsteps, int symExt)
{   
	int i, j;
	int *hLowSize, *hHighSize, *vLowSize, *vHighSize;
	Real *temp_in, *temp_out;
	
   // If form of extension unspecified, default to symmetric
   // extensions for symmetrical filters and periodic extensions for
   // asymmetrical filters
   if (symExt == -1)
		symExt = wavelet->symmetric;
	
   hLowSize = (int *) calloc(nsteps, sizeof(int));
   hHighSize = (int *) calloc(nsteps, sizeof(int));
   vLowSize =(int *) calloc(nsteps, sizeof(int));
   vHighSize =(int *) calloc(nsteps, sizeof(int));
	
   hLowSize[0] = (hsize+1)/2;
   hHighSize[0] = hsize/2;
   vLowSize[0] = (vsize+1)/2;
   vHighSize[0] = vsize/2;
	
   for (i = 1; i < nsteps; i++) {
		hLowSize[i] = (hLowSize[i-1]+1)/2;
		hHighSize[i] = hLowSize[i-1]/2;
		vLowSize[i] = (vLowSize[i-1]+1)/2;
		vHighSize[i] = vLowSize[i-1]/2;
   }
	
   temp_in = (Real *)calloc(2*wavelet->npad+MAX(hsize,vsize), sizeof(Real));
   temp_out = (Real *)calloc(2*wavelet->npad+MAX(hsize,vsize), sizeof(Real));
	
   copy (input, output, hsize*vsize);
	
   while (nsteps--)  {
      // Do a reconstruction for each of the columns
      for (j = 0; j < hLowSize[nsteps]+hHighSize[nsteps]; j++)  {
			// Copy column j to data array
			copy_p1_skip (output+j, hsize, temp_in+wavelet->npad, 
				vLowSize[nsteps]+vHighSize[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
			WaveletInvertStep (wavelet, temp_in, temp_out,
				vLowSize[nsteps]+vHighSize[nsteps], symExt);
			
			// Copy back to image
			copy_p2_skip (temp_out+wavelet->npad, output+j, hsize,
				vLowSize[nsteps]+vHighSize[nsteps]);
      }
		
      // Now do a reconstruction pass for each row
      for (j = 0; j < vLowSize[nsteps]+vHighSize[nsteps]; j++)  {
			// Copy row j to data array
			copy (output + (j*hsize), temp_in+wavelet->npad, 
				hLowSize[nsteps]+hHighSize[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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -