init
This commit is contained in:
commit
4ea5f3f2f9
88
TP_mosaique.m
Normal file
88
TP_mosaique.m
Normal file
|
@ -0,0 +1,88 @@
|
|||
clear all;
|
||||
close all;
|
||||
|
||||
% Lecture des images
|
||||
Im1 = imread('sweet1.pgm');
|
||||
Im2 = imread('sweet2.pgm');
|
||||
|
||||
Im1_coul = imread('sweet_couleur1.jpg');
|
||||
Im2_coul = imread('sweet_couleur2.jpg');
|
||||
Im3_coul = imread('sweet_couleur3.jpg');
|
||||
% Im1_coul = imread('rescaled_local_1.jpg');
|
||||
% Im2_coul = imread('rescaled_local_2.jpg');
|
||||
% Im3_coul = imread('rescaled_local_3.jpg');
|
||||
% Im4_coul = imread('rescaled_local_4.jpg');
|
||||
% Im5_coul = imread('rescaled_local_5.jpg');
|
||||
% Im6_coul = imread('rescaled_local_6.jpg');
|
||||
% Im7_coul = imread('rescaled_local_7.jpg');
|
||||
% Im8_coul = imread('rescaled_local_8.jpg');
|
||||
% Im1_coul = imread('im1.jpg');
|
||||
% Im2_coul = imread('im2.jpg');
|
||||
% Im3_coul = imread('im3.jpg');
|
||||
% Im4_coul = imread('im4.jpg');
|
||||
|
||||
% Affichage des deux premières images en niveaux de gris
|
||||
% figure;
|
||||
% affichage_image(Im1,'Image 1',1,2,1);
|
||||
% affichage_image(Im2,'Image 2',1,2,2);
|
||||
|
||||
% Choix des parametres
|
||||
TailleFenetre = 17;
|
||||
NbPoints = 100;
|
||||
k = 0.05;
|
||||
seuil = 0.80;
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Detection des points d'interet avec Harris %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% [XY_1,Res_1] = harris(Im1,TailleFenetre,NbPoints,k);
|
||||
% [XY_2,Res_2] = harris(Im2,TailleFenetre,NbPoints,k);
|
||||
% figure;
|
||||
% affichage_POI(Im1,XY_1,'POI Image 1',1,2,1);
|
||||
% affichage_POI(Im2,XY_2,'POI Image 2',1,2,2);
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Appariement des points d'interet %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% [XY_C1,XY_C2] = apparier_POI(Im1,XY_1,Im2,XY_2,TailleFenetre,seuil);
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Estimation (et verification) de l'homographie %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% H = homographie(XY_C1,XY_C2);
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Calcul de la mosaique %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Imos = mosaique(Im1,Im2,H);
|
||||
% figure;
|
||||
% affichage_image(uint8(Imos),'Mosaique obtenue a partir des 2 images initiales',1,1,1);
|
||||
% imwrite(uint8(Imos),'mosaique2.pgm');
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Version 2 pour la reconstruction %
|
||||
% A DECOMMENTER QUAND MOSAIQUEBIS AURA ETE ECRITE %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Imosbis = mosaiquebis(Im1,Im2,H);
|
||||
% figure;
|
||||
% affichage_image(uint8(Imosbis),'Mosaique obtenue a partir des 2 images initiales (version 2)',1,1,1);
|
||||
% imwrite(uint8(Imosbis),'mosaique2_bis.pgm');
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Version 3 pour la reconstruction avec les couleurs R, G et B %
|
||||
% A DECOMMENTER QUAND MOSAIQUECOUL AURA ETE ECRITE %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Imoscoul = mosaiquecoul(Im1_coul,Im2_coul,H);
|
||||
% figure;
|
||||
% affichage_image(uint8(Imoscoul),'Mosaique obtenue a partir des 2 images couleur initiales (version 2)',1,1,1);
|
||||
% imwrite(uint8(Imoscoul),'mosaique2_coul.pgm');
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Version 4 pour la reconstruction avec 3 images %
|
||||
% en couleurs et/ou en niveaux de gris %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Imoscoul = mosaiqueN(TailleFenetre, NbPoints, k, seuil, Im1_coul, Im2_coul, Im3_coul);
|
||||
Imoscoul = mosaiqueNbis(TailleFenetre, NbPoints, k, seuil, 2, Im1_coul, Im2_coul, Im3_coul);
|
||||
figure;
|
||||
affichage_image(Imoscoul,'Mosaique obtenue a partir des 3 images couleur initiales (version 2)',1,1,1);
|
||||
% imwrite(uint8(Imoscoul),'mosaique2_coul.pgm');
|
17
affichage_POI.m
Normal file
17
affichage_POI.m
Normal file
|
@ -0,0 +1,17 @@
|
|||
% Fonction permettant d'afficher les images avec les points d'interet
|
||||
% detectes
|
||||
% ENTREES
|
||||
% Im : Image
|
||||
% points : les points a afficher
|
||||
% message : le titre de la figure
|
||||
% l, c, numero : le nombre de lignes et colonnes de la figure et le numero
|
||||
% dans la sous-figure
|
||||
% SORTIE : la figure
|
||||
function [] = affichage_POI(Im,points,message,l,c,numero)
|
||||
% Affichage de l'image
|
||||
subplot(l,c,numero);
|
||||
colormap(gray);imshow(Im); hold on;
|
||||
plot_points(points,length(points),'o');
|
||||
title(message);
|
||||
hold off;
|
||||
end
|
28
affichage_appariement.m
Normal file
28
affichage_appariement.m
Normal file
|
@ -0,0 +1,28 @@
|
|||
% Fonction permettant d'afficher les images
|
||||
% avec les points d'interet numerotes
|
||||
% Les points portant le meme numero sont les correspondants
|
||||
% ENTREES
|
||||
% Im : Image
|
||||
% mesurex1,mesurey1 : les points à afficher
|
||||
% message : le titre de la figure
|
||||
% l, c, numero : le nombre de lignes et colonnes de la figure et le numero
|
||||
% dans la sous-figure
|
||||
% SORTIE : la figure
|
||||
function [] = affichage_appariement(Im,mesurex1,mesurey1,message,l,c,numero)
|
||||
% Affichage de l'image
|
||||
subplot(l,c,numero);
|
||||
imshow(Im);
|
||||
% Affichage des points
|
||||
hold on;
|
||||
plot(mesurex1,mesurey1,'r.','MarkerSize',15)
|
||||
% Affichage des numeros
|
||||
for i=1:size(mesurex1,1)
|
||||
if (i<10)
|
||||
text(mesurex1(i)-15,mesurey1(i),num2str(i),'Color','g','FontSize',12)
|
||||
else
|
||||
text(mesurex1(i)-30,mesurey1(i),num2str(i),'Color','g','FontSize',12)
|
||||
end
|
||||
end
|
||||
hold off;
|
||||
|
||||
end
|
13
affichage_image.m
Normal file
13
affichage_image.m
Normal file
|
@ -0,0 +1,13 @@
|
|||
% Fonction permettant d'afficher les images
|
||||
% ENTREES
|
||||
% Im : Image
|
||||
% message : le titre de la figure
|
||||
% l, c, numero : le nombre de lignes et colonnes de la figure et le numero
|
||||
% dans la sous-figure
|
||||
% SORTIE : la figure
|
||||
function [] = affichage_image(Im,message,l,c,numero)
|
||||
subplot(l,c,numero);
|
||||
colormap(gray);
|
||||
imshow(Im);
|
||||
title(message);
|
||||
end
|
47
apparier_POI.m
Normal file
47
apparier_POI.m
Normal file
|
@ -0,0 +1,47 @@
|
|||
function [XY_C1, XY_C2] = apparier_POI(Im1, XY_1, Im2, XY_2, TailleFenetre, seuil)
|
||||
% apparierPOI apparie les points d'interet stockes dans XY_1 et XY_2 entre
|
||||
% les images Im1 et Im2 avec une fenetre de correlation de taille
|
||||
% TailleFenetre
|
||||
% seuil correspond au seuil utilise pour eliminer les erreurs d'appariement
|
||||
% XY_C1 et XY_C2 sont les coordonnees des points de l'image 1
|
||||
% apparies avec les points XY_C2 de l'image 2
|
||||
|
||||
% Nombre de points a mettre en correspondance
|
||||
NbPoints = size(XY_1, 1);
|
||||
|
||||
% Calcul de ZNCC
|
||||
C = apparier_Points(Im1, XY_1, Im2, XY_2, TailleFenetre);
|
||||
C = abs(C);
|
||||
|
||||
% Recherche par methode WTA (Winner Takes All)
|
||||
% Indices des maxima sur les lignes
|
||||
[maxI1, ind1_2] = max(C, [], 2);
|
||||
ind1_2 = ind1_2(:);
|
||||
|
||||
% Indices des maxima sur les colonnes
|
||||
[~, ind2_1] = max(C, [], 1);
|
||||
ind2_1 = ind2_1(:);
|
||||
|
||||
% Verification de la contrainte de symetrie
|
||||
% + seuillage du score de correlation
|
||||
% Cette premiere ligne doit etre modifiee pour appliquer les contraintes souhaitees
|
||||
ind2ind = ind2_1(ind1_2);
|
||||
ind1 = find(maxI1 > seuil & vecnorm(XY_1(ind2ind, :) - XY_1, 2, 2) <= 0);
|
||||
% ind1(8) = [];
|
||||
|
||||
% Cette deuxieme doit etre gardee telle quelle
|
||||
ind2 = ind1_2(ind1);
|
||||
|
||||
% Affichage des appariements
|
||||
mesurex1 = XY_1(ind1, 1);
|
||||
mesurey1 = XY_1(ind1, 2);
|
||||
mesurex2 = XY_2(ind2, 1);
|
||||
mesurey2 = XY_2(ind2, 2);
|
||||
|
||||
figure;
|
||||
affichage_appariement(Im1, mesurex1, mesurey1, 'Points d''interet Image 1', 1, 2, 1);
|
||||
affichage_appariement(Im2, mesurex2, mesurey2, 'Points d''interet correspondants Image 2', 1, 2, 2);
|
||||
|
||||
XY_C1 = [mesurex1(:) mesurey1(:)];
|
||||
XY_C2 = [mesurex2(:) mesurey2(:)];
|
||||
end
|
83
apparier_Points.m
Normal file
83
apparier_Points.m
Normal file
|
@ -0,0 +1,83 @@
|
|||
% Fonction calculant pour chaque appariement de points possible
|
||||
% ZNCC (Zero-mean Normalized Cross Correlation) definie par :
|
||||
% (P1-/P1).(P2-/P2) Cov(P1,P2)
|
||||
% ZNCC(P1,P2) = --------------------- = -----------------------
|
||||
% ||P1 - /P1||||P2-/P2|| sqrt(Var(P1)*Var(P2))
|
||||
% * P1 = l'ensemble des niveaux de gris du voisinage du point p1=(p1x,p1y)
|
||||
% sur l'image I1
|
||||
% * P2 = l'ensemble des niveaux de gris du voisinage du point p2=(p2x,p2y)
|
||||
% sur l'image I2
|
||||
% * Cov(P1,P2) = E[(P1-E[P1])*(P2-E[P2])]
|
||||
% = Sum_{i=-k}^k Sum_{j=-k}^k (I1(p1x+i,p1y+j)-E[P1])
|
||||
% *(I2(p2x+i,p2y+j)-E[P2])/(2*k+1)^2
|
||||
% * E[P1] = esperance de P1
|
||||
% = Sum_{i=-k}^k Sum_{j=-k}^k I1(p1x+i,p1y+j)/(2*k+1)^2,
|
||||
% * E[P2] = esperance de P2
|
||||
% = Sum_{i=-k}^k Sum_{j=-k}^k I2(p2x+i,p2y+j)/(2*k+1)^2,
|
||||
% * Var(P1) = variance de P1
|
||||
% = Sum_{i=-k}^k Sum_{j=-k}^k (I1(p1x+i,p1y+j)-E[P1])^2/(2*k+1)^2
|
||||
%
|
||||
% * Var(P2) = variance de P2
|
||||
function C = apparier_Points(I1, Ptint1, I2, Ptint2, K)
|
||||
% I1, I2 : les deux images
|
||||
% Ptint1, Ptint2 : les coordonnees des points detectes sur l'image 1, resp. 2
|
||||
% C : matrice contenant, pour chaque paire de points (en ligne : les points
|
||||
% de l'image 1, en colonne : les points de l'image 2), la valeur de la
|
||||
% mesure de correlation pour ces paires de points
|
||||
% K : Taille de la fenetre de correlation utilisee
|
||||
|
||||
% Dimensions des images
|
||||
[htI1 lgI1] = size(I1); [htI2 lgI2] = size(I2);
|
||||
% Nombres de points d'interet de l'image 1 et de l'image 2
|
||||
nptI1 = size(Ptint1, 1); nptI2 = size(Ptint2, 1);
|
||||
% Construction de la matrice des mesures de correlation
|
||||
% Suppression de tous les points pour lesquels la fenêtre de corrélation
|
||||
% n'est pas appliquable
|
||||
C = zeros(nptI1, nptI2);
|
||||
|
||||
% Determination des points dont le voisinage est dans l'image
|
||||
indptI1 = find(Ptint1(:, 1) - K >= 1 & Ptint1(:, 1) + K <= lgI1 ...
|
||||
& Ptint1(:, 2) - K >= 1 & Ptint1(:, 2) + K <= htI1);
|
||||
indptI2 = find(Ptint2(:, 1) - K >= 1 & Ptint2(:, 1) + K <= lgI2 ...
|
||||
& Ptint2(:, 2) - K >= 1 & Ptint2(:, 2) + K <= htI2);
|
||||
nbptintI1 = size(indptI1, 1);
|
||||
nbptintI2 = size(indptI2, 1);
|
||||
|
||||
% Determination du voisinage : vois1, vois2 matrices composees
|
||||
% pour chaque ligne des niveaux de gris du voisinage du point
|
||||
% Appel a la fonction voisinage
|
||||
vois1 = voisinage(I1, Ptint1(indptI1, :), K);
|
||||
vois2 = voisinage(I2, Ptint2(indptI2, :), K);
|
||||
|
||||
% Nb Pixels par fenetre de correlation
|
||||
NbPix = K * K;
|
||||
% Calcul de tous les appariements possibles
|
||||
[i1, i2] = meshgrid(1:nbptintI1, 1:nbptintI2);
|
||||
i1 = i1(:); i2 = i2(:);
|
||||
|
||||
% Pour les images I1 et I2
|
||||
% Moyenne des niveaux de gris du voisinage de chaque point
|
||||
% Utilisation de mean
|
||||
moy1 = mean(vois1, 2);
|
||||
moy2 = mean(vois2, 2);
|
||||
|
||||
% % Variance des niveaux de gris du voisinage de chaque point
|
||||
% % Utilisation de var
|
||||
var1 = var(vois1, 0, 2);
|
||||
var2 = var(vois2, 0, 2);
|
||||
|
||||
% Pour chaque combinaison de paires de points, la covariance
|
||||
% entre les deux voisinages : le numerateur dans la formule ZNCC
|
||||
cov = (vois1 - moy1) * (vois2 - moy2)' / NbPix;
|
||||
|
||||
% Calcul du score de correlation :
|
||||
% ajouter le denominateur dans la formule ZNCC
|
||||
% (le produit des variances)
|
||||
cor = cov ./ sqrt(var1 * var2');
|
||||
|
||||
% cor = 1 ./ pdist2(vois1, vois2);
|
||||
|
||||
% Affectation a la matrice C
|
||||
C(indptI1(i1) + (indptI2(i2) - 1) * nptI1) = cor';
|
||||
|
||||
end
|
30
appliquerHomographie.m
Normal file
30
appliquerHomographie.m
Normal file
|
@ -0,0 +1,30 @@
|
|||
% Calcul des coordonnees (xy2) des points (xy1)
|
||||
% apres application d'une homographique H
|
||||
|
||||
function [xy2] = appliquerHomographie(H, xy1)
|
||||
|
||||
% Entrees :
|
||||
%
|
||||
% H : matrice (3x3) de l'homographie
|
||||
% xy1 : matrice (nbPoints x 2) representant les coordonnees
|
||||
% (colonne 1 : les x, colonne 2 : les y)
|
||||
% des nbPoints points auxquels H est appliquee
|
||||
%
|
||||
% Sortie :
|
||||
% xy2 : coordonnees des points apres application de l'homographie
|
||||
|
||||
% Nombre de points
|
||||
N = size(xy1, 1);
|
||||
|
||||
% Construction des coordonnees homogenes pour appliquer l'homographie
|
||||
xy1_tild = [xy1, ones(N, 1)];
|
||||
|
||||
% Application de l'homographie
|
||||
xy1_homo = H * xy1_tild';
|
||||
|
||||
% On retourne les coordonnees homogenes (x,y,1)
|
||||
% Pour cela, il faut diviser par z
|
||||
% Attention il ne faut garder que les deux premieres coordonnees
|
||||
xy1_homo = xy1_homo ./ xy1_homo(3, :);
|
||||
xy2 = xy1_homo(1:2, :)';
|
||||
end
|
14
distance_homographie.m
Normal file
14
distance_homographie.m
Normal file
|
@ -0,0 +1,14 @@
|
|||
function d = distance_homographie(XY1, XY2, H)
|
||||
|
||||
Hinv = inv(H);
|
||||
Hinv = Hinv ./ Hinv(3, 3);
|
||||
|
||||
XY1_ = appliquerHomographie(H, XY1);
|
||||
XY2_ = appliquerHomographie(Hinv, XY2);
|
||||
|
||||
d1 = sum((XY1_ - XY2).^2, 2);
|
||||
d2 = sum((XY2_ - XY1).^2, 2);
|
||||
|
||||
d = d1 + d2;
|
||||
|
||||
end
|
76
harris.m
Normal file
76
harris.m
Normal file
|
@ -0,0 +1,76 @@
|
|||
function [XY, R] = harris(Im, TailleFenetre, NbPoints, k)
|
||||
%[XY,Res]=harris(Im,TailleFenetre,NbPoints,k);
|
||||
%
|
||||
% Im -> image
|
||||
% TailleFenetre -> taille (impaire) de la fenetre du voisinage
|
||||
% valeurs conseillees : entre 9 et 25
|
||||
% NbPoints -> nombre de points desires
|
||||
% k -> poids utilise dans le calcul de la reponse R, k dans [0.04,0.06]
|
||||
% XY -> Matrice de taille NbPointsx2 contenant
|
||||
% respectivement les abscisses et les oordonnees des points
|
||||
% d'interets extraits
|
||||
% ATTENTION : La fonction de Harris ne doit pas retourner des points sur les bords
|
||||
% R -> Image des reponses par le detecteur de Harris
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Nota bene : les coordonnees utilisees sont x=j (numero de colonne) et y=i (numero de ligne). %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% Verification et correction eventuelle des parametres donnes
|
||||
if nargin < 4, k = 0.05; end;
|
||||
if nargin < 3, NbPoints = 50; end;
|
||||
if nargin < 2, TailleFenetre = 9; end;
|
||||
|
||||
% (1.1) Calcul des dérivées images suivant les lignes et les colonnes
|
||||
% en utilisant la fonction gradient
|
||||
Im = double(Im);
|
||||
[Ii, Ij] = gradient(Im);
|
||||
|
||||
% (1.2) Calcul du filtre de lissage gaussien
|
||||
% Calcul de sigma en fonction de la taille de la fenetre
|
||||
sig = (TailleFenetre - 1) / 4;
|
||||
L = fspecial('gaussian', TailleFenetre, sig);
|
||||
|
||||
% (1.3) Calcul de la reponse R
|
||||
% Calcul des elements A, B et C puis calcul de la reponse suivant l'equation (1)
|
||||
% Utiliser conv2 avec l'option 'same' pour appliquer le filtre de lissage L
|
||||
A = conv2(Ii.^2, L, 'same');
|
||||
B = conv2(Ij.^2, L, 'same');
|
||||
C = conv2(Ii .* Ij, L, 'same');
|
||||
R = A .* B - C.^2 - k * (A + B).^2;
|
||||
|
||||
% (2.1) Suppression des non-maxima locaux suivant l'equation (2)
|
||||
% ATTENTION : il faut gérer le cas particulier des bords
|
||||
% 1) Il est impossible de calculer le maximum local car une partie du voisinage n'existe pas
|
||||
% 2) Il faut leur attribuer la valeur minimale afin qu'il ne soit pas selectionne par la suite
|
||||
n2 = floor(TailleFenetre / 2);
|
||||
[l, c] = size(Im);
|
||||
Res = zeros(l, c);
|
||||
|
||||
for i = (n2 + 1):(l - n2)
|
||||
|
||||
for j = (n2 + 1):(c - n2)
|
||||
|
||||
Res(i, j) = max(max(R(i - n2:i + n2, j - n2:j + n2)));
|
||||
|
||||
if R(i, j) ~= Res(i, j)
|
||||
Res(i, j) = 0;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
% (2.2) Selection des NbPoints en fonction de "NbPoints" reponses les plus fortes
|
||||
% Tri des reponses : utiliser sort en LINEARISANT Res au préalable
|
||||
[~, is] = sort(Res(:), 'descend');
|
||||
|
||||
% Selection des indices de NbPoints de plus fortes reponses
|
||||
is = is(1:NbPoints);
|
||||
|
||||
% Calcul des indices dans l'image
|
||||
% Utiliser ind2sub, attention a l'ordre pour recuperer les coordonnees
|
||||
[Y, X] = ind2sub([l, c], is);
|
||||
XY = [X, Y];
|
||||
|
||||
end
|
49
homographie.m
Normal file
49
homographie.m
Normal file
|
@ -0,0 +1,49 @@
|
|||
% Estimation d'une matrice d'homographie H qui permet de passer d'une
|
||||
% image I1 a une autre image I2 a partir de paires de points (homologues)
|
||||
%
|
||||
% H = [ h11 h12 h13 ; h21 h22 h23 ; h31 h32 h33 ]
|
||||
% H possede 8 parametres independants.
|
||||
% Chaque correspondance donne 2 equations.
|
||||
% Ainsi pour estimer H, il faut au moins 4 paires de points.
|
||||
%
|
||||
% Il existe differentes manieres d'estimer H.
|
||||
% Nous choisissons la resolution sous la contrainte ||h33|| = 1,
|
||||
% au sens des moindres carres.
|
||||
|
||||
function [H] = homographie(XY_C1, XY_C2)
|
||||
% Entrees :
|
||||
%
|
||||
% XY_C1 : matrice (NbPointsx2) contenant les coordonnees des Nbpoints dans l'image I1
|
||||
% XY_C2 : matrice (NbPointsx2) contenant les coordonnees des Nbpoints HOMOLOGUES dans l'image I2
|
||||
% (colonne 1 : les x, colonne 2 : les y)
|
||||
%
|
||||
% Sortie :
|
||||
% H : la matrice d'homographie estimee
|
||||
|
||||
% Les parametres hij de la matrice d'homographie H sont ranges dans
|
||||
% un vecteur : H = [ h11 ... h33 ]' tel que
|
||||
% A * H = 0
|
||||
% avec A qui depend des coordonnees de paires homologues, cf. equation (2)
|
||||
% A = ( XY_C1(1,1) XY_C1(1,2) 1 0 0 0 -XY_C1(1,1)*XY_C2(1,1) -XY_C1(1,2)*XY_C2(1,1) -XY_C2(1,1)
|
||||
% 0 0 0 XY_C1(1,1) XY_C1(1,2) 1 -XY_C1(1,1)*XY_C2(1,2) -XY_C1(1,2)*XY_C2(1,2) -XY_C2(1,2)
|
||||
% ... etc ... )
|
||||
|
||||
% Stocker dans une variable le nombre de points apparies
|
||||
N = size(XY_C1, 1);
|
||||
|
||||
% Construction des matrices/vecteurs utiles pour construire la matrice A
|
||||
A = [
|
||||
XY_C1(:, 1:2), ones(N, 1), zeros(N, 3), -XY_C2(:, 1) .* XY_C1(:, 1), -XY_C2(:, 1) .* XY_C1(:, 2), -XY_C2(:, 1);
|
||||
zeros(N, 3), XY_C1(:, 1:2), ones(N, 1), -XY_C2(:, 2) .* XY_C1(:, 1), -XY_C2(:, 2) .* XY_C1(:, 2), -XY_C2(:, 2)
|
||||
];
|
||||
|
||||
% Estimation des parametres de H par decomposition en valeurs singulieres
|
||||
% Utiliser la fonction matlab svd :
|
||||
% H est le vecteur propre associee a la plus petite valeur propre de A^TA
|
||||
[~, ~, V] = svd(A' * A);
|
||||
H = V(:, end);
|
||||
|
||||
% Former la matrice H de taille 3x3
|
||||
H = reshape(H, 3, 3)';
|
||||
|
||||
end
|
99
mosaique.m
Normal file
99
mosaique.m
Normal file
|
@ -0,0 +1,99 @@
|
|||
% Calcul d'une mosaique d'image à partir de 2 images : I1 et I2
|
||||
% connaissant l'homographie H entre les 2.
|
||||
% L'image resultat est stockee dans Res.
|
||||
% On choisit de projeter I2 dans I1 pour construire la mosaique.
|
||||
% Attention !!!
|
||||
% On suppose un axe de rotation parallèle aux colonnes.
|
||||
% C'est la raison pour laquelle on inverse les lignes et les colonnes
|
||||
% dans la reconstruction de la mosaique.
|
||||
|
||||
function [Imos] = mosaique(I1, I2, H)
|
||||
|
||||
% On recupere la taille des deux images.
|
||||
[nblI1 nbcI1] = size(I1);
|
||||
[nblI2 nbcI2] = size(I2);
|
||||
|
||||
% On calcule l'homographie inverse, normalisee,
|
||||
% pour nous permettre d'effectuer la transformation de I2 vers I1.
|
||||
Hinv = inv(H);
|
||||
Hinv = Hinv ./ Hinv(3, 3);
|
||||
|
||||
% Calcul des dimensions de la mosaique.
|
||||
% Calcul des quatre coins dans l'image 2.
|
||||
% les coins de l'image 2 sont ranges en ligne selon :
|
||||
% haut_gauche, haut_droit, bas_droit, bas gauche.
|
||||
% Lignes et colonnes sont inversees.
|
||||
xy_coinsI2_R2 = [1 1; nbcI2 1; nbcI2 nblI2; 1 nblI2];
|
||||
|
||||
% Application de l'homographie Hinv sur ces coins.
|
||||
% Calcul des images des coins dans I1.
|
||||
xy_coinsI2_R1 = appliquerHomographie(Hinv, xy_coinsI2_R2);
|
||||
|
||||
% Determination des dimensions de l'image mosaique,
|
||||
% les xmin ymin xmax ymax, ou :
|
||||
% - xmin represente la plus petite abscisse parmi les abscisses des images
|
||||
% des coins de I2 projetes dans I1 et les coins dans I1,
|
||||
% - etc
|
||||
% Lignes et colonnes sont inversees.
|
||||
|
||||
xmin = min([xy_coinsI2_R1(:, 1)' 1]);
|
||||
ymin = min([xy_coinsI2_R1(:, 2)' 1]);
|
||||
xmax = max([xy_coinsI2_R1(:, 1)' nbcI1]);
|
||||
ymax = max([xy_coinsI2_R1(:, 2)' nblI1]);
|
||||
|
||||
% On arrondit de maniere a etre certain d'avoir les coordonnees initiales
|
||||
% bien comprises dans l'image.
|
||||
xmin = floor(xmin);
|
||||
ymin = floor(ymin);
|
||||
xmax = ceil(xmax);
|
||||
ymax = ceil(ymax);
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% CONTRUCTION DE LA MOSAIQUE %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% Calcul de la taille de la mosaique.
|
||||
% Lignes et colonnes sont inversees.
|
||||
nblImos = ymax - ymin + 1;
|
||||
nbcImos = xmax - xmin + 1;
|
||||
|
||||
Imos = zeros(nblImos, nbcImos);
|
||||
|
||||
% Calcul de l'origine de l'image I1 dans le repere de la mosaique Imos.
|
||||
O1x_Rmos = 1 - (xmin - 1);
|
||||
O1y_Rmos = 1 - (ymin - 1);
|
||||
|
||||
% Copie de l'image I1.
|
||||
% Lignes et colonnes sont inversees.
|
||||
Imos(O1y_Rmos:O1y_Rmos + nblI1 - 1, O1x_Rmos:O1x_Rmos + nbcI1 - 1) = I1;
|
||||
|
||||
% Copie de l'image I2 transformee par l'homographie H.
|
||||
for x = 1:nbcImos,
|
||||
|
||||
for y = 1:nblImos,
|
||||
% Calcul des coordonnees dans I1 connaissant les coordonnees du point origine de I1 dans Imos.
|
||||
y_R1 = y - O1y_Rmos;
|
||||
x_R1 = x - O1x_Rmos;
|
||||
% Dans le repere attache a l'image I1,
|
||||
% nous estimons les coordonnees du point image de (y_R1,x_R1)
|
||||
% par l'homographie H : (xy_R2).
|
||||
xy_R2 = appliquerHomographie(H, [x_R1 y_R1]);
|
||||
|
||||
% Il existe plusieurs strategies, mais, ici,
|
||||
% pour estimer les coordonnees (entieres) ,
|
||||
% on choisit : sans interpolation, le plus proche voisin.
|
||||
x_R2 = round(xy_R2(1));
|
||||
y_R2 = round(xy_R2(2));
|
||||
|
||||
% On verifie que xy_R2 appartient bien a l'image I2
|
||||
% avant d'affecter cette valeur a Imos
|
||||
% Lignes et colonnes sont inversees.
|
||||
if (x_R2 >= 1 & x_R2 <= nbcI2 & y_R2 >= 1 & y_R2 <= nblI2)
|
||||
Imos(y, x) = I2(y_R2, x_R2);
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
57
mosaiqueN.m
Normal file
57
mosaiqueN.m
Normal file
|
@ -0,0 +1,57 @@
|
|||
% Calcul d'une mosaique d'image à partir de 2 images : I1 et I2
|
||||
% connaissant l'homographie H entre les 2.
|
||||
% L'image resultat est stockee dans Res.
|
||||
% On choisit de projeter I2 dans I1 pour construire la mosaique.
|
||||
% Attention !!!
|
||||
% On suppose un axe de rotation parallèle aux colonnes.
|
||||
% C'est la raison pour laquelle on inverse les lignes et les colonnes
|
||||
% dans la reconstruction de la mosaique.
|
||||
|
||||
function [Imos] = mosaiqueN(TailleFenetre, NbPoints, k, seuil, varargin)
|
||||
Imos = im2double(varargin{1});
|
||||
for i = 2:nargin - 4
|
||||
Im1 = Imos;
|
||||
Im2 = im2double(varargin{i});
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Detection des points d'interet avec Harris %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
Im1_gray = rgb2gray(Im1);
|
||||
Im2_gray = rgb2gray(Im2);
|
||||
XY_1 = harris(Im1_gray, TailleFenetre, NbPoints, k);
|
||||
XY_2 = harris(Im2_gray, TailleFenetre, NbPoints, k);
|
||||
|
||||
% affichage temporaire
|
||||
figure;
|
||||
affichage_POI(Im1,XY_1,'POI Image 1',1,2,1);
|
||||
affichage_POI(Im2,XY_2,'POI Image 2',1,2,2);
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Appariement des points d'interet %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
[XY_C1, XY_C2] = apparier_POI(Im1_gray, XY_1, Im2_gray, XY_2, TailleFenetre, seuil);
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Estimation (et verification) de l'homographie %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
s = 4;
|
||||
t = 0.999;
|
||||
fitFuncHomo = @(XY) homographie(XY(:, 1:2), XY(:, 3:4));
|
||||
disFuncHomo = @(H, XY) distance_homographie(XY(:, 1:2), XY(:, 3:4), H);
|
||||
[H, idx] = ransac([XY_C1, XY_C2], fitFuncHomo, disFuncHomo, s, t);
|
||||
|
||||
figure('Name', 'Appariement des points d''interet RANSAC');
|
||||
affichage_appariement(Im1, XY_C1(idx, 1), XY_C1(idx, 2), 'Points d''interet Image 1', 1, 2, 1);
|
||||
affichage_appariement(Im2, XY_C2(idx, 1), XY_C2(idx, 2), 'Points d''interet correspondants Image 2', 1, 2, 2);
|
||||
|
||||
% https://github.com/hero9968/Multiple-View-Geometry-in-Computer-Vision/blob/master/vgg_examples/ransacfithomography_vgg.m
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Collage des deux images %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
Imos = mosaiquecoul(Im1, Im2, H);
|
||||
figure;
|
||||
affichage_image(Imos,'Mosaique obtenue a partir des 2 images initiales',1,1,1);
|
||||
end
|
||||
|
||||
end
|
71
mosaiqueNbis.m
Normal file
71
mosaiqueNbis.m
Normal file
|
@ -0,0 +1,71 @@
|
|||
% Calcul d'une mosaique d'image à partir de 2 images : I1 et I2
|
||||
% connaissant l'homographie H entre les 2.
|
||||
% L'image resultat est stockee dans Res.
|
||||
% On choisit de projeter I2 dans I1 pour construire la mosaique.
|
||||
% Attention !!!
|
||||
% On suppose un axe de rotation parallèle aux colonnes.
|
||||
% C'est la raison pour laquelle on inverse les lignes et les colonnes
|
||||
% dans la reconstruction de la mosaique.
|
||||
|
||||
function [Imos] = mosaiqueNbis(TailleFenetre, NbPoints, k, seuil, imref, varargin)
|
||||
homos = cell(1, length(varargin));
|
||||
homos(1) = {eye(3)};
|
||||
for i = 1:length(varargin) - 1
|
||||
Im1 = im2double(varargin{i});
|
||||
Im2 = im2double(varargin{i+1});
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Detection des points d'interet avec Harris %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
Im1_gray = rgb2gray(Im1);
|
||||
Im2_gray = rgb2gray(Im2);
|
||||
XY_1 = harris(Im1_gray, TailleFenetre, NbPoints, k);
|
||||
XY_2 = harris(Im2_gray, TailleFenetre, NbPoints, k);
|
||||
|
||||
% affichage temporaire
|
||||
figure;
|
||||
affichage_POI(Im1,XY_1,'POI Image 1',1,2,1);
|
||||
affichage_POI(Im2,XY_2,'POI Image 2',1,2,2);
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Appariement des points d'interet %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
[XY_C1, XY_C2] = apparier_POI(Im1_gray, XY_1, Im2_gray, XY_2, TailleFenetre, seuil);
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Estimation (et verification) de l'homographie %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% https://github.com/hero9968/Multiple-View-Geometry-in-Computer-Vision/blob/master/vgg_examples/ransacfithomography_vgg.m
|
||||
s = 4;
|
||||
t = 0.999;
|
||||
fitFuncHomo = @(XY) homographie(XY(:, 1:2), XY(:, 3:4));
|
||||
disFuncHomo = @(H, XY) distance_homographie(XY(:, 1:2), XY(:, 3:4), H);
|
||||
[H, idx] = ransac([XY_C1, XY_C2], fitFuncHomo, disFuncHomo, s, t);
|
||||
% XY = [XY_C1, XY_C2];
|
||||
% H = homographie(XY(:, 1:2), XY(:, 3:4));
|
||||
homos(i + 1) = {H};
|
||||
|
||||
figure('Name', 'Appariement des points d''interet RANSAC');
|
||||
affichage_appariement(Im1, XY_C1(idx, 1), XY_C1(idx, 2), 'Points d''interet Image 1', 1, 2, 1);
|
||||
affichage_appariement(Im2, XY_C2(idx, 1), XY_C2(idx, 2), 'Points d''interet correspondants Image 2', 1, 2, 2);
|
||||
|
||||
end
|
||||
|
||||
homos_to_ref = cell(1, length(varargin));
|
||||
homos_to_ref(imref) = {eye(3)};
|
||||
homos_tmp = eye(3);
|
||||
for i = imref-1:-1:1
|
||||
homos_tmp = homos_tmp / homos{i + 1};
|
||||
homos_to_ref(i) = {homos_tmp};
|
||||
end
|
||||
homos_tmp = eye(3);
|
||||
for i = imref+1:length(varargin)
|
||||
homos_tmp = homos_tmp * homos{i};
|
||||
homos_to_ref(i) = {homos_tmp};
|
||||
end
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Collage des images %
|
||||
%%%%%%%%%%%%%%%%%%%%%%
|
||||
Imos = mosaiqueter2(homos_to_ref, varargin);
|
||||
imwrite(Imos, "test.png");
|
125
mosaiquebis.m
Normal file
125
mosaiquebis.m
Normal file
|
@ -0,0 +1,125 @@
|
|||
% Calcul d'une mosaique d'image à partir de 2 images : I1 et I2
|
||||
% connaissant l'homographie H entre les 2.
|
||||
% L'image resultat est stockee dans Res.
|
||||
% On choisit de projeter I2 dans I1 pour construire la mosaique.
|
||||
% Attention !!!
|
||||
% On suppose un axe de rotation parallèle aux colonnes.
|
||||
% C'est la raison pour laquelle on inverse les lignes et les colonnes
|
||||
% dans la reconstruction de la mosaique.
|
||||
|
||||
function [Imos] = mosaiquebis(I1, I2, H)
|
||||
|
||||
% On recupere la taille des deux images.
|
||||
[nblI1 nbcI1] = size(I1);
|
||||
[nblI2 nbcI2] = size(I2);
|
||||
|
||||
% On calcule l'homographie inverse, normalisee,
|
||||
% pour nous permettre d'effectuer la transformation de I2 vers I1.
|
||||
Hinv = inv(H);
|
||||
Hinv = Hinv ./ Hinv(3, 3);
|
||||
|
||||
% Calcul des dimensions de la mosaique.
|
||||
% Calcul des quatre coins dans l'image 2.
|
||||
% les coins de l'image 2 sont ranges en ligne selon :
|
||||
% haut_gauche, haut_droit, bas_droit, bas gauche.
|
||||
% Lignes et colonnes sont inversees.
|
||||
xy_coinsI2_R2 = [1 1; nbcI2 1; nbcI2 nblI2; 1 nblI2];
|
||||
|
||||
% Application de l'homographie Hinv sur ces coins.
|
||||
% Calcul des images des coins dans I1.
|
||||
xy_coinsI2_R1 = appliquerHomographie(Hinv, xy_coinsI2_R2);
|
||||
|
||||
% Determination des dimensions de l'image mosaique,
|
||||
% les xmin ymin xmax ymax, ou :
|
||||
% - xmin represente la plus petite abscisse parmi les abscisses des images
|
||||
% des coins de I2 projetes dans I1 et les coins dans I1,
|
||||
% - etc
|
||||
% Lignes et colonnes sont inversees.
|
||||
|
||||
xmin = min([xy_coinsI2_R1(:, 1)' 1]);
|
||||
ymin = min([xy_coinsI2_R1(:, 2)' 1]);
|
||||
xmax = max([xy_coinsI2_R1(:, 1)' nbcI1]);
|
||||
ymax = max([xy_coinsI2_R1(:, 2)' nblI1]);
|
||||
|
||||
% On arrondit de maniere a etre certain d'avoir les coordonnees initiales
|
||||
% bien comprises dans l'image.
|
||||
xmin = floor(xmin);
|
||||
ymin = floor(ymin);
|
||||
xmax = ceil(xmax);
|
||||
ymax = ceil(ymax);
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% CONTRUCTION DE LA MOSAIQUE %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% Calcul de la taille de la mosaique.
|
||||
% Lignes et colonnes sont inversees.
|
||||
nblImos = ymax - ymin + 1;
|
||||
nbcImos = xmax - xmin + 1;
|
||||
|
||||
Imos = zeros(nblImos, nbcImos);
|
||||
|
||||
% Calcul de l'origine de l'image I1 dans le repere de la mosaique Imos.
|
||||
O1x_Rmos = 1 - (xmin - 1);
|
||||
O1y_Rmos = 1 - (ymin - 1);
|
||||
|
||||
% Copie de l'image I1.
|
||||
% Lignes et colonnes sont inversees.
|
||||
Imos(O1y_Rmos:O1y_Rmos + nblI1 - 1, O1x_Rmos:O1x_Rmos + nbcI1 - 1) = I1;
|
||||
|
||||
% Copie de l'image I2 transformee par l'homographie H.
|
||||
for x = 1:nbcImos
|
||||
|
||||
for y = 1:nblImos
|
||||
% Calcul des coordonnees dans I1 connaissant les coordonnees du point origine de I1 dans Imos.
|
||||
y_R1 = y - O1y_Rmos;
|
||||
x_R1 = x - O1x_Rmos;
|
||||
d1 = min([nbcI1 - x_R1, nblI1 - y_R1, x_R1, y_R1]);
|
||||
|
||||
% Dans le repere attache a l'image I1,
|
||||
% nous estimons les coordonnees du point image de (y_R1,x_R1)
|
||||
% par l'homographie H : (xy_R2).
|
||||
xy_R2 = appliquerHomographie(H, [x_R1 y_R1]);
|
||||
|
||||
% Il existe plusieurs strategies, mais, ici,
|
||||
% pour estimer les coordonnees (entieres) ,
|
||||
% on choisit : sans interpolation, le plus proche voisin.
|
||||
x_R2 = round(xy_R2(1));
|
||||
y_R2 = round(xy_R2(2));
|
||||
d2 = min([nbcI2 - x_R2, nblI2 - y_R2, x_R2, y_R2]);
|
||||
|
||||
% calcul des poids de l'interpolation.
|
||||
if d1 <= 0 || all(I1(y_R1, x_R1) == 0)
|
||||
d1 = 0;
|
||||
end
|
||||
if d2 <= 0 || all(I2(y_R2, x_R2) == 0)
|
||||
d2 = 0;
|
||||
end
|
||||
if d1 == 0 && d2 == 0
|
||||
p1 = 0;
|
||||
p2 = 0;
|
||||
else
|
||||
p1 = d1 / (d1 + d2);
|
||||
p2 = d2 / (d1 + d2);
|
||||
end
|
||||
|
||||
% On verifie que xy_R2 appartient bien a l'image I2
|
||||
% avant d'affecter cette valeur a Imos
|
||||
% Lignes et colonnes sont inversees.
|
||||
if p1 ~= 0
|
||||
t1 = p1 * I1(y_R1, x_R1);
|
||||
else
|
||||
t1 = 0;
|
||||
end
|
||||
if p2 ~= 0
|
||||
t2 = p2 * I2(y_R2, x_R2);
|
||||
else
|
||||
t2 = 0;
|
||||
end
|
||||
Imos(y, x) = t1 + t2;
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
19
mosaiquecoul.m
Normal file
19
mosaiquecoul.m
Normal file
|
@ -0,0 +1,19 @@
|
|||
% Calcul d'une mosaique d'image à partir de 2 images : I1 et I2
|
||||
% connaissant l'homographie H entre les 2.
|
||||
% L'image resultat est stockee dans Res.
|
||||
% On choisit de projeter I2 dans I1 pour construire la mosaique.
|
||||
% Attention !!!
|
||||
% On suppose un axe de rotation parallèle aux colonnes.
|
||||
% C'est la raison pour laquelle on inverse les lignes et les colonnes
|
||||
% dans la reconstruction de la mosaique.
|
||||
|
||||
function [Imos] = mosaiquecoul(I1, I2, H)
|
||||
|
||||
c = size(I1, 3);
|
||||
|
||||
Imos = [];
|
||||
for i = 1:c
|
||||
Imos = cat(3, Imos, mosaiquebis(I1(:,:,i), I2(:,:,i), H));
|
||||
end
|
||||
|
||||
end
|
138
mosaiqueter.m
Normal file
138
mosaiqueter.m
Normal file
|
@ -0,0 +1,138 @@
|
|||
% Calcul d'une mosaique d'image à partir de 2 images : I1 et I2
|
||||
% connaissant l'homographie H entre les 2.
|
||||
% L'image resultat est stockee dans Res.
|
||||
% On choisit de projeter I2 dans I1 pour construire la mosaique.
|
||||
% Attention !!!
|
||||
% On suppose un axe de rotation parallèle aux colonnes.
|
||||
% C'est la raison pour laquelle on inverse les lignes et les colonnes
|
||||
% dans la reconstruction de la mosaique.
|
||||
|
||||
function [Imos] = mosaiqueter(homos, imgs)
|
||||
|
||||
% On recupere la taille des deux images.
|
||||
Iref = im2double(imgs{1});
|
||||
[nblIref, nbcIref, nc] = size(Iref);
|
||||
|
||||
xmin = Inf;
|
||||
ymin = Inf;
|
||||
xmax = -Inf;
|
||||
ymax = -Inf;
|
||||
|
||||
for k=1:length(imgs)
|
||||
[nblIk, nbcIk, ~] = size(imgs{k});
|
||||
|
||||
% On calcule l'homographie inverse, normalisee,
|
||||
% pour nous permettre d'effectuer la transformation de I2 vers I1.
|
||||
Hinv = inv(homos{k});
|
||||
Hinv = Hinv ./ Hinv(3, 3);
|
||||
|
||||
% On calcule les coordonnees des 4 coins de I2 dans I1.
|
||||
xy_coinsIk_Rk = [1 1; nbcIk 1; nbcIk nblIk; 1 nblIk];
|
||||
|
||||
% Application de l'homographie Hinv sur ces coins.
|
||||
% Calcul des images des coins dans I1.
|
||||
xy_coinsIk_Rref = appliquerHomographie(Hinv, xy_coinsIk_Rk);
|
||||
|
||||
% Determination des dimensions de l'image mosaique,
|
||||
% les xmin ymin xmax ymax, ou :
|
||||
% - xmin represente la plus petite abscisse parmi les abscisses des images
|
||||
% des coins de I2 projetes dans I1 et les coins dans I1,
|
||||
% - etc
|
||||
% Lignes et colonnes sont inversees.
|
||||
xmin = min([xy_coinsIk_Rref(:, 1)' xmin]);
|
||||
ymin = min([xy_coinsIk_Rref(:, 2)' ymin]);
|
||||
xmax = max([xy_coinsIk_Rref(:, 1)' xmax]);
|
||||
ymax = max([xy_coinsIk_Rref(:, 2)' ymax]);
|
||||
end
|
||||
|
||||
% On arrondit de maniere a etre certain d'avoir les coordonnees initiales
|
||||
% bien comprises dans l'image.
|
||||
xmin = floor(xmin);
|
||||
ymin = floor(ymin);
|
||||
xmax = ceil(xmax);
|
||||
ymax = ceil(ymax);
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% CONTRUCTION DE LA MOSAIQUE %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% Calcul de la taille de la mosaique.
|
||||
% Lignes et colonnes sont inversees.
|
||||
nblImos = ymax - ymin + 1;
|
||||
nbcImos = xmax - xmin + 1;
|
||||
|
||||
Imos = zeros(nblImos, nbcImos, nc);
|
||||
|
||||
% Calcul de l'origine de l'image I1 dans le repere de la mosaique Imos.
|
||||
O1x_Rmos = 1 - (xmin - 1);
|
||||
O1y_Rmos = 1 - (ymin - 1);
|
||||
|
||||
% Copie de l'image I1.
|
||||
% Lignes et colonnes sont inversees.
|
||||
Imos(O1y_Rmos:O1y_Rmos + nblIref - 1, O1x_Rmos:O1x_Rmos + nbcIref - 1, :) = Iref;
|
||||
|
||||
% Copie de l'image I2 transformee par l'homographie H.
|
||||
for x = 1:nbcImos
|
||||
fprintf('%d/%d\r', x, nbcImos);
|
||||
for y = 1:nblImos
|
||||
% Calcul des coordonnees dans I1 connaissant les coordonnees du point origine de I1 dans Imos.
|
||||
y_Rref = y - O1y_Rmos;
|
||||
x_Rref = x - O1x_Rmos;
|
||||
|
||||
distances = zeros(1, length(imgs));
|
||||
|
||||
dref = min([nbcIref - x_Rref, nblIref - y_Rref, x_Rref, y_Rref]);
|
||||
if dref <= 0 || all(Iref(y_Rref, x_Rref, :) == 0)
|
||||
dref = 0;
|
||||
end
|
||||
distances(1) = dref;
|
||||
|
||||
% Dans le repere attache a l'image I1,
|
||||
% nous estimons les coordonnees du point image de (y_R1,x_R1)
|
||||
% par l'homographie H : (xy_R2).
|
||||
xy_Rs = zeros(length(imgs), 2);
|
||||
xy_Rs(1,:) = [x_Rref y_Rref];
|
||||
for k = 1:length(imgs)
|
||||
|
||||
xy_Rk = appliquerHomographie(homos{k}, [x_Rref y_Rref]);
|
||||
xy_Rs(k,:) = round(xy_Rk);
|
||||
% Il existe plusieurs strategies, mais, ici,
|
||||
% pour estimer les coordonnees (entieres) ,
|
||||
% on choisit : sans interpolation, le plus proche voisin.
|
||||
x_Rk = round(xy_Rk(1));
|
||||
y_Rk = round(xy_Rk(2));
|
||||
[nblIk, nbcIk, ~] = size(imgs{k});
|
||||
dk = min([nbcIk - x_Rk, nblIk - y_Rk, x_Rk, y_Rk]);
|
||||
|
||||
if dk <= 0 || all(imgs{k}(y_Rk, x_Rk, :) == 0)
|
||||
dk = 0;
|
||||
end
|
||||
|
||||
distances(k) = dk;
|
||||
end
|
||||
|
||||
poids = zeros(1, length(imgs));
|
||||
if sum(distances) ~= 0
|
||||
poids = distances / sum(distances);
|
||||
poids = max(poids, 0);
|
||||
end
|
||||
|
||||
% On verifie que xy_R2 appartient bien a l'image I2
|
||||
% avant d'affecter cette valeur a Imos
|
||||
% Lignes et colonnes sont inversees.
|
||||
ts = zeros(length(imgs), 3);
|
||||
for k = 1:length(imgs)
|
||||
if poids(k) ~= 0
|
||||
ts(k, :) = poids(k) * double(imgs{k}(xy_Rs(k,2), xy_Rs(k,1), :)) / 255;
|
||||
else
|
||||
ts(k, :) = [0 0 0];
|
||||
end
|
||||
end
|
||||
Imos(y, x, :) = sum(ts, 1);
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
fprintf('\n');
|
||||
|
||||
end
|
123
mosaiqueter2.m
Normal file
123
mosaiqueter2.m
Normal file
|
@ -0,0 +1,123 @@
|
|||
% Calcul d'une mosaique d'image à partir de 2 images : I1 et I2
|
||||
% connaissant l'homographie H entre les 2.
|
||||
% L'image resultat est stockee dans Res.
|
||||
% On choisit de projeter I2 dans I1 pour construire la mosaique.
|
||||
% Attention !!!
|
||||
% On suppose un axe de rotation parallèle aux colonnes.
|
||||
% C'est la raison pour laquelle on inverse les lignes et les colonnes
|
||||
% dans la reconstruction de la mosaique.
|
||||
|
||||
function [Imos] = mosaiqueter2(homos, imgs)
|
||||
|
||||
xmin = Inf;
|
||||
ymin = Inf;
|
||||
xmax = -Inf;
|
||||
ymax = -Inf;
|
||||
|
||||
for k=1:length(imgs)
|
||||
[nblIk, nbcIk, ~] = size(imgs{k});
|
||||
|
||||
% On calcule l'homographie inverse, normalisee,
|
||||
% pour nous permettre d'effectuer la transformation de I2 vers I1.
|
||||
Hinv = inv(homos{k});
|
||||
Hinv = Hinv ./ Hinv(3, 3);
|
||||
|
||||
% On calcule les coordonnees des 4 coins de I2 dans I1.
|
||||
xy_coinsIk_Rk = [1 1; nbcIk 1; nbcIk nblIk; 1 nblIk];
|
||||
|
||||
% Application de l'homographie Hinv sur ces coins.
|
||||
% Calcul des images des coins dans I1.
|
||||
xy_coinsIk_Rref = appliquerHomographie(Hinv, xy_coinsIk_Rk);
|
||||
|
||||
% Determination des dimensions de l'image mosaique,
|
||||
% les xmin ymin xmax ymax, ou :
|
||||
% - xmin represente la plus petite abscisse parmi les abscisses des images
|
||||
% des coins de I2 projetes dans I1 et les coins dans I1,
|
||||
% - etc
|
||||
% Lignes et colonnes sont inversees.
|
||||
xmin = min([xy_coinsIk_Rref(:, 1)' xmin]);
|
||||
ymin = min([xy_coinsIk_Rref(:, 2)' ymin]);
|
||||
xmax = max([xy_coinsIk_Rref(:, 1)' xmax]);
|
||||
ymax = max([xy_coinsIk_Rref(:, 2)' ymax]);
|
||||
end
|
||||
|
||||
% On arrondit de maniere a etre certain d'avoir les coordonnees initiales
|
||||
% bien comprises dans l'image.
|
||||
xmin = floor(xmin);
|
||||
ymin = floor(ymin);
|
||||
xmax = ceil(xmax);
|
||||
ymax = ceil(ymax);
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% CONTRUCTION DE LA MOSAIQUE %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% Calcul de la taille de la mosaique.
|
||||
% Lignes et colonnes sont inversees.
|
||||
nblImos = ymax - ymin + 1;
|
||||
nbcImos = xmax - xmin + 1;
|
||||
|
||||
% Calcul de l'origine de l'image I1 dans le repere de la mosaique Imos.
|
||||
O1x_Rmos = 1 - (xmin - 1);
|
||||
O1y_Rmos = 1 - (ymin - 1);
|
||||
|
||||
% Copie de l'image I2 transformee par l'homographie H.
|
||||
Imos = [];
|
||||
n_bloc = 4;
|
||||
bloc_size = floor(nblImos*nbcImos/n_bloc);
|
||||
for i = 1:n_bloc
|
||||
fprintf('%d/%d\r', i, n_bloc);
|
||||
[y, x] = ind2sub([nblImos, nbcImos], i*bloc_size+1:bloc_size*(i+1));
|
||||
y = y';
|
||||
x = x';
|
||||
|
||||
distances = zeros(bloc_size, length(imgs));
|
||||
|
||||
% Calcul des coordonnees dans I1 connaissant les coordonnees du point origine de I1 dans Imos.
|
||||
y_Rref = y - O1y_Rmos;
|
||||
x_Rref = x - O1x_Rmos;
|
||||
|
||||
% Dans le repere attache a l'image I1,
|
||||
% nous estimons les coordonnees du point image de (y_R1,x_R1)
|
||||
% par l'homographie H : (xy_R2).
|
||||
xy_Rs = zeros(bloc_size, length(imgs), 2);
|
||||
xy_Rs(:, 1, :) = [x_Rref y_Rref];
|
||||
for k = 1:length(imgs)
|
||||
|
||||
xy_Rk = appliquerHomographie(homos{k}, [x_Rref y_Rref]);
|
||||
xy_Rs(:,k,:) = round(xy_Rk);
|
||||
% Il existe plusieurs strategies, mais, ici,
|
||||
% pour estimer les coordonnees (entieres) ,
|
||||
% on choisit : sans interpolation, le plus proche voisin.
|
||||
x_Rk = round(xy_Rk(:,1));
|
||||
y_Rk = round(xy_Rk(:,2));
|
||||
[nblIk, nbcIk, ~] = size(imgs{k});
|
||||
|
||||
dk = min([nbcIk - x_Rk, nblIk - y_Rk, x_Rk, y_Rk], [], 2);
|
||||
dk(dk < 0) = 0;
|
||||
|
||||
distances(:,k) = dk;
|
||||
end
|
||||
|
||||
poids = distances ./ sum(distances, 2);
|
||||
poids(isnan(poids)) = 0;
|
||||
poids(:) = max(poids(:), 0);
|
||||
|
||||
% On verifie que xy_R2 appartient bien a l'image I2
|
||||
% avant d'affecter cette valeur a Imos
|
||||
% Lignes et colonnes sont inversees.
|
||||
ts = zeros(bloc_size, length(imgs), 3);
|
||||
for k = 1:length(imgs)
|
||||
imgk = im2double(imgs{k});
|
||||
[nblIk, nbcIk, ~] = size(imgk);
|
||||
imgk = reshape(imgk, nblIk*nbcIk, 3);
|
||||
|
||||
valid_pixels = (xy_Rs(:,k,1) >= 1) & (xy_Rs(:,k,1) <= nbcIk) & (xy_Rs(:,k,2) >= 1) & (xy_Rs(:,k,2) <= nblIk);
|
||||
ts(valid_pixels, k, :) = poids(valid_pixels,k) .* imgk(sub2ind([nblIk, nbcIk], xy_Rs(valid_pixels,k,2), xy_Rs(valid_pixels,k,1)), :);
|
||||
end
|
||||
Imos = cat(1, Imos, sum(ts, 2));
|
||||
end
|
||||
Imos = cat(1, Imos, zeros(nblImos*nbcImos - size(Imos, 1), 1, 3));
|
||||
Imos = reshape(Imos, nblImos, nbcImos, 3);
|
||||
fprintf('\n');
|
||||
end
|
16
plot_points.m
Normal file
16
plot_points.m
Normal file
|
@ -0,0 +1,16 @@
|
|||
function plot_points(XY,NbPoints,motif);
|
||||
% Affichage de points numerotes sur une image.
|
||||
% Cet affichage est superpose a la fenetre courante.
|
||||
% I-> vecteur colonne des numeros de lignes des points
|
||||
% J-> vecteur colonne des numeros de colonnes des points
|
||||
% NbPoints -> nombre de points a afficher
|
||||
% si ce parametre est absent, tous les points seront affiches
|
||||
% motif -> motif utilise pour l'affichage
|
||||
|
||||
if nargin < 3, NbPoints=length(I); end;
|
||||
|
||||
hold on;
|
||||
for p=1:NbPoints
|
||||
plot(XY(p,1),XY(p,2),motif,'MarkerEdgeColor','r','MarkerFaceColor','r','MarkerSize',10);
|
||||
end
|
||||
hold off;
|
494
sweet1.pgm
Normal file
494
sweet1.pgm
Normal file
File diff suppressed because one or more lines are too long
97
sweet2.pgm
Normal file
97
sweet2.pgm
Normal file
File diff suppressed because one or more lines are too long
BIN
sweet_couleur1.jpg
Normal file
BIN
sweet_couleur1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 MiB |
BIN
sweet_couleur2.jpg
Normal file
BIN
sweet_couleur2.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 MiB |
BIN
sweet_couleur3.jpg
Normal file
BIN
sweet_couleur3.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 MiB |
33
voisinage.m
Normal file
33
voisinage.m
Normal file
|
@ -0,0 +1,33 @@
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% fonction renvoyant les niveaux de gris du voisinage de chaque point en ligne
|
||||
|
||||
function voisins = voisinage(I, xyPt, TailleFenetre)
|
||||
% ENTREES
|
||||
% I : l'image
|
||||
% xyPt : les coordonnees des points dont nous cherchons le voisinage.
|
||||
% ATTENTION : on fait l'hypothese qu'il n'y a aucun point sur les bords
|
||||
% TailleFenetre : La taille de la fenêtre de correlation correspond
|
||||
% a TailleFenetre x TailleFenetre
|
||||
% SORTIE
|
||||
% voisins : une matrice contenant pour chaque ligne (= chaque point),
|
||||
% le voisinage du point associe
|
||||
% Nombre de points pour lesquels leur voisinage est cherche
|
||||
npt = size(xyPt, 1);
|
||||
|
||||
% Initialisation
|
||||
voisins = zeros(npt, TailleFenetre * TailleFenetre);
|
||||
|
||||
% Calcul de la demi-fenetre de correlation
|
||||
K = floor(TailleFenetre / 2);
|
||||
|
||||
% Pour chaque point
|
||||
for i = 1:npt
|
||||
% On recupere les coordonnees du point
|
||||
x = xyPt(i, 1);
|
||||
y = xyPt(i, 2);
|
||||
|
||||
% On recupere le voisinage du point
|
||||
voisins(i, :) = reshape(I(y - K:y + K, x - K:x + K), 1, TailleFenetre * TailleFenetre);
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue