Skip to content
Browse files

Added HSV_merge utility

This is a clone of the util that Trent is throwing around. This nice thing about my util is that it doesn't require me to setup osgeo and python bindings for gdal and other things.
  • Loading branch information...
1 parent 16555a8 commit 0fd16f0c87a537c80d44e2397f3db9a077118b15 Zack Moratto committed Apr 15, 2010
Showing with 116 additions and 0 deletions.
  1. +2 −0 configure.ac
  2. +6 −0 src/asp/Tools/Makefile.am
  3. +108 −0 src/asp/Tools/hsv_merge.cc
View
2 configure.ac
@@ -324,6 +324,7 @@ AX_APP(ALIGNDEM, [src/asp/Tools], yes, [VW_CARTOGRAPHY VW_INTEREST_POINT
AX_APP(GEODIFF, [src/asp/Tools], yes, [ISISIO VW BOOST])
AX_APP(DEMPROFILE, [src/asp/Tools], yes, [VW_CARTOGRAPHY VW])
AX_APP(PLATEORTHOPROJECT,[src/asp/Tools], no, [SESSIONS ISISIO VW_PLATE])
+AX_APP(HSVMERGE, [src/asp/Tools], yes, [VW_CARTOGRAPHY VW])
# These are here (instead of inside the APP macro where they belong)
# for backwards compatability with older versions of automake.
@@ -351,6 +352,7 @@ AM_CONDITIONAL(MAKE_APP_ALIGNDEM, [test "$MAKE_APP_ALIGNDEM" = "yes"])
AM_CONDITIONAL(MAKE_APP_GEODIFF, [test "$MAKE_APP_GEODIFF" = "yes"])
AM_CONDITIONAL(MAKE_APP_DEMPROFILE, [test "$MAKE_APP_DEMPROFILE" = "yes"])
AM_CONDITIONAL(MAKE_APP_PLATEORTHOPROJECT, [test "$MAKE_APP_PLATEORTHOPROJECT" = "yes"])
+AM_CONDITIONAL(MAKE_APP_HSVMERGE, [test "$MAKE_APP_HSVMERGE" = "yes"])
##################################################
# final processing
View
6 src/asp/Tools/Makefile.am
@@ -113,6 +113,12 @@ if MAKE_APP_PLATEORTHOPROJECT
plateorthoproject_LDADD = $(APP_PLATEORTHOPROJECT_LIBS)
endif
+if MAKE_APP_HSVMERGE
+ bin_PROGRAMS += hsv_merge
+ hsv_merge_SOURCES = hsv_merge.cc
+ hsv_merge_LDADD = $(APP_HSVMERGE_LIBS)
+endif
+
##############################################################################
# Tests #
##############################################################################
View
108 src/asp/Tools/hsv_merge.cc
@@ -0,0 +1,108 @@
+#include <boost/program_options.hpp>
+namespace po = boost::program_options;
+
+#include <boost/filesystem/path.hpp>
+namespace fs = boost::filesystem;
+
+#include <vw/Image.h>
+#include <vw/FileIO.h>
+#include <vw/Cartography/FileIO.h>
+#include <vw/Cartography/GeoReference.h>
+
+using namespace vw;
+
+// Functors
+template <class Arg1T, class Arg2T>
+struct ReplaceChannelFunc: public ReturnFixedType<Arg1T> {
+private:
+ int m_channel;
+public:
+ ReplaceChannelFunc( int const& channel ) : m_channel(channel) {}
+
+ inline Arg1T operator()( Arg1T const& arg1,
+ Arg2T const& arg2 ) const {
+ Arg1T t( arg1 );
+ t[m_channel] = arg2;
+ return t;
+ }
+};
+
+template <class Image1T, class Image2T>
+inline BinaryPerPixelView<Image1T, Image2T, ReplaceChannelFunc<typename Image1T::pixel_type, typename Image2T::pixel_type> >
+replace_channel( ImageViewBase<Image1T> const& image1,
+ int const& channel,
+ ImageViewBase<Image2T> const& image2 ) {
+ typedef ReplaceChannelFunc<typename Image1T::pixel_type, typename Image2T::pixel_type> func_type;
+ return BinaryPerPixelView<Image1T, Image2T, func_type >( image1.impl(), image2.impl(), func_type(channel));
+}
+
+// Standard Arguments
+struct Options {
+ std::string input_rgb, input_gray;
+ std::string output_file;
+};
+
+// Image Operations
+template <class ChannelT>
+void do_merge(Options const& opt) {
+ DiskImageView<PixelGray<ChannelT> > shaded_image( opt.input_gray );
+ DiskImageView<PixelRGB<ChannelT> > rgb_image( opt.input_rgb );
+ cartography::GeoReference georef;
+ cartography::read_georeference(georef, opt.input_rgb);
+
+ ImageViewRef<PixelRGB<ChannelT> > result = pixel_cast<PixelRGB<ChannelT> >(replace_channel(pixel_cast<PixelHSV<ChannelT> >(rgb_image),2,shaded_image));
+
+ cartography::write_georeferenced_image( opt.output_file, result, georef,
+ TerminalProgressCallback("tools.hsv_merge","Writing:") );
+}
+
+// Handle input
+int main( int argc, char *argv[] ) {
+
+ Options opt;
+
+ po::options_description desc("Description: Mimicks hsv_merge.py by Frank Warmerdam and Trent Hare. Use it to combine results from gdaldem.");
+ desc.add_options()
+ ("input-rgb", po::value<std::string>(&opt.input_rgb), "Explicitly specify the input rgb image.")
+ ("input-gray", po::value<std::string>(&opt.input_gray), "Explicitly specify the input gray image.")
+ ("output-file,o", po::value<std::string>(&opt.output_file), "Specify the output file.")
+ ("help,h", "Display this help message");
+ po::positional_options_description p;
+ p.add("input-rgb", 1 );
+ p.add("input-gray", 1 );
+
+ po::variables_map vm;
+ try {
+ po::store( po::command_line_parser( argc, argv ).options(desc).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 << desc << std::endl;
+ return 1;
+ }
+
+ if( vm.count("help") ||
+ (opt.input_rgb == "" && opt.input_gray == "" ) ) {
+ std::cout << desc << std::endl;
+ return 1;
+ }
+
+ try {
+ // Get the input RGB's type
+ DiskImageResource *rsrc = DiskImageResource::open(opt.input_rgb);
+ ChannelTypeEnum channel_type = rsrc->channel_type();
+ delete rsrc;
+
+ switch( channel_type ) {
+ case VW_CHANNEL_UINT8: do_merge<uint8>( opt ); break;
+ case VW_CHANNEL_INT16: do_merge<int16>( opt ); break;
+ case VW_CHANNEL_UINT16: do_merge<uint16>( opt ); break;
+ default: do_merge<float32>( opt );
+ }
+
+ } catch ( Exception& e ) {
+ std::cerr << "Error: " << e.what() << std::endl;
+ }
+ return 0;
+}

0 comments on commit 0fd16f0

Please sign in to comment.
Something went wrong with that request. Please try again.