Système SIFT

Bonjour,

Mon école me demande de créer un programme de “Détection de points caractéristiques d’une image avec le système SIFT” sous Visual Studio (C++). En gros, je dois détecter les points remarquables d’un objet, genre un coin ou un logo, et je dois les afficher sur l’image. Pour ça, mon tuteur m’a filé un programme qui a été créé sous Matlab. Problème: je connais pas Matlab. Pour l’instant, j’ai programmé l’affichage des images .JPG et .BMP. Maintenant, faut que je code le programme SIFT en lui-même.

Voilà le code sous Matlab:

[code]

% [descriptors, locs] = sift(imageFile)
%
% This function reads an image and returns its SIFT keypoints.
% Input parameters:
% imageFile: the file name for the image.
%
% Returned:
% image: the image array in double format
% descriptors: a K-by-128 matrix, where each row gives an invariant
% descriptor for one of the K keypoints. The descriptor is a vector
% of 128 values normalized to unit length.
% locs: K-by-4 matrix, in which each row has the 4 values for a
% keypoint location (row, column, scale, orientation). The
% orientation is in the range [-PI, PI] radians.
%
% Credits: Thanks for initial version of this program to D. Alvaro and
% J.J. Guerrero, Universidad de Zaragoza (modified by D. Lowe)

function [descriptors, locs] = sift(image)

% Load image

% If you have the Image Processing Toolbox, you can uncomment the following
% lines to allow input of color images, which will be converted to grayscale.
% if isrgb(image)
% image = rgb2gray(image);
% end

[rows, cols] = size(image);

% Convert into PGM imagefile, readable by “keypoints” executable
f = fopen(‘tmp.pgm’, ‘w’);
if f == -1
error(‘Could not create file tmp.pgm.’);
end
fprintf(f, ‘P5\n%d\n%d\n255\n’, cols, rows);
fwrite(f, image’, ‘uint8’);
fclose(f);

% Call keypoints executable
if isunix
command = '!./sift ';
else
command = '!siftWin32 ‘;
end
command = [command ’ <tmp.pgm >tmp.key’];
eval(command);

% Open tmp.key and check its header
g = fopen(‘tmp.key’, ‘r’);
if g == -1
error(‘Could not open file tmp.key.’);
end
[header, count] = fscanf(g, ‘%d %d’, [1 2]);
if count ~= 2
error(‘Invalid keypoint file beginning.’);
end
num = header(1);
len = header(2);
if len ~= 128
error(‘Keypoint descriptor length invalid (should be 128).’);
end

% Creates the two output matrices (use known size for efficiency)
locs = double(zeros(num, 4));
descriptors = double(zeros(num, 128));

% Parse tmp.key
for i = 1:num
[vector, count] = fscanf(g, ‘%f %f %f %f’, [1 4]); %row col scale ori
if count ~= 4
error(‘Invalid keypoint file format’);
end
locs(i, B) = vector(1, B);

[descrip, count] = fscanf(g, '%d', [1 len]);
if (count ~= 128)
    error('Invalid keypoint file value.');
end
% Normalize each input vector to unit length
descrip = descrip / sqrt(sum(descrip.^2));
descriptors(i, :D = descrip(1, :D;

end
fclose(g);

[\code]

Est-ce quelqu’un pourrait me donner des indications sur ce que fait ce code? Pour info, siftWin32.exe, c’est un .exe que mon prof m’a fourni. Dernière question, est-il possible d’insérer cet .exe dans mon programme sous Visual?
Merci

Tout d’abord bienvenu a toi. Pour un premier post, tu attaques fort!

Tu as pense a gete un coup d oeil sur SIFT++ implementation libre du truc ?

Maintenant si tu codes le trucs propre je serai interresse par le code B)

Je serai toi je lirai le papier de LOWE (http://www.cs.ubc.ca/~lowe/keypoints/) qui explique comment ca marche, et a mon avis tu vas devoir le coder toi meme… sauf si tu veux faire des call back sur le .exe (ce qui est possible). Est ce que tu peux etre plus precis sure ce que ton tuteur veut que tu fasses et le time frame ?

En lisant vite le code locs va stocker la position en pixel normalement et descriptors well l empreinte digital du keypoint.

Je pense que je peux t aider mais va falloir preciser.
Voilou

[quote=“koubiak, post:3, topic: 44967”]Tu as pense a gete un coup d oeil sur SIFT++ implementation libre du truc ?

Maintenant si tu codes le trucs propre je serai interresse par le code B)

Je serai toi je lirai le papier de LOWE (http://www.cs.ubc.ca/~lowe/keypoints/) qui explique comment ca marche, et a mon avis tu vas devoir le coder toi meme… sauf si tu veux faire des call back sur le .exe (ce qui est possible). Est ce que tu peux etre plus precis sure ce que ton tuteur veut que tu fasses et le time frame ?

En lisant vite le code locs va stocker la position en pixel normalement et descriptors well l empreinte digital du keypoint.

Je pense que je peux t aider mais va falloir preciser.
Voilou[/quote]

Mon projet s’oriente en 3 parties: 1) Affichage d’images .JPG et .BMP (je l’ai fais) 2)Détection de points caractéristiques (code SIFT) 3)Affichage de ces keypoints sur l’image (avec une classe Skowkeys).

Pour l’instant, j’ai crée un projet MFC/MDI, j’ai ajouté une classe CPicture pour gérer l’affichage d’images, et je viens de créer une classe CSift pour mettre le code SIFT.

Je suis bloqué à la partie 2: mon tuteur scientifique veut que je reprenne le code SIFT sous Matlab, que je le comprenne et que je le traduise pour le faire tourner sous Visual studio. Je pensais faire comme marqué sur le code: convertir les images en .PGM et faire des call back sur le .exe. Mais à vrai dire, j’ai encore jamais fais tout ça. Mon tuteur informatique (et oui, j’ai 2 tuteurs!) est incapable de m’aider (c’est pas cool!) parce qu’il connait pas Matlab et que c’est la première fois qu’il entend parler de .PGM.

J’ai trouvé un code sur le net pour la conversion mais pour l’instant, ça marche pas. J’essai de bidouiller. Et pour les call back, apparemment ya une fonction exec mais je l’ai pas encore testé.

Voilou

Bon alors c est tranquille tu trouves comment appeller un exe dans du code c++ je sais plus comment on fait. Apres tu lis les sortie le .txt qui a dans le code tout pareil que dans l exemple.

Si tu veux comprendre le code matlab tu prends une image simple et petite ou y a pas trop de sift points. Et tu executes le code ligne par ligne. Mais je pense que je t ai deja dit ce qu etait les deux trucs importants les coordonnées et les descriptors qui doivent si je me rappellent avoir 27 parametres.

Voila Voilou peut etre que qq un ici peut te dire comment executer un prog dans un autre, sinon google !

Good Luck
Koubiak

Alors j’avoue que je ne peux pas vraiment t’aider (je suis sur que tu vas trouver) mais je ne connaissais pas cette méthode et je suis assez impressionné par le papier de Lowe. Ça a l’air de vraiment bien marché et l’idée, même si les subtilités m’échappent parfois un peu (Notamment la première sélection des points : on regarde le même point plusieurs fois à différentes échelles ou une fois qu’un point a été jugé inintéressant il n’est plus réexaminé ? Est-ce que l’on élimine des points qui ont été jugé intéressants à une autre échelle mais qui ne le sont pas à une donnée ?)
Bref c’est cool, je tenais à le dire.

Oui il est bien ce papier, je crois sans me tromper que c est l un des meilleurs papiers sur le sujet de la decenie:)

Si je me rappelle il cherche les points qui pas les criteres et pas forcement a la meme echelles c est a dire en petit je peux accepter A mais le refuser a grande echelle mais je le garde quand meme pour la petite echelle.

Mais ca fait longtemps que je l ai pas lu.
Koubiak content que ca plaise

[quote=“Cheluco, post:1, topic: 44967”]Bonjour,

Mon école me demande de créer un programme de “Détection de points caractéristiques d’une image avec le système SIFT” sous Visual Studio (C++). En gros, je dois détecter les points remarquables d’un objet, genre un coin ou un logo, et je dois les afficher sur l’image. Pour ça, mon tuteur m’a filé un programme qui a été créé sous Matlab. Problème: je connais pas Matlab. Pour l’instant, j’ai programmé l’affichage des images .JPG et .BMP. Maintenant, faut que je code le programme SIFT en lui-même.

Est-ce quelqu’un pourrait me donner des indications sur ce que fait ce code? Pour info, siftWin32.exe, c’est un .exe que mon prof m’a fourni. Dernière question, est-il possible d’insérer cet .exe dans mon programme sous Visual?
Merci[/quote]

Yau,

Pour executer un programme tu fais appel a la fonction CreateProcess

[code]PROCESS_INFORMATION pi;
STARTUPINFO si;

::ZeroMemory(&pi, sizeof(pi));
::ZeroMemory(&si, sizeof(si));
si.cb = sizeof(STARTUPINFO);

BOOL bResult = ::CreateProcessW(NULL,
L"process.exe",
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&si,
&pi);

if (bResult == TRUE)
{
::CloseHandle(pi.hProcess);
::CloseHandle(pi.hThread);
ZeroMemory(&pi, sizeof(pi));
}[/code]

Sinon pour ce que fait ton code je vois une transformation de l’image en niveau de gris, un appel a l’exe sur cette image ensuite le remplissage d’une matrice normalisee. Si tu as besoin d’une bibliotheque pour les flottants, ne te casse pas la tete a la recoder il y en a des milliards sur le web.

Pour coder ta matrice, un vecteur de vecteur ca va.

[quote=“Moloch, post:8, topic: 44967”]Yau,

Pour executer un programme tu fais appel a la fonction CreateProcess

[code]PROCESS_INFORMATION pi;
STARTUPINFO si;

::ZeroMemory(&pi, sizeof(pi));
::ZeroMemory(&si, sizeof(si));
si.cb = sizeof(STARTUPINFO);

BOOL bResult = ::CreateProcessW(NULL,
L"process.exe",
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&si,
&pi);

if (bResult == TRUE)
{
::CloseHandle(pi.hProcess);
::CloseHandle(pi.hThread);
ZeroMemory(&pi, sizeof(pi));
}[/code]

Sinon pour ce que fait ton code je vois une transformation de l’image en niveau de gris, un appel a l’exe sur cette image ensuite le remplissage d’une matrice normalisee. Si tu as besoin d’une bibliotheque pour les flottants, ne te casse pas la tete a la recoder il y en a des milliards sur le web.

Pour coder ta matrice, un vecteur de vecteur ca va.[/quote]

Yop

Pour exécuter le programme (c’est une appli Win32), mon tuteur m’a aussi conseillé d’utiliser la tâche exec. Mais c’est un peu la misère à utiliser. Je sais pas si tu l’as déjà testé. Mais bon, je vais tester la fonction createprocess (je peux pas me fier à mon tuteur).

Merci

[quote=“Cheluco, post:9, topic: 44967”]Yop

Pour exécuter le programme (c’est une appli Win32), mon tuteur m’a aussi conseillé d’utiliser la tâche exec. Mais c’est un peu la misère à utiliser. Je sais pas si tu l’as déjà testé. Mais bon, je vais tester la fonction createprocess (je peux pas me fier à mon tuteur).

Merci[/quote]

Sous Windows on utilise CreateProcess, exec (UNIX) existe sous Windows mais resulte au final en un appel a CreateProcess.