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/06/15 21:08:12 $ 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 typedef psF32 psKernelType; 00027 00028 /** A convolution kernel */ 00029 typedef struct 00030 { 00031 psImage* image; ///< Kernel data, in the form of an image 00032 psS32 xMin; ///< Most negative x index 00033 psS32 yMin; ///< Most negative y index 00034 psS32 xMax; ///< Most positive x index 00035 psS32 yMax; ///< Most positive y index 00036 psKernelType** kernel; ///< Pointer to the kernel data 00037 psKernelType** p_kernelRows; ///< Pointer to the rows of the kernel data; not intended for user use. 00038 } 00039 psKernel; 00040 00041 /** Allocates a convolution kernel of the given range 00042 * 00043 * In order to perform a convolution, we need to define the convolution 00044 * kernel. We need a more general object than a psImage so that we can 00045 * incorporate the offset from the (0, 0) pixel to the (0, 0) value of the 00046 * kernel. It might be convenient to allow both positive and negative 00047 * indices to convey the positive and negative shifts. One might consider 00048 * setting the x0 and y0 members of a psImage to the appropriate offsets, 00049 * but this is not the purpose of these members, and doing so may affect the 00050 * behavior of other psImage operations. 00051 * 00052 * This construction allows the kernel member to use negative indices, while 00053 * preserving the location of psMemBlocks relative to allocated memory. 00054 * 00055 * The maximum extent of the kernel shifts shall be defined by the xMin, 00056 * xMax, yMin and yMax members. Note that xMin and yMin, under normal 00057 * circumstances, should be negative numbers. That is, 00058 * myKernel->kernel[-3][-2] may be defined if yMin and xMin are equal to or 00059 * more negative than -3 and -2, respectively. 00060 * 00061 * In the event that one of the minimum values is greater than the 00062 * corresponding maximum value, the function shall generate a warning, and 00063 * the offending values shall be exchanged. 00064 * 00065 * @return psKernel* A new kernel object 00066 */ 00067 psKernel* psKernelAlloc( 00068 psS32 xMin, ///< Most negative x index 00069 psS32 xMax, ///< Most positive x index 00070 psS32 yMin, ///< Most negative y index 00071 psS32 yMax ///< Most positive y index 00072 ); 00073 00074 /** Generates a kernel given a list of shift values 00075 * 00076 * Given a list of values (e.g., shifts made in the course of OT guiding), 00077 * psKernelGenerate shall return the appropriate kernel. The vectors xShifts 00078 * and yShifts, which are a list of shifts relative to some starting point, 00079 * will be supplied by the user. The elements of the vectors should be of an 00080 * integer type; otherwise the values shall be truncated to integers. The 00081 * output kernel shall be normalized such that the sum over the kernel is 00082 * unity. 00083 * 00084 * If the vectors are not of the same number of elements, then the function 00085 * shall generate a warning shall be generated, following which, the longer 00086 * vector trimmed to the length of the shorter, and the function shall continue. 00087 * 00088 * @return psKernel* new Kernel object 00089 */ 00090 psKernel* psKernelGenerate( 00091 const psVector* tShifts, ///< list of time shifts 00092 const psVector* xShifts, ///< list of x-axis shifts 00093 const psVector* yShifts, ///< list of y-axis shifts 00094 psBool relative 00095 ); 00096 00097 /** convolve an image with a kernel 00098 * 00099 * Given an input image and the convolution kernel, psImageConvolve shall 00100 * convolve the input image, in, with the kernel, kernel and return the 00101 * convolved image, out. 00102 * 00103 * Two methods shall be available for the convolution: if direct is true, 00104 * then the convolution shall be performed in real space (appropriate for 00105 * small kernels); otherwise, the convolution shall be performed using Fast 00106 * Fourier Transforms (FFTs; appropriate for larger kernels). The latter 00107 * option involves padding the input image, copying the kernel into an image 00108 * of the same size as the padded input image, performing an FFT on each, 00109 * multiplying the FFTs, and performing an inverse FFT before trimming the 00110 * image back to the original size. 00111 * 00112 * @return psImage* resulting image 00113 */ 00114 psImage* psImageConvolve( 00115 psImage* out, ///< a psImage to recycle. If NULL, a new psImage is made. 00116 const psImage* in, ///< the psImage to convolve 00117 const psKernel* kernel, ///< kernel to colvolve with 00118 psBool direct ///< specifies method, true=direct convolution, false=fourier 00119 ); 00120 00121 #endif // #ifndef PS_IMAGE_CONVOLVE_H
1.4.1