From: <da...@us...> - 2007-07-23 17:30:35
|
Revision: 2318 http://hugin.svn.sourceforge.net/hugin/?rev=2318&view=rev Author: dangelo Date: 2007-07-23 10:30:27 -0700 (Mon, 23 Jul 2007) Log Message: ----------- added subdirectory with VIPS implementation of merge to HDR function Added Paths: ----------- hugin/trunk/src/vips/ hugin/trunk/src/vips/CMakeLists.txt hugin/trunk/src/vips/dispatch.c hugin/trunk/src/vips/hugin_mergehdr.cpp hugin/trunk/src/vips/im_mergehdr.cpp hugin/trunk/src/vips/img2vips.cpp hugin/trunk/src/vips/vipsc++.cc hugin/trunk/src/vips/vipsc++.h Added: hugin/trunk/src/vips/CMakeLists.txt =================================================================== --- hugin/trunk/src/vips/CMakeLists.txt (rev 0) +++ hugin/trunk/src/vips/CMakeLists.txt 2007-07-23 17:30:27 UTC (rev 2318) @@ -0,0 +1,39 @@ +# various command line utilities + +########### +# Libraries + +# the basic vips operations package +add_library(im_panorama SHARED dispatch.c im_mergehdr.cpp) +# rename library to .plg +SET_TARGET_PROPERTIES(im_panorama PROPERTIES SUFFIX ".plg") +# set special compiler flags. +SET_TARGET_PROPERTIES(im_panorama PROPERTIES COMPILE_FLAGS "${VIPS_CFLAGS_OTHER_STRING}") +# set special linker flags +SET_TARGET_PROPERTIES(im_panorama PROPERTIES LINK_FLAGS "${VIPS_LDFLAGS_OTHER_STRING}") +target_link_libraries(im_panorama ${VIPS_LIBRARIES}) + +# the C++ interface to it +add_library(huginvips STATIC vipsc++.cc) +SET_TARGET_PROPERTIES(huginvips PROPERTIES COMPILE_FLAGS "${VIPSCC_CFLAGS_OTHER_STRING}") +# set special linker flags +SET_TARGET_PROPERTIES(huginvips PROPERTIES LINK_FLAGS "${VIPSCC_LDFLAGS_OTHER_STRING}") +target_link_libraries(huginvips ${VIPSCC_LIBRARIES}) + +install(TARGETS im_panorama huginvips + DESTINATION lib) + + +############## +# Applications + +add_executable(img2vips img2vips.cpp) +target_link_libraries(img2vips hugincommon ${image_libs} ${VIPSCC_LIBRARIES}) + +add_executable(vips_mergehdr hugin_mergehdr.cpp) +target_link_libraries(vips_mergehdr huginvips ${image_libs} ${VIPSCC_LIBRARIES}) + +install(TARGETS img2vips vips_mergehdr + DESTINATION bin) + + Added: hugin/trunk/src/vips/dispatch.c =================================================================== --- hugin/trunk/src/vips/dispatch.c (rev 0) +++ hugin/trunk/src/vips/dispatch.c 2007-07-23 17:30:27 UTC (rev 2318) @@ -0,0 +1,98 @@ +/* Function dispatch tables for arithmetic. + * + * J. Cupitt, 8/4/93. + */ + +/* + + This file is part of VIPS. + + VIPS is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + */ + +/* + + These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk + + */ + +#include <config.h> +#include <vips/intl.h> + +#include <stdio.h> + +#include <vips/vips.h> + +int +im_mergehdr( IMAGE **in, IMAGE *out ); + +/* Image vector in, one out + */ +static im_arg_desc many_in_one_out[] = { + IM_INPUT_IMAGEVEC( "ins" ), + IM_OUTPUT_IMAGE( "out" ), +}; + +/* Call im_mergehdr() via arg vector. + */ +static int +mergehdr_vec( im_object *argv ) +{ +#define FUNCTION_NAME "im_mergehdr" + im_imagevec_object *ins_vec= (im_imagevec_object*) argv[0]; + IMAGE *out= (IMAGE*) argv[1]; + IMAGE **ins= IM_ARRAY( out, ins_vec-> n + 1, IMAGE* ); + int i; + + if( ! ins ) + return -1; + + for( i= 0; i < ins_vec-> n; ++i ) + ins[ i ]= ins_vec-> vec[ i ]; + + ins[ ins_vec-> n ]= NULL; + + return im_mergehdr( ins, out ); + +#undef FUNCTION_NAME +} + + +/* Description of im_mergehdr. + */ +static im_function mergehdr_desc = { + "hugin_mergehdr", /* Name */ + N_( "merge multiple photometrically aligned images to a hdr image" ), + IM_FN_PIO | IM_FN_PTOP, /* Flags */ + mergehdr_vec, /* Dispatch function */ + IM_NUMBER( many_in_one_out ), /* Size of arg list */ + many_in_one_out /* Arg list */ +}; + +/* Package up all these functions. + */ +static im_function *panorama_list[] = { + &mergehdr_desc, +}; + +/* Define the package_table symbol. This is what VIPS looks for when loading + * the plugin. + */ +G_MODULE_EXPORT im_package package_table = { + "panorama", /* Package name */ + IM_NUMBER( panorama_list ), /* Function list */ + panorama_list +}; Added: hugin/trunk/src/vips/hugin_mergehdr.cpp =================================================================== --- hugin/trunk/src/vips/hugin_mergehdr.cpp (rev 0) +++ hugin/trunk/src/vips/hugin_mergehdr.cpp 2007-07-23 17:30:27 UTC (rev 2318) @@ -0,0 +1,56 @@ +/* compile with + + g++ -g -Wall blend.cc `pkg-config vipsCC-7.11 --cflags --libs` + + */ + +#include <config.h> + +#include "vipsc++.h" + +#include <vips/vips> +#include <unistd.h> + + +using namespace vips; + +int +main (int argc, char **argv) +{ + try + { + // 1 is the output image, the other args are input + if (argc < 2) + throw VError ("usage: out in1, in2 ...\n"); + + std::vector<VImage> ins; + int nin = argc - 2; + int w=0, h=0; + for (int i = 0; i < nin; i++) { + VImage in (argv[i+2]); + int nw = in.Xoffset() + in.Xsize(); + int nh = in.Yoffset() + in.Ysize(); + if (w < nw) w = nw; + if (h < nh) h = nh; + ins.push_back( in ); + } + + // embed in the output image + for (int i = 0; i < nin; i++) { + ins[i] = ins[i].embed (0, + ins[i].Xoffset(), + ins[i].Yoffset(), + w, h); + } + + // perform the actual merge operations + VImage out = PVImage::mergehdr(ins); + out.write (argv[1]); + } + catch (VError err) + { + err.perror (argv[0]); + } + + return (0); +} Added: hugin/trunk/src/vips/im_mergehdr.cpp =================================================================== --- hugin/trunk/src/vips/im_mergehdr.cpp (rev 0) +++ hugin/trunk/src/vips/im_mergehdr.cpp 2007-07-23 17:30:27 UTC (rev 2318) @@ -0,0 +1,268 @@ +/* @(#) Merge a stack of images. The images should c + * @(#) + * @(#) + * @(#) + * @(#) int + * @(#) im_mergehdr( in, out ) + * @(#) IMAGE **in, *out; + * @(#) + * @(#) Returns 0 on success and -1 on error + * @(#) + * + * Copyright: 2007, Pablo d'Angelo + * Author: Pablo d'Angelo + * Written on: 04/30/2007 + * Modified on: + */ + +/* + + This file is part of VIPS. + + VIPS is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + */ + +/* + + These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk + + */ + +#include <config.h> +//#include <vips/intl.h> + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <assert.h> + +#include <vips/vips.h> +//#include <vips/internal.h> + +#include <vigra_ext/lut.h> +#include <vigra_ext/HDRUtils.h> + +static void +mergehdr_fn_vigra( float **in, + float *out, int n, void * params, void * nimg ) +{ + int i; + int nB; + int nImg; + float ** tptr; + int sz; + nB = ((int*)params)[0]; + nImg = ((int*)params)[1]; + + sz = n*nB; + +// fprintf(stderr, "*** %d images, %d bands, %d pixels\n", +// nImg, nB, n); + // for all pixels + + vigra_ext::ReduceToHDRFunctor<vigra::RGBValue<float> > reduce; + vigra::RGBValue<float> val; + for( i = 0; i < n; i++ ) { + int im; + int b; + + reduce.reset(); + // for all images + for( im = 0; im < nImg; im++) { + float *v = in[im]+i*nB; + val[0] = v[0]; + val[1] = v[1]; + val[2] = v[2]; + reduce(val, v[nB-1]); + } + val = reduce(); + for (b = 0; b < 3; b++) { + out[i*nB+b] = val[b]; + } + // set alpha/mask to one + out[i*nB+nB-1] = 1; + } +} + + +extern "C" { + +static float +max_component(float *f, int n) +{ + float max; + int i; + max = f[0]; + for (i=1; i < n; i++) + if (f[i] > max) { + max = f[i]; + } +} + +static void +mergehdr_fn( float **in, + float *out, int n, void * params, void * nimg ) +{ + int i; + int nB; + int nImg; + float ** tptr; + int sz; + nB = ((int*)params)[0]; + nImg = ((int*)params)[1]; + + sz = n*nB; + +// fprintf(stderr, "*** %d images, %d bands, %d pixels\n", +// nImg, nB, n); + // for all pixels + for( i = 0; i < n; i++ ) { + float result[3]; + float weight; + float maxComp,minComp; + float maxW, minW; + float maxValue[3]; + float minValue[3]; + int im; + int b; + result[0] = 0; result[1] = 0; result[2] = 0; + weight = 0; + + maxComp = DBL_MIN; + minComp = DBL_MAX; + maxW= 0; + minW= 1; + + // for all images + for( im = 0; im < nImg; im++) { + float w; + float nm; + float *v = in[im]+i*nB; + // normalized original gray value (0..1) + nm = v[nB-1]; + // a simple triangular weight function should also work ok + w = 0.5-fabs(nm - 0.5); + // update weight and pixel + weight += w; + for (b = 0; b < nB-1; b++) { + result[b] += v[b]; + } + // store minimum and maximum weight and pixel values + if (nm > maxW) { + maxW = w; + } + if ( w < minW) { + minW = w; + } + + float cmax = max_component(v, nB-1); + + if (cmax > maxComp) + { + maxComp = cmax; + for (b = 0; b < nB-1; b++) + maxValue[b] = v[b]; + } + if (cmax < minComp) + { + minComp = cmax; + for (b = 0; b < nB-1; b++) + minValue[b] = v[b]; + } + } + +// fprintf(stderr, "*** weight: %f, minW: %f, maxW: %f, res: %f %f %f\n", +// weight, minW, maxW, result[0], result[1], result[2]); + + double eps = 1e-7; + // heuristics to deal with over and underexposed images. + if (minW > (1.0-eps) && maxW > (1.0-eps)) { + // all pixels overexposed, just use smallest value + for (b = 0; b < nB-1; b++) + out[i*nB+b] = minValue[b]; + // set alpha/mask to one + out[i*nB+nB-1] = 1; + } else if (minW < eps && maxW < eps) { + // all pixels underexposed. use brightest value + for (b = 0; b < nB-1; b++) + out[i*nB+b] = maxValue[b]; +// return maxValue; + // set alpha/mask to one + out[i*nB+nB-1] = 1; + } else if (weight > 0) { + for (b = 0; b < nB-1; b++) { + out[i*nB+b] = result[b]/weight; + } + // set alpha/mask to one + out[i*nB+nB-1] = 1; + } else + for (b = 0; b < nB; b++) + out[i*nB+b] = 0; + +// fprintf(stderr, "output: %f %f %f %f\n", out[i*nB], +// out[i*nB+1], out[i*nB+2], out[i*nB+3]); + + } +} + + +int +im_mergehdr( IMAGE **in, IMAGE *out ) +{ + int nImg; + int nBands; + IMAGE ** tptr; + /* Check parameters. + */ + if (in[0] == NULL) { + im_error( "im_hdrmerge", "need at least one input image" ); + return( -1 ); + } + if( in[0]->BandFmt != IM_BANDFMT_FLOAT || + in[0]->Bands != 4 || + in[0]->Coding != IM_CODING_NONE ) { + im_error( "im_hdrmerge", "bad input images" ); + return( -1 ); + } + + nBands = in[0]->Bands; + nImg = 0; + for(tptr=in; *tptr; tptr++) + nImg++; + + /* Set fields in output image. + */ + if( im_cp_desc( out, in[0] ) ) + return( -1 ); + + // memory leak! + int *params = new int[2]; + params[0] = nBands; + params[1] = nImg; + + /* Process! We don't use either of the + * user parameters in this function, + * so leave them as NULL. + */ + if( im_wrapmany( in, out, + (im_wrapmany_fn) mergehdr_fn_vigra, + params, NULL ) ) + return( -1 ); + + return( 0 ); +} + +} // extern "C" Added: hugin/trunk/src/vips/img2vips.cpp =================================================================== --- hugin/trunk/src/vips/img2vips.cpp (rev 0) +++ hugin/trunk/src/vips/img2vips.cpp 2007-07-23 17:30:27 UTC (rev 2318) @@ -0,0 +1,66 @@ +/* compile with + + g++ -g -Wall blend.cc `pkg-config vipsCC-7.11 --cflags --libs` + + */ + +#include <vips/vips> +#include <vips/vips.h> + +#include <vigra/impex.hxx> + +#include <string> +#include <common/utils.h> +#include <unistd.h> + +using namespace vips; +using namespace std; +using namespace utils; +using namespace vigra; + +void +convert_file (const char *filename) +{ + ImageImportInfo inFile(filename); + int bands = inFile.numBands(); + if (inFile.getPixelType() == std::string("FLOAT") && bands == 4) + { + cout << "Reading " << filename << " ... " << std::flush; + BasicImage<TinyVector<float,4> > img(inFile.size()); + importImage(inFile, destImage(img)); + cout << " done. " << std::flush; + void *data = &(img(0,0)); + VImage viout (data, img.size().x, img.size().y, bands, VImage::FMTFLOAT); + // copy position field + viout.image()->Xoffset = inFile.getPosition().x; + viout.image()->Yoffset = inFile.getPosition().y; + std::string outfile(utils::stripExtension(filename)); + outfile += ".v"; + cout << " Writing " << outfile << std::endl; + viout.write (outfile.c_str()); + } else { + throw VError("Fatal error: unsupported input file format (only RGB float with alpha supported right now)"); + } +} + +int +main (int argc, char **argv) +{ + try + { + // 1 is the output image, the other args are input + if (argc < 1) + throw VError ("usage: in1 (in2) ...\n"); + + int nin = argc - 1; + for (int i = 0; i < nin; i++) { + convert_file (argv[i + 1]); + } + } + catch (VError err) + { + err.perror (argv[0]); + } + + return (0); +} Property changes on: hugin/trunk/src/vips/img2vips.cpp ___________________________________________________________________ Name: svn:executable + * Added: hugin/trunk/src/vips/vipsc++.cc =================================================================== --- hugin/trunk/src/vips/vipsc++.cc (rev 0) +++ hugin/trunk/src/vips/vipsc++.cc 2007-07-23 17:30:27 UTC (rev 2318) @@ -0,0 +1,129 @@ + +#include "vipsc++.h" + +// im_hdrmerge: merge photometrically aligned images into a HDR image + +using namespace vips; + + +// Copy constructor +//PVImage::PVImage( const VImage &a ) +// : VImage(a) +//{ +// +//} + +// this file automatically generated from +// VIPS library 7.12.1-Wed Jun 27 14:47:06 CEST 2007 +// hugin_mergehdr: merge multiple photometrically aligned images to a hdr image +VImage PVImage::mergehdr( std::vector<VImage> ins ) throw( VError ) +{ + VImage out; + + Vargv _vec( "hugin_mergehdr" ); + + ((im_imagevec_object*) _vec.data(0))->n = ins.size(); + ((im_imagevec_object*) _vec.data(0))->vec = new IMAGE *[ins.size()]; + for( unsigned int i = 0; i < ins.size(); i++ ) + ((im_imagevec_object*) _vec.data(0))->vec[i] = ins[i].image(); + _vec.data(1) = out.image(); + _vec.call(); + for( unsigned int i = 0; i < ins.size(); i++ ) + out._ref->addref( ins[i]._ref ); + + return( out ); +} + + +#if 0 +using namespace vips; + +class Vargv2 { + // Function we are args to + im_function *fn; + + // Base of object vector + im_object *base; + +public: + Vargv2( const char *name ); + ~Vargv2(); + + // Reference to element of base + im_object &data( int i = 0 ) { return( base[i] ); }; + + // Invoke function + void call(); +}; + +// Create a Vargv from a name +Vargv2::Vargv2( const char *name ) +{ + im_function *f = im_find_function( (char *) name ); + + if( !f ) + verror(); + + fn = f; + base = new im_object[fn->argc]; + if( im_allocate_vargv( fn, base ) ) { + delete[] base; + verror(); + } +} + + +// Destroy a Vargv +Vargv2::~Vargv2() +{ + // free any memory allocated for input vectors + // this is the stuff allocated in each function during _object* build, + // see vipsc++.cc + for( int i = 0; i < fn->argc; i++ ) { + im_type_desc *ty = fn->argv[i].desc; + + if( !(ty->flags & IM_TYPE_OUTPUT) ) { + if( strcmp( ty->type, IM_TYPE_IMAGEVEC ) == 0 || + strcmp( ty->type, IM_TYPE_DOUBLEVEC ) == 0 || + strcmp( ty->type, IM_TYPE_INTVEC ) == 0 ) { + // will work for doublevec and intvec too + im_imagevec_object *io = + (im_imagevec_object *) base[i]; + + if( io->vec ) { + delete[] io->vec; + io->vec = NULL; + } + } + } + } + + im_free_vargv( fn, base ); + delete[] base; +} + +// Call the function +void +Vargv2::call() +{ + if( fn->disp( base ) ) + verror(); +} + + +VImage vips_mergehdr( std::vector<VImage> ins ) throw( VError ) +{ + VImage out; + Vargv _vec( "im_mergehdr" ); + ((im_imagevec_object*) _vec.data(0))->n = ins.size(); + ((im_imagevec_object*) _vec.data(0))->vec = new IMAGE *[ins.size()]; + for( unsigned int i = 0; i < ins.size(); i++ ) + ((im_imagevec_object*) _vec.data(0))->vec[i] = ins[i].image(); + _vec.data(1) = out.image(); + _vec.call(); + for( unsigned int i = 0; i < ins.size(); i++ ) + out._ref->addref( ins[i]._ref ); + + return( out ); +} +#endif Added: hugin/trunk/src/vips/vipsc++.h =================================================================== --- hugin/trunk/src/vips/vipsc++.h (rev 0) +++ hugin/trunk/src/vips/vipsc++.h 2007-07-23 17:30:27 UTC (rev 2318) @@ -0,0 +1,20 @@ + +#ifndef __VIPS_PANO_CC +#define __VIPS_PANO_CC + +#include <vector> +#include <vips/vips> +#include <vips/vips.h> + +class PVImage : public vips::VImage +{ +public: +// PVImage() {}; + + // Copy constructor +// PVImage( const vips::VImage &a ); + + static VImage mergehdr( std::vector<vips::VImage> ) throw( vips::VError ); +}; + +#endif // __VIPS_PANO_CC This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |