summaryrefslogtreecommitdiffstats
path: root/jni/feature_stab/src/dbregtest
diff options
context:
space:
mode:
authorWei-Ta Chen <weita@google.com>2011-06-14 16:53:04 -0700
committerWei-Ta Chen <weita@google.com>2011-07-04 17:39:34 +0800
commite295e32b68cf04f0d99138bf4a6d25555f3aef99 (patch)
tree5bf19e321f357789344c0890f67f7dfa68aa8682 /jni/feature_stab/src/dbregtest
parent95fd7f77171155a087b685ca405ac3891332f638 (diff)
downloadLegacyCamera-e295e32b68cf04f0d99138bf4a6d25555f3aef99.zip
LegacyCamera-e295e32b68cf04f0d99138bf4a6d25555f3aef99.tar.gz
LegacyCamera-e295e32b68cf04f0d99138bf4a6d25555f3aef99.tar.bz2
Check in mosaic stitching codes - the native part
Updated to v4-3-2. Bug: 4990566 Change-Id: I779dcc930323353964572918510f1492828c4db4
Diffstat (limited to 'jni/feature_stab/src/dbregtest')
-rw-r--r--jni/feature_stab/src/dbregtest/PgmImage.cpp260
-rw-r--r--jni/feature_stab/src/dbregtest/PgmImage.h95
-rw-r--r--jni/feature_stab/src/dbregtest/dbregtest.cpp399
-rw-r--r--jni/feature_stab/src/dbregtest/stdafx.cpp24
-rw-r--r--jni/feature_stab/src/dbregtest/stdafx.h28
-rw-r--r--jni/feature_stab/src/dbregtest/targetver.h29
6 files changed, 835 insertions, 0 deletions
diff --git a/jni/feature_stab/src/dbregtest/PgmImage.cpp b/jni/feature_stab/src/dbregtest/PgmImage.cpp
new file mode 100644
index 0000000..0891cfd
--- /dev/null
+++ b/jni/feature_stab/src/dbregtest/PgmImage.cpp
@@ -0,0 +1,260 @@
+/*
+ * 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.
+ */
+
+#include "PgmImage.h"
+#include <cassert>
+
+using namespace std;
+
+PgmImage::PgmImage(std::string filename) :
+m_w(0),m_h(0),m_colors(255),m_format(PGM_BINARY_GRAYMAP),m_over_allocation(256)
+{
+ if ( !ReadPGM(filename) )
+ return;
+}
+
+PgmImage::PgmImage(int w, int h, int format) :
+m_colors(255),m_w(w),m_h(h),m_format(format),m_over_allocation(256)
+{
+ SetFormat(format);
+}
+
+PgmImage::PgmImage(unsigned char *data, int w, int h) :
+m_colors(255),m_w(w),m_h(h),m_format(PGM_BINARY_GRAYMAP),m_over_allocation(256)
+{
+ SetData(data);
+}
+
+PgmImage::PgmImage(std::vector<unsigned char> &data, int w, int h) :
+m_colors(255),m_w(w),m_h(h),m_format(PGM_BINARY_GRAYMAP),m_over_allocation(256)
+{
+ if ( data.size() == w*h )
+ SetData(&data[0]);
+ else
+ //throw (std::exception("Size of data is not w*h."));
+ throw (std::exception());
+}
+
+PgmImage::PgmImage(const PgmImage &im) :
+m_colors(255),m_w(0),m_h(0),m_format(PGM_BINARY_GRAYMAP),m_over_allocation(256)
+{
+ DeepCopy(im, *this);
+}
+
+PgmImage& PgmImage::operator= (const PgmImage &im)
+{
+ if (this == &im) return *this;
+ DeepCopy(im, *this);
+ return *this;
+}
+
+void PgmImage::DeepCopy(const PgmImage& src, PgmImage& dst)
+{
+ dst.m_data = src.m_data;
+
+ // PGM data
+ dst.m_w = src.m_w;
+ dst.m_h = src.m_h;
+ dst.m_format = src.m_format;
+ dst.m_colors = src.m_colors;
+
+ dst.m_comment = src.m_comment;
+ SetupRowPointers();
+}
+
+PgmImage::~PgmImage()
+{
+
+}
+
+void PgmImage::SetFormat(int format)
+{
+ m_format = format;
+
+ switch (format)
+ {
+ case PGM_BINARY_GRAYMAP:
+ m_data.resize(m_w*m_h+m_over_allocation);
+ break;
+ case PGM_BINARY_PIXMAP:
+ m_data.resize(m_w*m_h*3+m_over_allocation);
+ break;
+ default:
+ return;
+ break;
+ }
+ SetupRowPointers();
+}
+
+void PgmImage::SetData(const unsigned char * data)
+{
+ m_data.resize(m_w*m_h+m_over_allocation);
+ memcpy(&m_data[0],data,m_w*m_h);
+ SetupRowPointers();
+}
+
+bool PgmImage::ReadPGM(const std::string filename)
+{
+ ifstream in(filename.c_str(),std::ios::in | std::ios::binary);
+ if ( !in.is_open() )
+ return false;
+
+ // read the header:
+ string format_header,size_header,colors_header;
+
+ getline(in,format_header);
+ stringstream s;
+ s << format_header;
+
+ s >> format_header >> m_w >> m_h >> m_colors;
+ s.clear();
+
+ if ( m_w == 0 )
+ {
+ while ( in.peek() == '#' )
+ getline(in,m_comment);
+
+ getline(in,size_header);
+
+ while ( in.peek() == '#' )
+ getline(in,m_comment);
+
+ m_colors = 0;
+
+ // parse header
+ s << size_header;
+ s >> m_w >> m_h >> m_colors;
+ s.clear();
+
+ if ( m_colors == 0 )
+ {
+ getline(in,colors_header);
+ s << colors_header;
+ s >> m_colors;
+ }
+ }
+
+ if ( format_header == "P5" )
+ m_format = PGM_BINARY_GRAYMAP;
+ else if (format_header == "P6" )
+ m_format = PGM_BINARY_PIXMAP;
+ else
+ m_format = PGM_FORMAT_INVALID;
+
+ switch(m_format)
+ {
+ case(PGM_BINARY_GRAYMAP):
+ m_data.resize(m_w*m_h+m_over_allocation);
+ in.read((char *)(&m_data[0]),m_data.size());
+ break;
+ case(PGM_BINARY_PIXMAP):
+ m_data.resize(m_w*m_h*3+m_over_allocation);
+ in.read((char *)(&m_data[0]),m_data.size());
+ break;
+ default:
+ return false;
+ break;
+ }
+ in.close();
+
+ SetupRowPointers();
+
+ return true;
+}
+
+bool PgmImage::WritePGM(const std::string filename, const std::string comment)
+{
+ string format_header;
+
+ switch(m_format)
+ {
+ case PGM_BINARY_GRAYMAP:
+ format_header = "P5\n";
+ break;
+ case PGM_BINARY_PIXMAP:
+ format_header = "P6\n";
+ break;
+ default:
+ return false;
+ break;
+ }
+
+ ofstream out(filename.c_str(),std::ios::out |ios::binary);
+ out << format_header << "# " << comment << '\n' << m_w << " " << m_h << '\n' << m_colors << '\n';
+
+ out.write((char *)(&m_data[0]), m_data.size());
+
+ out.close();
+
+ return true;
+}
+
+void PgmImage::SetupRowPointers()
+{
+ int i;
+ m_rows.resize(m_h);
+
+ switch (m_format)
+ {
+ case PGM_BINARY_GRAYMAP:
+ for(i=0;i<m_h;i++)
+ {
+ m_rows[i]=&m_data[m_w*i];
+ }
+ break;
+ case PGM_BINARY_PIXMAP:
+ for(i=0;i<m_h;i++)
+ {
+ m_rows[i]=&m_data[(m_w*3)*i];
+ }
+ break;
+ }
+}
+
+void PgmImage::ConvertToGray()
+{
+ if ( m_format != PGM_BINARY_PIXMAP ) return;
+
+ // Y = 0.3*R + 0.59*G + 0.11*B;
+ for ( int i = 0; i < m_w*m_h; ++i )
+ m_data[i] = (unsigned char)(0.3*m_data[3*i]+0.59*m_data[3*i+1]+0.11*m_data[3*i+2]);
+
+ m_data.resize(m_w*m_h+m_over_allocation);
+ m_format = PGM_BINARY_GRAYMAP;
+
+ SetupRowPointers();
+}
+
+std::ostream& operator<< (std::ostream& o, const PgmImage& im)
+{
+ o << "PGM Image Info:\n";
+ o << "Size: " << im.m_w << " x " << im.m_h << "\n";
+ o << "Comment: " << im.m_comment << "\n";
+ switch (im.m_format)
+ {
+ case PgmImage::PGM_BINARY_PIXMAP:
+ o << "Format: RGB binary pixmap";
+ break;
+ case PgmImage::PGM_BINARY_GRAYMAP:
+ o << "Format: PPM binary graymap";
+ break;
+ default:
+ o << "Format: Invalid";
+ break;
+ }
+ o << endl;
+ return o;
+}
diff --git a/jni/feature_stab/src/dbregtest/PgmImage.h b/jni/feature_stab/src/dbregtest/PgmImage.h
new file mode 100644
index 0000000..d4d1eeb
--- /dev/null
+++ b/jni/feature_stab/src/dbregtest/PgmImage.h
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <vector>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <memory.h>
+
+/*!
+ * Simple class to manipulate PGM/PPM images. Not suitable for heavy lifting.
+ */
+class PgmImage
+{
+ friend std::ostream& operator<< (std::ostream& o, const PgmImage& im);
+public:
+ enum {PGM_BINARY_GRAYMAP,PGM_BINARY_PIXMAP,PGM_FORMAT_INVALID};
+ /*!
+ * Constructor from a PGM file name.
+ */
+ PgmImage(std::string filename);
+ /*!
+ * Constructor to allocate an image of given size and type.
+ */
+ PgmImage(int w, int h, int format = PGM_BINARY_GRAYMAP);
+ /*!
+ * Constructor to allocate an image of given size and copy the data in.
+ */
+ PgmImage(unsigned char *data, int w, int h);
+ /*!
+ * Constructor to allocate an image of given size and copy the data in.
+ */
+ PgmImage(std::vector<unsigned char> &data, int w, int h);
+
+ PgmImage(const PgmImage &im);
+
+ PgmImage& operator= (const PgmImage &im);
+ ~PgmImage();
+
+ int GetHeight() const { return m_h; }
+ int GetWidth() const { return m_w; }
+
+ //! Copy pixels from data pointer
+ void SetData(const unsigned char * data);
+
+ //! Get a data pointer to unaligned memory area
+ unsigned char * GetDataPointer() { if ( m_data.size() > 0 ) return &m_data[0]; else return NULL; }
+ unsigned char ** GetRowPointers() { if ( m_rows.size() == m_h ) return &m_rows[0]; else return NULL; }
+
+ //! Read a PGM file from disk
+ bool ReadPGM(const std::string filename);
+ //! Write a PGM file to disk
+ bool WritePGM(const std::string filename, const std::string comment="");
+
+ //! Get image format (returns PGM_BINARY_GRAYMAP, PGM_BINARY_PIXMAP or PGM_FORMAT_INVALID)
+ int GetFormat() const { return m_format; }
+
+ //! Set image format (returns PGM_BINARY_GRAYMAP, PGM_BINARY_PIXMAP). Image data becomes invalid.
+ void SetFormat(int format);
+
+ //! If the image is PGM_BINARY_PIXMAP, convert it to PGM_BINARY_GRAYMAP via Y = 0.3*R + 0.59*G + 0.11*B.
+ void ConvertToGray();
+protected:
+ // Generic functions:
+ void DeepCopy(const PgmImage& src, PgmImage& dst);
+ void SetupRowPointers();
+
+ // PGM data
+ int m_w;
+ int m_h;
+ int m_format;
+ int m_colors;
+ int m_over_allocation;
+ std::vector<unsigned char> m_data;
+ std::string m_comment;
+
+ std::vector<unsigned char *> m_rows;
+};
+
+std::ostream& operator<< (std::ostream& o, const PgmImage& im);
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);
+ }
+}
+
diff --git a/jni/feature_stab/src/dbregtest/stdafx.cpp b/jni/feature_stab/src/dbregtest/stdafx.cpp
new file mode 100644
index 0000000..0c703e2
--- /dev/null
+++ b/jni/feature_stab/src/dbregtest/stdafx.cpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+// stdafx.cpp : source file that includes just the standard includes
+// dbregtest.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/jni/feature_stab/src/dbregtest/stdafx.h b/jni/feature_stab/src/dbregtest/stdafx.h
new file mode 100644
index 0000000..9bc06ea
--- /dev/null
+++ b/jni/feature_stab/src/dbregtest/stdafx.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#include "targetver.h"
+
+#include <stdio.h>
+
+// TODO: reference additional headers your program requires here
diff --git a/jni/feature_stab/src/dbregtest/targetver.h b/jni/feature_stab/src/dbregtest/targetver.h
new file mode 100644
index 0000000..9272b0d
--- /dev/null
+++ b/jni/feature_stab/src/dbregtest/targetver.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+// The following macros define the minimum required platform. The minimum required platform
+// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
+// your application. The macros work by enabling all features available on platform versions up to and
+// including the version specified.
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
+#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.
+#endif
+