double Classifier::getFilterError(string trainingDirectory, Annotations::Tag tag, ErrorType errorType) { Annotations annotations; Filter* filter = getFilter(tag); // read annotations string locationsFileName = trainingDirectory + "/" + Globals::annotationsFileName; annotations.readAnnotations(locationsFileName); // get the frames directory string framesDirectory = annotations.getFramesDirectory(); // reset total double totalError = 0; // iterate over the set of all annotations vector<FrameAnnotation*>& frameAnnotations = annotations.getFrameAnnotations(); for (unsigned int i = 0; i < frameAnnotations.size(); i++) { FrameAnnotation* fa = frameAnnotations[i]; // get LOI CvPoint& location = fa->getLOI(tag); if (!location.x && !location.y) continue; // compose filename char buffer[256]; sprintf(buffer, "frame_%d.png", fa->getFrameNumber()); string fileName = framesDirectory + "/" + buffer; // load image IplImage* inputImg = cvLoadImage((const char*)fileName.c_str()); if (!inputImg) { string err = "Filter::update. Cannot load file " + fileName + "."; throw (err); } IplImage* image = cvCreateImage(cvGetSize(inputImg), IPL_DEPTH_8U, 1); cvCvtColor(inputImg, image, CV_BGR2GRAY); // get the location of the left eye CvPoint offset; offset.x = offset.y = 0; IplImage* roi = (roiFunction)? roiFunction(image, *fa, offset, Annotations::Face) : 0; location.x -= offset.x; location.y -= offset.y; // apply filter fftw_complex* imageFFT = filter->preprocessImage((roi)? roi : image); IplImage* postFilterImg = filter->apply(imageFFT); // compute location double min; double max; CvPoint minLoc; CvPoint maxLoc; cvMinMaxLoc(postFilterImg, &min, &max, &minLoc, &maxLoc); // compute squared error as the distance between the location // found and the location as annotated double xdiff = abs(maxLoc.x - location.x); double ydiff = abs(maxLoc.y - location.y); switch (errorType) { case OneNorm: totalError += (xdiff + ydiff); break; case TwoNorm: totalError += sqrt(xdiff * xdiff + ydiff * ydiff); break; case MSE: totalError += (xdiff * xdiff + ydiff * ydiff); break; default: totalError += ((xdiff > ydiff)? xdiff : ydiff); break; } if (roi) cvReleaseImage(&roi); cvReleaseImage(&image); cvReleaseImage(&inputImg); } return totalError / frameAnnotations.size(); }
pair<double,string> Classifier::getError(string trainingDirectory) { Annotations annotations; // read annotations string locationsFileName = trainingDirectory + "/" + Globals::annotationsFileName; annotations.readAnnotations(locationsFileName); // get the frames directory string framesDirectory = annotations.getFramesDirectory(); double missclassified = 0; int counts[Globals::numZones]; int missCounts[Globals::numZones]; for (unsigned int i = 0; i < 3; i++) { counts[i] = 0; missCounts[i] = 0; } // iterate over the set of all annotations vector<FrameAnnotation*>& frameAnnotations = annotations.getFrameAnnotations(); for (unsigned int i = 0; i < frameAnnotations.size(); i++) { FrameAnnotation* fa = frameAnnotations[i]; int actualZone = fa->getZone(); if (actualZone < 3) actualZone = 1; else if (actualZone > 3) actualZone = 3; else actualZone = 2; counts[actualZone - 1]++; // compose filename char buffer[256]; sprintf(buffer, "frame_%d.png", fa->getFrameNumber()); string fileName = framesDirectory + "/" + buffer; // load image IplImage* inputImg = cvLoadImage((const char*)fileName.c_str()); double confidence; FrameAnnotation tf; int zone = getZone(inputImg, confidence, tf); if (zone < 3) zone = 1; else if (zone > 3) zone = 3; else zone = 2; if (zone != actualZone) { cout << "Classifier::getError. Expecting zone " << actualZone << " got zone " << zone << endl; missclassified++; missCounts[actualZone - 1]++; } cvReleaseImage(&inputImg); } int nAnnotations = frameAnnotations.size(); char buffer[Globals::largeBufferSize]; sprintf(buffer, "%d out of %d were miss-classified.", (int)missclassified, nAnnotations); string msg = buffer; sprintf(buffer, " Zones [%d, %d, %d].", counts[0], counts[1], counts[2]); msg += buffer; sprintf(buffer, " Missed [%d, %d, %d].", missCounts[0], missCounts[1], missCounts[2]); msg += buffer; return make_pair((missclassified / frameAnnotations.size()) * 100, msg); }
int main(int argc, char** argv) { string modelsFileName = ""; string imageFileName = ""; string imageDirectory = ""; int x = Globals::imgWidth / 2; int y = Globals::imgHeight / 2; for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "-i")) imageFileName = argv[i + 1]; else if (!strcmp(argv[i], "-d")) imageDirectory = argv[i + 1]; else if (!strcmp(argv[i], "-m")) modelsFileName = argv[i + 1]; else if (!strcmp(argv[i], "-c")) { char* str = argv[i + 1]; char* token = strtok(str, "(),"); if (token) x = atoi(token); token = strtok(NULL, "(),"); if (token) y = atoi(token); } else if (!strcmp(argv[i], "-h")) { cout << "Usage: classify -i <imageFileName> -m <modelsFileName>" << endl; return 0; } } if (modelsFileName == "") { cout << "Usage: classify -i <imageFileName> -m <modelsFileName>" << endl; return -1; } CvPoint center; center.x = x; center.y = y; CvSize size; size.width = Globals::roiWidth; size.height = Globals::roiHeight; double scale = 0.3; try { loadModel(modelsFileName); if (imageFileName != "") { Preprocess preprocess(size, scale, center, roiFunction); IplImage* image = cvLoadImage(imageFileName.c_str()); IplImage* imageVector = preprocess.generateImageVector(image); cout << "Sector " << classify(imageVector) << endl; cvReleaseImage(&image); cvReleaseImage(&imageVector); } else if (imageDirectory != "") { int counts[5][6]; for (int i = 0; i < 5; i++) for (int j = 0; j < 6; j++) counts[i][j] = 0; string annotationsFileName = imageDirectory + "/annotations.xml"; Annotations annotations; annotations.readAnnotations(annotationsFileName); CvPoint& center = annotations.getCenter(); Preprocess preprocess(size, scale, center, roiFunction); vector<FrameAnnotation*>& frameAnnotations = annotations.getFrameAnnotations(); for (unsigned int i = 0; i < frameAnnotations.size(); i++) { FrameAnnotation* fa = frameAnnotations[i]; fa->setFace(center); int expectedZone = fa->getSector(); counts[expectedZone - 1][5]++; // compose filename and update map char buffer[256]; sprintf(buffer, "frame_%d.png", fa->getFrameNumber()); string simpleName = buffer; string fileName = imageDirectory + "/" + simpleName; IplImage* image = cvLoadImage(fileName.c_str()); IplImage* imageVector = preprocess.generateImageVector(image); int zone = classify(imageVector); if (expectedZone == zone) counts[zone - 1][zone - 1]++; else counts[expectedZone - 1][zone - 1]++; cvReleaseImage(&image); cvReleaseImage(&imageVector); } cout << "Errors by class" << endl; for (int i = 0; i < 5; i++) { for (int j = 0; j < 6; j++) cout << counts[i][j] << "\t"; cout << endl; } } } catch (string err) { cout << err << endl; } return 0; }