kernel creation for FFT convolution

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
toasty
Posts: 16
Joined: 2012-12-06T17:56:02-07:00
Authentication code: 6789

kernel creation for FFT convolution

Post by toasty »

Hi all,

I'm still working with kernels trying to identify circular structures within an image.

Basically, I want to identify the best position and size of circles in an image. I am creating a set of circular kernels of different radii, that I convolve with the image and locate the peaks. The one with the highest peak is supposed to be the best fitting circular kernel. The problem is that creating a kernel like so:

Code: Select all

convert -size 1200x1200 xc:black -fill white -draw "circle 99,99,103,99" -alpha off circle_004.png
which produces a white circle on a black background, doesn't identify the circle edges so well. Small kernels will still match with larger circular structures in the image. What I want to do is put a negative border around the circle so that it will match best with a structure in the image that drops at the required radius. I tried this:

Code: Select all

convert -size 1200x1200 xc:gray50 -fill black -draw "circle 99,99,105,99" -fill white -draw "circle 99,99,103,99" -alpha off circle_004.png
which creates a black circle on a gray background, then paints a white circle of smaller radius on top.

When I use the FFT to convolve this with my image (which worked when I have the white circle on the black background), it doesn't seem to produce coherent outputs. I think that when using the FFT to convolve a kernel with an image, the kernel needs to exist over a small range, and must go to zero outsize that range. My second attempt is gray, and essentially non-zero everywhere except in the vicinity of the circle. What I'd like to do is have a kernel which is black (zero) everywhere, then paint a negative circle of radius r+2, then paint a positive (white) circle of radius r on top of it. I think this kernel might work.

However I don't know how to draw a circle of negative pixels. Can someone advise on how to do this, or suggest a better method?

Thanks
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: kernel creation for FFT convolution

Post by fmw42 »

If your circles are filled in your image and not rings, then it should work if you do normalize cross correlation in the FFT domain. See my unix bash script, normcrosscorr at the link below. Also see http://www.fmwconcepts.com/imagemagick/ ... mcrosscorr

Too bad IM does not have linear or circular Hough transforms. But you could get them using OpenCV
toasty
Posts: 16
Joined: 2012-12-06T17:56:02-07:00
Authentication code: 6789

Re: kernel creation for FFT convolution

Post by toasty »

I'm trying to generate an image that has negative numbers in it and take the FFT of that. I'm using an HDRI version of IM, but I'm not sure why the method I'm using is not producing negative numbers, or it's not fft'ing the negative numbers correctly.

This is how I'm doing it: first I create a canvas that is 50% gray. I draw what I want on the gray canvas, in this case a white circle, then I subtract the 50% gray that I added at the beginning. In this way, I can offset whatever I draw by any amount I want. The second line below saves the image into circle.png. The third line takes the fft of the image and the 4th line plots the magnitude spectrum into circle_FFT.png

Code: Select all

convert -size 200x200 xc:black -evaluate add 50% -fill white -draw "circle 100,100,110,100" -evaluate subtract 50%\
 \( +clone +write circle.png +delete \) \
 -roll -100-100 -fft \
 \( -clone 0 -auto-level -evaluate log 100 +write circle_FFT.png +delete \) \
 null:
This appears to work, at least from the "time" domain picture: the circle produced is 50% gray, and I can offset it by any amount I want and I can make a negative circle by drawing a black circle rather than a white one on the gray canvas. However, I don't understand why the frequency domain picture does not seem to match the time-domain one. For example, below I create a white canvas, draw a white circle, then subtract pure white, I should get nothing. Time domain shows nothing, but frequency domain still shows the original fft'd picture unchanged. Can someone explain to me why?

Code: Select all

convert -size 200x200 xc:black -evaluate add 100% -fill white -draw "circle 100,100,110,100" -evaluate subtract 100%\
 \( +clone +write circle.png +delete \) \
 -roll -100-100 -fft \
 \( -clone 0 -auto-level -evaluate log 100 +write circle_FFT.png +delete \) \
 null:
Post Reply