Vypracovali: Tomáš Macháček
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.
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:
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)'];
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:
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.