>Robert, > >Thank you so much for this FFT example. Now I have questions. Where in the >program can we change parameters to do filtering such as getting rid of >high frequency (noise) or low frequency (background) variations in pixel >intensity ? >Do we need to have a square image or only have width and height to be >multiples of 2 ? > >Thanks again. > >Cheers > >Patrick Patrick, The input image width and height both must be a power of 2, and square. The FFT menu Show Valid Samples item will show allowable dimensions. If you have an image that is not one of these sizes in one dimension for example but it is in the other, you can zero pad it to match in that dimension or zero - pad the entire image up to match if both are off. That is, create an image the next size up, and then fill it with black, and place your new image in the center. Or add a border to the one dimension that is lacking, keeping the image centered. Use the FN AdjustDestRect below to handle that, using the new image size as the constraints instead of Syswidth or the like. You will also need to change the array DIM size, and the gRect, and the image will now be contained in gDestRect. As far as filtering goes, the below is all I know currently, and it is partially a port from the C code included in the archive. No warranties of performance or fitness to purpose, the parameters are a complete guess as to value other than the Power one (filter 4). But at least shows something is going on. These menu items will handle all transforms in a single step. For more information on this particular code and FFT as applied here, check out Paul Bourke's site via the URL in the Read Me, then do a search on his site using the term FFT, and the appropriate pages will show up. Robert Try out this addition to the FFT beast. 3 easy Steps. 1. Add these menu items under the Filter menu Menu 4,2, _enable,"Low Pass" Menu 4,3, _enable,"Band Pass" Menu 4,4, _enable,"High Pass" Menu 4,5, _enable,"Power" 2. Then add these pups in the menu for select menu 4 in FN doMenu after the Invert Item 1. The params are a -guess- after some min/max tests I did earlier. Format: FilterResults(filter,lowcut,highcut,power) Power of 2 will fuzz out the image completely. case 2 gFilled = 0 if gWorld then FN TransformImage(_Forward) If gWorld Then FN DrawFFTSomething If gWorld Then FN FilterResults(1,-9,24,.25) if gWorld then FN TransformImage(_Reverse) If gWorld Then FN DrawFFTSomething case 3 gFilled = 0 if gWorld then FN TransformImage(_Forward) If gWorld Then FN DrawFFTSomething If gWorld Then FN FilterResults(2,-9,24,.25) if gWorld then FN TransformImage(_Reverse) If gWorld Then FN DrawFFTSomething case 4 gFilled = 0 if gWorld then FN TransformImage(_Forward) If gWorld Then FN DrawFFTSomething If gWorld Then FN FilterResults(3,-9,24,.25) if gWorld then FN TransformImage(_Reverse) If gWorld Then FN DrawFFTSomething case 5 gFilled = 0 if gWorld then FN TransformImage(_Forward) If gWorld Then FN DrawFFTSomething If gWorld Then FN FilterResults(4,-9,24,.25) if gWorld then FN TransformImage(_Reverse) If gWorld Then FN DrawFFTSomething 3. Try these after loading an image. This does the forward, filters, reverses all in one. Here is the filter include... Local DIM as double r,r1,r2,r3,r4 Local FN FilterResults(filter,cutoff1 as double,cutoff2 as double,power as double) DIM i,j as int DIM iWidth as Int DIM iHeight as int iWidth = gRect.right% iHeight = gRect.bottom% /* Perform the filtering 0 - no filter 1 - low pass rectangular 2 - band pass rectangular 3 - high pass rectangular 4 - 1 / f^p */ for i=0 TO iwidth-1 for j=0 TO iheight - 1 r1 = i*i + j*j r2 = (i-iwidth)*(i-iwidth) + j*j r3 = i*i + (j-iheight)*(j-iheight) r4 = (i-iwidth)*(i-iwidth) + (j-iheight)*(j-iheight) if r1 < r2 then r = r1 if r3 < r then r = r3 if r4 < r then r = r4 Select filter case 0/* No filtering */ Exit FN case 1 /* Low pass */ Long if (r > cutoff1*cutoff1) c.real(i,j) = 0 c.imag(i,j) = 0 End If case 2/* Band pass */ Long if (r < cutoff1*cutoff1 OR r > cutoff2*cutoff2) c.real(i,j) = 0 c.imag(i,j) = 0 End If case 3/* High pass */ Long if (r < cutoff1*cutoff1) c.real(i,j) = 0 c.imag(i,j) = 0 End If case 4 Long if r > 0 c.real(i,j) = c.real(i,j) * (1/(r^power)) c.imag(i,j) = c.imag(i,j) * (1/(r^power)) End if End Select next j/* j */ next i/* i */ END FN // End Filter additions. //------------------- //------------------ Additions/ changes required to Zero pad an invalid sized image------------------- //------------------- Begin Globals DIM gDestRect as Rect End GLobals Local Local FN AdjustDestRect(size) DIM cenRect as Rect DIM wWidth as Int DIM wHeight as int DIM scale as Fixed, scaleH as fixed, scaleV as fixed // assign your window or screen width here.* wWidth = size wHeight = size cenRect;8 = @gRect Call OffsetRect(cenRect,-cenRect.left,-cenRect.top) scale = FN Long2Fix(1) scaleH = FN FixRatio(wWidth,cenRect.right-cenRect.left) scaleV = FN FixRatio(wHeight,cenRect.bottom-cenRect.top) If scaleH < scale then scale = scaleH If scaleV < scale then scale = scaleV Long if scale <> FN Long2Fix(1) cenRect.right= FN Fix2Long(FN FixMul(scale,FN Long2Fix(cenRect.right))) cenRect.bottom= FN Fix2Long(FN FixMul(scale,FN Long2Fix(cenRect.bottom))) End If // to center a small image in a larger window (assign at * above) Call OffSetRect(cenRect,(wWidth-cenRect.right)/2,(wHeight-cenRect.bottom)/2) gDestRect;8 = @cenRect End Fn // Now, in FN ImportImage: gRect;8 = [PictH]+_PicFrame offsetRect(gRect,gRect.top%,gRect.left%) DIM max Long if gRect.right% <> gRect.bottom% if gRect.right% > gRect.bottom% then max = gRect.right% else max = gRect.bottom% End if /// You would compare Max to Valid Sample Sizes here and pick next size up using var Size. Size = FN YourFnHereToSelectBestSampleSizeUsingMax(max) // Then: FN AdjustDestRect(Size) Followed by: SetRect(gRect,0,0,Size,Size) Now make all well, and change the current to this: Color _zBlack CALL GETGWORLD(gScreenGW,gCurrDevice) CALL SETGWORLD(gDrawGW,0) call PaintRect(gRect) call Drawpicture (PictH,gDestRect) CALL SETGWORLD(gUndoGW,0) call PaintRect(gRect) call Drawpicture (PictH,gDestRect) CALL SETGWORLD(gDraw2GW,0) call PaintRect(gRect) call Drawpicture (PictH,gDestRect) Call Killpicture(PictH) call SETGWORLD(gScreenGW, gCurrDevice) Then all should work fine. Unless you exceed your array dimensions. :) Robert