Problem with undefine reference to cv::CascadeClassifier
-
This is the first time I try to practice others' project (which is shared free on the Stanford education website). My versions is Qt 5.5.0 and mingw 4.92
The .pro code#------------------------------------------------- # # Project created by QtCreator 2015-08-18T20:12:30 # #------------------------------------------------- QT += core QT -= gui TARGET = HomoPyramidBlend CONFIG += console CONFIG -= app_bundle TEMPLATE = app SOURCES += main.cpp # them duong dan openCV win32{ INCLUDEPATH += "C:/ti/opencv/include/" INCLUDEPATH += "C:/ti/opencv/include/opencv/" LIBS += -LC:/ti/opencv/x86/mingw/lib \ -lopencv_core300.dll \ -lopencv_features2d300.dll \ -lopencv_flann300.dll \ -lopencv_hal300 \ -lopencv_highgui300.dll \ -lopencv_imgcodecs300.dll \ -lopencv_imgproc300.dll \ -lopencv_ml300.dll \ -lopencv_calib3d300.dll \ -lopencv_video300.dll \ -lopencv_videoio300.dll \ -lopencv_photo300.dll } DISTFILES += \ lbpcascade_frontalface.xml \ photo 1.JPG \ photo 2.JPG \ photo 3.JPG
The .cpp code (rather long)
#include <QCoreApplication> #include <iostream> #include <string> #include <vector> #include <algorithm> #include "opencv2/opencv.hpp" using namespace cv; using namespace std; //function to find all faces using open CV's Haar cascade library Mat findAllFaces(Mat img, CascadeClassifier face_cascade, vector<int>& faceWidth, vector<int>& faceCenters_x, vector<int>& faceCenters_y); //function to get image number based on where we drag the cursor on the bar to select a photo for a face void myCallbackForImageNumChange(int pos, void* userdata); int iImgNum; int main(){ vector<string> inputImagePaths;//Stores all the image paths //Here give the new image names that you want to combine inputImagePaths.push_back("g3.jpg"); inputImagePaths.push_back("g2.jpg"); inputImagePaths.push_back("g1.jpg"); inputImagePaths.push_back("g4.jpg"); inputImagePaths.push_back("g5.jpg"); string outputImagePath="faces_final.jpg";//Stores final result path vector<Mat> images; //Reads the images for(int i=0;i<inputImagePaths.size();i++){ Mat I=imread(inputImagePaths[i],CV_LOAD_IMAGE_COLOR); resize(I,I,Size(816,612),0,0,1); images.push_back(I); } int num_of_photos=images.size();//Stores number of images taken int reference_image_num=0;//Stores the image number that is taken as the reference image, in which the faces are replaced string face_cascade_name = "lbpcascade_frontalface.xml"; CascadeClassifier face_cascade; //-- 1. Load the cascades //Returns error if loading Haar cascade library fails if( !face_cascade.load( face_cascade_name ) ) { cout<<"--(!)Error loading\n"; return -1; } //stores the width and center coordinates of the detected face region for all faces in any one image vector<int> faceWidth,faceCenters_x,faceCenters_y; //stores the width and center coordinates of the detected face region for all faces in all images vector<vector<int> >faceWidth_all_photos,faceCenters_x_all_photos,faceCenters_y_all_photos; vector<Mat> images_with_faces; for(int num_photos=0;num_photos<num_of_photos;num_photos++){ Mat refImg = images.at(num_photos); //function to find all faces using open CV's Haar cascade library Mat img_display=findAllFaces(refImg, face_cascade, faceWidth, faceCenters_x,faceCenters_y); images_with_faces.push_back(img_display); faceWidth_all_photos.push_back(faceWidth); faceCenters_x_all_photos.push_back(faceCenters_x); faceCenters_y_all_photos.push_back(faceCenters_y); } int num_of_faces=faceWidth_all_photos[reference_image_num].size();//Stores number of faces in each photo vector<int> image_number;//Image number for chosen face of each person for(int num_faces=0;num_faces<num_of_faces;num_faces++){ //For each face crop each photo to get the detected face Rect roi(faceCenters_x_all_photos[0].at(num_faces)-100, faceCenters_y_all_photos[0].at(num_faces)-100,200,200); Mat faces_cropped_all_photos=images[0](roi); for(int num_photos=1;num_photos<num_of_photos;num_photos++){ Rect roi(faceCenters_x_all_photos[num_photos].at(num_faces)-100, faceCenters_y_all_photos[num_photos].at(num_faces)-100,200,200); //Horizontally concatenate each faces's all photos hconcat(faces_cropped_all_photos,images[num_photos](roi),faces_cropped_all_photos); } //Interface for the user to choose the faces imshow("Select one of these faces by dragging the bar and then press any key",faces_cropped_all_photos); createTrackbar("Image Num", "Select one of these faces by dragging the bar and then press any key", &iImgNum, num_of_photos-1, myCallbackForImageNumChange); waitKey(0); image_number.push_back(iImgNum); } //stores the width and center coordinates of the chosen faces for all people in all images vector<int>faceWidth_final,faceCenters_x_final,faceCenters_y_final; for(int num_faces=0;num_faces<num_of_faces;num_faces++){ faceWidth_final.push_back(faceWidth_all_photos[image_number[num_faces]].at(num_faces)); faceCenters_x_final.push_back(faceCenters_x_all_photos[image_number[num_faces]].at(num_faces)); faceCenters_y_final.push_back(faceCenters_y_all_photos[image_number[num_faces]].at(num_faces)); } vector<int> center_x,center_y; vector<int> side; center_x=faceCenters_x_final;//x coordinate of center of chosen faces center_y=faceCenters_y_final;//y coordinate of center of chosen faces side=faceWidth_final;//bounding box edge length of chosen faces //From the center coordinates and width of the detected face bounding box, calculate //its top left corner coordinates vector<int> corner_x,corner_y; for(int num_faces=0;num_faces<num_of_faces;num_faces++){ corner_x.push_back(center_x[num_faces]-(side[num_faces]/2)); corner_y.push_back(center_y[num_faces]-(side[num_faces]/2)); } vector<int> width; width=side;//bounding box width of chosen faces vector<int> height; height=side;//bounding box height of chosen faces vector<Mat> im2_cropped;//Stores all cropped chosen faces for(int num_faces=0;num_faces<num_of_faces;num_faces++){ Mat im2_Gray; Rect roi(corner_x[num_faces], corner_y[num_faces],width[num_faces],height[num_faces]); im2_cropped.push_back(images[image_number[num_faces]](roi)); } int row,col; for(int num_faces=0;num_faces<num_of_faces;num_faces++){ //For each chosen face we loop through -40 to 40 in x and y direction double d2=1000000000000; for (int i=-40;i<=40;i++){ for (int j=-40;j<=40;j++){ double d1,d1_1,d1_2,d1_3,d1_4; //We take 20 pixels left boundary column in each chosen face's bounding box region on the reference image shifted by i //and j in the x and y direction respectively Mat im3 = images[reference_image_num](Rect(corner_x[num_faces]-i,corner_y[num_faces]-j,20,height[num_faces])); //We take left 20 pixels column in each chosen face's bounding box region Mat im4 = im2_cropped[num_faces](Rect(0,0,20,height[num_faces])); //calculate the difference between the two Mat diff=abs(im3-im4); //Calculate the norm of difference d1_1=norm(diff, NORM_L2); //Repeat the above process for the 20 pixel right boundary column im3 = images[reference_image_num](Rect(corner_x[num_faces]-i+width[num_faces]-20,corner_y[num_faces]-j,20,height[num_faces])); im4 = im2_cropped[num_faces](Rect(width[num_faces]-20,0,20,height[num_faces])); diff=abs(im3-im4); d1_2=norm(diff, NORM_L2); //Repeat the process for the 20 pixel top boundary column im3 = images[reference_image_num](Rect(corner_x[num_faces]-i,corner_y[num_faces]-j,width[num_faces],20)); im4 = im2_cropped[num_faces](Rect(0,0,width[num_faces],20)); diff=abs(im3-im4); d1_3=norm(diff, NORM_L2); //Repeat the process for the 20 pixel bottom boundary column im3 = images[reference_image_num](Rect(corner_x[num_faces]-i,corner_y[num_faces]-j+height[num_faces]-20,width[num_faces],20)); im4 = im2_cropped[num_faces](Rect(0,height[num_faces]-20,width[num_faces],20)); diff=abs(im3-im4); d1_4=norm(diff, NORM_L2); d1=d1_1+d1_2+d1_3+d1_4;//Add up all the norms //Find i and j that minimises the sum of norms and store them in col and row respectively if(d1<d2){ d2=d1; row=j; col=i; } } } //Paste the cropped face into the reference image at a position shifted by the row and column in the y and x direction //from the cropped face's original position in the image from which it was cropped im2_cropped[num_faces].copyTo(images[reference_image_num](Rect(corner_x[num_faces]-col,corner_y[num_faces]-row,width[num_faces],height[num_faces]))); } //Display final image and also write it into output file path imshow("final_result",images[reference_image_num]); imwrite(outputImagePath,images[reference_image_num]); waitKey(0); return 0; } //function to get image number based on where we drag the cursor on the bar to select a photo for a face void myCallbackForImageNumChange(int pos, void* userdata) { iImgNum = pos; } //function to find all faces using open CV's Haar cascade library Mat findAllFaces(Mat img, CascadeClassifier face_cascade, vector<int>& faceWidth, vector<int>& faceCenters_x, vector<int>& faceCenters_y) { vector<Rect> faces; Mat img_gray; cvtColor( img, img_gray, CV_BGR2GRAY ); equalizeHist( img_gray, img_gray ); //-- Detect faces face_cascade.detectMultiScale( img_gray, faces, 1.1, 3, 0|CV_HAAR_SCALE_IMAGE, Size(40, 40) ); int face_width;//Stores width of detected face's bounding box int faceCenter_x,faceCenter_y;//Stores center coordinates of detected face's bounding box Mat img_display; img.copyTo(img_display); for (size_t nFace = 0; nFace < faces.size(); nFace++) { face_width = faces[nFace].width*2; faceCenter_x = (faces[nFace].x-50 + face_width*0.5); faceCenter_y =(faces[nFace].y-50 + face_width*0.5); rectangle(img_display, Point(faces[nFace].x-50,faces[nFace].y-50), Point(faces[nFace].x-50 + faces[nFace].width*2,faces[nFace].y-50 + faces[nFace].width*2), Scalar(255,0,255), 2); faceWidth.push_back(face_width); faceCenters_x.push_back(faceCenter_x); faceCenters_y.push_back(faceCenter_y); } imwrite("Detected_faces.jpg",img_display); return img_display;//Return image with detected faces }
The .xml file is just front face's traning resource with Haar like features obtained from Opencv itself
And here's the issues list
In function `main':undefined reference to `cv::CascadeClassifier::CascadeClassifier()' undefined reference to `cv::CascadeClassifier::load(cv::String const&)' undefined reference to `cv::CascadeClassifier::~CascadeClassifier()' undefined reference to `cv::CascadeClassifier::~CascadeClassifier()' undefined reference to `cv::CascadeClassifier::~CascadeClassifier()' undefined reference to `cv::CascadeClassifier::~CascadeClassifier()' In function `Z12findAllFacesN2cv3MatENS_17CascadeClassifierERSt6vectorIiSaIiEES5_S5_': error: undefined reference to `cv::CascadeClassifier::detectMultiScale(cv::_InputArray const&,std::vector<cv:: Rect_<int>, std::allocator<cv::Rect_<int> > >&, double, int, int, cv::Size_<int>, cv::Size_<int>)' collect2.exe:-1: error: error: ld returned 1 exit status
Also I received the warning message which I have little idea of what's going on:
Warnings while parsing QML type information of C:/Qt/Qt5.5.0/5.5/mingw492_32/qml:
<dump of C:\Qt\Qt5.5.0\5.5\mingw492_32\qml>:1:24: Reading only version 1.1 parts.
<dump of C:\Qt\Qt5.5.0\5.5\mingw492_32\qml>:10:5: Expected only Component and ModuleApi object definitions.Thank you sincerely.
[edit: fixed missing coding tags SGaist]
-
Hi and welcome to devnet,
Your LIBS statement is wrong. You don't link to dlls, you link to .lib files. Just remove the .dll from all these lines and you should be good to go.