1
$\begingroup$

i have mini project to do about homography , but i am really a beginner in matlab . i have calculated the homography matrix easily by taking a set pixels from both images but the problem is how to apply this matrix to all pixels of the original image (i think it's difficult to treat each pixel individually ) . here is the original image : enter image description here

i want to apply the homography to this image ( i have already extracted the homography matrix ) to get a frontal view of the cover.

so with my weak knowledge of matlab , i applied the folowing operations:

i get 4 points from the corners of the original image and the corresponding points in the output image

i have estimated the homography :

0.9638 -0.0960 52.5754; 
0.2449 1.3808 -17.0081; 
-0.0001 0.0013 1.0000

then i have applied it on the image using this poor matlab code:

function [Ired] = affect(I,P)
I1=im2double(I);
for i=1:308
i
for j=1:288
v1 = [j;i;1];
v2 = P*v1;
v3 =v2/v2(3,1);
if (v3(1,1) <0 || v3(2,1)<0 || v3(3,1)<0)
   continue;
else     
Ired(round(1+v3(2,1)),round(1+v3(1,1)))=I1(i,j);
end
end 

end

and the result is the following:

enter image description here

- but the problem with this code is it takes a lot of time (sometimes 10 minutes) to perform the operation on the image especially if the size of the image is high so is there a way to implement this code without loops to make it faster? .

- i get these black dots all over the image , i can do a dilation but the image will be distorted , do you have an idea how to eliminate this dots without distorting the image ?.

$\endgroup$

1 Answer 1

2
$\begingroup$

Matrix/vector operations are really strongly optimized in Matlab/Octave. Use them whenever you can.

In your case, instead of multiplying the 3x3 homography matrix with a 3x1 vector for NxM times you can easily modify your calculation to do a multiplication with a 3x3 matrix and a 3xM matrix for N times.

Check out this Octave code:

warning ("off", "Octave:broadcast");
w = 1280;
h = 720;
H = rand(3);

tic();
for i=1:h 
    for j=1:w 
        H*[i;j;1]/(H(3,:)*[i;j;1]); 
    end
end; 
toc();

tic();
for i=1:h 
    v=[ones(1,w)*i;1:w;ones(1,w)];
    (H*v)./(H(3,:)*v); 
end; 
toc();

It gives me the following result:

Elapsed time is 25.5651 seconds.
Elapsed time is 0.273893 seconds.

Maybe you can go further by generating a 3x(N*M) matrix with all the image coordinates.

There is a simple solution to the 'black dots' problem. Right now you have the homography $H$ between the original image and the cover image and you generate the points by looping through the pixels of the original image $(x,y)$ to color the points $(x',y')$ in the destination image.

Let's have the homography $H^{-1}$, loop through all the pixels in the destination image and calculate the pixel address of the original image you want to sample the color from.

$\endgroup$
1
  • $\begingroup$ thank you very much, now i do not have to wait 5 minutes to do the operation, for the black dots problem i understand what do you mean and i will try that right away. $\endgroup$
    – Yesbra Bra
    Mar 3, 2015 at 21:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.