int main(int argc, const char * argv[]) { try { // define requested input CmdLine cmd ("undistort a set of images using opencv", ' ', "0", false); typedef ValueArg<string> ArgStr; typedef UnlabeledMultiArg<string> MultiargStr; ArgStr cmdOutput ("o", "output", "directory for output images", true, "", "string", cmd); ArgStr cmdCalibr ("c", "calibr", "opencv calibration file", true, "", "string", cmd); MultiargStr cmdInput ("input", "input images path pattern", true, "string", cmd); // parse user input cmd.parse(argc, argv); path outDirPath = path(cmdOutput.getValue()); path calibrPath = path(cmdCalibr.getValue()); vector<string> inPathList = cmdInput.getValue(); // check existance of calibration file if (! exists(calibrPath) ) { cerr << "Calibration file " << absolute(calibrPath) << " does not exist" << endl; return -1; } // create a new directory if necessary if (! exists(outDirPath) ) if (! create_directory(outDirPath) ) { cerr << "Could not create directory " << absolute(outDirPath) << ". Stop" << endl; return -1; } // for every file for (int i = 0; i != inPathList.size(); ++i) { path inImagePath = path(inPathList[i]); cout << "working on file: " << inImagePath << "... " << flush; // open image Mat image; if ( !evg::loadImage (inImagePath.string(), image) ) { cout << "failed to open." << endl; continue; } // undistort image if ( !evg::undistortImageBool (calibrPath.string(), image) ) { cout << "failed to undistort." << endl; continue; } // save image path outImagePath = outDirPath / inImagePath.filename(); if ( !imwrite(outImagePath.string(), image) ) { cout << "failed to save image. Will stop now." << endl; return -1; }; cout << "succeded." << endl; } cout << "Complete." << endl; return 0; } catch(...) { cerr << "Exception in undistortImages(). Stop." << endl; return -1; } }
int main(int argc, const char * argv[]) { // parse input CmdLine cmd ("match a pair of images using specified features"); vector<string> featureTypes; featureTypes.push_back("sift"); featureTypes.push_back("surf"); featureTypes.push_back("orb"); featureTypes.push_back("brisk"); ValuesConstraint<string> cmdFeatureTypes( featureTypes ); ValueArg<string> cmdFeature("f", "feature", "feature type", true, "", &cmdFeatureTypes, cmd); ValueArg<string> cmd1st ("1", "1st", "1st image file path", true, "", "string", cmd); ValueArg<string> cmd2nd ("2", "2nd", "2nd image file path", true, "", "string", cmd); ValueArg<float> cmdThresh ("t", "threshold", "threshold for matching, 0-1, higher gives more matches", true, 3, "float", cmd); ValueArg<string> cmdOutM ("o", "outmat", "file path for matches", false, "/dev/null", "string", cmd); SwitchArg cmdDisableImshow ("", "disable_image", "don't show image", cmd); MultiSwitchArg cmdVerbose ("v", "", "level of verbosity of output", cmd); cmd.parse(argc, argv); string featureType = cmdFeature.getValue(); float threshold = cmdThresh.getValue(); string imageName1 = cmd1st.getValue(); string imageName2 = cmd2nd.getValue(); string outMName = cmdOutM.getValue(); bool disableImshow = cmdDisableImshow.getValue(); int verbose = cmdVerbose.getValue(); // file for output path outMPath = absolute(path(outMName)); if (! exists(outMPath.parent_path())) { cerr << "parent path " << outMPath.parent_path() << " doesn't exist." << endl; return -1; } if (is_directory(outMPath)) { cerr << "writeSimpleMatches: Need a filename, not a directory: " << outMPath << endl; return -1; } // load images Mat im1, im2; if (!evg::loadImage(imageName1, im1)) return 0; if (!evg::loadImage(imageName2, im2)) return 0; // setup detectors Ptr<FeatureDetector> detector = newFeatureDetector (featureType); Ptr<DescriptorExtractor> extractor = newDescriptorExtractor (featureType); Ptr<DescriptorMatcher> matcher = newMatcher (featureType, verbose); // match vector<KeyPoint> keypoints1, keypoints2; Mat descriptors1, descriptors2; vector< vector<DMatch> > matchesPairs; detector->detect (im1, keypoints1); detector->detect (im2, keypoints2); extractor->compute (im1, keypoints1, descriptors1); extractor->compute (im2, keypoints2, descriptors2); matcher->knnMatch (descriptors1, descriptors2, matchesPairs, 2); // filter based on relative distance to the two closest vector<DMatch> matches; matches.reserve (matchesPairs.size()); for (int i = 0; i != matchesPairs.size(); ++i) { float ratio = matchesPairs[i][0].distance / matchesPairs[i][1].distance; if (ratio < threshold) { if (verbose >= 2) cout << ratio << " "; matchesPairs[i][0].distance = ratio; matches.push_back (matchesPairs[i][0]); } } if (verbose >= 2) cout << endl; // write results evg::writeSimpleMatches (outMPath.string(), imageName1, imageName2, keypoints1, keypoints2, matches); if (!disableImshow) { Mat im1gray, im2gray; cvtColor(im1, im1gray, CV_RGB2GRAY); cvtColor(im2, im2gray, CV_RGB2GRAY); float factor = float(1440) / im1gray.cols / 2; vector<KeyPoint> keypoints1im = keypoints1, keypoints2im = keypoints2; for (int i = 0; i != keypoints1im.size(); ++i) { keypoints1im[i].pt.x = keypoints1im[i].pt.x * factor; keypoints1im[i].pt.y = keypoints1im[i].pt.y * factor; } for (int i = 0; i != keypoints2im.size(); ++i) { keypoints2im[i].pt.x = keypoints2im[i].pt.x * factor; keypoints2im[i].pt.y = keypoints2im[i].pt.y * factor; } resize(im1gray, im1gray, Size(), factor, factor); resize(im2gray, im2gray, Size(), factor, factor); Mat imgMatches; drawMatches (im1gray, keypoints1im, im2gray, keypoints2im, matches, imgMatches, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS ); imshow( "matches", imgMatches ); if (waitKey(0) == 27) return 0; } return 0; }
void parseOptions ( int argc, char** argv ) { try { CmdLine cmd ( "keypoints", ' ', kVersion ); MyOutput my; cmd.setOutput ( &my ); SwitchArg aArgFullScale ( "","fullscale", "Uses full scale image to detect keypoints (default:false)\n", false ); // SURF has a better performance than the other descriptors, use it by default, if it is enabled ValueArg<int> aArgSurfScoreThreshold ( "","surfscore", "Detection score threshold (default : 1000)\n", false, 1000, "int" ); ValueArg<int> aArgSieve1Width ( "","sievewidth", "Interest point sieve: Number of buckets on width (default : 10)", false, 10, "int" ); ValueArg<int> aArgSieve1Height ( "","sieveheight", "Interest point sieve : Number of buckets on height (default : 10)", false, 10, "int" ); ValueArg<int> aArgSieve1Size ( "","sievesize", "Interest point sieve : Max points per bucket (default : 10)\n", false, 10, "int" ); ValueArg<std::string> aArgOutputFormat ( "","format", "Output format (text, autopano-xml, descperf), default text\n", false, "text", "string" ); ValueArg<std::string> aArgOutputFile ( "o","output", "Output file. If not specified, print to standard out\n", false, "", "string" ); SwitchArg aArgInterestPoints ( "","interestpoints", "output only the interest points and the scale (default:false)\n", false ); ValueArg<std::string> aArgFixedInterestPoint ( "","ip", "Compute descriptor at x,y,scale,ori \n", false, "", "string" ); cmd.add ( aArgSurfScoreThreshold ); cmd.add ( aArgFullScale ); cmd.add ( aArgSieve1Width ); cmd.add ( aArgSieve1Height ); cmd.add ( aArgSieve1Size ); cmd.add ( aArgOutputFormat ); cmd.add ( aArgOutputFile ); cmd.add ( aArgInterestPoints ); cmd.add ( aArgFixedInterestPoint ); /* SwitchArg aArgTest("t","test", "Enables test mode\n", false); cmd.add( aArgTest ); */ UnlabeledMultiArg<string> aArgFiles ( "fileName", "Image files", true, "string" ); cmd.add ( aArgFiles ); cmd.parse ( argc,argv ); // // Set variables // vector<string> aFiles = aArgFiles.getValue(); if ( aFiles.size() != 1 ) { exit ( 1 ); } double surfScoreThreshold=1000; if ( aArgSurfScoreThreshold.isSet() ) { surfScoreThreshold = ( aArgSurfScoreThreshold.getValue() ); } bool downscale = true; if ( aArgFullScale.isSet() ) { downscale = false; } int sieveWidth = 10; if ( aArgSieve1Width.isSet() ) { sieveWidth = aArgSieve1Width.getValue(); } int sieveHeight = 10; if ( aArgSieve1Height.isSet() ) { sieveHeight = aArgSieve1Height.getValue(); } int sieveSize = 10; if ( aArgSieve1Size.isSet() ) { sieveSize = aArgSieve1Size.getValue(); } bool onlyInterestPoints = false; if ( aArgInterestPoints.isSet() ) { onlyInterestPoints = true; } std::ostream* outstream; if ( aArgOutputFile.isSet() ) { outstream = new std::ofstream(aArgOutputFile.getValue().c_str()); } else { outstream = & std::cout; } KeypointWriter* writer = 0; std::string outputformat = "text"; if ( aArgOutputFormat.isSet() ) { outputformat = aArgOutputFormat.getValue(); } if (outputformat == "text") { writer = new SIFTFormatWriter(*outstream); } else if (outputformat == "autopano-sift-xml") { writer = new AutopanoSIFTWriter(*outstream); } else if (outputformat == "descperf") { writer = new DescPerfFormatWriter(*outstream); } else { std::cerr << "Unknown output format, valid values are text, autopano-sift-xml, descperf" << std::endl; exit(1); } KeyPointPtr preKPPtr; if ( aArgFixedInterestPoint.isSet() ) { preKPPtr = KeyPointPtr(new KeyPoint()); preKPPtr->_x = -10001; preKPPtr->_ori = -10001; int nf = sscanf(aArgFixedInterestPoint.getValue().c_str(), "%lf:%lf:%lf:%lf", &(preKPPtr->_x), &(preKPPtr->_y), &(preKPPtr->_scale), &(preKPPtr->_ori)); std::cerr << "passed orientation: " << preKPPtr->_ori << std::endl; if (nf < 3) { std::cerr << "Invalid value for --ip option, expected --ip x:y:scale:ori" << std::endl; exit(1); } } DetectKeypoints ( aFiles[0], downscale, surfScoreThreshold, preKPPtr, onlyInterestPoints, sieveWidth, sieveHeight, sieveSize, *writer ); if ( aArgOutputFile.isSet() ) { delete outstream; } } catch ( ArgException& e ) { cout << "ERROR: " << e.error() << " " << e.argId() << endl; } }
/** * main procedure * * @param argc # of args * @param argv args * * @return no error */ int main ( int argc, char** argv ) { try { //CmdLine Parser generator CmdLine cmd ( "Quasi Affine Transform in dimension 2", ' ', "0.3" ); vector<Arg *> xorlist; //Option (not required) SwitchArg backwardSwitch ( "l","linearbackward","Bilinear Backward Mapping", false ); xorlist.push_back(&backwardSwitch); SwitchArg backwardNNSwitch ( "n","NNbackward","Nearest Neighbor Backward Mapping", false ); xorlist.push_back(&backwardNNSwitch); SwitchArg naiveSwitch ( "","naive","Naive BoundingRect method",false ); xorlist.push_back(&naiveSwitch); SwitchArg periodicitySwitch ( "p","periodicity","Use paving periodicity", false ); xorlist.push_back(&periodicitySwitch); cmd.xorAdd ( xorlist); SwitchArg nomultiplySwitch ( "m","no_multiplication","No multiplications in the paving computation", false ); cmd.add ( nomultiplySwitch ); SwitchArg fakeColorSwitch ( "f","fake_color","Output fake colors to illustrate pavings (non contracting AQA only)", false ); cmd.add ( fakeColorSwitch ); SwitchArg compositionSwitch ( "","composition","Composition test: f.f^{-1}", false ); cmd.add ( compositionSwitch ); ValueArg<string> transformFile ( "t","transform","The transform file name (this file should contain in this order : omega, a, b, c, d, e, f, separated with spaces, where the quasi-affine transform is : (ax + by + e, cx + dy + f) / omega)",true,"","file name" ); cmd.add ( transformFile ); ValueArg<string> outFile ( "o","output","The output image file name",true,"","file name" ); cmd.add ( outFile ); ValueArg<string> inFile ( "i","input","The input image file name",true,"","file name" ); cmd.add ( inFile ); // Parse the argv array. cmd.parse ( argc, argv ); // Get the value parsed by each arg. InterpolationType interp = NO_BM; if ( backwardSwitch.getValue() ) interp = LINEAR; else if ( backwardNNSwitch.getValue() ) interp = NN; bool useBoundingRect = naiveSwitch.getValue(); bool noMultiply = nomultiplySwitch.getValue(); bool usePeriodicity = periodicitySwitch.getValue(); bool fakeColor = fakeColorSwitch.getValue(); bool composition = compositionSwitch.getValue(); cout <<"Cmd Line Test: [ "; cout << "Interpolation type : " << interp <<", "; cout << "BoundingRect : "; if ( useBoundingRect ) cout << "Y, "; else cout << "N, "; cout << "noMultiply : "; if ( noMultiply ) cout << "Y, "; else cout << "N, "; cout << "Periodicity : "; if ( usePeriodicity ) cout << "Y"; else cout << "N"; cout << " ]"<<endl; cout << "Fake Colors: "; if ( fakeColor ) cout << "Y"; else cout << "N"; cout << " ]"<<endl; // Aquisition de données int o, a, b, c, d, e, f; fstream transform ( transformFile.getValue().c_str(), fstream::in ); transform >> o>> a >> b >> c >> d >> e >> f; transform.close(); Image initialImage ( inFile.getValue() ); QAT qat ( Matrix2x2 ( a, b, c, d ), o, Vector2D ( e, f ) ); QAT qat2 ( Matrix2x2 ( a, b, c, d ), o, Vector2D ( e, f ) ); if ( composition ) { Image finalImage = qat.applyToImage ( initialImage, interp, useBoundingRect, usePeriodicity, noMultiply, fakeColor, false ); cout << "Inverse computation..."<<endl; Image inverse = qat2.applyToImage ( finalImage, interp, useBoundingRect, usePeriodicity, noMultiply, fakeColor, true ); inverse.write ( outFile.getValue() ); double db = psnr ( initialImage, inverse ); cout << "PSNR = "<<db<<" db"<<endl; } else { Image finalImage = qat.applyToImage ( initialImage, interp , useBoundingRect, usePeriodicity, noMultiply, fakeColor, false ); finalImage.write ( outFile.getValue() ); } } catch ( ArgException &e ) // catch any exceptions { std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; } return 0; }