Permalink
Browse files

Added Control Network Toolkit

This also includes the first new tool, reduce_match, to be copied from my Apollo Metric Processing repo.
  • Loading branch information...
Zack Moratto
Zack Moratto committed Jul 15, 2010
1 parent 8429f0d commit 97a01a6771b1cb25a3f5423b1def5608167543ab
Showing with 262 additions and 2 deletions.
  1. +3 −0 .gitignore
  2. +4 −1 configure.ac
  3. +41 −0 src/asp/ControlNetTK/Makefile.am
  4. +116 −0 src/asp/ControlNetTK/equalization.h
  5. +95 −0 src/asp/ControlNetTK/reduce_match.cc
  6. +3 −1 src/asp/Makefile.am
View
@@ -114,6 +114,9 @@ src/asp/PhotometryTK/tests/TestFullIteration
src/asp/PhotometryTK/tests/shadow_mask
src/asp/PhotometryTK/tests/*.ptk*
+# Control Network Toolkit
+src/asp/ControlNetTK/reduce_match
+
# Doc
docs/book/*aux
docs/book/*log
View
@@ -1,4 +1,4 @@
-dnl __BEGIN_LICENSE__
+'dnl __BEGIN_LICENSE__
dnl Copyright (C) 2006-2010 United States Government as represented by
dnl the Administrator of the National Aeronautics and Space Administration.
dnl All Rights Reserved.
@@ -370,6 +370,7 @@ AX_APP(HSVMERGE, [src/asp/Tools], yes, [VW_CARTOGRAPHY VW])
# Toolkits (like module, but doesn't build a library)
AX_MODULE(PHOTOMETRYTK, [src/asp/PhotometryTK], [libaspPhotometryTK.la], no, [RABBITMQ_C PROTOBUF VW_PLATE], [BOOST])
+AX_MODULE(CONTROLNETTK, [src/asp/ControlNetTK], [], no, [VW_BUNDLEADJUSTMENT], [BOOST])
# These are here (instead of inside the APP macro where they belong)
# for backwards compatability with older versions of automake.
@@ -379,6 +380,7 @@ AM_CONDITIONAL(MAKE_MODULE_SPICEIO, [test "$MAKE_MODULE_SPICEIO" = "yes"])
AM_CONDITIONAL(MAKE_MODULE_SESSIONS, [test "$MAKE_MODULE_SESSIONS" = "yes"])
AM_CONDITIONAL(MAKE_MODULE_MPI, [test "$MAKE_MODULE_MPI" = "yes"])
AM_CONDITIONAL(MAKE_MODULE_PHOTOMETRYTK, [test "$MAKE_MODULE_PHOTOMETRYTK" = "yes"])
+AM_CONDITIONAL(MAKE_MODULE_CONTROLNETTK, [test "$MAKE_MODULE_CONTROLNETTK" = "yes"])
AM_CONDITIONAL(MAKE_APP_STEREO, [test "$MAKE_APP_STEREO" = "yes"])
AM_CONDITIONAL(MAKE_APP_STEREOGUI, [test "$MAKE_APP_STEREOGUI" = "yes"])
@@ -446,6 +448,7 @@ AC_CONFIG_FILES([ \
src/asp/Tools/Makefile \
src/asp/PhotometryTK/Makefile \
src/asp/PhotometryTK/tests/Makefile \
+ src/asp/ControlNetTK/Makefile \
])
AC_OUTPUT
@@ -0,0 +1,41 @@
+# __BEGIN_LICENSE__
+# Copyright (C) 2006-2010 United States Government as represented by
+# the Administrator of the National Aeronautics and Space Administration.
+# All Rights Reserved.
+# __END_LICENSE__
+
+
+#########################################################################
+# sources
+#########################################################################
+
+if MAKE_MODULE_CONTROLNETTK
+
+include_HEADERS =
+
+#libaspControlNetTK_la_LIBADD = @MODULE_PHOTOMETRYTK_LIBS@
+#lib_LTLIBRARIES = libaspControlNetTK.la
+
+if ENABLE_EXCEPTIONS
+
+CNETTK_LOCAL_LIBS = @MODULE_CONTROLNETTK_LIBS@
+
+reduce_match_SOURCES = reduce_match.cc
+reduce_match_LDADD = $(CNETTK_LOCAL_LIBS)
+
+bin_PROGRAMS = reduce_match
+
+endif
+
+endif
+
+#########################################################################
+# general
+#########################################################################
+
+AM_CPPFLAGS = @ASP_CPPFLAGS@
+AM_LDFLAGS = @ASP_LDFLAGS@
+
+includedir = $(prefix)/include/asp/ControlNetTK
+
+include $(top_srcdir)/config/rules.mak
@@ -0,0 +1,116 @@
+// This will knock off weak points where we already have a lot of
+// points. This is hopefully to produce a better distribution.
+#ifndef __EQUALIZATION_H__
+#define __EQUALIZATION_H__
+
+#include <vw/InterestPoint/InterestData.h>
+#include <vector>
+
+// Algorithm for removing interest points
+inline void remove_max( std::vector<std::vector<InterestPoint> > &b_ip1,
+ std::vector<std::vector<InterestPoint> > &b_ip2 ) {
+ int max_index = 0;
+ int max_count = 0;
+ for ( unsigned i = 0; i < b_ip1.size(); i++ )
+ if (b_ip1[i].size() > max_count ) {
+ max_count = b_ip1[i].size();
+ max_index = i;
+ }
+
+ int point_idx = 0;
+ int point_interest = -200000;
+ for ( unsigned i = 0; i < b_ip1[max_index].size(); i++ ) {
+ if ( b_ip1[max_index][i].interest > point_interest ) {
+ point_interest = b_ip1[max_index][i].interest;
+ point_idx = i;
+ }
+ }
+
+ // Okay dokey making my remove
+ b_ip1[max_index].erase( b_ip1[max_index].begin() + point_idx );
+ b_ip2[max_index].erase( b_ip2[max_index].begin() + point_idx );
+}
+
+// divide block
+std::vector<BBox2i> divide_block( BBox2i const& orginal,
+ int div_x, int div_y ) {
+ std::vector<BBox2i> bboxes;
+ Vector2 min = orginal.min();
+
+ Vector2 lmin, lmax;
+
+ for ( unsigned i = 0; i < div_x; i++ ) {
+ lmin.x() = min.x() + i*orginal.width()/float(div_x);
+ if ( i == div_x -1 )
+ lmax.x() = orginal.max().x();
+ else
+ lmax.x() = min.x() + (i+1)*orginal.width()/float(div_x);
+ for ( unsigned j = 0; j < div_y; j++ ) {
+ lmin.y() = min.y() + j*orginal.height()/float(div_y);
+ if ( j == div_y-1 )
+ lmax.y() = orginal.max().y();
+ else
+ lmax.y() = min.y() + (j+1)*orginal.height()/float(div_y);
+
+ bboxes.push_back( BBox2i( lmin, lmax ) );
+ }
+ }
+
+ return bboxes;
+}
+
+void equalization( std::vector<vw::ip::InterestPoint>& l_ip,
+ std::vector<vw::ip::InterestPoint>& r_ip,
+ int max_points ) {
+
+ // Checking for early exit condition
+ if ( l_ip.size() <= max_points ) {
+ std::cout << "\t> Exiting early, found less than " << max_points << " matches.\n";
+ return;
+ }
+
+ //TerminalProgressCallback progress;
+ //progress.report_progress(0);
+
+ // Reducing to an even distribution
+ std::cout << "Building Bounding Boxes:\n";
+ BBox2i total_bbox;
+ for ( unsigned i = 0; i < l_ip.size(); ++i )
+ total_bbox.grow( Vector2( l_ip[i].x, l_ip[i].y ) );
+ std::vector<BBox2i> bboxes = divide_block( total_bbox, 5, 5 );
+ std::vector<std::vector<InterestPoint> > b_ip1;
+ std::vector<std::vector<InterestPoint> > b_ip2;
+ b_ip1.resize( bboxes.size() );
+ b_ip2.resize( bboxes.size() );
+ for ( unsigned b = 0; b < bboxes.size(); ++b )
+ for ( unsigned i = 0; i < l_ip.size(); ++i )
+ if ( bboxes[b].contains( Vector2( l_ip[i].x, l_ip[i].y ) ) ) {
+ b_ip1[b].push_back( l_ip[i] );
+ b_ip2[b].push_back( r_ip[i] );
+ }
+
+ // Finding how many points there are
+ int count = 0;
+ for ( unsigned b = 0; b < b_ip1.size(); ++b )
+ count += b_ip1[b].size();
+
+ // Remove until less that max
+ //int diff = count - max_points;
+ while ( count > max_points ) {
+ //progress.report_progress(1-float(count-max_points)/float(diff));
+ remove_max( b_ip1, b_ip2 );
+ count--;
+ }
+ //progress.report_finished();
+
+ // Reorganize back into correct form
+ l_ip.clear();
+ r_ip.clear();
+ for ( unsigned b = 0; b < b_ip1.size(); ++b )
+ for ( unsigned i = 0; i < b_ip1[b].size(); ++i ) {
+ l_ip.push_back( b_ip1[b][i] );
+ r_ip.push_back( b_ip2[b][i] );
+ }
+}
+
+#endif//__EQUALIZATION_H__
@@ -0,0 +1,95 @@
+// std header
+#include <stdlib.h>
+#include <iostream>
+#include <vector>
+
+// Boost
+#include <boost/program_options.hpp>
+namespace po = boost::program_options;
+#include <boost/filesystem/operations.hpp>
+namespace fs = boost::filesystem;
+
+// Vision Workbench
+#include <vw/Math.h>
+#include <vw/InterestPoint/InterestData.h>
+#include <vw/InterestPoint/Matcher.h>
+using namespace vw;
+using namespace vw::ip;
+
+// From this project
+#include "equalization.h"
+
+int main( int argc, char* argv[] ) {
+
+ std::vector<std::string> match_files;
+ int max_points, min_points;
+
+ po::options_description general_options("Options");
+ general_options.add_options()
+ ("max-pts,m",po::value<int>(&max_points)->default_value(100),"Max points a pair can have. If it execeeds we trim.")
+ ("min-pts,n",po::value<int>(&min_points)->default_value(10),"Minimum points a pair is required to have. Delete if fails this.")
+ ("help,h", "Display this help message");
+
+ po::options_description hidden_options("");
+ hidden_options.add_options()
+ ("input-files", po::value<std::vector<std::string> >(&match_files));
+
+ po::options_description options("Allowed Options");
+ options.add(general_options).add(hidden_options);
+
+ po::positional_options_description p;
+ p.add("input-files", -1);
+
+ std::ostringstream usage;
+ usage << "Usage: " << argv[0] << " [options] <match-files> ...\n\n";
+ usage << general_options << std::endl;
+
+ po::variables_map vm;
+ try {
+ po::store( po::command_line_parser( argc, argv ).options(options).positional(p).run(), vm );
+ po::notify( vm );
+ } catch ( po::error &e ) {
+ std::cout << "An error occured while parsing command line arguments.\n";
+ std::cout << "\t" << e.what() << "\n\n";
+ std::cout << usage.str();
+ return 1;
+ }
+
+ if( vm.count("help") ) {
+ vw_out() << usage.str();
+ return 1;
+ }
+
+ if( match_files.size() < 1 ) {
+ vw_out() << "Error: Must specify at least one input file!" << std::endl << std::endl;
+ vw_out() << usage.str();
+ return 1;
+ }
+
+ for ( unsigned i = 0; i < match_files.size(); i++ ) {
+ vw_out() << "Attempting to load: " << match_files[i] << "\n";
+
+ std::vector<InterestPoint> ip1, ip2;
+ read_binary_match_file( match_files[i], ip1, ip2 );
+
+ vw_out() << "\t>Found " << ip1.size() << " matches.\n\n";
+
+ if ( ip1.size() < min_points ) {
+ std::cout << "Match failed to have enough pairs.\n";
+ fs::remove( match_files[i] );
+ continue;
+ }
+
+ vw_out() << "Performing equalization\n";
+ equalization( ip1,
+ ip2, max_points );
+ vw_out() << "\t> Reduced matches to " << ip1.size() << " pairs.\n";
+
+ // Finally write back out the reduced match file
+ vw_out() << "Writing back out\n";
+ write_binary_match_file( match_files[i], ip1, ip2 );
+ }
+
+ vw_out() << "Finished!\n";
+ return 0;
+}
View
@@ -27,12 +27,14 @@ mpi_subdirs = MPI
photometry_subdirs = PhotometryTK
+controlnet_subdirs = ControlNetTK
+
include_HEADERS = $(core_headers) $(spiceio_headers) \
$(isisio_headers) $(sessions_headers) asp_config.h
SUBDIRS = $(core_subdirs) $(spiceio_subdirs) $(isisio_subdirs) \
$(sessions_subdirs) $(tools_subdirs) $(mpi_subdirs) \
- $(photometry_subdirs)
+ $(photometry_subdirs) $(controlnet_subdirs)
CLEANFILES = asp_config.h.pre.in~

0 comments on commit 97a01a6

Please sign in to comment.