<< Chapter < Page
  Digital signal processing - dsp     Page 21 / 21
Chapter >> Page >

The inverse Fourier transform output

The output produced by performing an inverse Fourier transform on the complex wavenumber spectrum is shown in the rightmost image in Figure 16 . This output compares favorably with the input surface shown in the leftmost image in Figure 16 .

You can view the code that created this surface in Listing 22 near the end of the module.

The end of the getSpatialData method

Listing 20 shows the end of the method named getSpatialData and the end of the class named ImgMod31 .

Listing 20. The end of the getSpatialData method.
default: System.out.println("Case must be " +"between 0 and 13 inclusive."); System.out.println("Terminating program."); System.exit(0);}//end switch statementreturn spatialData; }//end getSpatialData}//end class ImgMod31

A default case is provided in the switch statement to deal with the possibility that the user may specify a case that is not included in theallowable limits of 0 through 13 inclusive.

The method ends by returning a reference to the array object containing the 3D surface that was created by the selected case in the switch statement.

Run the program

I encourage you to copy, compile, and run the programs that you will find in Listing 21 and Listing 22 near the end of the module.

(You will also need to go to the module titled Plotting 3D Surfaces using Java and get a copy of the source code for the program named ImgMod29 .)

Modify the programs and experiment with them in order to learn as much as you can about 2D Fourier transforms.

Create some different test cases and work with them until you understand why they produce the results that they do.

Summary

I began Part 1 of this two-part series by explaining how the space domain and the wavenumber domain in two-dimensional analysis are analogous to the time domainand the frequency domain in one-dimensional analysis.

Then I introduced you to some practical examples showing how 2D Fourier transforms and wavenumber spectra can be useful in solving engineering problemsinvolving antenna arrays.

In this module, I provided and explained a class that can be used to perform forward and inverse 2D Fourier transforms, and can also be used to shift thewavenumber origin from the top-left to the center for a more pleasing plot of the wavenumber spectral data.

Finally, I provided and explained a program that is used to:

  • Test the forward and inverse 2D Fourier transforms to confirm that the code is correct and that the transforms behave as they should
  • Produce wavenumber spectra for simple surfaces to help the student gain a feel for the relationships that exist between the space domain and thewavenumber domain

Complete program listings

Complete listings of the classes presented in this module are provided in Listing 21 and Listing 22 below.

Listings for other programs mentioned in the module, such as Dsp029 , are provided in other modules. Those modules are identified in the text of this module.

Listing 21. ImgMod30.java.
/*File ImgMod30.java Copyright 2005, R.G.BaldwinThe purpose of this program is to provide 2D Fourier Transform capability to be used for imageprocessing and other purposes. The class provides three static methods:xform2D: Performs a forward 2D Fourier transform on a surface described by a 2D array of doublevalues in the space domain to produce a spectrum in the wavenumber domain. The method returnsthe real part, the imaginary part, and the amplitude spectrum, each in its own 2D array ofdouble values. inverseXform2D: Performs an inverse 2D Fouriertransform from the wavenumber domain into the space domain using the real and imaginary partsof the wavenumber spectrum as input. Returns the surface in the space domain in a 2D array ofdouble values. shiftOrigin: The wavenumber spectrum producedby xform2D has its origin in the top-left corner with the Nyquist folding wave numbersnear the center. This is not a very suitable format for visual analysis. This methodrearranges the data to place the origin at the center with the Nyquist folding wave numbersalong the edges. Tested using J2SE 5.0 and WinXP************************************************/ import static java.lang.Math.*;class ImgMod30{ //This method computes a forward 2D Fourier// transform from the space domain into the // wavenumber domain. The number of points// produced for the wavenumber domain matches // the number of points received for the space// domain in both dimensions. Note that the // input data must be purely real. In other// words, the program assumes that there are // no imaginary values in the space domain.// Therefore, it is not a general purpose 2D // complex-to-complex transform.static void xform2D(double[][]inputData, double[][] realOut,double[][]imagOut, double[][] amplitudeOut){int height = inputData.length; int width = inputData[0].length; System.out.println("height = " + height);System.out.println("width = " + width); //Two outer loops iterate on output data.for(int yWave = 0;yWave<height;yWave++){ for(int xWave = 0;xWave<width;xWave++){ //Two inner loops iterate on input data.for(int ySpace = 0;ySpace<height; ySpace++){for(int xSpace = 0;xSpace<width; xSpace++){//Compute real, imag, and ampltude. Note that it // was necessary to sacrifice indentation to// force these very long equations to be // compatible with this narrow publication format// and still be somewhat readable. realOut[yWave][xWave] +=(inputData[ySpace][xSpace]*cos(2*PI*((1.0* xWave*xSpace/width)+(1.0*yWave*ySpace/height))))/sqrt(width*height); imagOut[yWave][xWave ] -=(inputData[ySpace][xSpace]*sin(2*PI*((1.0*xWave* xSpace/width) + (1.0*yWave*ySpace/height))))/sqrt(width*height); amplitudeOut[yWave][xWave] =sqrt( realOut[yWave][xWave] * realOut[yWave][xWave] +imagOut[yWave][xWave]* imagOut[yWave][xWave]); }//end xSpace loop}//end ySpace loop }//end xWave loop}//end yWave loop }//end xform2D method//-------------------------------------------// //This method computes an inverse 2D Fourier// transform from the wavenumber domain into // the space domain. The number of points// produced for the space domain matches // the number of points received for the wave-// number domain in both dimensions. Note that // this method assumes that the inverse// transform will produce purely real values in // the space domain. Therefore, in the// interest of computational efficiency, it // does not compute the imaginary output// values. Therefore, it is not a general // purpose 2D complex-to-complex transform. For// correct results, the input complex data must // match that obtained by performing a forward// transform on purely real data in the space // domain.static void inverseXform2D(double[][]real, double[][] imag,double[][]dataOut){ int height = real.length;int width = real[0].length;System.out.println("height = " + height); System.out.println("width = " + width);//Two outer loops iterate on output data. for(int ySpace = 0;ySpace<height;ySpace++){ for(int xSpace = 0;xSpace<width; xSpace++){//Two inner loops iterate on input data. for(int yWave = 0;yWave<height; yWave++){for(int xWave = 0;xWave<width; xWave++){//Compute real output data. Note that it was // necessary to sacrifice indentation to force// this very long equation to be compatible with // this narrow publication format and still be// somewhat readable. dataOut[ySpace][xSpace] +=(real[yWave][xWave]*cos(2*PI*((1.0 * xSpace* xWave/width) + (1.0*ySpace*yWave/height))) -imag[yWave][xWave]*sin(2*PI*((1.0 * xSpace* xWave/width) + (1.0*ySpace*yWave/height))))/sqrt(width*height); }//end xWave loop}//end yWave loop }//end xSpace loop}//end ySpace loop }//end inverseXform2D method//-------------------------------------------// //Method to shift the wavenumber origin and// place it at the center for a more visually // pleasing display. Must be applied// separately to the real part, the imaginary // part, and the amplitude spectrum for a wave-// number spectrum. static double[][] shiftOrigin(double[][] data){int numberOfRows = data.length; int numberOfCols = data[0].length; int newRows;int newCols; double[][] output =new double[numberOfRows][numberOfCols]; //Must treat the data differently when the// dimension is odd than when it is even. if(numberOfRows%2 != 0){//oddnewRows = numberOfRows + (numberOfRows + 1)/2;}else{//even newRows = numberOfRows + numberOfRows/2;}//end else if(numberOfCols%2 != 0){//oddnewCols = numberOfCols + (numberOfCols + 1)/2;}else{//even newCols = numberOfCols + numberOfCols/2;}//end else //Create a temporary working array.double[][]temp = new double[newRows][newCols];//Copy input data into the working array. for(int row = 0;row<numberOfRows;row++){ for(int col = 0;col<numberOfCols;col++){ temp[row][col] = data[row][col];}//col loop }//row loop//Do the horizontal shift first if(numberOfCols%2 != 0){//shift for odd//Slide leftmost (numberOfCols+1)/2 columns // to the right by numberOfCols columnsfor(int row = 0;row<numberOfRows;row++){ for(int col = 0;col<(numberOfCols+1)/2;col++){ temp[row][col + numberOfCols] =temp[row][col]; }//col loop}//row loop //Now slide everything back to the left by// (numberOfCols+1)/2 columns for(int row = 0;row<numberOfRows;row++){ for(int col = 0;col<numberOfCols;col++){ temp[row][col] =temp[row][col+(numberOfCols + 1)/2]; }//col loop}//row loop }else{//shift for even//Slide leftmost (numberOfCols/2) columns // to the right by numberOfCols columns.for(int row = 0;row<numberOfRows;row++){ for(int col = 0;col<numberOfCols/2;col++){ temp[row][col + numberOfCols] =temp[row][col]; }//col loop}//row loop //Now slide everything back to the left by// numberOfCols/2 columns for(int row = 0;row<numberOfRows;row++){ for(int col = 0;col<numberOfCols;col++){ temp[row][col] =temp[row][col + numberOfCols/2]; }//col loop}//row loop }//end else//Now do the vertical shift if(numberOfRows%2 != 0){//shift for odd//Slide topmost (numberOfRows+1)/2 rows // down by numberOfRows rows.for(int col = 0;col<numberOfCols;col++){ for(int row = 0;row<(numberOfRows+1)/2;row++){ temp[row + numberOfRows][col] =temp[row][col]; }//row loop}//col loop//Now slide everything back up by // (numberOfRows+1)/2 rows.for(int col = 0;col<numberOfCols;col++){ for(int row = 0;row<numberOfRows;row++){ temp[row][col] =temp[row+(numberOfRows + 1)/2][col]; }//row loop}//col loop }else{//shift for even//Slide topmost (numberOfRows/2) rows down // by numberOfRows rowsfor(int col = 0;col<numberOfCols;col++){ for(int row = 0;row<numberOfRows/2;row++){ temp[row + numberOfRows][col] =temp[row][col]; }//row loop}//col loop //Now slide everything back up by// numberOfRows/2 rows. for(int col = 0;col<numberOfCols;col++){ for(int row = 0;row<numberOfRows;row++){ temp[row][col] =temp[row + numberOfRows/2][col]; }//row loop}//col loop }//end else//Shifting of the origin is complete. Copy // the rearranged data from temp to output// array. for(int row = 0;row<numberOfRows;row++){ for(int col = 0;col<numberOfCols;col++){ output[row][col] = temp[row][col];}//col loop }//row loopreturn output; }//end shiftOrigin method}//end class ImgMod30
Listing 22. ImgMod31.java.
/*File ImgMod31.java Copyright 2005, R.G.BaldwinThe purpose of this program is to exercise and test the 2D Fourier Transform methods and theaxis shifting method provided by the class named ImgMod30.The main method in this class reads a command- line parameter and uses it to select a specificcase involving a particular kind of input data in the space domain. The program then performsa 2D Fourier transform on that data followed by an inverse 2D Fourier transform.There are 14 cases built into the program with case numbers ranging from 0 to 13 inclusive.Each of the cases is designed such that the results should be known in advance by a personfamiliar with 2D Fourier analysis and the wave- number domain. The cases are also designed toillustrate the impact of various space-domain characteristics on the wavenumber spectrum.This information will be useful later when analyzing the results of performing 2Dtransforms on photographic images and other images as well.Each time the program is run, it produces a stack of six output images in the top-left corner ofthe screen. The type of each image is listed below. This list is in top-to-bottom order. Toview the images further down in the stack, you must physically move those on top to get themout of the way. The top-to-bottom order of the output images isas follows: 1. Space-domain output of inverse Fouriertransform. Compare with original input in 6 below.2. Amplitude spectrum in wavenumber domain with shifted origin. Compare with 5 below.3. Imaginary wavenumber spectrum with shifted origin.4. Real wavenumber spectrum with shifted origin.5. Amplitude spectrum in wavenumber domain without shifted origin. Compare with 2 above.6. Space-domain input data. Compare with 1 above.In addition, the program produces some numeric output on the command-line screen that may beuseful in confirming the validity of the inverse transform. The following is an example:height = 41 width = 41height = 41 width = 412.0 1.9999999999999916 0.5000000000000002 0.499999999999998450.49999999999999956 0.4999999999999923 1.7071067811865475 1.70710678118655260.2071067811865478 0.20710678118654233 0.20710678118654713 0.207106781186554351.0 1.0000000000000064 -0.4999999999999997 -0.49999999999999484-0.5000000000000003 -0.4999999999999965 The first two lines above indicate the size ofthe spatial surface for the forward transform. The second two lines indicate the size of thewavenumber surface for the inverse transform. The remaining nine lines indicate somethingabout the quality of the inverse transform in terms of its ability to replicate the originalspatial surface. These lines also indicate something about the correctness or lack thereofof the overall scaling from original input to final output. Each line contains a pair ofvalues. The first value is from the original spatial surface. The second value is from thespatial surface produced by performing an inverse transform on the wavenumber spectrum. The twovalues in each pair of values should match. If they match, this indicates the probability of avalid result. Note however that this is a very small sampling of the values that makeup the original and replicated spatial data and problems could arise in areas that are notincluded in this small sample. The match is very good in the example shown above. This exampleis from Case #12. Usage: java ImgMod31 CaseNumber DisplayTypeCaseNumber from 0 to 13 inclusive. If a case number is not provided, Case #2 will berun by default. If a display type is not provided, display type 1 will be used by default.A description of each case is provided by the comments in this program.See ImgMod29 for a definition of DisplayType, which can have a value of 0, 1, or 2.You can terminate the program by clicking on the close button on any of the display framesproduced by the program. Tested using J2SE 5.0 and WinXP************************************************/ import static java.lang.Math.*;class ImgMod31{ public static void main(String[]args){ //Get input parameters to select the case to// be run and the displayType. See ImgMod29 // for a description of displayType. Use// default case and displayType if the user // fails to provide that information.// If the user provides a non-numeric input // parameter, an exception will be thrown.int switchCase = 2;//default int displayType = 1;//defaultif(args.length == 1){ switchCase = Integer.parseInt(args[0]); }else if(args.length == 2){switchCase = Integer.parseInt(args[0]);displayType = Integer.parseInt(args[1]);}else{ System.out.println("Usage: java ImgMod31 "+ "CaseNumber DisplayType"); System.out.println("CaseNumber from 0 to 13 inclusive."); System.out.println("DisplayType from 0 to 2 inclusive."); System.out.println("Running case "+ switchCase + " by default."); System.out.println("Running DisplayType "+ displayType + " by default."); }//end else//Create the array of test data. int rows = 41;int cols = 41; //Get a test surface in the space domain.double[][]spatialData = getSpatialData(switchCase,rows,cols);//Display the spatial data. Don't display // the axes.new ImgMod29(spatialData,3,false, displayType);//Perform the forward transform from the // space domain into the wavenumber domain.// First prepare some array objects to // store the results.double[][]realSpect = //Real part new double[rows][cols];double[][]imagSpect = //Imaginary part new double[rows][cols];double[][]amplitudeSpect = //Amplitude new double[rows][cols];//Now perform the transform ImgMod30.xform2D(spatialData,realSpect,imagSpect,amplitudeSpect); //Display the raw amplitude spectrum without// shifting the origin first. Display the // axes.new ImgMod29(amplitudeSpect,3,true, displayType);//At this point, the wavenumber spectrum is // not in a format that is good for viewing.// In particular, the origin is at the t0p-// left corner. The horizontal Nyquist // folding wavenumber is near the// horizontal center of the plot. The // vertical Nyquist folding wave number is// near the vertical center of the plot. It // is much easier for most people to// understand what is going on when the // wavenumber origin is shifted to the// center of the plot with the Nyquist // folding wave numbers at the edges of the// plot. The method named shiftOrigin can be // used to rearrange the data and to shift// the orgin in that manner. //Shift the origin and display the real part// of the spectrum, the imaginary part of the // spectrum, and the amplitude of the// spectrum. Display the axes in all three // cases.double[][]shiftedRealSpect = ImgMod30.shiftOrigin(realSpect);new ImgMod29(shiftedRealSpect,3,true, displayType);double[][]shiftedImagSpect = ImgMod30.shiftOrigin(imagSpect);new ImgMod29(shiftedImagSpect,3,true, displayType);double[][]shiftedAmplitudeSpect = ImgMod30.shiftOrigin(amplitudeSpect);new ImgMod29(shiftedAmplitudeSpect,3,true, displayType);//Now test the inverse transform by // performing an inverse transform on the// real and imaginary parts produced earlier // by the forward transform.//Begin by preparing an array object to store // the results.double[][]recoveredSpatialData = new double[rows][cols];//Now perform the inverse transform. ImgMod30.inverseXform2D(realSpect,imagSpect,recoveredSpatialData); //Display the output from the inverse// transform. It should compare favorably // with the original spatial surface.new ImgMod29(recoveredSpatialData,3,false, displayType);//Use the following code to confirm correct // scaling. If the scaling is correct, the// two values in each pair of values should // match. Note that this is a very small// subset of the total set of values that // make up the original and recovered// spatial data. for(int row = 0;row<3;row++){ for(int col = 0;col<3;col++){ System.out.println(spatialData[row][col]+ " " + recoveredSpatialData[row][col] + " ");}//col }//row}//end main //===========================================////This method constructs and returns a 3D // surface in a 2D array of type double// according to the identification of a // specific case received as an input// parameter. There are 14 possible cases. A // description of each case is provided in the// comments. The other two input parameters // specify the size of the surface in units of// rows and columns. private static double[][] getSpatialData(int switchCase,int rows,int cols){ //Create an array to hold the data. All// elements are initialized to a value of // zero.double[][]spatialData = new double[rows][cols];//Use a switch statement to select and // create a specified case.switch(switchCase){ case 0://This case places a single non-zero // point at the origin in the space// domain. The origin is at the top- // left corner. In signal processing// terminology, this point can be viewed // as an impulse in space. This produces// a flat spectrum in wavenumber space. spatialData[0][0] = 1;break; case 1://This case places a single non-zero // point near but not at the origin in// space. This produces a flat spectrum // in wavenumber space as in case 0.// However, the real and imaginary parts // of the transform are different from// case 0 and the result is subject to // arithmetic accuracy issues. The// plotted flat spectrum doesn't look // very good because the color switches// back and forth between three values // that are very close to together. This// is the result of the display program // normalizing the surface values based// on the maximum and minimum values, // which in this case are very close// together. spatialData[2][2] = 1;break; case 2://This case places a box on the diagonal // near the origin. This produces a// sin(x)/x shape to the spectrum with // its peak at the origin in wavenumber// space. spatialData[3][3] = 1;spatialData[3][4]= 1; spatialData[3][5] = 1;spatialData[4][3]= 1; spatialData[4][4] = 1;spatialData[4][5]= 1; spatialData[5][3] = 1;spatialData[5][4]= 1; spatialData[5][5] = 1;break; case 3://This case places a box at the top near // the origin. This produces the same// amplitude spectrum as case 2. However, // the real and imaginary parts, (or the// phase) is different from case 2 due to // the difference in location of the box// relative to the origin in space. spatialData[0][3] = 1;spatialData[0][4]= 1; spatialData[0][5] = 1;spatialData[1][3]= 1; spatialData[1][4] = 1;spatialData[1][5]= 1; spatialData[2][3] = 1;spatialData[2][4]= 1; spatialData[2][5] = 1;break; case 4://This case draws a short line along the // diagonal from top-left to lower// right. This results in a spectrum with // a sin(x)/x shape along that axis and a// constant along the axis that is // perpendicular to that axisspatialData[0][0]= 1; spatialData[1][1] = 1;spatialData[2][2]= 1; spatialData[3][3] = 1;spatialData[4][4]= 1; spatialData[5][5] = 1;spatialData[6][6]= 1; spatialData[7][7] = 1;break; case 5://This case draws a short line // perpendicular to the diagonal from// top-left to lower right. The // spectral result is shifted 90 degrees// relative to that shown for case 4 // where the line was along the diagonal.// In addition, the line is shorter // resulting in wider lobes in the// spectrum. spatialData[0][3] = 1;spatialData[1][2]= 1; spatialData[2][1] = 1;spatialData[3][0]= 1; break;case 6: //This case draws horizontal lines,// vertical lines, and lines on both // diagonals. The weights of the// individual points is such that the // average of all the weights is 0.// The weight at the point where the // lines intersect is also 0. This// produces a spectrum that is // symmetrical across the axes at 0,// 45, and 90 degrees. The value of // the spectrum at the origin is zero// with major peaks at the folding // wavenumbers on the 45-degree axes.// In addition, there are minor peaks // at various other points as well.spatialData[0][0]= -1; spatialData[1][1] = 1;spatialData[2][2]= -1; spatialData[3][3] = 0;spatialData[4][4]= -1; spatialData[5][5] = 1;spatialData[6][6]= -1; spatialData[6][0] = -1;spatialData[5][1]= 1; spatialData[4][2] = -1;spatialData[3][3]= 0; spatialData[2][4] = -1;spatialData[1][5]= 1; spatialData[0][6] = -1;spatialData[3][0]= 1; spatialData[3][1] = -1;spatialData[3][2]= 1; spatialData[3][3] = 0;spatialData[3][4]= 1;spatialData[3][5]= -1; spatialData[3][6] = 1;spatialData[0][3]= 1; spatialData[1][3] = -1;spatialData[2][3]= 1; spatialData[3][3] = 0;spatialData[4][3]= 1; spatialData[5][3] = -1;spatialData[6][3]= 1; break;case 7: //This case draws a zero-frequency// sinusoid (DC) on the surface with an // infinite number of samples per cycle.// This causes a single peak to appear in // the spectrum at the wavenumber// origin. This origin is the top-left // corner for the raw spectrum, and is// at the center cross hairs after the // origin has been shifted to the// center for better viewing. for(int row = 0; row<rows; row++){ for(int col = 0; col<cols; col++){ spatialData[row][col] = 1.0;}//end inner loop }//end outer loopbreak; case 8://This case draws a sinusoidal surface // along the horizontal axis with one// sample per cycle. This function is // under-sampled by a factor of 2.// This produces a single peak in the // spectrum at the wave number origin.// The result is the same as if the // sinusoidal surface had zero frequency// as in case 7.. for(int row = 0; row<rows; row++){ for(int col = 0; col<cols; col++){ spatialData[row][col] =cos(2*PI*col/1); }//end inner loop}//end outer loop break;case 9: //This case draws a sinusoidal surface on// the horizontal axis with 2 samples per // cycle. This is the Nyquist folding// wave number. This causes a single // peak to appear in the spectrum at the// negative folding wave number on the // horizontal axis. A peak would also// appear at the positive folding wave // number if it were visible, but it is// one unit outside the boundary of the // plot.for(int row = 0; row<rows; row++){ for(int col = 0; col<cols; col++){ spatialData[row][col] =cos(2*PI*col/2); }//end inner loop}//end outer loop break;case 10: //This case draws a sinusoidal surface on// the vertical axis with 2 samples per // cycle. Again, this is the Nyquist// folding wave number but the sinusoid // appears along a different axis. This// causes a single peak to appear in the // spectrum at the negative folding wave// number on the vertical axis. A peak // would also appear at the positive// folding wave number if it were // visible, but it is one unit outside// the boundary of the plot. for(int row = 0; row<rows; row++){ for(int col = 0; col<cols; col++){ spatialData[row][col] =cos(2*PI*row/2); }//end inner loop}//end outer loop break;case 11: //This case draws a sinusoidal surface on// the horizontal axis with 8 samples per // cycle. You might think of this surface// as resembling a sheet of corrugated // roofing material. This produces// symmetrical peaks on the horizontal // axis on either side of the wave-// number origin. for(int row = 0; row<rows; row++){ for(int col = 0; col<cols; col++){ spatialData[row][col] =cos(2*PI*col/8); }//end inner loop}//end outer loop break;case 12: //This case draws a sinusoidal surface on// the horizontal axis with 3 samples per // cycle plus a sinusoidal surface on the// vertical axis with 8 samples per // cycle. This produces symmetrical peaks// on the horizontal and vertical axes on // all four sides of the wave number// origin. for(int row = 0; row<rows; row++){ for(int col = 0; col<cols; col++){ spatialData[row][col] =cos(2*PI*row/8) + cos(2*PI*col/3); }//end inner loop}//end outer loop break;case 13: //This case draws a sinusoidal surface at// an angle of approximately 45 degrees // relative to the horizontal. This// produces a pair of peaks in the // wavenumber spectrum that are// symmetrical about the origin at // approximately 45 degrees relative to// the horizontal axis. double phase = 0;for(int row = 0; row<rows; row++){ for(int col = 0; col<cols; col++){ spatialData[row][col] =cos(2.0*PI*col/8 - phase); }//end inner loop//Increase phase for next row phase += .8;}//end outer loop break;default: System.out.println("Case must be " +"between 0 and 13 inclusive."); System.out.println("Terminating program."); System.exit(0);}//end switch statement return spatialData;}//end getSpatialData }//end class ImgMod31

Miscellaneous

This section contains a variety of miscellaneous information.

Housekeeping material
  • Module name: Java1491-2D Fourier Transforms using Java, Part 2
  • File: Java1491.htm
  • Published: 08/09/05

Examine the code for a Java class that can be used to perform forward and inverse 2D Fourier transforms on 3D surfaces in the space domain. Learn how the 2D Fourier transform behaves for a variety of different sample surfaces in the space domain.

Disclaimers:

Financial : Although the Connexions site makes it possible for you to download a PDF file for thismodule at no charge, and also makes it possible for you to purchase a pre-printed version of the PDF file, you should beaware that some of the HTML elements in this module may not translate well into PDF.

I also want you to know that, I receive no financial compensation from the Connexions website even if you purchase the PDF version of the module.

In the past, unknown individuals have copied my modules from cnx.org, converted them to Kindle books, and placed them for sale on Amazon.com showing me as the author. Ineither receive compensation for those sales nor do I know who does receive compensation. If you purchase such a book, please beaware that it is a copy of a module that is freely available on cnx.org and that it was made and published withoutmy prior knowledge.

Affiliation : I am a professor of Computer Information Technology at Austin Community College in Austin, TX.

-end-

Get Jobilize Job Search Mobile App in your pocket Now!

Get it on Google Play Download on the App Store Now




Source:  OpenStax, Digital signal processing - dsp. OpenStax CNX. Jan 06, 2016 Download for free at https://legacy.cnx.org/content/col11642/1.38
Google Play and the Google Play logo are trademarks of Google Inc.

Notification Switch

Would you like to follow the 'Digital signal processing - dsp' conversation and receive update notifications?

Ask