video_stitcher.cpp
Go to the documentation of this file.
00001 /*
00002  * matching_test.cpp
00003  *
00004  *  Created on: Oct 17, 2010
00005  *      Author: ethan
00006  */
00007 
00008 #include "pano_core/ImageAtom.h"
00009 #include "pano_core/feature_utils.h"
00010 #include "pano_core/MoleculeProcessor.h"
00011 #include "pano_core/CaptureEngine.h"
00012 #include "pano_core/ModelFitter.h"
00013 #include "pano_core/Blender.h"
00014 #include "pano_core/panoutils.h"
00015 
00016 #include <opencv2/core/core.hpp>
00017 #include <opencv2/highgui/highgui.hpp>
00018 
00019 #include "pano_core/BlurDetector.h"
00020 
00021 #include <sstream>
00022 #include <iostream>
00023 #include <list>
00024 
00025 using namespace std;
00026 using namespace cv;
00027 using namespace pano;
00028 
00029 //void onMatchCB(const AtomPair& pair)
00030 //{
00031 //  static Mat matches_img;
00032 //  pair.atom2()->images().src().copyTo(matches_img);
00033 //  if (!pair.result().success())
00034 //    bitwise_not(matches_img, matches_img);
00035 //  drawMatchesRelative(pair.atom1()->features(), pair.atom2()->features(), pair.matches(), matches_img,
00036 //                      pair.result().inlier_mask());
00037 //  imshow("prior matches", matches_img);
00038 //}
00039 
00040 int main(int ac, char ** av)
00041 {
00042 
00043   if (ac != 4)
00044   {
00045     cout << "usage: " << av[0] << " camera.yml <video device number> outputdir" << endl;
00046     return 1;
00047   }
00048 
00049   string output_dir = av[3];
00050 
00051   Camera camera;
00052   camera.setCameraIntrinsics(av[1]);
00053 
00054   BriefDescriptorExtractor brief(32);
00055 
00056   Ptr<FeatureDetector> detector(new GriddedDynamicDetectorAdaptor(400,3, 4, 4,FastAdjuster()));
00057 
00058   VideoCapture capture;
00059   capture.open(atoi(av[2]));
00060   if (!capture.isOpened())
00061   {
00062     cout << "capture device failed to open!" << endl;
00063     return 1;
00064   }
00065 
00066   cout << "following keys do stuff:" << endl;
00067   cout << "l : starts capturing the live preview ##DO THIS TO START##" << endl << endl;
00068   cout << "r : resets the pano" << endl;
00069   cout << "i/I : lower/raise inlier thresh" << endl;
00070   cout << "e/E : lower/raise error thresh" << endl;
00071   cout << "m/M : lower/raise max iterations" << endl;
00072   cout << "s : serialize the pano data" << endl;
00073   cout << "c : capture as an avi the taking of the pano" << endl;
00074   cout << "b : blends the pano" << endl;
00075   cout << "q : quit" << endl;
00076 
00077   Mat frame;
00078 
00079   bool ref_live = false;
00080 
00081   SVDRSolverParams params;
00082   params.error_thresh = 4;
00083   params.inliers_thresh = 10;
00084   params.maxiters = 25;
00085   params.nNeeded = 2;
00086 
00087   Ptr<SVDFitter> svdfitter(new SVDFitter(params));
00088 
00089   Ptr<ModelFitter> fitter(reinterpret_cast<const Ptr<ModelFitter>&> (svdfitter));
00090 
00091   Mat outimage(Size(800, 400), CV_8UC3);
00092 
00093   BlenderAlpha blender;
00094 
00095   Mat glob_out = Mat::zeros(Size(800, 400), CV_8UC3);
00096   Mat blended_out = Mat::zeros(Size(1500, 750), CV_8UC3);
00097 
00098   namedWindow("blended", CV_WINDOW_KEEPRATIO);
00099 
00100   VideoWriter video_writer;
00101 
00102   CaptureEngine capture_engine(fitter, detector, camera, output_dir);
00103 
00104   //the glob stores the pano graph
00105   //think of it as the map
00106   MoleculeGlob& glob = capture_engine.glob();
00107 
00108   BlurDetector blur_detector;
00109 
00110   int f_count = 0;
00111   double total_t;
00112   for (;;)
00113   {
00114 
00115     capture >> frame;
00116     if (frame.empty())
00117       continue;
00118 
00119     if (ref_live)
00120     {
00121 
00122       f_count++;
00123       double t = getTickCount();
00124 
00125       cv::Mat frame_;
00126       sharpen_backwards_heat_equation(frame.clone(), frame_);
00127       frame_.convertTo( frame, frame.type() );
00128       Ptr<ImageAtom> added = capture_engine.onNewFrame(frame);
00129 
00130 
00131       if (!added.empty())
00132       {
00133 
00134 
00135         blender.BlendMolecule(*glob.getBiggestMolecule(), glob_out);
00136       }
00137 
00138 
00139 
00140       //copy the map pano, so that the current image doesn't "paint" the more perfect map pano
00141       glob_out.copyTo(outimage);
00142 
00143       //draw the current observed frame to the output
00144       blender.blendIncremental(capture_engine.latestAtom(), outimage);
00145 
00146       imshow("blended", outimage);
00147 
00148       //capture the current output to the video file
00149       if (video_writer.isOpened())
00150         video_writer << outimage;
00151 
00152       //frame timing
00153       total_t += ((double)getTickCount() - t) / getTickFrequency();
00154 
00155       if (f_count % 30 == 0)
00156       {
00157         cout << "estimated W" << capture_engine.latestAtom().extrinsics().mat(Extrinsics::W) << endl;
00158         cout << "total tracking time per frame: " << total_t * 1000.0f / f_count << " milliseconds, averaged over "
00159             << f_count << " frames" << endl;
00160         total_t = 0;
00161         f_count = 0;
00162       }
00163 
00164     }
00165     char key = 0xFF & waitKey(2);
00166 
00167     switch (key)
00168     {
00169       case 'c':
00170         video_writer.open(output_dir + "/video_capture.avi", CV_FOURCC('H', 'F', 'Y', 'U')/*codec*/, 30/*fps*/,
00171                           outimage.size(), true/*color*/);
00172         break;
00173       case 'C':
00174         // video
00175         break;
00176       case 'l':
00177         ref_live = true;
00178         break;
00179       case 'b':
00180         cout << "blending...";
00181         cout.flush();
00182         blender.BlendMolecule(*glob.getBiggestMolecule(), blended_out);
00183         imwrite(output_dir + "/blended.jpg", blended_out);
00184         cout << " done blending. look at " << output_dir + "/blended.jpg" << endl;
00185         break;
00186       case 'r':
00187         cout << "reseting pano" << endl;
00188         glob.reset();
00189         glob_out = Scalar::all(0);
00190         break;
00191       case 'e':
00192         params.error_thresh -= 0.2;
00193         cout << "new error_thresh " << params.error_thresh << endl;
00194         break;
00195       case 'E':
00196         params.error_thresh += 0.2;
00197         cout << "new error_thresh " << params.error_thresh << endl;
00198         break;
00199       case 'i':
00200         params.inliers_thresh--;
00201         cout << "new inliers_thresh " << params.inliers_thresh << endl;
00202         break;
00203       case 'I':
00204         params.inliers_thresh++;
00205         cout << "new inliers_thresh " << params.inliers_thresh << endl;
00206         break;
00207       case 'm':
00208         params.maxiters--;
00209         cout << "new maxiters " << params.maxiters << endl;
00210         break;
00211       case 'M':
00212         params.maxiters++;
00213         cout << "new maxiters " << params.maxiters << endl;
00214         break;
00215       case 'g':
00216         //dont_check_blur = false;
00217         break;
00218       case 'G':
00219        //dont_check_blur = true;
00220         break;
00221       case 's':
00222       {
00223         FileStorage fs(output_dir + "/glob.yml.gz", FileStorage::WRITE);
00224         fs << "glob";
00225         glob.serialize(fs);
00226         fs.release();
00227       }
00228         break;
00229       case 27:
00230       case 'q':
00231         return 0;
00232         break;
00233       default:
00234         break;
00235     }
00236 
00237     //update the fitter wiht any params that changed
00238     (*svdfitter) = SVDFitter(params);
00239 
00240   }
00241   return 0;
00242 }


pano_core
Author(s): Ethan Rublee
autogenerated on Mon Oct 6 2014 08:04:38