diff options
Diffstat (limited to 'jni/feature_stab/src/dbregtest/dbregtest.cpp')
-rw-r--r-- | jni/feature_stab/src/dbregtest/dbregtest.cpp | 399 |
1 files changed, 399 insertions, 0 deletions
diff --git a/jni/feature_stab/src/dbregtest/dbregtest.cpp b/jni/feature_stab/src/dbregtest/dbregtest.cpp new file mode 100644 index 0000000..5087362 --- /dev/null +++ b/jni/feature_stab/src/dbregtest/dbregtest.cpp @@ -0,0 +1,399 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// $Id: dbregtest.cpp,v 1.24 2011/06/17 14:04:33 mbansal Exp $ +#include "stdafx.h" +#include "PgmImage.h" +#include "../dbreg/dbreg.h" +#include "../dbreg/dbstabsmooth.h" +#include <db_utilities_camera.h> + +#include <iostream> +#include <iomanip> + +#if PROFILE + #include <sys/time.h> +#endif + + +using namespace std; + +const int DEFAULT_NR_CORNERS=500; +const double DEFAULT_MAX_DISPARITY=0.2; +const int DEFAULT_MOTION_MODEL=DB_HOMOGRAPHY_TYPE_AFFINE; +//const int DEFAULT_MOTION_MODEL=DB_HOMOGRAPHY_TYPE_R_T; +//const int DEFAULT_MOTION_MODEL=DB_HOMOGRAPHY_TYPE_TRANSLATION; +const bool DEFAULT_QUARTER_RESOLUTION=false; +const unsigned int DEFAULT_REFERENCE_UPDATE_PERIOD=3; +const bool DEFAULT_DO_MOTION_SMOOTHING = false; +const double DEFAULT_MOTION_SMOOTHING_GAIN = 0.75; +const bool DEFAULT_LINEAR_POLISH = false; +const int DEFAULT_MAX_ITERATIONS = 10; + +void usage(string name) { + + const char *helpmsg[] = { + "Function: point-based frame to reference registration.", + " -m [rt,a,p] : motion model, rt = rotation+translation, a = affine (default = affine).", + " -c <int> : number of corners (default 1000).", + " -d <double>: search disparity as portion of image size (default 0.1).", + " -q : quarter the image resolution (i.e. half of each dimension) (default on)", + " -r <int> : the period (in nr of frames) for reference frame updates (default = 5)", + " -s <0/1> : motion smoothing (1 activates motion smoothing, 0 turns it off - default value = 1)", + " -g <double>: motion smoothing gain, only used if smoothing is on (default value =0.75)", + NULL + }; + + cerr << "Usage: " << name << " [options] image_list.txt" << endl; + + const char **p = helpmsg; + + while (*p) + { + cerr << *p++ << endl; + } +} + +void parse_cmd_line(stringstream& cmdline, + const int argc, + const string& progname, + string& image_list_file_name, + int& nr_corners, + double& max_disparity, + int& motion_model_type, + bool& quarter_resolution, + unsigned int& reference_update_period, + bool& do_motion_smoothing, + double& motion_smoothing_gain + ); + +int main(int argc, char* argv[]) +{ + int nr_corners = DEFAULT_NR_CORNERS; + double max_disparity = DEFAULT_MAX_DISPARITY; + int motion_model_type = DEFAULT_MOTION_MODEL; + bool quarter_resolution = DEFAULT_QUARTER_RESOLUTION; + + unsigned int reference_update_period = DEFAULT_REFERENCE_UPDATE_PERIOD; + + bool do_motion_smoothing = DEFAULT_DO_MOTION_SMOOTHING; + double motion_smoothing_gain = DEFAULT_MOTION_SMOOTHING_GAIN; + const bool DEFAULT_USE_SMALLER_MATCHING_WINDOW = true; + + int default_nr_samples = DB_DEFAULT_NR_SAMPLES/5; + + bool use_smaller_matching_window = DEFAULT_USE_SMALLER_MATCHING_WINDOW; + + + bool linear_polish = DEFAULT_LINEAR_POLISH; + + if (argc < 2) { + usage(argv[0]); + exit(1); + } + + stringstream cmdline; + string progname(argv[0]); + string image_list_file_name; + +#if PROFILE + timeval ts1, ts2, ts3, ts4; +#endif + + // put the options and image list file name into the cmdline stringstream + for (int c = 1; c < argc; c++) + { + cmdline << argv[c] << " "; + } + + parse_cmd_line(cmdline, argc, progname, image_list_file_name, nr_corners, max_disparity, motion_model_type,quarter_resolution,reference_update_period,do_motion_smoothing,motion_smoothing_gain); + + ifstream in(image_list_file_name.c_str(),ios::in); + + if ( !in.is_open() ) + { + cerr << "Could not open file " << image_list_file_name << ". Exiting" << endl; + + return false; + } + + // feature-based image registration class: + db_FrameToReferenceRegistration reg; +// db_StabilizationSmoother stab_smoother; + + // input file name: + string file_name; + + // look-up tables for image warping: + float ** lut_x = NULL, **lut_y = NULL; + + // if the images are color, the input is saved in color_ref: + PgmImage color_ref(0,0); + + // image width, height: + int w,h; + + int frame_number = 0; + + while ( !in.eof() ) + { + getline(in,file_name); + + PgmImage ref(file_name); + + if ( ref.GetDataPointer() == NULL ) + { + cerr << "Could not open image" << file_name << ". Exiting." << endl; + return -1; + } + + cout << ref << endl; + + // color format: + int format = ref.GetFormat(); + + // is the input image color?: + bool color = format == PgmImage::PGM_BINARY_PIXMAP; + + w = ref.GetWidth(); + h = ref.GetHeight(); + + if ( !reg.Initialized() ) + { + reg.Init(w,h,motion_model_type,DEFAULT_MAX_ITERATIONS,linear_polish,quarter_resolution,DB_POINT_STANDARDDEV,reference_update_period,do_motion_smoothing,motion_smoothing_gain,default_nr_samples,DB_DEFAULT_CHUNK_SIZE,nr_corners,max_disparity,use_smaller_matching_window); + lut_x = db_AllocImage_f(w,h); + lut_y = db_AllocImage_f(w,h); + + } + + if ( color ) + { + // save the color image: + color_ref = ref; + } + + // make a grayscale image: + ref.ConvertToGray(); + + // compute the homography: + double H[9],Hinv[9]; + db_Identity3x3(Hinv); + db_Identity3x3(H); + + bool force_reference = false; + +#if PROFILE + gettimeofday(&ts1, NULL); +#endif + + reg.AddFrame(ref.GetRowPointers(),H,false,false); + cout << reg.profile_string << std::endl; + +#if PROFILE + gettimeofday(&ts2, NULL); + + double elapsedTime = (ts2.tv_sec - ts1.tv_sec)*1000.0; // sec to ms + elapsedTime += (ts2.tv_usec - ts1.tv_usec)/1000.0; // us to ms + cout <<"\nelapsedTime for Reg<< "<<elapsedTime<<" ms >>>>>>>>>>>>>\n"; +#endif + + if (frame_number == 0) + { + reg.UpdateReference(ref.GetRowPointers()); + } + + + //std::vector<int> &inlier_indices = reg.GetInliers(); + int *inlier_indices = reg.GetInliers(); + int num_inlier_indices = reg.GetNrInliers(); + printf("[%d] #Inliers = %d\n",frame_number,num_inlier_indices); + + reg.Get_H_dref_to_ins(H); + + db_GenerateHomographyLut(lut_x,lut_y,w,h,H); + + // create a new image and warp: + PgmImage warped(w,h,format); + +#if PROFILE + gettimeofday(&ts3, NULL); +#endif + + if ( color ) + db_WarpImageLutBilinear_rgb(color_ref.GetRowPointers(),warped.GetRowPointers(),w,h,lut_x,lut_y); + else + db_WarpImageLut_u(ref.GetRowPointers(),warped.GetRowPointers(),w,h,lut_x,lut_y,DB_WARP_FAST); + +#if PROFILE + gettimeofday(&ts4, NULL); + elapsedTime = (ts4.tv_sec - ts3.tv_sec)*1000.0; // sec to ms + elapsedTime += (ts4.tv_usec - ts3.tv_usec)/1000.0; // us to ms + cout <<"\nelapsedTime for Warp <<"<<elapsedTime<<" ms >>>>>>>>>>>>>\n"; +#endif + + // write aligned image: name is aligned_<corresponding input file name> + stringstream s; + s << "aligned_" << file_name; + warped.WritePGM(s.str()); + + /* + // Get the reference and inspection corners to write to file + double *ref_corners = reg.GetRefCorners(); + double *ins_corners = reg.GetInsCorners(); + + // get the image file name (without extension), so we + // can generate the corresponding filenames for matches + // and inliers + string file_name_root(file_name.substr(0,file_name.rfind("."))); + + // write matches to file + s.str(string("")); + s << "Matches_" << file_name_root << ".txt"; + + ofstream match_file(s.str().c_str()); + + for (int i = 0; i < reg.GetNrMatches(); i++) + { + match_file << ref_corners[3*i] << " " << ref_corners[3*i+1] << " " << ins_corners[3*i] << " " << ins_corners[3*i+1] << endl; + } + + match_file.close(); + + // write the inlier matches to file + s.str(string("")); + s << "InlierMatches_" << file_name_root << ".txt"; + + ofstream inlier_match_file(s.str().c_str()); + + for(int i=0; i<num_inlier_indices; i++) + { + int k = inlier_indices[i]; + inlier_match_file << ref_corners[3*k] << " " + << ref_corners[3*k+1] << " " + << ins_corners[3*k] << " " + << ins_corners[3*k+1] << endl; + } + inlier_match_file.close(); + */ + + frame_number++; + } + + if ( reg.Initialized() ) + { + db_FreeImage_f(lut_x,h); + db_FreeImage_f(lut_y,h); + } + + return 0; +} + +void parse_cmd_line(stringstream& cmdline, + const int argc, + const string& progname, + string& image_list_file_name, + int& nr_corners, + double& max_disparity, + int& motion_model_type, + bool& quarter_resolution, + unsigned int& reference_update_period, + bool& do_motion_smoothing, + double& motion_smoothing_gain) +{ + // for counting down the parsed arguments. + int c = argc; + + // a holder + string token; + + while (cmdline >> token) + { + --c; + + int pos = token.find("-"); + + if (pos == 0) + { + switch (token[1]) + { + case 'm': + --c; cmdline >> token; + if (token.compare("rt") == 0) + { + motion_model_type = DB_HOMOGRAPHY_TYPE_R_T; + } + else if (token.compare("a") == 0) + { + motion_model_type = DB_HOMOGRAPHY_TYPE_AFFINE; + } + else if (token.compare("p") == 0) + { + motion_model_type = DB_HOMOGRAPHY_TYPE_PROJECTIVE; + } + else + { + usage(progname); + exit(1); + } + break; + case 'c': + --c; cmdline >> nr_corners; + break; + case 'd': + --c; cmdline >> max_disparity; + break; + case 'q': + quarter_resolution = true; + break; + case 'r': + --c; cmdline >> reference_update_period; + break; + case 's': + --c; cmdline >> do_motion_smoothing; + break; + case 'g': + --c; cmdline >> motion_smoothing_gain; + break; + default: + cerr << progname << "illegal option " << token << endl; + case 'h': + usage(progname); + exit(1); + break; + } + } + else + { + if (c != 1) + { + usage(progname); + exit(1); + } + else + { + --c; + image_list_file_name = token; + } + } + } + + if (c != 0) + { + usage(progname); + exit(1); + } +} + |