"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/camera/pfsalign.cpp" between
pfstools-2.1.0.tgz and pfstools-2.2.0.tgz

About: pfstools are a set of command line programs (and one GUI program) for reading, writing, manipulating, and viewing high-dynamic range (HDR) images and video frames (similar as the netpbm package does for low-dynamic range images).

pfsalign.cpp  (pfstools-2.1.0.tgz):pfsalign.cpp  (pfstools-2.2.0.tgz)
skipping to change at line 43 skipping to change at line 43
* $Id: pfsalign.cpp,v 1.11 2013/11/14 21:28:28 rafm Exp $ * $Id: pfsalign.cpp,v 1.11 2013/11/14 21:28:28 rafm Exp $
*/ */
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <algorithm> #include <algorithm>
#include <getopt.h> #include <getopt.h>
#include <string.h> #include <string.h>
// Because non-free OpenCV modules is not included in most of the distributions
// the current codes relies now on a less restrictive AKAZE feature detector
// Uncomment the line below to use SURF
//#define USE_SURF
#include <opencv2/core/core.hpp> #include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp> #include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp> #include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/calib3d/calib3d.hpp> #include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgproc/imgproc.hpp> #include <opencv2/imgproc/imgproc.hpp>
#include <libexif/exif-data.h> #include <libexif/exif-data.h>
#ifdef USE_SURF
#include <opencv2/nonfree/features2d.hpp>
#endif
#include <pfs.h> #include <pfs.h>
#define PROG_NAME "pfsalign" #define PROG_NAME "pfsalign"
#define VERBOSE_STR if( verbose ) std::cerr << PROG_NAME ": " #define VERBOSE_STR if( verbose ) std::cerr << PROG_NAME ": "
bool verbose = false; bool verbose = false;
class QuietException class QuietException
{ {
}; };
skipping to change at line 74 skipping to change at line 82
void printHelp() void printHelp()
{ {
fprintf( stderr, PROG_NAME " [-r index|--reference index] [-c (min|max)|--cr op (min|max)] [-d|--display-matches] [-f|--fail-no-match] -v -h\n" fprintf( stderr, PROG_NAME " [-r index|--reference index] [-c (min|max)|--cr op (min|max)] [-d|--display-matches] [-f|--fail-no-match] -v -h\n"
"See man page for more information.\n" ); "See man page for more information.\n" );
} }
class Toc class Toc
{ {
double tickCount; double tickCount;
bool newLine;
const char *name;
public: public:
void tic( const char *name = NULL ) void tic( const char *name = NULL, bool newLine = false )
{ {
if( name != NULL ) { this->name = name;
VERBOSE_STR << "Starting " << name << "..."; this->newLine = newLine;
} else { if( name != NULL )
VERBOSE_STR << "Starting processing ..."; name = "processing";
} VERBOSE_STR << "Starting " << name << "...";
if( newLine )
VERBOSE_STR << std::endl;
tickCount = static_cast<double>( getTickCount() ); tickCount = static_cast<double>( getTickCount() );
} }
void toc( ) void toc( )
{ {
double duration = (static_cast<double>( getTickCount() ) - tickCount) / getTickFrequency(); double duration = (static_cast<double>( getTickCount() ) - tickCount) / getTickFrequency();
if( verbose ) if( newLine ) {
std::cerr << "completed. It took " << duration << " seconds." << std VERBOSE_STR << "Completed " << name << ". It took " << duration << "
::endl; seconds." << std::endl;
} else
VERBOSE_STR << "completed. It took " << duration << " seconds." << s
td::endl;
} }
}; };
void pruneNNDR( std::vector<std::vector<DMatch> > &matches, float ratio ) void pruneNNDR( std::vector<std::vector<DMatch> > &matches, float ratio )
{ {
for( vector<vector<DMatch> >::iterator it = matches.begin(); it != matches.e nd(); it++ ) { for( vector<vector<DMatch> >::iterator it = matches.begin(); it != matches.e nd(); it++ ) {
bool prune = false; bool prune = false;
if( it->size() < 2 ) if( it->size() < 2 )
prune = true; prune = true;
else { else {
skipping to change at line 135 skipping to change at line 149
} }
} }
/** /**
Match feature points in a pair image and find homography. Match feature points in a pair image and find homography.
*/ */
bool alignImagePair( const Mat &ref_img, const Mat &exp_img, Mat &homography, in t sensitivity, bool display_matches ) bool alignImagePair( const Mat &ref_img, const Mat &exp_img, Mat &homography, in t sensitivity, bool display_matches )
{ {
Toc toc; Toc toc;
Toc toc_global;
toc_global.tic( "alignment of image pair", true );
homography = Mat::eye( 3, 3, CV_64F ); homography = Mat::eye( 3, 3, CV_64F );
// cv::imshow( "Result", ref_img ); // cv::imshow( "Result", ref_img );
// cv::imshow( "Result2", exp_img ); // cv::imshow( "Result2", exp_img );
// cv::waitKey(0); // cv::waitKey(0);
Ptr<FeatureDetector> detector(new DynamicAdaptedFeatureDetector( new SurfAdj
uster( (11-sensitivity) * 100.f, 2, 1000 ),
100, 1000,
sensitivity/2+2 ));
// Ptr<FeatureDetector> detector; // Ptr<FeatureDetector> detector;
// detector = new GoodFeaturesToTrackDetector(); // detector = new GoodFeaturesToTrackDetector();
// detector = new SurfFeatureDetector(); // detector = new SurfFeatureDetector();
std::vector<KeyPoint> keypoints1, keypoints2; std::vector<KeyPoint> keypoints1, keypoints2;
Mat descr_ref, descr_exp;
toc.tic( "feature detection" ); #ifdef USE_SURF
detector->detect( ref_img, keypoints1 ); Ptr<FeatureDetector> detector(new DynamicAdaptedFeatureDetector( new Sur
detector->detect( exp_img, keypoints2 ); fAdjuster( (11-sensitivity) * 100.f, 2, 1000 ),
toc.toc( ); 100, 1000,
sensitivity/2+2 ));
toc.tic( "feature detection" );
detector->detect( ref_img, keypoints1 );
detector->detect( exp_img, keypoints2 );
toc.toc( );
#else
Ptr<AKAZE> akaze = AKAZE::create();
toc.tic( "feature detection and extraction" );
akaze->setThreshold( 0.005f );
akaze->detectAndCompute( ref_img, noArray(), keypoints1, descr_ref);
akaze->detectAndCompute( exp_img, noArray(), keypoints2, descr_exp);
toc.toc( );
VERBOSE_STR << "Detected " << keypoints1.size() << " keypoints in the re
ference image." << endl;
VERBOSE_STR << "Detected " << keypoints2.size() << " keypoints in the te
st image." << endl;
#endif
if( keypoints1.size() < 10 || keypoints2.size() < 10 ) { if( keypoints1.size() < 10 || keypoints2.size() < 10 ) {
cerr << PROG_NAME ": Could not detect a sufficient number of keypoints ( found " cerr << PROG_NAME ": Could not detect a sufficient number of keypoints ( found "
<< keypoints1.size() << " and " << keypoints2.size() << " keypoint s)" << endl; << keypoints1.size() << " and " << keypoints2.size() << " keypoint s)" << endl;
if( display_matches ) { if( display_matches ) {
Mat vis; Mat vis;
vector<char> inliners_c; vector<char> inliners_c;
std::vector<cv::DMatch> matches_sym; std::vector<cv::DMatch> matches_sym;
drawMatches( ref_img, keypoints1, exp_img, keypoints2, matches_sym, vis, Scalar(0,0,255), Scalar(0,255,255), inliners_c, DrawMatchesFlags::DRAW_RICH _KEYPOINTS ); drawMatches( ref_img, keypoints1, exp_img, keypoints2, matches_sym, vis, Scalar(0,0,255), Scalar(0,255,255), inliners_c, DrawMatchesFlags::DRAW_RICH _KEYPOINTS );
cv::namedWindow( "Image pair matches" ); cv::namedWindow( "Image pair matches" );
cv::imshow( "Image pair matches", vis ); cv::imshow( "Image pair matches", vis );
cv::waitKey(0); cv::waitKey(0);
} }
return false; return false;
} }
// SiftDescriptorExtractor surfDesc; // SiftDescriptorExtractor surfDesc;
SurfDescriptorExtractor surfDesc; #ifdef USE_SURF
SurfDescriptorExtractor surfDesc;
Mat descr_ref, descr_exp;
toc.tic( "descriptor extraction" );
surfDesc.compute( ref_img, keypoints1, descr_ref );
surfDesc.compute( exp_img, keypoints2, descr_exp );
toc.toc( );
FlannBasedMatcher matcher;
// BruteForceMatcher< cv::L2<float> > matcher;
toc.tic( "descriptor extraction" );
surfDesc.compute( ref_img, keypoints1, descr_ref );
surfDesc.compute( exp_img, keypoints2, descr_exp );
toc.toc( );
#endif
#ifdef USE_SURF
FlannBasedMatcher matcher;
// BruteForceMatcher< cv::L2<float> > matcher;
#else
BFMatcher matcher(NORM_HAMMING);
#endif
toc.tic( "matching" ); toc.tic( "matching" );
std::vector< std::vector<cv::DMatch> > matches_rt; std::vector< std::vector<cv::DMatch> > matches_rt;
matcher.knnMatch( descr_ref, descr_exp, matches_rt, 2 );
std::vector< std::vector<cv::DMatch> > matches_tr; std::vector< std::vector<cv::DMatch> > matches_tr;
matcher.knnMatch( descr_ref, descr_exp, matches_rt, 2 );
matcher.knnMatch( descr_exp, descr_ref, matches_tr, 2 ); matcher.knnMatch( descr_exp, descr_ref, matches_tr, 2 );
pruneNNDR( matches_rt, 1 ); pruneNNDR( matches_rt, 1 );
pruneNNDR( matches_tr, 1 ); pruneNNDR( matches_tr, 1 );
std::vector<cv::DMatch> matches_sym; std::vector<cv::DMatch> matches_sym;
symmetryTest( matches_rt, matches_tr, matches_sym ); symmetryTest( matches_rt, matches_tr, matches_sym );
toc.toc( ); toc.toc( );
std::vector<cv::DMatch>::iterator it; std::vector<cv::DMatch>::iterator it;
skipping to change at line 226 skipping to change at line 258
if( matches_sym.size() < 9 ) { if( matches_sym.size() < 9 ) {
cerr << PROG_NAME ": Not enough matches found between a pair of images ( found " << matches_sym.size() << ")" << endl; cerr << PROG_NAME ": Not enough matches found between a pair of images ( found " << matches_sym.size() << ")" << endl;
return false; return false;
} }
// Mat affine = estimateRigidTransform( e1, e2, false ); // Mat affine = estimateRigidTransform( e1, e2, false );
vector<uchar> inliners(matches_sym.size(), 0); vector<uchar> inliners(matches_sym.size(), 0);
// affine = findHomography( pp1, pp2, inliners, CV_RANSAC, 1. ); // affine = findHomography( pp1, pp2, inliners, CV_RANSAC, 1. );
homography = findHomography( pp2, pp1, CV_RANSAC, 1., inliners ); homography = findHomography( pp2, pp1, RANSAC, 1., inliners );
// solve( pp1, pp2, affine, DECOMP_SVD ); // solve( pp1, pp2, affine, DECOMP_SVD );
// Mat affine = (Mat_<float>(2,3) << 1, 0, 0, 0, 1, 10); // Mat affine = (Mat_<float>(2,3) << 1, 0, 0, 0, 1, 10);
int inliner_count = count( inliners.begin(), inliners.end(), 1 ); int inliner_count = count( inliners.begin(), inliners.end(), 1 );
VERBOSE_STR << "Found " << matches_sym.size() << " matching features, reduce d to " << inliner_count << " inliners." << endl; VERBOSE_STR << "Found " << matches_sym.size() << " matching features, reduce d to " << inliner_count << " inliners." << endl;
if( display_matches ) { if( display_matches ) {
Mat vis; Mat vis;
vector<char> inliners_c(matches_sym.size(), 0); vector<char> inliners_c(matches_sym.size(), 0);
skipping to change at line 253 skipping to change at line 285
cv::imshow( "Image pair matches", vis ); cv::imshow( "Image pair matches", vis );
cv::waitKey(0); cv::waitKey(0);
} }
if( inliner_count < 9 ) { if( inliner_count < 9 ) {
homography = Mat::eye( 3, 3, CV_64F ); homography = Mat::eye( 3, 3, CV_64F );
cerr << PROG_NAME ": Not enough inliners to find a reliable transformati on." << endl; cerr << PROG_NAME ": Not enough inliners to find a reliable transformati on." << endl;
return false; return false;
} }
toc_global.toc();
return true; return true;
} }
/** /**
Convert floating point image to 8-bit image. Convert floating point image to 8-bit image.
*/ */
Mat convert_to_8bit( Mat &in, bool apply_gamma ) Mat convert_to_8bit( Mat &in, bool apply_gamma )
{ {
skipping to change at line 632 skipping to change at line 665
for( int ll = min( kk, reference_index )+1; ll <= max( kk, reference_ind ex); ll++ ) for( int ll = min( kk, reference_index )+1; ll <= max( kk, reference_ind ex); ll++ )
{ {
if( ll > 0 ) if( ll > 0 )
trans = trans*homoM[ll-1]; trans = trans*homoM[ll-1];
} }
if( kk < reference_index ) if( kk < reference_index )
trans = trans.inv(); trans = trans.inv();
homoMC.push_back( trans ); homoMC.push_back( trans );
double data[4][3] = { { 0, 0, 1 }, { frames[kk].size.width, 0, 1 }, { fr ames[kk].size.width, frames[kk].size.height, 1 }, { 0, frames[kk].size.height, 1 } }; double data[4][3] = { { 0., 0., 1. }, { (double)frames[kk].size.width, 0 ., 1. }, { (double)frames[kk].size.width, (double)frames[kk].size.height, 1. }, { 0., (double)frames[kk].size.height, 1. } };
Mat corners( 4, 3, CV_64F, data ); Mat corners( 4, 3, CV_64F, data );
Mat corners_trans = trans * corners.t(); Mat corners_trans = trans * corners.t();
// VERBOSE_STR << "Image: " << fileNames[kk] << endl; // VERBOSE_STR << "Image: " << fileNames[kk] << endl;
// VERBOSE_STR << " Corners: " << trans * corners.t() << endl; // VERBOSE_STR << " Corners: " << trans * corners.t() << endl;
Mat p_nh; //( 4, 3, CV_32F ); Mat p_nh; //( 4, 3, CV_32F );
Mat_<float> corners_f; Mat_<float> corners_f;
corners_trans.convertTo( corners_f, CV_32F ); corners_trans.convertTo( corners_f, CV_32F );
 End of changes. 18 change blocks. 
32 lines changed or deleted 68 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)