How to Normalize Centroid Distance Function Results in Order to Create Invariant Fourier Descriptors

5 views (last 30 days)
Hello All,
I'm working on a project to detect a shape in an image, given a shape to look for. The second image may or may not be shifted, rotated, or scaled, so my main challenge is to make the detection invariant to translation, scale, or rotation.
The code I have so far is:
CHECKIMAGE = im2bw(imread('SHAPE.jpg'),.3); %Convert image to binary for bwboundaries
CHECKIMAGE = bwlabel(CHECKIMAGE); %Convert image to binary for centroid discovery
[B,L] = bwboundaries(CHECKIMAGE,'noholes'); %Detect boundaries, store as coordinates
BOUNDARY = B{1}; %Store boundaries for later use
C = regionprops(CHECKIMAGE, 'Centroid'); %Detect centroid
CENTROID = C.Centroid;
for k = 1:length(BOUNDARY); %Calculate centroid distance
CDIST(k) = sqrt(((BOUNDARY(k,1)-CENTROID(1))^2+(BOUNDARY(k,2)-CENTROID(2))^2));
end
N = 128; %Define value of N for FFT
FDESC = abs(fft(CDIST, N)) / N; %Take fourier transform of centroid distance
K = find(FDESC > eps); % Leave a little wiggle room... use eps instead of 0
FIRSTFREQ = FDESC(K(1));
FDESC = FDESC / FIRSTFREQ; %TODO: NEED BETTER WAY TO MAKE INVARIANT
figure; plot(FDESC);
CHECKIMAGE2 = im2bw(imread('SHAPEROTATE.jpg'),.3); %Convert image to binary for bwboundaries
CHECKIMAGE2 = bwlabel(CHECKIMAGE2); %Convert image to binary for centroid discovery
[B2,L2] = bwboundaries(CHECKIMAGE2,'noholes'); %Detect boundaries, store as coordinates
C2 = regionprops(CHECKIMAGE2, 'Centroid'); %Detect centroid
CENTROID2 = C2.Centroid;
BOUNDARY2 = B2{1}; %Store boundaries for later use
for k = 1:length(BOUNDARY2);
CDIST2(k) = sqrt(((BOUNDARY2(k,1)-CENTROID2(1))^2+(BOUNDARY2(k,2)-CENTROID2(2))^2));
end
FDESC2 = abs(fft(CDIST2, N)) / N; %Take fourier transform of centroid distance
K = find(FDESC2 > eps); % Leave a little wiggle room... use eps instead of 0
FIRSTFREQ = FDESC2(K(1));
FDESC2 = FDESC2 / FIRSTFREQ; %TODO: NEED BETTER WAY TO MAKE INVARIANT
figure; plot(FDESC2);
CHECK = FDESC == FDESC2;
ERROR = 0;
for k = 1:length(FDESC)
if CHECK(k) == 0;
ERROR = ERROR + 1;
end
end
ERROR = ERROR / length(FDESC);
if ERROR <= .80;
TEXT = ['Images ', 'Match'];
WINDOW = msgbox(TEXT,'Success');
else
TEXT = ['Images ', 'Do ', 'Not ', 'Match'];
WINDOW = msgbox(TEXT, 'Failure');
end
Which works when the second image is the exact same as the first image, but this does not work when the second image is rotated or scaled differently than the first image.
I've been trying to think of different ways to make the data normalized so that the FFT returns an invariant series of descriptors, but it's been bugging me for a while now.
Any advice or hints would be much appreciated.
I've also attached the two images I'm using to test this code with.

Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!