Då kör vi uppdateringen på phase correlation som lovades i KFly tråden!

Detta är då en helt annat sätt av att göra optic flow som baseras i frekvensplanet.
Jag har bifogat två dokument, en liten förklaring av mig som beskriver hur phase correlation fungerar och ett dokument om en komplett optical flow algoritm.
kflow_v1.pdf
phasecorrelation5.pdf
Exempel - här är två bilder där den ena har skiftats 15 pixlar i x och y led:
pic1_fill.png
pic2_fill.png
Den svarta linjen motsvarar ett dödområde i sensorn.
Efter min algoritm och efter IFFTn så är detta resultatet:
ifft.png
Den vita punkten är i positionen (15, 15) - dvs perfekt matchning.
När det kommer till beräkningskomplexitet så behövs det (om bilden har NxN pixlar) 2*N FFTer samt lika många IFFTer, där max N stycken kan köras i parallell.
Dvs för en 256 x 256 bild så behövs det totalt 512 st 256 punkters FFTer och lika många IFFTer. Så denna algoritm är extremt bra för parallella beräkningar i tex en FPGA!
Här är ett script (bestående av 3 filer) som gör precis detta, men bra för translation. Dvs den tar inte hänsyn till rotation och skalning.
Men den är ganska kul att leka med.
Huvudscriptet:
Kod: Markera allt
close all;
clc;
clear all;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Phase correlation of Images based motion estimation example
% (uses a webcam to demo the algorithm)
%
% Note: Only translation, not rotation nor scaling is identified.
%
% By Emil Fresk, Luleå University of Technology
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create video input object.
% Follow the steps here to install neccessary software:
% http://www.mathworks.se/help/imaq/basic-image-acquisition-procedure.html
% Work computer webcam:
% vid = videoinput('winvideo',1,'I420_176x144');
% Laptop webcam:
vid = videoinput('winvideo',1,'MJPG_352x288');
vid_size = 256;
% Set video input object properties for this application.
% Note that example uses both SET method and dot notation method.
set(vid,'TriggerRepeat',100);
vid.FrameGrabInterval = 4;
% Set value of a video source object property.
vid_src = getselectedsource(vid);
%set(vid_src,'Tag','motion detection setup');
%set(vid_src,'FrameRate', '20.0000');
%set(vid_src,'ExposureMode', 'manual');
% Create a figure window.
f = figure(1);
% Start acquiring frames.
start(vid)
% Create local variables
old_fft = zeros(vid_size, vid_size);
x = 0;
y = 0;
first = true;
while (1)
% Wait until a frame is available
while(vid.FramesAvailable == 0)
end
% Get the new image from the webcam
new_image = getdata(vid,1);
% Convert the data uint8 -> double
new_image = double(new_image(1:vid_size, 1:vid_size, 1));
% Calculate the optic flow based on the old fft and the new image
[of, old_fft, dx, dy] = get_optic_flow(new_image, old_fft, vid_size);
% Minor thing to cancel start up defects
if first == true
dx = 0;
dy = 0;
first = false;
end
% Integrate the deltas to get total translation
x = x + dx;
y = y - dy;
% Plot the image and correlation in a subplot with results as text
subplot(1,2,1), imshow(imresize(new_image ./ max(max(new_image)), 3));
title(['x: ', int2str(x), ', y: ', int2str(y)])
subplot(1,2,2), imshow(imresize(of, 3));
title(['(dx: ', int2str(dx), ', dy: ', int2str(-dy), ')']);
set(findall(f,'type','text'),'FontSize',30,'fontWeight','bold')
drawnow % update figure window
% Check if 'e' has been pressed, if so exit the loop.
key = get(f,'CurrentCharacter');
if (key == 'e')
fprintf('End of flow.\n')
break;
end
end
stop(vid)
Hjälpfunktioner:
Kod: Markera allt
function [A, new_fft, dx, dy] = get_optic_flow(new_img, old_fft, vid_size)
D1 = old_fft;
D2 = fft2(apply_window(new_img));
M = D1.*conj(D2);
A = abs(ifft2(M ./ abs(M)));
A = fftshift(A ./ max(max(A)));
[~, I] = max(A(:));
dx = round(I / vid_size) - (vid_size / 2) - 1;
dy = mod(I, vid_size) - (vid_size / 2) - 1;
new_fft = D2;
end
Kod: Markera allt
function X = apply_window(img)
% w - Window function, N x 1
% d - Image N x N
N = length(img);
m = zeros(N,N); % Initialize space for mask
w = hamming(N);
% Initialize windows along column direction
for n=1:N
m(:,n) = w;
end
% Apply windows along rows
m = m .* m';
X = img .* m;
end
Har ni frågor så släng dom på mig!
