Open Cv fisherfaces
c++, compiler-errors, opencv, visual-studio-2010, windows
Solution
I see you are using OpenCV 2.4.0. As the developer I admit the confusion is my fault: I didn't thoroughly check the input data passed to the training method back then, so people passing wrongly aligned data got error messages like yours. Most likely the error you see happens, because your training images don't have equal size. This is necessary for the Eigenfaces and Fisherfaces algorithm (not for the Local Binary Patterns Histograms). OpenCV 2.4.0 just tries to reshape the data to a matrix and blows up with the error message you see; OpenCV 2.4.2 instead checks (before training) if the input data is correctly aligned and throws a meaningful exception... with a very clear message.
This post assumes it could also be due to linking the OpenCV libraries:
- Getting OpenCV Error "Image step is wrong" in Fisherfaces.train() method
If it's not linking the libraries it might be due to the image size. Resizing your training images, can easily be done OpenCV with cv::resize:
- http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html#resize
But you probably should consider to switch to OpenCV 2.4.2, where all this is added:
- http://opencv.org/opencv-v2-4-2-released.html
This version also comes with an extensive documentation at:
- http://docs.opencv.org/trunk/modules/contrib/doc/facerec/index.html
However if you can't change to OpenCV 2.4.2 and you'll need to stay with OpenCV 2.4.0, then you could also use libfacerec:
- https://github.com/bytefish/libfacerec
This is the project, that got merged into OpenCV. I made sure it works with OpenCV 2.4.0 and it'll leave you with exactely the same interface as the OpenCV 2.4.2 version. So once you feel like updating to OpenCV 2.4.2, you'll only switch the includes.
Problem
I have this problem, when i run with vs2010 (debug) (open cv 2.4.0) facerec_demo.cpp gaves me the program this error OpenCV Error: Image step is wrong (The matrix is not continuous, thus its number of rows can not be changed) in unknown function, file ......\src\opencv\modul es\core>\src\matrix.cpp, line 801 This error derives me to this line in facerec.cpp (Fisherfaces::train(InputArray src, InputArray _lbls) ``` Mat data = asRowMatrix(src, CV_64FC1); <-- this gets a exeption, not handled. ``` and a i use at pgm img database and this is my original *facerec_demo.cpp* file ``` #include "stdafx.h" #include <opencv2/opencv.hpp> #include <iostream> #include <fstream> #include <vector> #include <string> #include <sstream> using namespace cv; using namespace std; vector<string> split_at_commas(const string& row) { vector<string> res; istringstream buf(row); string s; while (getline(buf, s, ';')) res.push_back(s); return res; } Mat toGrayscale(InputArray _src) { Mat src = _src.getMat(); // only allow one channel if(src.channels() != 1) CV_Error(CV_StsBadArg, "Only Matrices with one channel are supported"); // create and return normalized image Mat dst; cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1); return dst; } void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, char separator = ';') { //std::ifstream file(filename.c_str(), ifstream::in); std::ifstream file(_T("D:\\Users\\PC ACER\\Documents\\mycsv4.csv")); if (!file) throw std::exception(); string line="", path="", classlabel=""; while (getline(file, line)) { //vector<string> values = split_at_commas(line); stringstream liness(line); getline(liness, path, ';'); getline(liness, classlabel); images.push_back(imread(path, 0)); labels.push_back(atoi(classlabel.c_str())); } } int main(int argc, const char *argv[]) { // check for command line arguments if (argc != 2) { cout << "usage: " << argv[0] << " <csv.ext>" << endl; exit(1); } // path to your CSV string fn_csv = string(argv[1]); // images and corresponding labels vector<Mat> images; vector<int> labels; // read in the data try { read_csv(fn_csv, images, labels); } catch (exception&) { cerr << "Error opening file \"" << fn_csv << "\"." << endl; exit(1); } // get width and height //int width = images[0].cols; int height = images[0].rows; // get test instances Mat testSample = images[images.size() - 1]; int testLabel = labels[labels.size() - 1]; // ... and delete last element images.pop_back(); labels.pop_back(); // build the Fisherfaces model Ptr<FaceRecognizer> model = createFisherFaceRecognizer(); model->train(images, labels); // test model int predicted = model->predict(testSample); cout << "predicted class = " << predicted << endl; cout << "actual class = " << testLabel << endl; // get the eigenvectors Mat W = model->eigenvectors(); // show first 10 fisherfaces for (int i = 0; i < min(10, W.cols); i++) { // get eigenvector #i Mat ev = W.col(i).clone(); // reshape to original size AND normalize between [0...255] Mat grayscale = toGrayscale(ev.reshape(1, height)); // show image (with Jet colormap) Mat cgrayscale; applyColorMap(grayscale, cgrayscale, COLORMAP_JET); imshow(format("%d", i), cgrayscale); } waitKey(0); return 0; } ```