ProgRoman 9 Жалоба Опубликовано March 6, 2013 Сейчас реализую PCA для распознавания(применяю его для сокращения размерности) так как дескрипторы могут получаться довольно большими поискал в интернете примеры есть вот вставлю один из примеров использования класса PCA я брал за основу этот постPCA-opencv как оказалось ссылка http://www.bytefish.de/blog/pca_in_opencv довольно хорошо описывает но тем не менее возникли вопросы по коду вставлю его ниже Mat normalize(const Mat& src) { Mat srcnorm; normalize(src, srcnorm, 0, 255, NORM_MINMAX, CV_8UC1); return srcnorm; } int main(int argc, char* argv[]) { string pathD = "E:\\Projects\\ComputerVision\\Data_bases\\att_faces\\"; vector<Mat> db; // load greyscale images (these are from http:// www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html) db.push_back(imread(pathD+"s1\\1.pgm",0)); db.push_back(imread(pathD+"s1\\2.pgm",0)); db.push_back(imread(pathD+"s1\\3.pgm",0)); db.push_back(imread(pathD+"s2\\1.pgm",0)); db.push_back(imread(pathD+"s2\\2.pgm",0)); db.push_back(imread(pathD+"s2\\3.pgm",0)); db.push_back(imread(pathD+"s3\\1.pgm",0)); db.push_back(imread(pathD+"s3\\2.pgm",0)); db.push_back(imread(pathD+"s3\\3.pgm",0)); db.push_back(imread(pathD+"s4\\1.pgm",0)); db.push_back(imread(pathD+"s4\\2.pgm",0)); db.push_back(imread(pathD+"s4\\3.pgm",0)); Mat i1 = imread(pathD+"s4\\5.pgm",0).reshape(1,1).row(0); Mat imt; i1.convertTo(imt, CV_32FC1, 1/255.); int total = db[0].rows * db[0].cols; // build matrix (column) Mat mat(db.size(), total, CV_32FC1); for(int i = 0; i < db.size(); i++) { Mat X = mat.row(i); db[i].reshape(1, 1).row(0).convertTo(X, CV_32FC1, 1/255.); } // Change to the number of principal components you want: int numPrincipalComponents = 12; // Do the PCA: PCA pca(mat, Mat(), CV_PCA_DATA_AS_ROW, numPrincipalComponents); Mat im_pr = pca.project(imt);// это как я понимаю я просто проецирую входное изображение на базис построенный по всей базе // Create the Windows: namedWindow("avg", 1); namedWindow("pc1", 1); namedWindow("pc2", 1); namedWindow("pc3", 1); // Mean face: imshow("avg", pca.mean.reshape(1, db[0].rows)); // First three eigenfaces: imshow("pc1", normalize(pca.eigenvectors.row(0)).reshape(1, db[0].rows)); imshow("pc2", normalize(pca.eigenvectors.row(1)).reshape(1, db[0].rows)); imshow("pc3", normalize(pca.eigenvectors.row(2)).reshape(1, db[0].rows)); // Show the windows: waitKey(0); return 0; } вопросы такие как я понимаю проецирование тут ведётся на всю базу т.е. можно потом будет сравнивать как далеко данный вектор находится от вектора лица(обобщёного лица), а что бы распознавать отдельно по классам каждое изображение как я понимаю нужно отдельно для каждого класса строить матрицу mat которая будет использована для построения проекции входного изображения.. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано March 6, 2013 После проведения PCA вы получаете базис. Зачем это нужно? Это делается для того, чтобы уменьшить размерность сравниваемых векторов до количества векторов базиса. Фактически, Вы получаете статистическую модель лица, управляемую небольшим количеством параметров. То есть, вначале каждое лицо представляет собой вектор, размерность которого равна количеству пикселей в изображении этого лица. Дальше, при помощи PCA мы получаем несколько (сколько задаем сами), собственных векторов матрицы ковариации с максимальными собственными числами (оси, вдоль которых, параметры меняются максимально (ковариация максимальна) ). Это наш новый базис(новая система координат) размерность которого совпадает с исходной размерностью картинок, т.к. это векторы в исходной системе координат. А состоит он из, скажем 10 векторов с максимальными собственными числами. Дальше проецируем туда базу лиц, с которыми будем сравнивать (тех кого знаем), получаем их представление в виде 10 чисел, по числу векторов базиса. Для того, чтобы произвести опознание, надо спроецировать новое лицо на наш новый базис (10 чисел), и найти расстояние по метрике Махаланобиса (ведь мы знаем матрицу ковариации) до каждого из лиц, имеющихся в базе. До кого расстояние меньше, тот и победил Мне эти два ролика нравятся по теме: Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано March 7, 2013 это вроде уже обсуждалось, можете посмотреть код в теме про MNIST. дескрипторы могут получаться довольно большими большими это какими и сколько времени на всё про всё уходит? во первых про SVM+PCA http://metaoptimize.com/qa/questions/11595/pca-with-svm еще гид по настройке SVM http://www.csie.ntu.edu.tw/~cjlin/papers/guide/guide.pdf есть еще вроде специальные SVM побыстрее(чем libsvm,lightsvm) и заточенные под что то(большая размерность вектора или большой объемы данных), liblinear(только линейная классификация) и herosvm просто быстрее по их бенчмаркам. проецирование тут ведётся на всю базу т.е. можно потом будет сравнивать как далеко данный вектор находится от вектора лица(обобщёного лица), а что бы распознавать отдельно по классам каждое изображение как я понимаю нужно отдельно для каждого класса строить матрицу mat которая будет использована для построения проекции входного изображения.. базис строиться по всей базе. но тут остается немного другой вопрос, допустим у нас есть группы лиц - 1 группа это 1 человек, кол-во лиц в группе разное. мы из всех изображений делаем базис, потом берем новое изображение и проецируем на базис и хотим по какой либо метрике найти ближайшего соседа, получается что мы до этого должны спроецировать все наши лица на базис и потом выполнить knn search? или тут можно взять и усреднить все лица по индивиду и смотреть принадлежность к группе уже так?(т.е. немного сократили для knn search кол-во сэмплов). еще как быть если в группе мы большее кол-во лиц имеем настоящие и какое то кол-во имеем шум или от другого человека, как отфильтровать? кластеризовать на 2 кластера и взять больший? и про проблемы. самое главное это если изображения не выровненны друг относительно друга. и вычислительные проблемы тут возникают когда мы имеем samples x vector и min(samples,vector) такой большой, что всё начинает не влезать в память. но тут есть вроде что то типа online learning или probalistic PCA, но я до этого так и не докопал. п.с. еще есть такая книжка интересная Face Image Analysis by Unsupervised Learning Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ProgRoman 9 Жалоба Опубликовано March 7, 2013 спасибо, как я понял что бы отдельно распознавать по классам надо строить отдельные базисы лдя каждого класса вот и проецировать в каждый из базисов входное изображение и наверно смотреть к каком базисе к данному классу ближе изображение.. на днях напишу код скину сюда большими это какими и сколько времени на всё про всё уходит? по времени не знаю сегодня завтра замерю а по размеру около 10000 вот ещё интересует вопрос есть ли какие-нибудь методы которые понизят размерность и гарантированно улучшат(ну или точно не ухудшат) распознавательные способности алгоритма ну типа сжатия без потерь информации что-то в таком духе... или может есть какие-нибудь методы по извлечению особо информативных областей из дескрипторов.. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано March 7, 2013 Не надо делать по базису на индивида. Надо сделать один базис на все лица и работать в нем. Кластеризовать, измерять расстояния и т.д. Делая базис для каждого индивида отдельно, Вы теряете общую систему координат, и теряете возможность сравнения. Базис для отдельного человека делают когда работают с изменениями его лица, такими как эмоции, мимические жесты, освещение и т.д. А в данной задаче, как я понял, нужно сравнивать индивидов, как их сравнивать, если у каждого своя система координат? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано March 7, 2013 ну да для лиц это не нужно, но там потом уже про классы похоже разговор, типа машины и самолеты. кстати интересно, что будет если их всё равно в 1 базис слить? Делая базис для каждого индивида отдельно, Вы теряете общую систему координат, и теряете возможность сравнения. ну можно наверно просто брать расстояние до ближайшего в классе(или до центра класса) и так сравнивать между классами. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано March 7, 2013 Так и надо их слить в один базис (рассматривать в одной системе координат), если хотим найти статистическую модель данных. ну можно наверно просто брать расстояние до ближайшего в классе(или до центра класса) и так сравнивать между классами. У меня такое чувство, что это не совсем корректно, опять таки из-за того, что расстояния измеряться будут каждое в своей системе координат. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано March 26, 2013 http://scikit-learn.org/stable/auto_examples/applications/face_recognition.html#example-applications-face-recognition-py кстати тут вот PCA делают перед запихиванием в SVM. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах