Я пытаюсь реализовать распознавание лиц с использованием LDA с SIFT. У меня есть существующий код PCA с SIFT, который использует SIFT для определения ключевых точек и извлечения дескрипторов и PCA для проекции этих дескрипторов в подпространстве PCA. Я пытаюсь достичь аналогичной функциональности, используя LDA с SIFT.
Я пытаюсь создать объект LDA, который, в свою очередь, вызовет свою функцию-член ‘project’, но я получаю следующую ошибку:
OpenCV Error: Bad argument (The number of samples must equal the number of labels. Given 0 labels, 45 samples. ) in lda, file /home/shaurya/opencv-2.4.9/modules/contrib/src/lda.cpp, line 1015
terminate called after throwing an instance of 'cv::Exception'
what(): /home/mypath/opencv-2.4.9/modules/contrib/src/lda.cpp:1015: error: (-5) The number of samples must equal the number of labels. Given 0 labels, 45 samples. in function lda Aborted (core dumped)
Ниже приведен PCA с кодом SIFT, который я выполнил:
#include <iostream>
#include <stdio.h>
#include <dirent.h>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/features2d/features2d.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
if(argc != 3)
{
cout << "Usage: ./output <training database path> <test image>" << endl;
return -1;
}
// Reading training images paths
vector<string> namesTrainingImages;
vector<string>::iterator stringIt;
DIR *dir;
struct dirent *ent;
if ((dir = opendir (argv[1])) != NULL)
{
while ((ent = readdir (dir)) != NULL)
{
if((strcmp(ent -> d_name, ".") == 0) || (strcmp(ent -> d_name, "..") == 0))
{
continue;
}
string tempName(string(argv[1]) + string(ent -> d_name));
namesTrainingImages.push_back(tempName);
}
}
closedir(dir);
vector<Mat> trainingImages;
vector<Mat>::iterator imageIt;
// Reading training images
for(stringIt = namesTrainingImages.begin(); stringIt != namesTrainingImages.end(); ++stringIt)
{
Mat tempImage;
tempImage = imread(*stringIt, CV_LOAD_IMAGE_GRAYSCALE);
waitKey(5000);
if(!tempImage.data )
{
cout << "Could not open or find the image" << std::endl ;
continue;
}
else
{
trainingImages.push_back(tempImage);
}
}
vector< vector<KeyPoint> > keypoints;
vector<Mat> descriptor;
vector<Mat>::iterator descriptorIt;
SIFT sift;
double percentage = 0.95;
for(imageIt = trainingImages.begin(); imageIt != trainingImages.end(); ++imageIt)
{
vector<KeyPoint> tempKeypoints;
Mat tempDescriptor1, tempDescriptor2, tempDescriptor3;
// Generating keypoints and descriptors from training images
sift.operator()(*imageIt, *imageIt, tempKeypoints, tempDescriptor1, false);
keypoints.push_back(tempKeypoints);
// Using PCA to project and then backProject the descriptors of training images
PCA pca(tempDescriptor1, Mat(), CV_PCA_DATA_AS_ROW, percentage);
pca.PCA::project(tempDescriptor1, tempDescriptor2);
tempDescriptor3 = pca.PCA::backProject(tempDescriptor2);
descriptor.push_back(tempDescriptor3);
}// Reading the test image
Mat testImage;
testImage = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE);
waitKey(5000);
if(!testImage.data)
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
vector<KeyPoint> testKeypoints;
Mat testDescriptor, testDescriptor1, testDescriptor2;
// Generating teh keypoints and the descriptor of the test image
sift.operator()(testImage, testImage, testKeypoints, testDescriptor1, false);
// Using PCA to project and then backProject the descriptor of the test image
PCA pca(testDescriptor1, Mat(), CV_PCA_DATA_AS_ROW, percentage);
pca.PCA::project(testDescriptor1, testDescriptor2);
testDescriptor = pca.PCA::backProject(testDescriptor2);
// Flann based matching to determine the best matching training image
FlannBasedMatcher matcher;
vector<DMatch> matches;
vector<DMatch> good_matches;
int goodMatchesCtr = -1, tempCtr = -1, ctr = -1;
for(descriptorIt = descriptor.begin(); descriptorIt != descriptor.end(); ++descriptorIt)
{
++tempCtr;
vector<DMatch> tempMatches;
vector<DMatch> temp_good_matches;
int tempGoodMatchesCtr = 0;
double min_dist = 100;
matcher.match(testDescriptor, *descriptorIt, tempMatches);
for(int i = 0; i < testDescriptor.rows && i < (*descriptorIt).rows; ++i)
{
double dist = tempMatches[i].distance;
if(dist < min_dist)
{
min_dist = dist;
}
}
for(int i = 0; i < testDescriptor.rows && i < (*descriptorIt).rows; ++i)
{
if(tempMatches[i].distance <= max(2 * min_dist, 0.02))
{
temp_good_matches.push_back(tempMatches[i]);
++tempGoodMatchesCtr;
}
}
if(tempGoodMatchesCtr > goodMatchesCtr)
{
goodMatchesCtr = tempGoodMatchesCtr;
matches = tempMatches;
good_matches = temp_good_matches;
ctr = tempCtr;
}
}
// Displaying the test image alongside the best matching training image
Mat img_matches;
drawMatches(testImage, testKeypoints, trainingImages[ctr], keypoints[ctr], good_matches, img_matches, Scalar ::all(-1), Scalar ::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
for( int i = 0; i < (int)good_matches.size(); ++i )
{
printf( "-- Good Match [%d] Keypoint 1: %d -- Keypoint 2: %d \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx );
}
imshow("Good Matches", img_matches);
waitKey(0);
cout << "Executed!" << '\n';
return 0;
}
Ниже приводится LDA с кодом SIFT, который я пытаюсь выполнить:
#include <iostream>
#include <stdio.h>
#include <dirent.h>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/features2d/features2d.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
if(argc != 3)
{
cout << "Usage: ./output <training database path> <test image>" << endl;
return -1;
}
// Reading training images paths
vector<string> namesTrainingImages;
vector<string>::iterator stringIt;
DIR *dir;
struct dirent *ent;
if ((dir = opendir (argv[1])) != NULL)
{
while ((ent = readdir (dir)) != NULL)
{
if((strcmp(ent -> d_name, ".") == 0) || (strcmp(ent -> d_name, "..") == 0))
{
continue;
}
string tempName(string(argv[1]) + string(ent -> d_name));
namesTrainingImages.push_back(tempName);
}
}
closedir(dir);
vector<Mat> trainingImages;
vector<Mat>::iterator imageIt;
// Reading training images
for(stringIt = namesTrainingImages.begin(); stringIt != namesTrainingImages.end(); ++stringIt)
{
Mat tempImage;
tempImage = imread(*stringIt, CV_LOAD_IMAGE_GRAYSCALE);
waitKey(5000);
if(!tempImage.data )
{
cout << "Could not open or find a training image" << std::endl ;
continue;
}
else
{
trainingImages.push_back(tempImage);
}
}
vector< vector<KeyPoint> > keypoints;
vector<Mat> descriptor;
vector<Mat>::iterator descriptorIt;
SIFT sift;
for(imageIt = trainingImages.begin(); imageIt != trainingImages.end(); ++imageIt)
{
vector<KeyPoint> tempKeypoints;
Mat tempDescriptor;
// Generating keypoints and descriptors from training images
sift.operator()(*imageIt, *imageIt, tempKeypoints, tempDescriptor, false);
keypoints.push_back(tempKeypoints);
// Trying to use LDA to project the descriptors of training images
LDA lda(tempDescriptor, Mat());
lda.LDA::project(tempDescriptor);
descriptor.push_back(tempDescriptor);
}
// Reading the test image
Mat testImage;
testImage = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE);
waitKey(5000);
if(!testImage.data)
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
vector<KeyPoint> testKeypoints;
Mat testDescriptor;
// Generating the keypoints and the descriptor of the test image
sift.operator()(testImage, testImage, testKeypoints, testDescriptor, false);
// Trying to use LDA to project the descriptor of the test image
LDA lda(testDescriptor, Mat());
lda.LDA::project(testDescriptor);
// Flann based matching to determine the best matching training image
FlannBasedMatcher matcher;
vector<DMatch> matches;
vector<DMatch> good_matches;
int goodMatchesCtr = -1, tempCtr = -1, ctr = -1;
for(descriptorIt = descriptor.begin(); descriptorIt != descriptor.end(); ++descriptorIt)
{
++tempCtr;
vector<DMatch> tempMatches;
vector<DMatch> temp_good_matches;
int tempGoodMatchesCtr = 0;
double min_dist = 100;
matcher.match(testDescriptor, *descriptorIt, tempMatches);
for(int i = 0; i < testDescriptor.rows && i < (*descriptorIt).rows; ++i)
{
double dist = tempMatches[i].distance;
if(dist < min_dist)
{
min_dist = dist;
}
}
for(int i = 0; i < testDescriptor.rows && i < (*descriptorIt).rows; ++i)
{
if(tempMatches[i].distance <= max(2 * min_dist, 0.02))
{
temp_good_matches.push_back(tempMatches[i]);
++tempGoodMatchesCtr;
}
}
if(tempGoodMatchesCtr > goodMatchesCtr)
{
goodMatchesCtr = tempGoodMatchesCtr;
matches = tempMatches;
good_matches = temp_good_matches;
ctr = tempCtr;
}
}
// Displaying the test image alogside the best matching training image
Mat img_matches;
drawMatches(testImage, testKeypoints, trainingImages[ctr], keypoints[ctr], good_matches, img_matches, Scalar ::all(-1), Scalar ::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
for( int i = 0; i < (int)good_matches.size(); ++i )
{
printf( "-- Good Match [%d] Keypoint 1: %d -- Keypoint 2: %d \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx );
}
imshow("Good Matches", img_matches);
waitKey(0);
cout << "Executed!" << '\n';
return 0;
}
Я пишу эти программы в текстовом редакторе gedit и выполняю эти программы в Ubuntu 12.04 с OpenCV 2.4.9.
РЕДАКТИРОВАТЬ: В основном я хочу, чтобы преобразовать приведенные ниже строки кода SIFT-PCA в SIFT-LDA
PCA pca(testDescriptor1, Mat(), CV_PCA_DATA_AS_ROW, percentage);
pca.PCA::project(testDescriptor1, testDescriptor2);
testDescriptor = pca.PCA::backProject(testDescriptor2);
Я попытался заменить конструктор PCA конструктором LDA следующим образом:
LDA lda(testDescriptor, Mat());
lda.LDA::project(testDescriptor);
Но я получил вышеупомянутую ошибку. Я предполагаю, что я передаю неверные аргументы в конструктор LDA. Я уже просмотрел документацию по классу LDA Вот, но не повезло найти мою ошибку.
Любая помощь по вышеупомянутой проблеме будет оценена.
Заранее спасибо!
Задача ещё не решена.