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;
    }
}
Esempio n. 4
0
/**
 * 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;
}