00001 /** @file psImageConvolve.h 00002 * 00003 * @brief image convolution functionality 00004 * 00005 * @ingroup Transform 00006 * 00007 * @author Robert DeSonia, MHPCC 00008 * 00009 * @version $Revision: 1.1.1.1 $ $Name: $ 00010 * @date $Date: 2005/09/14 20:42:48 $ 00011 * 00012 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii 00013 */ 00014 00015 #ifndef PS_IMAGE_CONVOLVE_H 00016 #define PS_IMAGE_CONVOLVE_H 00017 00018 #include "psImage.h" 00019 #include "psVector.h" 00020 #include "psType.h" 00021 00022 #define PS_TYPE_KERNEL PS_TYPE_F32 /**< the data member to use for kernel image */ 00023 #define PS_TYPE_KERNEL_DATA F32 /**< the data member to use for kernel image */ 00024 #define PS_TYPE_KERNEL_NAME "psF32" /**< the data type for kernel as a string */ 00025 00026 /** Kernel Type 00027 * 00028 * A floating-point data type used for storing kernel data. 00029 * 00030 */ 00031 //typedef float psKernelType; 00032 00033 /** A convolution kernel */ 00034 typedef struct 00035 { 00036 psImage* image; ///< Kernel data, in the form of an image 00037 int xMin; ///< Most negative x index 00038 int yMin; ///< Most negative y index 00039 int xMax; ///< Most positive x index 00040 int yMax; ///< Most positive y index 00041 float** kernel; ///< Pointer to the kernel data 00042 float** p_kernelRows; ///< Pointer to the rows of the kernel data; not intended for user use. 00043 } 00044 psKernel; 00045 00046 /** Allocates a convolution kernel of the given range 00047 * 00048 * In order to perform a convolution, we need to define the convolution 00049 * kernel. We need a more general object than a psImage so that we can 00050 * incorporate the offset from the (0, 0) pixel to the (0, 0) value of the 00051 * kernel. It might be convenient to allow both positive and negative 00052 * indices to convey the positive and negative shifts. One might consider 00053 * setting the x0 and y0 members of a psImage to the appropriate offsets, 00054 * but this is not the purpose of these members, and doing so may affect the 00055 * behavior of other psImage operations. 00056 * 00057 * This construction allows the kernel member to use negative indices, while 00058 * preserving the location of psMemBlocks relative to allocated memory. 00059 * 00060 * The maximum extent of the kernel shifts shall be defined by the xMin, 00061 * xMax, yMin and yMax members. Note that xMin and yMin, under normal 00062 * circumstances, should be negative numbers. That is, 00063 * myKernel->kernel[-3][-2] may be defined if yMin and xMin are equal to or 00064 * more negative than -3 and -2, respectively. 00065 * 00066 * In the event that one of the minimum values is greater than the 00067 * corresponding maximum value, the function shall generate a warning, and 00068 * the offending values shall be exchanged. 00069 * 00070 * @return psKernel* A new kernel object 00071 */ 00072 psKernel* psKernelAlloc( 00073 int xMin, ///< Most negative x index 00074 int xMax, ///< Most positive x index 00075 int yMin, ///< Most negative y index 00076 int yMax ///< Most positive y index 00077 ); 00078 00079 /** Checks the type of a particular pointer. 00080 * 00081 * Uses the appropriate deallocation function in psMemBlock to check the ptr datatype. 00082 * 00083 * @return bool: True if the pointer matches a psKernel structure, false otherwise. 00084 */ 00085 bool psMemCheckKernel( 00086 psPtr ptr ///< the pointer whose type to check 00087 ); 00088 00089 00090 /** Generates a kernel given a list of shift values 00091 * 00092 * Given a list of values (e.g., shifts made in the course of OT guiding), 00093 * psKernelGenerate shall return the appropriate kernel. The vectors xShifts 00094 * and yShifts, which are a list of shifts relative to some starting point, 00095 * will be supplied by the user. The elements of the vectors should be of an 00096 * integer type; otherwise the values shall be truncated to integers. The 00097 * output kernel shall be normalized such that the sum over the kernel is 00098 * unity. 00099 * 00100 * If the vectors are not of the same number of elements, then the function 00101 * shall generate a warning shall be generated, following which, the longer 00102 * vector trimmed to the length of the shorter, and the function shall continue. 00103 * 00104 * @return psKernel* new Kernel object 00105 */ 00106 psKernel* psKernelGenerate( 00107 const psVector* tShifts, ///< list of time shifts 00108 const psVector* xShifts, ///< list of x-axis shifts 00109 const psVector* yShifts, ///< list of y-axis shifts 00110 bool relative 00111 /**< specifies the starting point for the shifts; true=relative to previous shift 00112 * false = relative to some other starting point. */ 00113 ); 00114 00115 /** convolve an image with a kernel 00116 * 00117 * Given an input image and the convolution kernel, psImageConvolve shall 00118 * convolve the input image, in, with the kernel, kernel and return the 00119 * convolved image, out. 00120 * 00121 * Two methods shall be available for the convolution: if direct is true, 00122 * then the convolution shall be performed in real space (appropriate for 00123 * small kernels); otherwise, the convolution shall be performed using Fast 00124 * Fourier Transforms (FFTs; appropriate for larger kernels). The latter 00125 * option involves padding the input image, copying the kernel into an image 00126 * of the same size as the padded input image, performing an FFT on each, 00127 * multiplying the FFTs, and performing an inverse FFT before trimming the 00128 * image back to the original size. 00129 * 00130 * @return psImage* resulting image 00131 */ 00132 psImage* psImageConvolve( 00133 psImage* out, ///< a psImage to recycle. If NULL, a new psImage is made. 00134 const psImage* in, ///< the psImage to convolve 00135 const psKernel* kernel, ///< kernel to colvolve with 00136 bool direct ///< specifies method, true=direct convolution, false=fourier 00137 ); 00138 00139 /** Smooths an image by parts using 1D Gaussian independently in x and y. 00140 * 00141 * Applies a circularly symmetric Gaussian smoothing first in x and then in y 00142 * directions with just a vector. This process is 2N faster than 2D convolutions (in general). 00143 */ 00144 void psImageSmooth( 00145 psImage *image, ///< the image to be smoothed 00146 double sigma, ///< the width of the smoothing kernel in pixels 00147 double Nsigma ///< the size of the smoothing box in sigmas 00148 ); 00149 00150 00151 #endif // #ifndef PS_IMAGE_CONVOLVE_H
1.4.2