//-------------------------------------------------- // As of writing this, you can use: // FAST, STAR, SIFT, SURF, MSER, GFTT, HARRIS, L vector<KeyPoint> MatchableImage::findFeatures(string alg_name) { log(LOG_LEVEL_DEBUG, "finding features using %s", alg_name.c_str()); if(featuresCurrent && featureAlgUsed.compare(alg_name)==0) return features; if(empty()) { log(LOG_LEVEL_ERROR, "in findFeatures(), image is empty"); } // "L" isn't in the "createDetector" thingie. // TO DO: Figure out what these vars do & how to pass them in! // For that matter, how to pass in parameters to any of the other feature detectors? if(alg_name.compare("L")==0) { Size patchSize(32, 32); int radius = 7; int threshold = 20; int nOctaves=2; int nViews=2000; int clusteringDistance = 2; ldetector = LDetector(radius, threshold, nOctaves, nViews, patchSize.width, clusteringDistance); ldetector.setVerbose(true); double backgroundMin=0; double backgroundMax=256; double noiseRange=5; bool randomBlur=true; double lambdaMin=0.8; double lambdaMax=1.2; double thetaMin=-CV_PI/2; double thetaMax=CV_PI/2; double phiMin=-CV_PI/2; double phiMax=CV_PI/2; gen = PatchGenerator(backgroundMin, backgroundMax, noiseRange, randomBlur, lambdaMin, lambdaMax, thetaMin, thetaMax, phiMin, phiMax); int maxPoints=100; ldetector.getMostStable2D(bw(), features, maxPoints, gen); } else { Ptr<FeatureDetector> detector = createFeatureDetector( alg_name ); if(detector==0) { log(LOG_LEVEL_ERROR, "Feature detector %s not found!", alg_name.c_str()); } detector->detect( bw(), features ); } log(LOG_LEVEL_DEBUG, "in findFeatures(), %d features", features.size()); featuresCurrent = true; descriptorsCurrent = false; matcherTrained=false; featureAlgUsed=alg_name; return features; }
Ostream& processorBoundaryPatch::operator<<(Ostream& os) const { os << patchName() << nl << token::BEGIN_BLOCK << nl << " type " << patchType() << token::END_STATEMENT << nl << " nFaces " << patchSize() << token::END_STATEMENT << nl << " startFace " << patchStart() << token::END_STATEMENT << nl << " myProcNo " << myProcNo_ << token::END_STATEMENT << nl << " neighbProcNo " << neighbProcNo_ << token::END_STATEMENT << nl << token::END_BLOCK << endl; return os; }
//-------------------------------------------------- // As of writing this, you can use: // ONEWAY, FERN, BruteForce, BruteForce-L1, Planar void MatchableImage::trainMatcher(string alg_name) { if(matcherTrained && matchAlgUsed.compare(alg_name)==0) return; log(LOG_LEVEL_DEBUG, "Training matcher %s", alg_name.c_str()); /* // These don't require descriptors. It's all rolled up in the matcher. if(!alg_name.compare("FERN")||!alg_name.compare("ONEWAY")||!alg_name.compare("CALONDER")) { findFeatures(); genericDescriptorMatch = createDescriptorMatcher(alg_name, "fern_params.xml"); log(LOG_LEVEL_DEBUG, "training matcher"); Mat img = bw(); genericDescriptorMatch->add( img, features ); } */ if(!alg_name.compare("BruteForce")||!alg_name.compare("BruteForce-L1")) { findDescriptors(); descriptorMatcher = createDescriptorMatcher(alg_name.c_str()); descriptorMatcher->clear(); descriptorMatcher->add( descriptors ); } if(!alg_name.compare("Planar")) { if(featureAlgUsed.compare("L")!=0) { log(LOG_LEVEL_DEBUG, "Planar detector works best with L detector. Switching!"); findFeatures("L"); } Size patchSize(32, 32); planarDetector.setVerbose(true); planarDetector.train(pyramid(ldetector.nOctaves-1), features, patchSize.width, 100, 11, 10000, ldetector, gen); } matchAlgUsed = alg_name; }
void getNCCBlock(const ImgG& img, double x, double y, NCCBlock& blk) { cv::Mat cvImg(img.rows, img.cols, CV_8UC1, img.data); cv::Size patchSize(2 * SL_NCCBLK_HW + 1, 2 * SL_NCCBLK_HW + 1); cv::Mat patch; cv::getRectSubPix(cvImg, patchSize, cv::Point2d(x, y), patch); memcpy(blk.I, patch.data, SL_NCCBLK_LEN); /*compute NCC parameters*/ double a = 0, b = 0; blk.avgI = 0; for (int j = 0; j < SL_NCCBLK_LEN; ++j) { a += blk.I[j]; b += double(blk.I[j]) * blk.I[j]; blk.avgI += blk.I[j]; } blk.A = a; blk.B = b; blk.C = 1 / sqrt(SL_NCCBLK_LEN * b - a * a); blk.avgI /= SL_NCCBLK_LEN; }
void getNCCBlocks(const ImgG& scaledImg, Mat_d& pts, PtrVec<NCCBlock>& nccBlks, double scale) { if (pts.empty()) return; nccBlks.clear(); nccBlks.reserve(pts.rows * 2); int bw = 2 * SL_NCCBLK_HW + 1; if (scale == 1.0) { cv::Mat cvImg(scaledImg.rows, scaledImg.cols, CV_8UC1, scaledImg.data); cv::Size patchSize(bw, bw); cv::Mat patch; for (int i = 0; i < pts.rows; i++) { double x = pts.data[2 * i]; double y = pts.data[2 * i + 1]; cv::getRectSubPix(cvImg, patchSize, cv::Point2d(x, y), patch); NCCBlock* blk = new NCCBlock(0); /* copy image block */ for (int j = 0; j < SL_NCCBLK_LEN; ++j) { blk->I[j] = patch.data[j]; } /* compute NCC parameters */ double a = 0, b = 0; blk->avgI = 0; for (int j = 0; j < SL_NCCBLK_LEN; ++j) { a += blk->I[j]; b += double(blk->I[j]) * blk->I[j]; blk->avgI += blk->I[j]; } blk->A = a; blk->B = b; blk->C = 1 / sqrt(SL_NCCBLK_LEN * b - a * a); blk->avgI /= SL_NCCBLK_LEN; nccBlks.push_back(blk); } } else { cv::Mat cvOrgImg(scaledImg.rows, scaledImg.cols, CV_8UC1, scaledImg.data); cv::Mat cvImg; cv::resize(cvOrgImg, cvImg, cv::Size(), scale, scale); cv::Size patchSize(bw, bw); cv::Mat patch; for (int i = 0; i < pts.rows; i++) { double x = pts.data[2 * i] * scale; double y = pts.data[2 * i + 1] * scale; cv::getRectSubPix(cvImg, patchSize, cv::Point2d(x, y), patch); NCCBlock* blk = new NCCBlock(0); /* copy image block */ for (int j = 0; j < SL_NCCBLK_LEN; ++j) { blk->I[j] = patch.data[j]; } /* compute NCC parameters */ double a = 0, b = 0; blk->avgI = 0; for (int j = 0; j < SL_NCCBLK_LEN; ++j) { a += blk->I[j]; b += double(blk->I[j]) * blk->I[j]; blk->avgI += blk->I[j]; } blk->A = a; blk->B = b; blk->C = 1 / sqrt(SL_NCCBLK_LEN * b - a * a); blk->avgI /= SL_NCCBLK_LEN; nccBlks.push_back(blk); } } }
void getNCCBlocks(const ImgG& scaledImg, const std::vector<FeaturePoint*>& vecFeatPts, PtrVec<NCCBlock>& nccBlks, double scale) { if (vecFeatPts.empty()) return; nccBlks.clear(); nccBlks.reserve(vecFeatPts.size() * 2); int bw = 2 * SL_NCCBLK_HW + 1; if (scale == 1.0) { cv::Mat cvImg(scaledImg.rows, scaledImg.cols, CV_8UC1, scaledImg.data); cv::Size patchSize(bw, bw); cv::Mat patch; for (size_t i = 0; i < vecFeatPts.size(); i++) { FeaturePoint* pFt = vecFeatPts[i]; cv::getRectSubPix(cvImg, patchSize, cv::Point2d(pFt->xo, pFt->yo), patch); NCCBlock* blk = new NCCBlock(pFt); /* copy image block */ for (int j = 0; j < SL_NCCBLK_LEN; ++j) { blk->I[j] = patch.data[j]; } /* compute NCC parameters */ double a = 0, b = 0; blk->avgI = 0; for (int j = 0; j < SL_NCCBLK_LEN; ++j) { a += blk->I[j]; b += double(blk->I[j]) * blk->I[j]; blk += blk->I[j]; } blk->A = a; blk->B = b; blk->C = 1 / sqrt(SL_NCCBLK_LEN * b - a * a); blk->avgI /= SL_NCCBLK_LEN; nccBlks.push_back(blk); } } else { cv::Mat cvOrgImg(scaledImg.rows, scaledImg.cols, CV_8UC1, scaledImg.data); cv::Mat cvImg; cv::resize(cvOrgImg, cvImg, cv::Size(), scale, scale); cv::Size patchSize(bw, bw); cv::Mat patch; for (size_t i = 0; i < vecFeatPts.size(); i++) { FeaturePoint* pFt = vecFeatPts[i]; cv::getRectSubPix(cvImg, patchSize, cv::Point2d(pFt->xo * scale, pFt->yo * scale), patch); NCCBlock* blk = new NCCBlock(pFt); /* copy image block */ for (int j = 0; j < SL_NCCBLK_LEN; ++j) { blk->I[j] = patch.data[j]; } /* compute NCC parameters */ double a = 0, b = 0; blk->avgI = 0; for (int j = 0; j < SL_NCCBLK_LEN; ++j) { a += blk->I[j]; b += double(blk->I[j]) * blk->I[j]; blk->avgI += blk->I[j]; } blk->A = a; blk->B = b; blk->C = 1 / sqrt(SL_NCCBLK_LEN * b - a * a); blk->avgI /= SL_NCCBLK_LEN; nccBlks.push_back(blk); } } }
// name : detect function // input : image and dataset // output : classification result and detect picture CDetectionResult CRForest::detection(CTestDataset &testSet) const { int classNum = classDatabase.vNode.size();//contain class number std::vector<CTestPatch> testPatch; std::vector<const LeafNode*> result; //std::vector<const LeafNode*> storedLN(0); //std::vector<std::vector<CParamset> > cluster(0); //std::vector<CParamset> clusterMean(0); cv::vector<cv::Mat> outputImage(classNum); cv::vector<cv::Mat> voteImage(classNum);//voteImage(classNum); //cv::vector<cv::Mat_<std::vector<CParamset> > > voteParam(classNum); std::vector<int> totalVote(classNum,0); //boost::timer t; //boost::timer::auto_cpu_timer t; //boost::timer::nanosecond_type time; std::vector<paramHist**> voteParam2(classNum); //timer.start(); testSet.loadImage(conf); testSet.extractFeatures(conf); //std::cout << "extracted feature " << t.elapsed() << " sec" << std::endl; //testSet.releaseImage(); //t.restart() // image row and col int imgRow = testSet.img.at(0)->rows; int imgCol = testSet.img.at(0)->cols; #pragma omp parallel { #pragma omp for for(int i = 0; i < classNum; ++i) { outputImage.at(i) = testSet.img.at(0)->clone(); voteImage.at(i) = cv::Mat::zeros(imgRow,imgCol,CV_32FC1); voteParam2.at(i) = new paramHist*[imgRow]; for(int j = 0; j < imgRow; ++j) voteParam2.at(i)[j] = new paramHist[imgCol]; } } //paramHist voteParam[testSet.img.at(0)->rows][testSet.img.at(0)->cols][classNum]; // extract feature from test image //features.clear(); //extractFeatureChannels(image.at(0), features); // add depth image to features //features.push_back(image.at(1)); // extract patches from features extractTestPatches(testSet,testPatch,this->conf); //std::cout << "extracted feature " << t.elapsed() << " sec" << std::endl; std::cout << "patch num: " << testPatch.size() << std::endl; std::cout << "detecting..." << std::endl; // regression and vote for every patch std::cout << "class num = " << classNum << std::endl; for(int j = 0; j < testPatch.size(); ++j) { // regression current patch result.clear(); this->regression(result, testPatch.at(j)); // for each tree leaf for(int m = 0; m < result.size(); ++m) { #pragma omp parallel { #pragma omp for for(int l = 0; l < result.at(m)->pfg.size(); ++l) { if(result.at(m)->pfg.at(l) > 0.9) { int cl = classDatabase.search(result.at(m)->param.at(l).at(0).getClassName()); for(int n = 0; n < result.at(m)->param.at(cl).size(); ++n) { cv::Point patchSize(conf.p_height/2,conf.p_width/2); cv::Point rPoint = result.at(m)->param.at(cl).at(n).getCenterPoint(); if(conf.learningMode != 2) { cv::Mat tempDepth = *testPatch[j].getDepth(); cv::Rect tempRect = testPatch[j].getRoi(); cv::Mat realDepth = tempDepth(tempRect); double centerDepth = realDepth.at<ushort>(tempRect.height / 2 + 1, tempRect.width / 2 + 1) + conf.mindist; rPoint *= centerDepth; rPoint.x /= 1000; rPoint.y /= 1000; } cv::Point pos(testPatch.at(j).getRoi().x + patchSize.x + rPoint.x, testPatch.at(j).getRoi().y + patchSize.y + rPoint.y); // vote to result image if(pos.x > 0 && pos.y > 0 && pos.x < voteImage.at(cl).cols && pos.y < voteImage.at(cl).rows) { double v = result.at(m)->pfg.at(cl) / ( result.size() * result.at(m)->param.at(l).size()); voteImage.at(cl).at<float>(pos.y,pos.x) += v;//(result.at(m)->pfg.at(c) - 0.9);// * 100;//weight * 500; voteParam2.at(cl)[pos.y][pos.x].roll.at<double>(0,result.at(m)->param.at(l).at(n).getAngle()[0]) += v * 10000; voteParam2.at(cl)[pos.y][pos.x].pitch.at<double>(0,result.at(m)->param.at(l).at(n).getAngle()[1]) += v * 10000; voteParam2.at(cl)[pos.y][pos.x].yaw.at<double>(0,result.at(m)->param.at(l).at(n).getAngle()[2]) += v * 10000; //std::cout << result.at(m)->param.at(l).at(n).getAngle() << std::endl; //std::cout << v << std::endl; totalVote.at(cl) += 1; } } //for(int n = 0; n < result.at(m)->param.at(cl).size(); ++n){ } //if(result.at(m)->pfg.at(l) > 0.9){ } //for(int l = 0; l < result.at(m)->pfg.size(); ++l){ }//pragma omp parallel } // for every leaf } // for every patch // vote end #pragma omp parallel { #pragma omp for // find balance by mean shift for(int i = 0; i < classNum; ++i) { cv::GaussianBlur(voteImage.at(i),voteImage.at(i), cv::Size(21,21),0); } } // measure time // double time = t.elapsed(); // std::cout << time << "sec" << std::endl; // std::cout << 1 / (time) << "Hz" << std::endl; // output image to file std::string opath; // if(!conf.demoMode){ // //create result directory // opath = testSet.getRgbImagePath(); // opath.erase(opath.find_last_of(PATH_SEP)); // std::string imageFilename = testSet.getRgbImagePath(); // imageFilename.erase(imageFilename.find_last_of(".")); // //imageFilename.erase(imageFilename.begin(),imageFilename.find_last_of(PATH_SEP)); // imageFilename = imageFilename.substr(imageFilename.rfind(PATH_SEP),imageFilename.length()); // //opath += PATH_SEP; // opath += imageFilename; // std::string execstr = "mkdir -p "; // execstr += opath; // system( execstr.c_str() ); // for(int c = 0; c < classNum; ++c){ // std::stringstream cToString; // cToString << c; // std::string outputName = "output" + cToString.str() + ".png"; // std::string outputName2 = opath + PATH_SEP + "vote_" + classDatabase.vNode.at(c).name + ".png"; // //cv::imwrite(outputName.c_str(),outputImage.at(c)); // //cv::cvtColor(voteImage) // cv::Mat writeImage; // //hist.convertTo(hist, hist.type(), 200 * 1.0/second_val,0); // voteImage.at(c).convertTo(writeImage, CV_8UC1, 254); // cv::imwrite(outputName2.c_str(),writeImage); // } // } // create detection result CDetectionResult detectResult; detectResult.voteImage = voteImage; // show ground truth std::cout << "show ground truth" << std::endl; // std::cout << dataSet.className.size() << std::endl; // std::cout << dataSet.centerPoint.size() << std::endl; for(int i = 0; i < testSet.param.size(); ++i) { testSet.param.at(i).showParam(); } // show detection reslut std::cout << "show result" << std::endl; // for every class for(int c = 0; c < classNum; ++c) { double min,max; cv::Point minLoc,maxLoc; cv::minMaxLoc(voteImage.at(c),&min,&max,&minLoc,&maxLoc); double min_pose_value[3], max_pose_value[3]; cv::Point min_pose[3], max_pose[3]; paramHist hist; for(int x = 0; x < conf.paramRadius; ++x) { for(int y = 0; y < conf.paramRadius; ++y) { if( maxLoc.x + x < imgCol && maxLoc.y + y < imgRow) hist += voteParam2.at(c)[maxLoc.y + y][maxLoc.x + x]; if(maxLoc.x - x > 0 && maxLoc.y - y > 0) hist += voteParam2.at(c)[maxLoc.y - y][maxLoc.x - x]; } } //hist.showHist(); // for(int p = 0; p < 360; ++p){ // std::cout << p << " " << voteParam2.at(c)[maxLoc.y][maxLoc.x].yaw.at<double>(0,p) << std::endl; // } //voteParam2.at(c)[maxLoc.y][maxLoc.x].showHist(); cv::minMaxLoc(hist.roll, &min_pose_value[0], &max_pose_value[0], &min_pose[0], &max_pose[0]); cv::minMaxLoc(hist.pitch, &min_pose_value[1], &max_pose_value[1], &min_pose[1], &max_pose[1]); cv::minMaxLoc(hist.yaw, &min_pose_value[2], &max_pose_value[2], &min_pose[2], &max_pose[2]); // draw detected class bounding box to result image // if you whant add condition of detection threshold, add here cv::Size tempSize = classDatabase.vNode.at(c).classSize; cv::Rect_<int> outRect(maxLoc.x - tempSize.width / 2,maxLoc.y - tempSize.height / 2 , tempSize.width,tempSize.height); cv::rectangle(outputImage.at(c),outRect,cv::Scalar(0,0,200),3); cv::putText(outputImage.at(c),classDatabase.vNode.at(c).name,cv::Point(outRect.x,outRect.y),cv::FONT_HERSHEY_SIMPLEX,1.2, cv::Scalar(0,0,200), 2, CV_AA); // draw grand truth to result image if(!conf.demoMode) { for(int i = 0; i < testSet.param.size(); ++i) { int tempClassNum = classDatabase.search(testSet.param.at(i).getClassName()); if(tempClassNum != -1) { cv::Size tempSize = classDatabase.vNode.at(tempClassNum).classSize; cv::Rect_<int> outRect(testSet.param.at(i).getCenterPoint().x - tempSize.width / 2,testSet.param.at(i).getCenterPoint().y - tempSize.height / 2 , tempSize.width,tempSize.height); cv::rectangle(outputImage.at(tempClassNum),outRect,cv::Scalar(200,0,0),3); cv::putText(outputImage.at(tempClassNum),classDatabase.vNode.at(c).name,cv::Point(testSet.param.at(i).getCenterPoint().x, testSet.param.at(i).getCenterPoint().y),cv::FONT_HERSHEY_SIMPLEX,1.2, cv::Scalar(200,0,0), 2, CV_AA); } } } // show result std::cout << c << " Name : " << classDatabase.vNode.at(c).name << "\tvote : " << totalVote.at(c) << " Score : " << voteImage.at(c).at<float>(maxLoc.y, maxLoc.x) << " CenterPoint : " << maxLoc << std::endl << " Pose : roll " << max_pose[0].x << " pitch : " << max_pose[1].x << " yaw : " << max_pose[2].x << std::endl; // if not in demo mode, output image to file if(!conf.demoMode) { std::string outputName = opath + PATH_SEP + "detectionResult" + "_" + classDatabase.vNode.at(c).name + ".png"; cv::imwrite(outputName.c_str(),outputImage.at(c)); } CDetectedClass detectedClass; detectedClass.name = classDatabase.vNode.at(c).name; detectedClass.angle[0] = max_pose[0].x; // calc euclidean dist to nearest object double minError = DBL_MAX; std::string nearestObject; for(int d = 0; d < testSet.param.size(); ++d) { double tempError = euclideanDist(maxLoc,testSet.param.at(d).getCenterPoint());//= std::sqrt(std::pow((double)(maxLoc.x - testSet.param.at(0).getCenterPoint().x), 2) + std::pow((double)(maxLoc.y - testSet.param.at(0).getCenterPoint().y), 2)); //std::cout << tempError << std::endl; if(tempError < minError) { minError = tempError; nearestObject = testSet.param.at(d).getClassName(); } } // calc and output result detectedClass.error = minError; detectedClass.nearestClass = nearestObject; detectedClass.score = voteImage.at(c).at<float>(maxLoc.y, maxLoc.x); detectResult.detectedClass.push_back(detectedClass); } // for every class for(int k = 0; k < classNum; ++k) { for(int i = 0; i < imgRow; ++i) { delete[] voteParam2.at(k)[i]; } } return detectResult; }
int main(int argc, char *const *argv) { std::vector<std::string> lbdNames; lbdNames.push_back("Freak"); lbdNames.push_back("Random Freak"); lbdNames.push_back("Brief"); lbdNames.push_back("Ex. Freak"); int measures = 512; int psize = 32; int iterations = 100; int samples = 20; int c = 0; while( (c = getopt(argc, argv, "i:p:m:s:")) != -1) { switch(c) { case 'i': iterations = atoi(optarg); break; case 'p': psize = atoi(optarg); break; case 'm': measures = atoi(optarg); break; case 's': samples = atoi(optarg); break; default: break; } } cv::Mat testImage = cv::imread(argv[argc-1], 0); if (!testImage.data) { std::cerr << "Error reading: " << argv[argc-1] << std::endl; return -1; } cv::Mat imagef; testImage.convertTo(imagef, CV_32F, 1.0/255.0); cv::RNG rng(getpid()); cv::Size patchSize(psize,psize); for (int i = 0; i < lbdNames.size(); ++i) { lts2::LBDOperator *LBD = lts2::CreateLbdOperator(i, measures); LBD->initWithPatchSize(patchSize); float norm = 0.0; for (int k = 0; k < samples; ++k) { // Select a random patch cv::Rect ROI; ROI.x = rng(imagef.cols-psize); ROI.y = rng(imagef.rows-psize); ROI.width = patchSize.width; ROI.height = patchSize.height; cv::Mat patch; imagef(ROI).copyTo(patch); // Compute the norm float current_norm = lts2::LinearOperator::EstimateOperatorNorm(*LBD, patch, iterations); norm = MAX(norm, current_norm); } std::cout << lbdNames[i] << " has norm: " << norm << std::endl; delete LBD; } return EXIT_SUCCESS; }
int main(int argc, char **argv) { if (argc < 2) { print_usage(stdout, argv); return 0; } int lbdType = 0; int pside = 32; int M = 512; int normalize = 0; static struct option long_options[] = { {"lbd", required_argument, 0, 0}, {0, 0, 0, 0} }; int optionIndex; int c = getopt_long(argc, argv, "i:m:n:p:", long_options, &optionIndex); while (c != -1) { switch (c) { case 0: if (optionIndex == 0) { if (strncmp(optarg, "freak", 5) == 0) lbdType = (int)lbd::eTypeFreak; else if (strncmp(optarg, "brief", 5) == 0) lbdType = (int)lbd::eTypeBrief; else if (strncmp(optarg, "exfreak", 7) == 0) lbdType = (int)lbd::eTypeExFreak; else lbdType = lbd::eTypeRandomFreak; } break; case 'm': M = MAX(1, atoi(optarg)); break; case 'n': normalize = atoi(optarg); break; case 'p': pside = atoi(optarg); pside += (pside % 2); // Enforce even size break; case '?': std::cerr << "Unknown option: -" << c << " (ignored)\n"; break; default: break; } c = getopt_long(argc, argv, "m:n:p:", long_options, &optionIndex); } cv::Size patchSize(pside,pside); lts2::LBDOperator *LBD = lts2::CreateLbdOperator(lbdType, M); LBD->initWithPatchSize(patchSize); cv::Mat result; LBD->drawSelfInImage(result, normalize); cv::normalize(result, result, 0.0, 1.0, cv::NORM_MINMAX); std::stringstream windowNameStr; cv::Mat res8; result.convertTo(res8, CV_8U, 255.0); cv::imwrite(argv[argc-1], res8); return EXIT_SUCCESS; }
int main(int argc, char **argv) { if (argc < 2) { print_usage(stdout, argv); return 0; } int lbdType = 0; int pside = 32; int normalize = 1; static struct option long_options[] = { {"lbd", required_argument, 0, 0}, {0, 0, 0, 0} }; int optionIndex; int c = getopt_long(argc, argv, "n:p:", long_options, &optionIndex); while (c != -1) { switch (c) { case 0: if (optionIndex == 0) { if (strncmp(optarg, "freak", 5) == 0) lbdType = (int)lbd::eTypeFreak; else if (strncmp(optarg, "brief", 5) == 0) lbdType = (int)lbd::eTypeBrief; else if (strncmp(optarg, "exfreak", 7) == 0) lbdType = (int)lbd::eTypeExFreak; else lbdType = lbd::eTypeRandomFreak; } break; case 'n': normalize = atoi(optarg); break; case 'p': pside = atoi(optarg); pside += (pside % 2); // Enforce even size break; case '?': std::cerr << "Unknown option: -" << c << " (ignored)\n"; break; default: break; } c = getopt_long(argc, argv, "n:p:", long_options, &optionIndex); } int N = atoi(argv[argc-2]); cv::Size patchSize(pside,pside); lts2::LBDOperator *LBD = lts2::CreateLbdOperator(lbdType); LBD->initWithPatchSize(patchSize); std::string lbdName; switch(lbdType) { case lbd::eTypeFreak: lbdName = "freak"; break; case lbd::eTypeExFreak: lbdName = "exfreak"; break; case lbd::eTypeRandomFreak: lbdName = "rafreak"; break; case lbd::eTypeBrief: lbdName = "brief"; break; } std::vector<cv::Mat> frame; LBD->drawBasis(frame, normalize); cv::Mat res8; for (int i = 0; i < N; ++i) { std::stringstream nameStream; nameStream << argv[argc-1] << "/" << lbdName << "-"; nameStream << std::setw(3) << std::setfill('0') << (i+1); nameStream << ".png"; frame[i].convertTo(res8, CV_8U, 255.0); cv::imwrite(nameStream.str(), res8); } return EXIT_SUCCESS; }