Mosaic

 

Vypracovali:                Tomáš Macháček

                                   Miroslav Koblížek

Zadání

Ze dvou zadaných fotografií, které jsou nafoceny z jednoho místa složte jednu obsahující informace z obou dvou. Souřadnice korespondujících bodů jsou uloženy v souboru.

 

Rozbor problému

Při vyfocení 3D scény pomocí kamery dochází k transformaci ze souřadnic (x,y) do souřadnic (u,v) dle vztahu:

kde

Známe-li dostatečný počet bodů (xi,y i) a k nim náležející transformované body (ui,v i) lze vypočítat parametry matice H. K jednoznačnému výpočtu matice H jsou potřeba čtyři body. Většinou však pracujeme s větším počtem nepřesně určených bodů. Potom vyžadujeme, aby nám větší počet korespondujících bodů zajistil vyšší přesnost při určování matice H. Potom ale pracujeme s přeurčenou soustavou rovnic, která nemá řešení – ale snažíme se najít takové hodnoty v matici H, aby se levé strany rovni co nejvíce rovnaly pravým. K vyřešení takového problému sestavíme nejprve soustavu lineárních rovnic pro vyřešení matice H:

Matici H potom určíme jako nulový prostor matice A.

Hodnost matice A je 8 to znamená, že existuje netriviální řešení matice h. Matice h se získá pomocí SDV (Singular value decomposition). Matice h má rozměr 9x1 ta se přerovná do matice H, která má rozměr 3x3.

 

         

 

Pomocí takto získané matice H potom transformujeme všechny body o souřadnicích (x,y) ze zdrojového obrázku do bodu o souřadnicích (u,v) v cílovém obraze:

Tato transformace by však způsobila díry ve výsledném obraze, proto se používá transformace inverzní z cílového obrazu do obrazu zdrojového:

 

 

Postup při řešení

natažení souřadnic korespondujících bodů

load panoramap

 

natažení zdrojových obrázků a jejich konverze na černobílé

im1 = double(rgb2gray(imread('panorama1.jpg')));

im2 = double(rgb2gray(imread('panorama2.jpg')));

im1 = im1/max(im1(:));

im2 = im2/max(im2(:));

 

přerovnání souřadnic korespondujících bodů tak, aby u1 obsahovalo souřadnice v obraze im1 a u2 souřadnice v obraze im2

u1  = [I2(:,1)';I1(:,1)'];

u2  = [I2(:,2)';I1(:,2)'];

 

zobrazení obou obrázků a korespondujících bodů v obrázcích

figure

imshow(im1)

hold

plot(u1(2,:),u1(1,:),'*g')

figure

imshow(im2)

hold

plot(u2(2,:),u2(1,:),'*g')

 

alokace matice pro výsledný obraz o dvojnásobném rozměru než im1

im = zeros(2*size(im1));

 

Nakopírování obrazu im1 do cílového obrazu na pozici  (SizeX(im1), SizeY(im1)/2)

im([1:size(im1,1)]+size(im1,1)/2,[1:size(im1,2)]+size(im1,2))=im1;

 

Posunutí souřadnic korespondujících bodů z obrázku im1 do souřadnic ve výsledném obrazu im

u  = u1 + [size(im1,1)/2;size(im1,2)]*ones(1,size(u1,2));

 

zobrazení výsledného obrazu

figure

imshow(im)

hold

 

zobrazení přetransformovaných korespondujících bodů

plot(u(2,:),u(1,:),'*g')

 

nalezení mapovací matice ze souřadnic v obraze im2 do souřadnic výsledného obrazu

H  = uu2homog(u2,u);

 

výpočet okrajů obrazu im2

v2 = [1 1 ; size(im2,1) 1 ;1 size(im2,2); size(im2)]';

 

transformace okrajů obrázku im2 do výsledného obrazu

v  = p2e(H * e2p(v2));

 

vykreslení okrajů obrázku im2 ve výsledném obraze

plot(v(2,:),v(1,:),'*r')

 

nalezení obrysového obdélníka transformovaných obrysů obrázku im2 ve výsledném obraze im

b  = [floor(min(v')) ceil(max(v'))];

 

přerovnání souřadnic obrysového obdélníka

b  = b([1 3 2 4]);

 

vytvoření souřadnic rohů obrysového obdélníka

bp = [b([1 3])' b([1 4])' b([2 4])' b([2 3])'];

 

vykreslení obrysového obdélníka

plot(bp(2,[1:4 1]),bp(1,[1:4 1]),'m')

 

vytvoří se matice x a y, které pro každý bod obsahují souřadnici X a Y. Tyto matice jsou sloupcové vektory, které mají pro každý bod uvnitř obrysového obdélníka jeden prvek

 [y,x]         = meshgrid(b(3):b(4),b(1):b(2));

 

vytvoření dvouřádkové matice, která má pro každý bod uvnitř obrysového obdélníka jeden sloupec se souřadnicemi X a Y

uv            = [x(:)';y(:)'];

 

k výše vypočítaným bodům vypočte adresy paměti bitmapě výsledného obrazu

idx           = round(uv(1,:))+round((uv(2,:)-1))*size(im,1);

 

transformace souřadnic uv cílového obrazu do souřadnic uv2 v obrazu im2

uv2           = p2e(inv(H) * e2p(uv));

 

k výše vypočítaným bodům vypočte adresy paměti bitmapě obrazu im2

idx2          = round(uv2(1,:))+round((uv2(2,:)-1))*size(im2,1);

 

vytoření bitové mapy logických hodnot, která vybere pouze body v uv i uv (protože body spolu korespondují), které leží v obraze im2

ix2= (uv2(1,:)>=1) & (uv2(1,:)<=size(im2,1)) & (uv2(2,:)>=1)

         & (uv2(2,:)<=size(im2,2)-20);

 

Do obrazu im se přes indexy idx přiřadí přes indexy idx2 body z obrazu im2, ale pouze jen takové, které mají logickou hodnotu 1 v matixi ix2 adresované indexy transformovaných bodů.

im(idx(ix2))  = im2(idx2(ix2));

 

zobrazení výsledného obrazu

figure

imshow(im)

 

 

V programu byla použita funkce uu2homog, která najde transformační matici souřadnic bodů u2 do souřadnic bodů u. V našem případě použijeme funkci matA, která nám vytvoří matici A:

function A=matA(u1,u2,i)

for n=1:i

   A=[A;[u1(1,n) u1(2,n) 1 0 0 0 -u1(1,n)*u2(1,n) -u1(2,n)*u2(1,n) -u2(1,n)]];

   A=[A;[0 0 0 u1(1,n) u1(2,n) 1 -u1(1,n)*u2(2,n) -u1(2,n)*u2(2,n) -u2(2,n)]];

end

end

 

Výpočet potom bude vypadat následovně:

A=matA(u,u2);

h=null(A);

H=(h[1] h[4] h[7]; h[2] h[5] h[8]; h[3] h[6] h[9]);

 

Výsledný složený obraz:

 

Závěr

Popsaný postup byl prakticky realizován a ověřen. Oba obrázky byly úspěšně spojeny. Spojení však nebylo zcela kvalitní, protože nebyly zřejmě přesně zadány korespondující body.