I'm currently modifying the facerec_demo from OpenCV and I'm getting the following errors when I compile my code.
Creating library C:\Users\L\op_models\20nodes.project\20nodes-scenario1.dev64.i0.nt.lib and object C:\Users\L\op_models\20nodes.project\20nodes-scenario1.dev64.i0.nt.exp
wlan_mac_hcf.dev64.i0.pr.obj : error LNK2019: unresolved external symbol "class cv::Ptr<class cv::FaceRecognizer> __cdecl cv::createFisherFaceRecognizer(int,double)" (?createFisherFaceRecognizer@cv@@YA?AV?$Ptr@VFaceRecognizer@cv@@@1@HN@Z) referenced in function "void __cdecl faceRecognition(struct _IplImage *,char *,char *,double *,double *,double (* const)[2])" (?faceRecognition@@YAXPEAU_IplImage@@PEAD1PEAN2QEAY01N@Z)
wlan_mac_hcf.dev64.i0.pr.obj : error LNK2019: unresolved external symbol "int __cdecl cv::_interlockedExchangeAdd(int *,int)" (?_interlockedExchangeAdd@cv@@YAHPEAHH@Z) referenced in function "public: __cdecl cv::Mat::Mat(class cv::Mat const &)" (??0Mat@cv@@QEAA@AEBV01@@Z)
C:\Users\L\op_models\20nodes.project\20nodes-scenario1.dev64.i0.nt.dll : fatal error LNK1120: 2 unresolved externals
Microsoft (R) Manifest Tool version 5.2.3790.2076
I know that this issue normally arises when you forget to include a library in the linker options, so I double checked my settings and they are as follows:
/LIBPATH:C:\OpenCV2.4\opencv\build\x64\vc9\lib
opencv_calib3d240.lib
opencv_contrib240.lib
opencv_core240.lib
opencv_features2d240.lib
opencv_flann240.lib
opencv_gpu240.lib
opencv_haartraining_engine.lib
opencv_highgui240.lib
opencv_imgproc240.lib
opencv_legacy240.lib
opencv_ml240.lib
opencv_nonfree240.lib
opencv_objdetect240.lib
opencv_photo240.lib
opencv_stitching240.lib
opencv_ts240.lib
opencv_video240.lib
opencv_videostab240.lib
I don't believe that I missed any library files so I'm not sure what could be causing the issue; here is my code for reference. Sorry for the messiness, it's still a work in progress.
#include "opencv2\core\core.hpp"
#include "opencv2\contrib\contrib.hpp"
#include "opencv2\highgui\highgui.hpp"
#include "opencv2\imgproc\imgproc.hpp"
#include "opencv2\objdetect\objdetect.hpp"
void faceRecognition( IplImage* img, char * in,char * d,double *accu, double *error,double truthArray[][2] )
{
using namespace cv;
// Get the path to your CSV:
//string fn_haar = cascade); // we don't need to load the xml because it is a global assigned elsewhere.
std::string fn_csv = "faces.csv";
// These vectors hold the images and corresponding labels:
std::vector<cv::Mat> images;
std::vector<int> labels;
// Read in the data (fails if no valid input filename is given, but you'll get an error message):
try
{
read_csv(fn_csv, images, labels);
}
catch (cv::Exception& e)
{
return;
}
// Get the height from the first image. We'll need this
// later in code to reshape the images to their original
// size AND we need to reshape incoming faces to this size:
int im_width = images[0].cols;
int im_height = images[0].rows;
// Create a FaceRecognizer and train it on the given images:
Ptr<FaceRecognizer> model = createFisherFaceRecognizer();
model->train(images, labels);
// That's it for learning the Face Recognition model. You now
// need to create the classifier for the task of Face Detection.
// We are going to use the haar cascade you have specified in the
// command line arguments:
cv::CascadeClassifier haar_cascade;
//load the xml global assigned elsewhere
haar_cascade.load(cascade_name);
// convert input image into Mat format
cv::Mat frame(img);
// Clone the current frame:
cv::Mat original = frame.clone();
// Convert the current frame to grayscale:
cv::Mat gray;
cvtColor(original, gray, CV_BGR2GRAY);
// Find the faces in the frame:
std::vector< cv::Rect_<int> > faces;
haar_cascade.detectMultiScale(gray, faces);
// At this point you have the position of the faces in
// faces. Now we'll get the faces, make a prediction and
// annotate it in the video. Cool or what?
for(int i = 0; i < faces.size(); i++)
{
// Process face by face:
cv::Rect face_i = faces[i];
// Crop the face from the image. So simple with OpenCV C++:
cv::Mat face = gray(face_i);
// Resizing the face is necessary for Eigenfaces and Fisherfaces. You can easily
// verify this, by reading through the face recognition tutorial coming with OpenCV.
// Resizing IS NOT NEEDED for Local Binary Patterns Histograms, so preparing the
// input data really depends on the algorithm used.
//
// I strongly encourage you to play around with the algorithms. See which work best
// in your scenario, LBPH should always be a contender for robust face recognition.
//
// Since I am showing the Fisherfaces algorithm here, I also show how to resize the
// face you have just found:
cv::Mat face_resized;
cv::resize(face, face_resized, cv::Size(im_width, im_height), 1.0, 1.0, cv::INTER_CUBIC);
// Now perform the prediction, see how easy that is:
int prediction = model->predict(face_resized);
// And finally write all we've found out to the original image!
// First of all draw a green rectangle around the detected face:
rectangle(original, face_i, CV_RGB(0, 255,0), 1);
// Create the text we will annotate the box with:
std::string box_text = cv::format("Prediction = %d", prediction);
// Calculate the position for annotated text (make sure we don't
// put illegal values in there):
int pos_x = std::max(face_i.tl().x - 10, 0);
int pos_y = std::max(face_i.tl().y - 10, 0);
// And now put it into the image:
}
From what I can see from your libraries I believe you have forgotten to include the face library found in opencv_contrib.
The library must be built as a seperate entity and included in the above linker. https://github.com/Itseez/opencv_contrib
Once you build this library, you'll find a new .lib / .a containing the word face. This is the one you'll want to link your project.
As a side note, I am currently working on a face recognition project using the EigenFaces algorithm and this is what my cmake looks like.
find_package(OpenCV COMPONENTS core highgui face REQUIRED)
This is enough to make the algorithm work with your training set and your testing set.
Also, by adding all the libraries to your project you greatly increase the linkage time and size of your library.
Hope this helps,