Prakticky použitelným problémem je složení obrazů pořízených kamerou z jednoho místa. Nejzávažnějším problémem na cestě k mozaice z obrazů je nalezení bodů korespondence. Pomocí těchto bodů lze pak již jednoduše vypočítat koeficienty transformační matice a tou pak transformovat ostatní body.
K správnému složení dvou obrazů pořízených
z jednoho místa různě natočenou kamerou potřebujeme body korespondence - body v
prvním obrázku a jim odpovídající body v obrázku druhém. Teoreticky je dokázáno, že nutný počet bodů je právě 4,
prakticky však máme bodů více, avšak ne zcela přesně korespondentních.
Transformace, ke které dojde při vyfocení scény je dána rovnicí:
Z nám známých bodů korespondence jsme poté schopni spočítat koeficienty matice H. Máme-li bodů více než 4, získáme soustavu rovnic, která obecně nemá řešení. Proto nejprve sestavíme matici A - soustavu lineárních rovnic:
Matici H lze následně získat jako nulový prostor matice A.
Metoda, kterou získáme matici h se nazývá SVD (Singular Value Decomposition). Tuto matici poté jednoduše transformujeme na hledanou matici H.
Matici H poté použijeme na transformaci souřadnic všech bodů ze vstupního obrazu do souřadnic bodů ve výsledné mozaice, podle následujícího vztahu:
Praktické ověření výše uvedených faktů proběhlo v programu MatLab pomocí následujícího skriptu. Komentáře blíže popisují funkci jednotlivých příkazů.
load
panoramap %nahraje
2x 4 body
im1 =
double(rgb2gray(imread('panorama1.jpg'))); %nahraje
obrazky a prevede do sedi
im2 =
double(rgb2gray(imread('panorama2.jpg'))); %0-255
im1 =
im1/max(im1(:)); %0-1
im2 = im2/max(im2(:));
u1 = [I2(:,1)';I1(:,1)']; %prevod matice bodu
u2 = [I2(:,2)';I1(:,2)'];
figure
imshow(im1) %zobraz
obr. 1
hold
plot(u1(2,:),u1(1,:),'*g') %a body
figure
imshow(im2) %obr. 2
hold
plot(u2(2,:),u2(1,:),'*g') %a body
im =
zeros(2*size(im1)); %velky
cerny obr.
im([1:size(im1,1)]+size(im1,1)/2,[1:size(im1,2)]+size(im1,2))=im1; %vpravo doprostred vykreslime im1
u = u1 +
[size(im1,1)/2;size(im1,2)]*ones(1,size(u1,2)); %souradnice
prepocteme na
%globalni
figure
imshow(im)
hold
plot(u(2,:),u(1,:),'*g') %body vykreslime
H = uu2homog(u2,u); %najdeme transformační matici souřadnic bodů u2 do
%souřadnic bodů u
v2 =
[1 1 ; size(im2,1) 1 ;1 size(im2,2); size(im2)]'; %okraje obr. 2
v = p2e(H * e2p(v2)); %transformace rohovych (okrajovych) bodu
plot(v(2,:),v(1,:),'*r') %jejich vykresleni
b
= [floor(min(v')) ceil(max(v'))]; %vypocet
min. obdelnikove oblasti pro
%transformaci
b = b([1 3 2 4]);
bp =
[b([1 3])' b([1 4])' b([2 4])' b([2 3])'];
plot(bp(2,[1:4
1]),bp(1,[1:4 1]),'m') %vykresleni
obdelniku
[y,x] = meshgrid(b(3):b(4),b(1):b(2)); %vygenerujeme souradnice nasi
%obdelnikove oblasti
uv = [x(:)';y(:)'];
idx =
round(uv(1,:))+round((uv(2,:)-1))*size(im,1); %index
do im
uv2 = p2e(inv(H) * e2p(uv)); %transformace
idx2 =
round(uv2(1,:))+round((uv2(2,:)-1))*size(im2,1); %index do im2
ix2 = (uv2(1,:)>=1) & (uv2(1,:)<=size(im2,1)) & (uv2(2,:)>=1) & (uv2(2,:)<=size(im2,2)-20); %maska 0 a 1, -20 vyhodi cerny pruh
im(idx(ix2)) = im2(idx2(ix2)); %vlozeni im2 do im podle indexu
figure
imshow(im)
return
Výsledek snažení programu:
Obr. 2 – fotografie s vyznačenými body korespondence
Obr. 3 – obdélníková oblast pro transformaci Obr. 4 – složený obrázek
Prakticky jsme si ověřili teoretické poznatky o problému mozaiky, aplikace programu MatLab je v tomto případě vhodná díky jednoduchosti implementace a názornosti výsledků. Ze složeného obrázku je zřejmé, že výsledek není zcela přesný. Zejména napojení obrazů je zatíženo chybou, která může být způsobena drobnými nepřesnostmi dvojic odpovídajících si bodů a ztrátou informace v důsledku digitalizace obrazu.