From: <bru...@us...> - 2008-07-23 22:08:07
|
Revision: 3223 http://hugin.svn.sourceforge.net/hugin/?rev=3223&view=rev Author: brunopostle Date: 2008-07-23 22:08:03 +0000 (Wed, 23 Jul 2008) Log Message: ----------- Update ChangeLog for 2.5.0 release. Pablo seems to have a different svn2cl... Modified Paths: -------------- autopano-sift-C/trunk/ChangeLog autopano-sift-C/trunk/README.1ST Modified: autopano-sift-C/trunk/ChangeLog =================================================================== --- autopano-sift-C/trunk/ChangeLog 2008-07-23 21:58:36 UTC (rev 3222) +++ autopano-sift-C/trunk/ChangeLog 2008-07-23 22:08:03 UTC (rev 3223) @@ -1,70 +1,453 @@ -2008-02-01 Pablo d'Angelo +2008-04-24 21:00 brunopostle - * MatchKeys.c: Corrected possible buffer overflow when many images - are used. + * APSCpp/CMakeLists.txt, CMakeLists.txt: Don't try and install a + file called /usr/README -2008-01-14 Pablo d'Angelo - - * CMakeLists.txt, CMakeModules: Added CMake based build system, only - tested on windows so far. +2008-03-09 18:39 tksharpless - * *.c *.h: fix source for compilation with windows (mainly adding - a lot of explicit casts). + * APSCpp/APSCpp_main.c: APSCpp/APSCpp_main.c replace <ctime> with + <time.h>; fix Time_t casting error. -2008-01-02 Pablo d'Angelo +2008-03-08 22:04 tksharpless - * Makefile, AutoPanoSift.h, DisplayImage.c: build against pano13 - by default. + * APSCpp/ANNkd_wrap.cpp: ooops, forgot to add ANNkd_wrap.cpp. Here + 'tis -2007-04-18 Alexandre Duret-Lutz <ad...@gn...> +2008-03-08 21:31 tksharpless - * LoweDetector.c (LoweFeatureDetector_DetectFeaturesDownscaled): Do - not erase img here, as it usually belong to the octave... - * ScaleSpace.c (OctavePyramid_BuildOctaves): ... erase it here, - if it doesn't. - (DScaleSpace_delete): No point in cleaning memory before freeing it. - * DisplayImage.c (DisplayImage_delete): Free self. - * KeypointXML.c (KeypointXMLList_new0): Supply the keypoints' - destructor. - * AutoPano.c (main): Free the result of Component_ToString. - (WritePTOFile): Free the imageNameTab hash and resolutions list. - (RefineKeypoints): Delete the patches after they have been used. - (ExtractKeypoints): Delete the temporary feature detector instance. - * MatchKeys.c (MultiMatch_new0): Do not allocate - filteredMatchSets and globalKeyKD, it's always done later before - they are filled. + * APSCpp/APSCpp.c, APSCpp/APSCpp.cpp, APSCpp/APSCpp_main.c, + APSCpp/APSCpp_main.cpp, APSCpp/CMakeLists.txt: Repackaged ANN + kd-tree in a C - callable C++ wrapper. + Replaced the .cpp versions of APSCpp and APSCpp_main witn .c + versions. + This lets Nowozin's code be compiled as C++ on Windows and as C + elsewhere -- the only way that seems to work. + Adjusted APSCpp/CMakeLists.txt accordingly. +2008-03-08 16:16 tksharpless -2007-04-16 Alexandre Duret-Lutz <ad...@gn...> + * APSCpp/APSCpp.cpp, APSCpp/APSCpp_main.cpp, AutoPanoSift.h, + Utils.c: fixes for C++ compile errors on Linux - * ScaleSpace.c (DScaleSpace_GenerateKeypointSingle): Use calloc() - instead of malloc() to allocate the orientation histogram as all - bins may not get filled later (and they get filled with "+="). - (Keypoint_CreateVector): Use calloc() instead of malloc() to - allocate the feature vector. From what I understand, - DScaleSpace_CreateDescriptors() may not fill it entirely and - the normalization of DScaleSpace_CapAndNormalizeFV() needs 0.0. - * DisplayImage.c (DisplayImage_Carve): Initialize the result image - with code duplicated from DisplayImage_ScaleSimple(), otherwise - result->dest is NULL and the code crashes. - * MatchKeys.c (MultiMatch_TwoPatchMatch): - MultiMatch_LoadKeysetsFromMemory() acquires the keysets, so do not - free this list afterwards. - (MultiMatch_LoadKeysets): Error out if keypoints could not be read. - * ImageMatchModel.c (MatchDriver_FilterMatchSet): Erase the - returned model from the list of models, so it doesn't get freed. - (ImageMatchModel_FittingErrorSingle): Delete the X and Xexptected - matrices. - * KeypointXML.c (KeypointN_clone): Allocate the descriptor - for the instance being created, not the one being copied. - * BondBall.c (BondBall_ToString): Do not output all decimals or - it may overflow the allocated string. - (BondBall_StretchImages): Print xs as an integer. - * Transform.c (AffineTransform2D_BuildTransformFromTwoPairs): Return - NULL if A2 and B2 are equal, do not abort. ImageMatchModel_FitModel() - expects this. - * Makefile ($(OBJECTS)): All objects depend on AutoPanoSift.h. - * AutoPano.c (RefineKeypoints): Delete old images. - * LoweDetector.c (LoweFeatureDetector_DetectFeaturesDownscaled): - Delete the imagemap. +2008-03-08 14:55 tksharpless + * APSCpp/APSCpp.cpp: Changed match acceptance policy to eliminate + duplicate control points -- seems to give better alignments, and + slighly faster too. + +2008-03-07 18:21 tksharpless + + * APSCpp/ANN, APSCpp/ANN/ANN.cpp, APSCpp/ANN/ANN.h, + APSCpp/ANN/ANNperf.h, APSCpp/ANN/ANNx.h, + APSCpp/ANN/CMakeLists.txt, APSCpp/ANN/Copyright.txt, + APSCpp/ANN/License.txt, APSCpp/ANN/ReadMe.txt, + APSCpp/ANN/bd_fix_rad_search.cpp, APSCpp/ANN/bd_pr_search.cpp, + APSCpp/ANN/bd_search.cpp, APSCpp/ANN/bd_tree.cpp, + APSCpp/ANN/bd_tree.h, APSCpp/ANN/brute.cpp, + APSCpp/ANN/kd_dump.cpp, APSCpp/ANN/kd_fix_rad_search.cpp, + APSCpp/ANN/kd_fix_rad_search.h, APSCpp/ANN/kd_pr_search.cpp, + APSCpp/ANN/kd_pr_search.h, APSCpp/ANN/kd_search.cpp, + APSCpp/ANN/kd_search.h, APSCpp/ANN/kd_split.cpp, + APSCpp/ANN/kd_split.h, APSCpp/ANN/kd_tree.cpp, + APSCpp/ANN/kd_tree.h, APSCpp/ANN/kd_util.cpp, + APSCpp/ANN/kd_util.h, APSCpp/ANN/perf.cpp, APSCpp/ANN/pr_queue.h, + APSCpp/ANN/pr_queue_k.h, APSCpp/APSCpp.cpp, + APSCpp/APSCpp_main.cpp: add ANN subdir + +2008-03-07 18:18 tksharpless + + * APSCpp/APSCpp.c, APSCpp/APSCpp_main.c, APSCpp/CMakeLists.txt, + APSCpp/HermiteSpline.h, APSCpp/README-autopano-sift-c.txt, + APSCpp/saInterp.h, APSCpp/saRemap.c, APSCpp/sphereAlign.h, + AutoPanoSift.h, CMakeLists.txt, MatchKeys.c, README.1ST: + autopano-sift-c uses faster ANN kd-tree by default; also better + defaults for maxdim and ransac. + Added ANN source diredtory (NOTE: custom ANN.h) + Cleaned up CMake scripts ==> Only tested in Windows <== + Assigned package version number 2.5.0 + +2008-03-04 17:14 tksharpless + + * APSCpp/APSCpp_main.c: Made command line error handling more + reliable and informative + +2008-03-03 09:10 dangelo + + * APSCpp/sphereAlign.h, AutoPanoSift.h: Enable compilation with gcc + +2008-03-03 09:06 dangelo + + * config.h.in.cmake: Added #define HAVE_MALLOC 1 on apple as this + seems to fix some problem with realloc + +2008-03-03 09:04 dangelo + + * Makefile: removed obselete makefile + +2008-03-03 03:56 tksharpless + + * MatchKeys.c: adding older version with Seb's fix + +2008-03-03 03:55 tksharpless + + * MatchKeys.c: removing current head rev + +2008-03-03 03:37 tksharpless + + * APSCpp/APSCpp_main.c: correct a messsage about output file + +2008-03-03 03:21 tksharpless + + * APSCpp/CMakeLists.txt: Try again to add APSCpp/CMakeLists.txt + +2008-03-03 02:45 tksharpless + + * APSCpp/cmakelists.txt: change name of APSCpp/CMakeLists.txt to + correct case + +2008-03-01 02:58 tksharpless + + * APSCpp, APSCpp/APSCpp.c, APSCpp/APSCpp_main.c, APSCpp/CamLens.c, + APSCpp/HermiteSpline.c, APSCpp/HermiteSpline.h, + APSCpp/README-autopano-sift-c.txt, APSCpp/cmakelists.txt, + APSCpp/saInterp.c, APSCpp/saInterp.h, APSCpp/saRemap.c, + APSCpp/sphereAlign.h, AutoPanoSift.h, CMakeLists.txt, + DisplayImage.c, ImageMap.c, LoweDetector.c, ScaleSpace.c, + Utils.c: Major extension of APSC, now renamed autopano-sift-c, + adds stereographic projection and reduces memory demand. + Source is in subdir APSCpp. Some bugfixes in libsift in addition + to the change from double to float for image maps, which almost + doubles useful image size for generatekeys as well as + autopano-sift-c. + +2008-03-01 01:45 tksharpless + + * MatchKeys.c: Rewrote Component_ToString to eliminate 2 bugs (one + serious, leading to seg faults). This fix replaces Seb's recent + fix of the same major bug, because I am too tired to merge them + properly. + +2008-02-22 21:01 tksharpless + + * ArrayList.c: Undoing previous commit -- I just didn't understand + how + ArrayList was supposed to work -- Sorry, TKS + +2008-02-21 12:41 tksharpless + + * ArrayList.c: ArrayList_new() was initializing list full instead + of empty, leaving (dim) null entries at start of list. + +2008-02-20 22:57 brunopostle + + * CMakeLists.txt: Don't put compiled binary in tarball + +2008-02-17 23:33 dangelo + + * CMakeLists.txt, config.h.in.cmake: #define HAVE_MALLOC on OSX, it + seems to fix an out of memory situation due to the use of + realloc. + +2008-02-15 22:44 dangelo + + * CMakeLists.txt: Renamed APSC to autopano-sift-c, to match the + naming style of most other tools shipped with hugin. + +2008-02-08 19:48 sebpz + + * APSCmain.c: Default 800 for maxdim + +2008-02-07 20:58 sebpz + + * MatchKeys.c: Fix for Seg Fault in Component_ToString + +2008-02-07 16:02 tksharpless + + * APSCmain.c, AutoPano.c: Made the "-" option work. Anyone who uses + it must donate 1 Euro to the hugin project :) + +2008-02-07 01:44 tksharpless + + * APSCmain.c, CMakeLists.txt, Utils.c: Add APSC, which combines + generatekeys and autopano in one executable. + + fflush stdout writes in utils.c + +2008-02-05 18:41 brunopostle + + * autopano-c-complete: Perl version of autopano-c-complete, should + be 100% compatible + +2008-02-05 02:13 tksharpless + + * CMakeLists.txt: installs vbs script on Windows, else shell + script. + +2008-02-05 02:00 tksharpless + + * autopano-c-complete.vbs: Finds the autopano executables if they + are in a reasonable place; if not, quits with explicit error. + +2008-02-03 20:39 yuv + + * CMakeLists.txt: INSTALL target for Windows in build directory + instead of "C:\Program Files", for SDK integration + +2008-02-03 18:51 yuv + + * autopano-c-complete.vbs: Pete Holzmann added wildcard + functionality and improved output + +2008-02-02 19:50 sebpz + + * KeypointXML.c, MatchKeys.c, autopano-c-complete.sh: Adding gz + output for keyfiles + +2008-02-02 17:31 sebpz + + * Makefile, autopano-c-complete.sh: Reverting previous change - + gzip not supported by autopano + +2008-02-02 17:09 sebpz + + * Makefile, autopano-c-complete.sh: Create gzip compressed key + files + +2008-02-01 16:44 dangelo + + * ChangeLog, MatchKeys.c: Corrected possible crash when many images + are used. + +2008-02-01 04:39 yuv + + * autopano-c-complete.vbs: added feedback-loop to avoid concurrent + execution of multiple instances of generatekeys + +2008-02-01 04:18 yuv + + * autopano-c-complete.vbs: corrected for space in path + +2008-01-31 02:05 yuv + + * autopano-c-complete.vbs: Windows translation of + autopano-c-complete.sh + +2008-01-29 13:54 brunopostle + + * CMakeLists.txt: Revert and fix previous commit + +2008-01-29 12:55 brunopostle + + * CMakeLists.txt: Don't install duplicate man pages + +2008-01-29 12:20 brunopostle + + * CMakeLists.txt: autopano-c-complete.sh needs to be installed + executable + +2008-01-29 11:49 brunopostle + + * CMakeLists.txt, CMakeModules/FindJPEG.cmake, + CMakeModules/FindLibXml2.cmake, CMakeModules/FindPANO13.cmake, + CMakeModules/FindPNG.cmake, CMakeModules/FindTIFF.cmake, + CMakeModules/FindZLIB.cmake, config.h.in.cmake: Fix line endings, + no other changes + +2008-01-29 11:44 brunopostle + + * CMakeLists.txt: Don't put a generated Makefile in the tarball + +2008-01-29 11:40 brunopostle + + * CMakeLists.txt: Don't put the compiled binaries in the tarball + +2008-01-29 08:22 dangelo + + * CMakeLists.txt: unified libxml config on windows and unix + +2008-01-29 08:08 dangelo + + * CMakeLists.txt: remove MY prefix leftover from some testing. + +2008-01-29 04:07 tksharpless + + * CMakeLists.txt: fixed bad Unix compiler flag from previous fix + (my fault) + +2008-01-28 20:59 tksharpless + + * CMakeLists.txt: changed root cmakelists.txt so it works on + Windows with the sdk; tried not to break Linux build but this is + not verified. + +2008-01-28 00:15 btownshend + + * DisplayImage.c: Removed unused variable declaration + +2008-01-28 00:14 btownshend + + * DisplayImage.c: Fixed handling of 16-bit files + Fixed memory overrun during malloc of images + +2008-01-15 07:19 dangelo + + * AutoPanoSift.h, CMakeLists.txt, KeypointXML.c: Fixed compilation + with gcc + +2008-01-15 06:53 dangelo + + * AreaFilter.c, ArrayList.c, AutoPano.c, AutoPanoSift.h, + BondBall.c, CMakeLists.txt, CMakeModules, + CMakeModules/FindJPEG.cmake, CMakeModules/FindLibXml2.cmake, + CMakeModules/FindLibraryWithDebug.cmake, + CMakeModules/FindPANO13.cmake, CMakeModules/FindPNG.cmake, + CMakeModules/FindPackageHandleStandardArgs.cmake, + CMakeModules/FindTIFF.cmake, CMakeModules/FindZLIB.cmake, + ChangeLog, GenerateKeys.c, ImageMatchModel.c, KDTree.c, + KeypointXML.c, LoweDetector.c, MatchKeys.c, RANSAC.c, README.1ST, + ScaleSpace.c, TestArray.c, TestKDTree.c, TestRandom.c, Utils.c, + autopano-c-complete.sh, config.h.in.cmake: Added CMake build + system and fixed source, so that it compiles with MSVC. + +2008-01-02 22:25 brunopostle + + * Makefile: Allow setting PREFIX and CFLAGS + +2008-01-02 22:23 brunopostle + + * doc/autopano-c-complete.1, doc/autopano-c-complete.txt, + doc/autopano-complete.1, doc/autopano-complete.txt, + doc/autopano-sift-c.7, doc/autopano-sift-c.txt, + doc/autopano-sift.7, doc/autopano-sift.txt, doc/autopanog.1, + doc/autopanog.txt, doc/template.1: man page cleanup and rename + +2008-01-02 14:56 dangelo + + * ChangeLog: + +2008-01-02 14:54 dangelo + + * AutoPanoSift.h, DisplayImage.c, Makefile: build against pano13 by + default + +2008-01-02 09:37 brunopostle + + * Makefile: install target typo fix (Yuval Levy) + +2007-12-30 22:21 brunopostle + + * Transform.c: Apply fix from bug #1808333 seems to work for me. + https://sourceforge.net/tracker/index.php?func=detail&aid=1808333&group_id=77506&atid=550441 + +2007-12-30 22:15 brunopostle + + * autopano-c-complete.sh: Fix bug with directories containing + spaces + +2007-07-20 17:17 brunopostle + + * Makefile: Create man directories + +2007-07-20 16:53 brunopostle + + * Makefile: Add man pages to install target + +2007-07-19 17:03 dangelo + + * Makefile: added a simple install target + +2007-05-29 23:51 dangelo + + * AreaFilter.c, ArrayList.c, AutoPano.c, AutoPanoSift.h, + BondBall.c, ChangeLog, DisplayImage.c, GaussianConvolution.c, + GenerateKeys.c, HashTable.c, ImageMap.c, ImageMatchModel.c, + KDTree.c, KeypointXML.c, LICENSE, LoweDetector.c, Makefile, + MatchKeys.c, RANSAC.c, README, README.1ST, Random.c, + ScaleSpace.c, SimpleMatrix.c, TestArray.c, TestKDTree.c, + TestRandom.c, Transform.c, Utils.c, autopano-c-complete.sh, doc: + moved files to trunk directory + +2007-05-29 23:49 dangelo + + * autopano-sift-C: moved to trunk directory + +2007-04-18 20:16 brunopostle + + * autopano-sift-C, autopano-sift-C/.cvsignore, + autopano-sift-C/Makefile, autopano-sift-C/autopano-c-complete.sh: + add autopano-c-complete.sh script + +2007-04-18 16:33 dangelo + + * autopano-sift-C/AutoPano.c, autopano-sift-C/BondBall.c, + autopano-sift-C/ChangeLog, autopano-sift-C/DisplayImage.c, + autopano-sift-C/ImageMatchModel.c, autopano-sift-C/KeypointXML.c, + autopano-sift-C/LoweDetector.c, autopano-sift-C/Makefile, + autopano-sift-C/MatchKeys.c, autopano-sift-C/ScaleSpace.c, + autopano-sift-C/Transform.c: applied patch by Alexandre + Duret-Lutz + +2007-02-05 23:52 brunopostle + + * autopano-sift-C/Makefile: rewrite dist target + +2007-02-02 21:41 dangelo + + * autopano-sift-C/AutoPano.c, autopano-sift-C/MatchKeys.c: applied + patch + +2007-02-02 21:14 dangelo + + * autopano-sift-C/AutoPanoSift.h, autopano-sift-C/Makefile: find + include files in standart directories + +2007-02-02 21:04 dangelo + + * autopano-sift-C/LoweDetector.c: added debug statement + +2007-02-02 21:04 dangelo + + * autopano-sift-C/ImageMap.c: ups + +2007-02-02 21:03 dangelo + + * autopano-sift-C/ImageMap.c: fixed minimum search + +2007-01-23 22:11 brunopostle + + * autopano-sift-C/Makefile: Minor tweak to build on a system with + pano12 installed + +2006-08-21 06:35 dangelo + + * autopano-sift-C, autopano-sift-C/AreaFilter.c, + autopano-sift-C/ArrayList.c, autopano-sift-C/AutoPano.c, + autopano-sift-C/AutoPanoSift.h, autopano-sift-C/BondBall.c, + autopano-sift-C/DisplayImage.c, + autopano-sift-C/GaussianConvolution.c, + autopano-sift-C/GenerateKeys.c, autopano-sift-C/HashTable.c, + autopano-sift-C/ImageMap.c, autopano-sift-C/ImageMatchModel.c, + autopano-sift-C/KDTree.c, autopano-sift-C/KeypointXML.c, + autopano-sift-C/LICENSE, autopano-sift-C/LoweDetector.c, + autopano-sift-C/Makefile, autopano-sift-C/MatchKeys.c, + autopano-sift-C/RANSAC.c, autopano-sift-C/README, + autopano-sift-C/README.1ST, autopano-sift-C/Random.c, + autopano-sift-C/ScaleSpace.c, autopano-sift-C/SimpleMatrix.c, + autopano-sift-C/TestArray.c, autopano-sift-C/TestKDTree.c, + autopano-sift-C/TestRandom.c, autopano-sift-C/Transform.c, + autopano-sift-C/Utils.c, autopano-sift-C/doc, + autopano-sift-C/doc/autopano-complete.1, + autopano-sift-C/doc/autopano-complete.txt, + autopano-sift-C/doc/autopano-sift.7, + autopano-sift-C/doc/autopano-sift.txt, + autopano-sift-C/doc/autopano.1, autopano-sift-C/doc/autopano.txt, + autopano-sift-C/doc/autopanog.1, + autopano-sift-C/doc/autopanog.txt, + autopano-sift-C/doc/generatekeys.1, + autopano-sift-C/doc/generatekeys.txt, + autopano-sift-C/doc/template.1: Initial revision + +2006-08-21 06:35 + + * .: New repository initialized by cvs2svn. + Modified: autopano-sift-C/trunk/README.1ST =================================================================== --- autopano-sift-C/trunk/README.1ST 2008-07-23 21:58:36 UTC (rev 3222) +++ autopano-sift-C/trunk/README.1ST 2008-07-23 22:08:03 UTC (rev 3223) @@ -6,7 +6,8 @@ which is available at http://www.cs.tu-berlin.de/~nowozin/autopano-sift -The only dependances are libpano12 and libxml2... +The only dependencies are: +libpano13, libpng, libtiff, libjpeg, zlib and libxml2 The doc directory contains verbatim copies from the original This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gko...@us...> - 2009-02-22 23:01:25
|
Revision: 3664 http://hugin.svn.sourceforge.net/hugin/?rev=3664&view=rev Author: gkohlmeyer Date: 2009-02-22 21:39:34 +0000 (Sun, 22 Feb 2009) Log Message: ----------- Updated CMake files for libxml2 2.7.3, wxWidgets 2.8.9 and current libpano Modified Paths: -------------- autopano-sift-C/trunk/CMakeLists.txt autopano-sift-C/trunk/CMakeModules/FindLibXml2.cmake autopano-sift-C/trunk/CMakeModules/FindPANO13.cmake Modified: autopano-sift-C/trunk/CMakeLists.txt =================================================================== --- autopano-sift-C/trunk/CMakeLists.txt 2009-02-22 13:32:03 UTC (rev 3663) +++ autopano-sift-C/trunk/CMakeLists.txt 2009-02-22 21:39:34 UTC (rev 3664) @@ -28,14 +28,13 @@ SET( CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/INSTALL/FILES CACHE FILEPATH "install prefix" FORCE) # look in wxWidgets distribution for depending packages. - SET(wxWidgets_LIB_DIR ${SOURCE_BASE_DIR}/wxMSW-2.8.7/lib/vc_lib) - SET(wxWidgets_ROOT_DIR ${SOURCE_BASE_DIR}/wxMSW-2.8.7) + SET(wxWidgets_LIB_DIR ${SOURCE_BASE_DIR}/wxWidgets-2.8.9/lib/vc_lib) + SET(wxWidgets_ROOT_DIR ${SOURCE_BASE_DIR}/wxWidgets-2.8.9) ENDIF(WIN32) ## ## External libraries ## - FIND_PACKAGE(TIFF REQUIRED) INCLUDE_DIRECTORIES(${TIFF_INCLUDE_DIR}) FIND_PACKAGE(JPEG REQUIRED) @@ -83,15 +82,15 @@ # Stop MSVC9 from bitching about POSIX names without underscores ADD_DEFINITIONS(/D_CRT_NONSTDC_NO_DEPRECATE) # compile everything for the static C runtime - STRING(REPLACE /MD /MT CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) - STRING(REPLACE /MD /MT CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) - STRING(REPLACE /MD /MT CMAKE_CXX_FLAGS_MINSIZEREL ${CMAKE_CXX_FLAGS_MINSIZEREL}) - STRING(REPLACE /MD /MT CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}) - STRING(REPLACE /MD /MT CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE}) - STRING(REPLACE /MD /MT CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG}) - STRING(REPLACE /MD /MT CMAKE_C_FLAGS_MINSIZEREL ${CMAKE_C_FLAGS_MINSIZEREL}) - STRING(REPLACE /MD /MT CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELWITHDEBINFO}) - + FOREACH(TYPE C CXX) + FOREACH(CFG "_DEBUG" "_MINSIZEREL" "_RELEASE" "_RELWITHDEBINFO") + SET(NEW_FLAGS "${CMAKE_${TYPE}_FLAGS${CFG}}") + STRING(REPLACE "/MD" "/MT" NEW_FLAGS "${NEW_FLAGS}") + SET(CMAKE_${TYPE}_FLAGS${CFG} "${NEW_FLAGS}" CACHE STRING + "CMAKE_${TYPE}_FLAGS${CFG} (overwritten to ensure static build)" FORCE) + ENDFOREACH(CFG) + ENDFOREACH(TYPE) + # yes we DO have pano13 ADD_DEFINITIONS( /DHAS_PANO13 ) Modified: autopano-sift-C/trunk/CMakeModules/FindLibXml2.cmake =================================================================== --- autopano-sift-C/trunk/CMakeModules/FindLibXml2.cmake 2009-02-22 13:32:03 UTC (rev 3663) +++ autopano-sift-C/trunk/CMakeModules/FindLibXml2.cmake 2009-02-22 21:39:34 UTC (rev 3664) @@ -29,6 +29,7 @@ PATHS ${_LibXml2IncDir} ${SOURCE_BASE_DIR}/libxml2-2.6.31/include + ${SOURCE_BASE_DIR}/libxml2-2.7.3/include PATH_SUFFIXES libxml2 ) @@ -36,6 +37,7 @@ PATHS ${_LibXml2LinkDir} ${SOURCE_BASE_DIR}/libxml2-2.6.31/win32/bin.msvc + ${SOURCE_BASE_DIR}/libxml2-2.7.3/win32/bin.msvc ) INCLUDE(FindPackageHandleStandardArgs) Modified: autopano-sift-C/trunk/CMakeModules/FindPANO13.cmake =================================================================== --- autopano-sift-C/trunk/CMakeModules/FindPANO13.cmake 2009-02-22 13:32:03 UTC (rev 3663) +++ autopano-sift-C/trunk/CMakeModules/FindPANO13.cmake 2009-02-22 21:39:34 UTC (rev 3664) @@ -16,6 +16,7 @@ /usr/local/include /usr/include ${SOURCE_BASE_DIR}/libpano + ${SOURCE_BASE_DIR}/libpano/pano13 ${SOURCE_BASE_DIR} ) @@ -27,6 +28,7 @@ NAMES pano13 PATHS /usr/lib /usr/local/lib ${PANO13_INCLUDE_DIR}/pano13/Release + "${SOURCE_BASE_DIR}/libpano/pano13/Release LIB CMD" ${SOURCE_BASE_DIR}/pano13/lib ${SOURCE_BASE_DIR}/pano13 ) @@ -38,6 +40,7 @@ NAMES Panotools pano13d pano13 PATHS /usr/lib /usr/local/lib ${PANO13_INCLUDE_DIR}/pano13/Debug + "${SOURCE_BASE_DIR}/libpano/pano13/Debug LIB CMD" ${SOURCE_BASE_DIR}/pano13/lib ${SOURCE_BASE_DIR}/pano13 ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bru...@us...> - 2009-03-08 22:16:29
|
Revision: 3713 http://hugin.svn.sourceforge.net/hugin/?rev=3713&view=rev Author: brunopostle Date: 2009-03-08 22:16:28 +0000 (Sun, 08 Mar 2009) Log Message: ----------- fix binary cpack generator (Kornel Benko) Modified Paths: -------------- autopano-sift-C/trunk/CMakeLists.txt autopano-sift-C/trunk/ChangeLog Modified: autopano-sift-C/trunk/CMakeLists.txt =================================================================== --- autopano-sift-C/trunk/CMakeLists.txt 2009-03-08 22:11:25 UTC (rev 3712) +++ autopano-sift-C/trunk/CMakeLists.txt 2009-03-08 22:16:28 UTC (rev 3713) @@ -176,7 +176,6 @@ SET(CPACK_PACKAGE_VERSION_PATCH "${V_PATCH}") SET(CPACK_PACKAGE_INSTALL_DIRECTORY "CMake ${V_MAJOR}.${V_MINOR}") SET(CPACK_SOURCE_PACKAGE_FILE_NAME "autopano-sift-C-${V_MAJOR}.${V_MINOR}.${V_PATCH}") -SET(CPACK_GENERATOR "TGZ;TBZ2") SET(CPACK_SOURCE_GENERATOR "TGZ;TBZ2") SET(CPACK_SET_DESTDIR "ON") # Find the revision number and use it as the release in rpm-package-build. @@ -184,6 +183,7 @@ # installing from that rpm package. FIND_PROGRAM(_svnversion svnversion) EXECUTE_PROCESS(COMMAND ${_svnversion} WORKING_DIRECTORY "${CMAKE_HOME_DIRECTORY}" OUTPUT_VARIABLE CPACK_RPM_PACKAGE_RELEASE OUTPUT_STRIP_TRAILING_WHITESPACE) +SET(CPACK_PACKAGE_CONTACT "hug...@go...") SET(CPACK_SOURCE_IGNORE_FILES "/autopano$" "/generatekeys$" Modified: autopano-sift-C/trunk/ChangeLog =================================================================== --- autopano-sift-C/trunk/ChangeLog 2009-03-08 22:11:25 UTC (rev 3712) +++ autopano-sift-C/trunk/ChangeLog 2009-03-08 22:16:28 UTC (rev 3713) @@ -1,3 +1,31 @@ +2009-03-04 19:04 brunopostle + + * CMakeLists.txt: cpack stuff required for RPM and DEB generators + (Kornel Benko) + +2009-03-03 23:43 brunopostle + + * ScaleSpace.c: Eliminate a couple of rare cases in which + autopano-sift-C chooses to print an + error message and die, rather than doing anything sensible + (Norman Yarvin) + +2009-02-27 21:39 gkohlmeyer + + * CMakeLists.txt: Small change in CMakeLists.txt to get rid of + version warning in CMake + +2009-02-22 21:39 gkohlmeyer + + * CMakeLists.txt, CMakeModules/FindLibXml2.cmake, + CMakeModules/FindPANO13.cmake: Updated CMake files for libxml2 + 2.7.3, wxWidgets 2.8.9 and current libpano + +2008-07-23 22:08 brunopostle + + * ChangeLog, README.1ST: Update ChangeLog for 2.5.0 release. + Pablo seems to have a different svn2cl... + 2008-04-24 21:00 brunopostle * APSCpp/CMakeLists.txt, CMakeLists.txt: Don't try and install a This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bru...@us...> - 2009-05-29 20:51:32
|
Revision: 3894 http://hugin.svn.sourceforge.net/hugin/?rev=3894&view=rev Author: brunopostle Date: 2009-05-29 20:50:45 +0000 (Fri, 29 May 2009) Log Message: ----------- Inline ImageMap_SetPixel() and ImageMap_GetPixel() patch #2798145 (Scott Crosby) Modified Paths: -------------- autopano-sift-C/trunk/AutoPanoSift.h autopano-sift-C/trunk/ImageMap.c Modified: autopano-sift-C/trunk/AutoPanoSift.h =================================================================== --- autopano-sift-C/trunk/AutoPanoSift.h 2009-05-29 17:32:06 UTC (rev 3893) +++ autopano-sift-C/trunk/AutoPanoSift.h 2009-05-29 20:50:45 UTC (rev 3894) @@ -292,15 +292,25 @@ ImageMap* ImageMap_ScaleDouble(ImageMap* self); ImageMap* ImageMap_ScaleHalf(ImageMap* self); ImageMap* ImageMap_GaussianConvolution(ImageMap* self, double); -void ImageMap_SetPixel(ImageMap* self, int x, int y, float val); -double ImageMap_GetPixel(ImageMap* self, int x, int y); ImageMap* ImageMap_Add(ImageMap* f1, ImageMap* f2); ImageMap* ImageMap_Sub(ImageMap* f1, ImageMap* f2); ImageMap* ImageMap_Mul(ImageMap* f1, ImageMap* f2); void ImageMap_Normalize(ImageMap* self); ImageMap* ImageMap_GaussianConvolution(ImageMap* self, double sigma); +static inline double ImageMap_GetPixel(ImageMap* self, int x, int y) +{ + return self->values[x][y]; +} +static inline void ImageMap_SetPixel(ImageMap* self, int x, int y, float value) +{ + self->values[x][y]=value; +} + + + + typedef struct ConvLinearMask ConvLinearMask; struct ConvLinearMask { int Dim; Modified: autopano-sift-C/trunk/ImageMap.c =================================================================== --- autopano-sift-C/trunk/ImageMap.c 2009-05-29 17:32:06 UTC (rev 3893) +++ autopano-sift-C/trunk/ImageMap.c 2009-05-29 20:50:45 UTC (rev 3894) @@ -66,16 +66,6 @@ fclose(fp); } -double ImageMap_GetPixel(ImageMap* self, int x, int y) -{ - return self->values[x][y]; -} - -void ImageMap_SetPixel(ImageMap* self, int x, int y, float value) -{ - self->values[x][y]=value; -} - // Double the size of an imagemap using linear interpolation. // It is not a real doubling as the last line is omitted (the image size // would always be odd otherwise and we have no second line for This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bru...@us...> - 2009-05-30 20:16:49
|
Revision: 3897 http://hugin.svn.sourceforge.net/hugin/?rev=3897&view=rev Author: brunopostle Date: 2009-05-30 20:16:45 +0000 (Sat, 30 May 2009) Log Message: ----------- unify line-endings Modified Paths: -------------- autopano-sift-C/trunk/APSCmain.c autopano-sift-C/trunk/APSCpp/ANN/CMakeLists.txt autopano-sift-C/trunk/APSCpp/ANNkd_wrap.cpp autopano-sift-C/trunk/APSCpp/APSCpp.c autopano-sift-C/trunk/APSCpp/APSCpp_main.c autopano-sift-C/trunk/APSCpp/CMakeLists.txt autopano-sift-C/trunk/APSCpp/CamLens.c autopano-sift-C/trunk/APSCpp/HermiteSpline.h autopano-sift-C/trunk/APSCpp/README-autopano-sift-c.txt autopano-sift-C/trunk/APSCpp/saInterp.c autopano-sift-C/trunk/APSCpp/saInterp.h autopano-sift-C/trunk/APSCpp/saRemap.c autopano-sift-C/trunk/APSCpp/sphereAlign.h autopano-sift-C/trunk/CMakeLists.txt autopano-sift-C/trunk/MatchKeys.c Modified: autopano-sift-C/trunk/APSCmain.c =================================================================== --- autopano-sift-C/trunk/APSCmain.c 2009-05-29 22:20:37 UTC (rev 3896) +++ autopano-sift-C/trunk/APSCmain.c 2009-05-30 20:16:45 UTC (rev 3897) @@ -1,776 +1,776 @@ - -/* APSCmain.c 06Feb2008 TKSharpless - Single-executable form of AutoPano-sift-C for Hugin 0.7 - Here, GenerateKeys is a subroutine - - * Keypoint file correlation and hugin panorama file creation utility. - * - * (C) Copyright 2004 -- Sebastian Nowozin (no...@cs...) - * - * "The University of British Columbia has applied for a patent on the SIFT - * algorithm in the United States. Commercial applications of this software - * may require a license from the University of British Columbia." - * For more information, see the LICENSE file supplied with the distribution. - * - * This program is free software released under the GNU General Public - * License, which is included in this software package (doc/LICENSE). -*/ - -#include "AutoPanoSift.h" - -void Usage () -{ - WriteLine ("APSC: Generate and Match Keypoints giving Hugin project file\n"); - WriteLine (" Version %s\n", PACKAGE_VERSION); - WriteLine ("usage: APSC.exe [options] output.pto image1 image2 [..]\n"); - WriteLine ("Options"); - WriteLine (" --ransac <on|off|1|0> Switch RANSAC filtration on or off (default: on)"); - WriteLine (" --maxmatches <matches> Use no more than the given number of matches"); - WriteLine (" (default: 16, use zero for unlimited)"); - - WriteLine (" --disable-areafilter Do not use max-area filtration, which is default."); - WriteLine (" See manpage for details."); - WriteLine (" --integer-coordinates Truncate match coordinates to integer numbers."); - WriteLine (" --absolute-pathnames <on|off|1|0> Use the absolute pathname of the image"); - WriteLine (" file in the PTO output file. Disabled by default."); - WriteLine (" --maxdim <integer> input images are repeatedly halfed in size until"); - WriteLine (" both width and height are below 'maxdim' (default: 800)."); - WriteLine (""); - - WriteLine ("Alignment options"); - WriteLine (" --align Automatically pre-align images in PTO file."); - WriteLine (" --bottom-is-left"); - WriteLine (" --bottom-is-right Use in case the automatic algorithm fails."); - WriteLine (" --generate-horizon <c> Generate up to 'c' horizon lines."); - WriteLine (""); - - WriteLine ("Refinement options"); - WriteLine (" --refine Refine the found control points using the"); - WriteLine (" original images."); - WriteLine (" --refine-by-middle Use the best middle point to refine (default)."); - WriteLine (" --refine-by-mean Use the mean of the patches control points."); - WriteLine (" --keep-unrefinable <on|off|1|0>"); - WriteLine (" Keep unrefinable matches (default: on)."); - - WriteLine ("output.pto: The output PTO panorama project file."); - WriteLine (" The filename can be \"-\", then stdout is used"); - WriteLine ("image<n>: input image files (any common format: JPEG, PNG, TIFF, ..)"); - WriteLine ("Notice: for the aligning to work, the input images shall be"); - WriteLine (" 1. All of the same dimension and scale"); - WriteLine (" 2. The first images must be an ordered row. See manpage."); - WriteLine (""); -} - -// subroutine equivalent to GenerateKeys.c -KeypointXMLList * GenerateKeys( char* imgname, int downRes ) -{ - // 1. load the image file - DisplayImage* pic = DisplayImage_new(imgname); - int pW = pic->width; - int pH = pic->height; - ImageMap* picMap; - LoweFeatureDetector* lf; - KeypointXMLList* kpp; - double startScale = 1.0; - - if (downRes > 0) { - startScale = DisplayImage_ScaleWithin(pic, downRes); -// WriteLine ("Scaled picture, starting with scale %0.04f", startScale); - } - picMap = DisplayImage_ConvertToImageMap(pic); - DisplayImage_delete(pic); - - // 2. find the features - lf = LoweFeatureDetector_new0(); - - if (downRes > 0) { - LoweFeatureDetector_DetectFeaturesDownscaled (lf, picMap, 0, 1.0 / startScale); - } else - LoweFeatureDetector_DetectFeatures (lf, picMap); - - /* build the return value - We need a new copy of the list held in lf because lf is about to be deleted. - The following code adapted from LoweFeatureDetector_GlobalNaturalKeypoints() - does that, and also a needed format conversion (lucky this is not C++!) - */ - ArrayList * globalNaturalKeypoints = ArrayList_new0 (KeypointN_delete); - int i; - for(i=0; i < ArrayList_Count(lf->globalKeypoints); i++) { - Keypoint* kp = (Keypoint *) ArrayList_GetItem( lf->globalKeypoints, i ); - ArrayList_AddItem ( globalNaturalKeypoints, KeypointN_new( kp )); - } - // package result as a KeypointXMLList - kpp = KeypointXMLList_new ( imgname, pW, pH, globalNaturalKeypoints ); - - LoweFeatureDetector_delete(lf); - - // disable the patent warning message (for any subsequent images) - LoweFeatureDetector_SetPrintWarning(false); - - return kpp; -} - - -typedef struct Resolution Resolution; -struct Resolution -{ - int x, y; -}; - -Resolution* Resolution_new0() -{ - Resolution* self = (Resolution*)malloc(sizeof(Resolution)); - return self; -} - -Resolution* Resolution_new(int x, int y) -{ - Resolution* self = Resolution_new0(); - self->x = x; - self->y = y; - return self; -} - -void Resolution_delete(Resolution* self) -{ - if (self) { - free(self); - } -} - -int Resolution_CompareTo (Resolution* self, int x, int y) -{ - - if (self->x == x && self->y == y) - return (0); - - return (1); -} - - - - -// The maximum radius to consider around a keypoint that is refined. That -// is, at most a patch of a maximum size of twice this value in both -// horizontal and vertical direction is extracted. -int RefinementRadiusMaximum = 96; -int (*refineHandler)(int index, int total); - - -void RefineKeypoints (ArrayList* msList, - bool selectMiddlePoint, bool neverLosePoints); -DisplayImage* ExtractPatch (DisplayImage* large, - int px, int py, double scale, int* radius); -ArrayList* ExtractKeypoints (DisplayImage* pic); -bool YesNoOption (char* optionName, char* val); - -// selectMiddlePoint: if true, select the middle point in the patch, -// otherwise build the mean -// neverLosePoints: if true, and if we cannot do the refinement, still use -// the control point. -void RefineKeypoints (ArrayList* msList, - bool selectMiddlePoint, bool neverLosePoints) -{ - DisplayImage* pic1 = NULL; - DisplayImage* pic2 = NULL; - char* pic1Name = NULL; - char* pic2Name = NULL; - - /* Keep stats for the refineHandler delegate - */ - int totalRefines = 0; - int doneRefines = 0; - int i; - for(i=0; i<ArrayList_Count(msList); i++) { - MatchSet* ms = (MatchSet*) ArrayList_GetItem(msList, i); - int j; - for(j=0; j<ArrayList_Count(ms->matches); j++) { - ArrayList_GetItem(ms->matches, j); - totalRefines += 1; - } - } - - - for(i=0; i<ArrayList_Count(msList); i++) { - MatchSet* ms = (MatchSet*) ArrayList_GetItem(msList, i); - WriteLine (" between \"%s\" and \"%s\"", - ms->file1, ms->file2); - - if (pic1Name != ms->file1) { - pic1Name = ms->file1; - pic1 = DisplayImage_new (ms->file1); - } - if (pic2Name != ms->file2) { - pic2Name = ms->file2; - pic2 = DisplayImage_new (ms->file2); - } - /*WriteLine ("pair: %s, %s, %d keypoint matches", - ms->file1, ms->file2, ArrayList_Count(ms->Matches));*/ - - ArrayList* refinedMatches = ArrayList_new0 (NULL); - - int j; - for(j=0; j<ArrayList_Count(ms->matches); j++) { - Match* m = (Match*) ArrayList_GetItem(ms->matches, j); - - int p1x = (int) (m->kp1->x + 0.5); - int p1y = (int) (m->kp1->y + 0.5); - int p1radius; - DisplayImage* patch1 = ExtractPatch (pic1, p1x, p1y, - m->kp1->scale, &p1radius); - - int p2x = (int) (m->kp2->x + 0.5); - int p2y = (int) (m->kp2->y + 0.5); - int p2radius; - DisplayImage* patch2 = ExtractPatch (pic2, p2x, p2y, - m->kp2->scale, &p2radius); - - /* Call the refine handler delegate in case there is one to - * inform the callee of a single refining step (for progress - * bar displays and such). - */ - doneRefines += 1; - if (refineHandler != NULL) - refineHandler (doneRefines, totalRefines); - - // Skip over keypoint matches we cannot refine as part of the - // image lies outside. - if (patch1 == NULL || patch2 == NULL) { - if (neverLosePoints) - ArrayList_AddItem(refinedMatches, m); - DisplayImage_delete(patch1); - DisplayImage_delete(patch2); - continue; - } - - // Otherwise, run the SIFT algorithm on both small patches. - ArrayList* p1kp = ExtractKeypoints (patch1); - ArrayList* p2kp = ExtractKeypoints (patch2); - /*WriteLine ("p1kp = %d, p2kp = %d", ArrayList_Count(p1kp), - ArrayList_Count(p2kp));*/ - - // Apply the matching, RANSAC enabled. - MultiMatch* mm = MultiMatch_new0 (); - mm->verbose = false; - - ArrayList* matches = NULL; - matches = MultiMatch_TwoPatchMatch (mm, p1kp, - patch1->width, patch1->height, p2kp, patch2->width, - patch2->height, true); - DisplayImage_delete(patch1); - DisplayImage_delete(patch2); - - /* In case there are less than three keypoints in the - * two patches, we ignore them all. - */ - if (0 /*was exception ???*/ ) { - matches = NULL; - } - - if (matches == NULL || ArrayList_Count(matches) != 1) { - if (neverLosePoints) - ArrayList_AddItem(refinedMatches, m); - - continue; - } - - MatchSet* pSet = (MatchSet*) ArrayList_GetItem(matches, 0); - - // Now get the real new control point coordinates from the - // patches. We have two options and assume all points are - // equal quality-wise: - // a) Select the one that is most in the middle - // (selectMiddlePoint == true) - // b) Build the mean of all the control point matches in the - // patches (selectMiddlePoint == false). - double kp1X = 0.0; - double kp1Y = 0.0; - double kp2X = 0.0; - double kp2Y = 0.0; - double kpMidDist = Double_PositiveInfinity; - - int k; - for(k=0; k<ArrayList_Count(pSet->matches); k++) { - Match* pM = (Match*) ArrayList_GetItem(pSet->matches, k); - if (selectMiddlePoint) { - double dist = sqrt ( - pow (pM->kp1->x - p1radius, 2.0) + - pow (pM->kp1->y - p1radius, 2.0)); - - if (dist < kpMidDist) { - kpMidDist = dist; - - kp1X = pM->kp1->x; - kp1Y = pM->kp1->y; - - kp2X = pM->kp2->x; - kp2Y = pM->kp2->y; - } - } else { - kp1X += pM->kp1->x; - kp1Y += pM->kp1->y; - - kp2X += pM->kp2->x; - kp2Y += pM->kp2->y; - } - - /*WriteLine ("(%g, %g) matches (%g, %g)", - pM->kp1->x, pM->kp1->y, pM->kp2->x, pM->kp2->y);*/ - } - - if (selectMiddlePoint == false) { - kp1X /= (double) ArrayList_Count(pSet->matches); - kp1Y /= (double) ArrayList_Count(pSet->matches); - kp2X /= (double) ArrayList_Count(pSet->matches); - kp2Y /= (double) ArrayList_Count(pSet->matches); - } - - kp1X += p1x - p1radius; - kp1Y += p1y - p1radius; - - kp2X += p2x - p2radius; - kp2Y += p2y - p2radius; - - Match* mn = Match_clone (m); - - // Adjust the original keypoints location to be the mean of - // all the highly precise superresolution points. - mn->kp1->x = kp1X; - mn->kp1->y = kp1Y; - - mn->kp2->x = kp2X; - mn->kp2->y = kp2Y; - - /*WriteLine ("MASTER POINT MATCH: (%g,%g) to (%g,%g)", - kp1X, kp1Y, kp2X, kp2Y);*/ - - ArrayList_AddItem(refinedMatches, mn); - /* - DisplayImage_Save (patch1, "patch-1.jpg"); - DisplayImage_Save (patch2, "patch-2.jpg"); - exit (0); - */ - } - - ms->matches = refinedMatches; - } -} - -/** Extract a small image patch from a larger image, centered at the given - * coordinates. - */ -DisplayImage* ExtractPatch (DisplayImage* large, - int px, int py, double scale, int* radius) -{ - *radius = (int) (9.0 * scale + 0.5); - if (*radius > RefinementRadiusMaximum) - *radius = RefinementRadiusMaximum; - - /*WriteLine ("patch centered at (%d,%d), scale %g, radius = %d", - px, py, scale, *radius);*/ - - int pxe = px + *radius; - int pye = py + *radius; - px -= *radius; - py -= *radius; - - if (px < 0 || py < 0 || pxe >= large->width || pye >= large->height) { - /*WriteLine (" (%d,%d)-(%d,%d) out of (0,0)-(%d,%d)", - px, py, pxe, pye, large->width, large->height);*/ - - return (NULL); - } else { - //WriteLine (" extracting patch"); - } - DisplayImage* patch = DisplayImage_Carve (large, px, py, *radius*2, *radius*2); - - return (patch); -} - -/** Produce keypoints for a small image patch. - */ -ArrayList* ExtractKeypoints (DisplayImage* pic) -{ - ImageMap* picMap = DisplayImage_ConvertToImageMap (pic); - - LoweFeatureDetector* lf = LoweFeatureDetector_new0 (); - LoweFeatureDetector_SetPrintWarning(false); - LoweFeatureDetector_SetVerbose(false); - LoweFeatureDetector_DetectFeatures (lf, picMap); - - ArrayList* res = LoweFeatureDetector_GlobalNaturalKeypoints(lf); - lf->globalNaturalKeypoints = NULL; // Make sure res won't get deleted. - LoweFeatureDetector_delete(lf); - return res; -} - -bool YesNoOption (char* optionName, char* val) -{ - if (strcmp (val, "1") == 0 || strcmp (val, "on") == 0) - return (true); - else if (strcmp (val, "0") == 0 || strcmp (val, "off") == 0) - return (false); - - FatalError ("'%s' is no valid truth value for option '%s'. Please see manpage for help.", - val, optionName); - return false; -} - -void WritePTOFile (FILE* pto, MultiMatch* mm, - ArrayList* msList, BondBall* bb, int generateHorizon, bool integerCoordinates, - bool useAbsolutePathnames) -{ - fprintf(pto, "# Hugin project file\n"); - fprintf(pto, "# automatically generated by autopano-sift, available at\n"); - fprintf(pto, "# http://cs.tu-berlin.de/~nowozin/autopano-sift/\n\n"); - fprintf(pto, "p f2 w3000 h1500 v360 n\"JPEG q90\"\n"); - fprintf(pto, "m g1 i0\n\n"); - - int imageIndex = 0; - HashTable* imageNameTab = HashTable_new0 (NULL, NULL); - ArrayList* resolutions = ArrayList_new0 (Resolution_delete); - int i; - for(i=0; i<ArrayList_Count(mm->keySets); i++) { - KeypointXMLList* kx = (KeypointXMLList*) ArrayList_GetItem(mm->keySets, i); - HashTable_AddItem(imageNameTab, kx->imageFile, (void*)imageIndex); - ArrayList_AddItem(resolutions, Resolution_new (kx->xDim, kx->yDim)); - - char* imageFile = kx->imageFile; - - // If the resolution was already there, use the first image with - // the exact same resolution as reference for camera-related - // values. - - int refIdx; - for (refIdx = 0 ; refIdx < (ArrayList_Count(resolutions) - 1) ; ++refIdx) { - if (Resolution_CompareTo((Resolution*) ArrayList_GetItem(resolutions, refIdx), kx->xDim, kx->yDim) == 0) - break; - } - if (refIdx == (ArrayList_Count(resolutions) - 1)) - refIdx = -1; - - Position* pos = bb == NULL ? NULL : - (Position*) HashTable_GetItem(bb->positions, imageFile); - /* - if (pos != NULL) { - WriteLine ("yaw %g, pitch %g, rotation %g", - pos->yaw, pos->pitch, pos->rotation); - }*/ - - double yaw = 0.0, pitch = 0.0, rotation = 0.0; - if (pos != NULL) { - yaw = pos->yaw; - pitch = pos->pitch; - rotation = pos->rotation; - } - - if (imageIndex == 0 || refIdx == -1) { - fprintf(pto, "i w%d h%d f0 a0 b-0.01 c0 d0 e0 p%g r%g v180 y%g u10 n\"%s\"\n", - kx->xDim, kx->yDim, pitch, rotation, yaw, imageFile); - } else { - fprintf(pto, "i w%d h%d f0 a=%d b=%d c=%d d0 e0 p%g r%g v=%d y%g u10 n\"%s\"\n", - kx->xDim, kx->yDim, refIdx, refIdx, refIdx, pitch, rotation, refIdx, yaw, imageFile); - } - imageIndex += 1; - } - - fprintf(pto, "\nv p1 r1 y1\n\n"); - - fprintf(pto, "# match list automatically generated\n"); - int j; - for(j=0; j<ArrayList_Count(msList); j++) { - MatchSet* ms = (MatchSet*) ArrayList_GetItem(msList, j); - int k; - for(k=0; k<ArrayList_Count(ms->matches); k++) { - Match* m = (Match*) ArrayList_GetItem(ms->matches, k); - if (integerCoordinates == false) { - fprintf(pto, "c n%d N%d x%.6f y%.6f X%.6f Y%.6f t0\n", - (int)HashTable_GetItem(imageNameTab, ms->file1), (int)HashTable_GetItem(imageNameTab, ms->file2), - m->kp1->x, m->kp1->y, m->kp2->x, m->kp2->y); - } else { - fprintf(pto, "c n%d N%d x%d y%d X%d Y%d t0\n", - (int)HashTable_GetItem(imageNameTab, ms->file1), (int)HashTable_GetItem(imageNameTab, ms->file2), - (int) (m->kp1->x + 0.5), (int) (m->kp1->y + 0.5), - (int) (m->kp2->x + 0.5), (int) (m->kp2->y + 0.5)); - } - } - } - - // Generate horizon if we should - if (bb != NULL && generateHorizon > 0) { - WriteLine ("Creating horizon..."); - - int kMain = 2; - int hPoints = generateHorizon; - int horizonPointsMade = 0; - - bool hasGood = true; - while (hPoints > 0 && hasGood) { - hasGood = false; - int kStep = 2 * kMain; - - int p; - for (p = 0 ; hPoints > 0 && p < kMain ; ++p) { - double stepSize = ((double) ArrayList_Count(bb->firstRow)) / ((double) kStep); - double beginIndex = p * stepSize; - double endIndex = (((double) ArrayList_Count(bb->firstRow)) / (double) kMain) + - p * stepSize; - -// Round to next integer and check if their image distance -// is larger than 1. If its not, we skip over this useless -// horizon point. - int bi = (int) (beginIndex + 0.5); - int ei = (int) (endIndex + 0.5); - if ((ei - bi) <= 1) - continue; - - hasGood = true; - - bi %= ArrayList_Count(bb->firstRow); - ei %= ArrayList_Count(bb->firstRow); - fprintf(pto, "c n%s N%s x%d y%d X%d Y%d t2\n", - (char*)HashTable_GetItem(imageNameTab, ArrayList_GetItem(bb->firstRow, bi)), - (char*)HashTable_GetItem(imageNameTab, ArrayList_GetItem(bb->firstRow, ei)), - ((Resolution*) ArrayList_GetItem(resolutions,bi))->x / 2, - ((Resolution*) ArrayList_GetItem(resolutions,bi))->y / 2, - ((Resolution*) ArrayList_GetItem(resolutions,ei))->x / 2, - ((Resolution*) ArrayList_GetItem(resolutions,ei))->y / 2); - - horizonPointsMade += 1; - hPoints -= 1; - } - -// Increase density for next generation lines - kMain *= 2; - } - WriteLine (" made %d horizon lines.\n", horizonPointsMade); - } - - fprintf(pto, "\n# :-)\n\n"); - - WriteLine ("\nYou can now load the output file into hugin."); - WriteLine ("Notice: You absolutely must adjust the field-of-view value for the images"); - - ArrayList_delete(resolutions); - HashTable_delete(imageNameTab); -} - - -int main (int argc, char* argv[]) -{ - WriteLine ("autopano-sift, Automatic panorama generation program\n"); - - if (argc+1 < 3) { - Usage (); - exit (1); - } - - // downscale option for GenerteKeys - int mindim = 800; // default maxdim = 800 - - // output to stdout flag - bool streamout = false; - - // Automatic pre-aligning of images - bool preAlign = false; - int bottomDefault = -1; - int generateHorizon = 0; - - // Use RANSAC algorithm match filtration. - bool useRansac = true; - - // Use area based weighting for final match selection. - bool useAreaFiltration = true; - - // Truncate match coordinates to integer numbers. - bool useIntegerCoordinates = false; - - // Use the absolute pathname of the image files in the output PTO - // file. - bool useAbsolutePathnames = false; - - // Use "keep-best" filtration, keep the maxMatches best. - int maxMatches = 16; // default: 16 - - // Refinement options - bool refine = false; - bool refineMiddle = true; - bool keepUnrefinable = true; - - int optionCount = 0; - int optionN = 1; - while (optionN < argc && - strlen(argv[optionN]) >= 2 - && argv[optionN][0] == '-' - && argv[optionN][1] == '-') - { - char* optionStr = argv[optionN]; - - if (strcmp (optionStr, "--maxdim") == 0) { - mindim = atoi(argv[optionN + 1]); - optionN += 2; - } else if (strcmp (optionStr, "--ransac") == 0) { - useRansac = YesNoOption ("--ransac", argv[optionN + 1]); - optionN += 2; - } else if (strcmp (optionStr, "--maxmatches") == 0) { - if (sscanf(argv[optionN + 1], "%d", &maxMatches) != 1) { - WriteLine ("Parameter to maxmatches option invalid. See the usage help."); - exit (1); - } - if (maxMatches < 0) { - WriteLine ("Maximum number of matches must be positive or zero (unlimited)."); - exit (1); - } - optionN += 2; - } else if (strcmp (optionStr, "--disable-areafilter") == 0) { - useAreaFiltration = false; - optionN += 1; - } else if (strcmp (optionStr, "--integer-coordinates") == 0) { - useIntegerCoordinates = true; - optionN += 1; - } else if (strcmp (optionStr, "--absolute-pathnames") == 0) { - useAbsolutePathnames = YesNoOption ("--absolute-pathnames", argv[optionN + 1]); - optionN += 2; - } else if (strcmp (optionStr, "--align") == 0) { - preAlign = true; - optionN += 1; - } else if (strcmp (optionStr, "--bottom-is-left") == 0) { - bottomDefault = 0; - optionN += 1; - } else if (strcmp (optionStr, "--bottom-is-right") == 0) { - bottomDefault = 1; - optionN += 1; - } else if (strcmp (optionStr, "--generate-horizon") == 0) { - if (sscanf(argv[optionN + 1], "%d", &generateHorizon) != 1) { - WriteLine ("Parameter to generate-horizon option invalid. See the usage help."); - exit (1); - } - if (generateHorizon < 0) { - WriteLine ("The number of horizon lines to generate must be positive."); - exit (1); - } - - optionN += 2; - } else if (strcmp (optionStr, "--refine") == 0) { - refine = true; - optionN += 1; - } else if (strcmp (optionStr, "--refine-by-middle") == 0) { - refineMiddle = true; - optionN += 1; - } else if (strcmp (optionStr, "--refine-by-mean") == 0) { - refineMiddle = false; - optionN += 1; - } else if (strcmp (optionStr, "--keep-unrefinable") == 0) { - keepUnrefinable = YesNoOption ("--keep-unrefinable", argv[optionN + 1]); - optionN += 2; - } else { - WriteLine ("Option error. Run without arguments for help."); - exit (1); - } - } - optionCount = optionN; - // is there an output name and at least one input name? - if( argc - optionN < 2 ){ - WriteLine ("Error. Output name and at least one image name required."); - Usage(); - exit(1); - } - // next arg is either output file name or "-" for stdout - // anything else beginning with '-' is an error - if( argv[optionCount][0] == '-' ){ - if( strcmp( argv[optionCount], "-" ) == 0 )streamout = true; - else { - WriteLine ("Option error. Run without arguments for help."); - exit (1); - } - } - - if (bottomDefault != -1 && preAlign == false) { - WriteLine ("Please enable automatic alignment (\"--align\") before using the"); - WriteLine ("--bottom-is-* options. Run without arguments for help."); - - exit (1); - } - - if (generateHorizon > 0 && preAlign == false) { - WriteLine ("Please enable automatic alignment (\"--align\") before using the"); - WriteLine ("--generate-horizon option. Run without arguments for help."); - - exit (1); - } - - MultiMatch* mm = MultiMatch_new0 (); -//------------ - ArrayList* keylists = ArrayList_new0(NULL); - int i; - for( i=0; i<argc - 1 - optionCount; i++) { - ArrayList_AddItem(keylists, GenerateKeys( argv[i+optionCount+1], mindim ) ); - } - MultiMatch_LoadKeysetsFromMemory (mm, keylists); - // note mm now owns keylists and will delete it when destroyed -//------------- - - WriteLine ("\nMatching...%s", useRansac == true ? " RANSAC enabled" : ""); - ArrayList* msList = MultiMatch_LocateMatchSets (mm, 3, maxMatches, - useRansac, useAreaFiltration); - - // Connected component check - WriteLine ("\nConnected component check..."); - ArrayList* components = MultiMatch_ComponentCheck (mm, msList); - WriteLine ("Connected component identification resulted in %d component%s:", - ArrayList_Count(components), ArrayList_Count(components) > 1 ? "s" : ""); - - int compN = 1; - int j; - for(j=0; j<ArrayList_Count(components); j++) { - Component* comp = (Component*) ArrayList_GetItem(components, j); - char* compstr = Component_ToString(comp); - WriteLine ("component %d: %s", compN++, compstr); - free(compstr); - } - - if (ArrayList_Count(components) > 1) { - WriteLine (""); - WriteLine ("Warning: There is one or more components that are not connected through control"); - WriteLine (" points. An optimization of the resulting PTO will not be possible"); - WriteLine (" without prior adding of control points between the components listed"); - WriteLine (" above. Please see the manual page for autopano(1) for details."); - WriteLine (""); - } else - WriteLine (""); - - // BondBall algorithm - BondBall* bb = NULL; - if (preAlign) { - bb = MultiMatch_BuildBondBall (mm, msList, bottomDefault); - - if (bb == NULL) { - WriteLine ("WARNING: Failed to build bondball as requested. No pre-aligning of images"); - WriteLine (" takes place.\n"); - } - } - - if (refine) { - WriteLine ("Refining keypoints"); - RefineKeypoints (msList, refineMiddle, keepUnrefinable); - } - - FILE* pto; - if ( streamout ) { - pto = stdout; - } else { - WriteLine ("Creating output file \"%s\"", argv[optionCount]); - pto = fopen(argv[optionCount], "w"); - } - - WritePTOFile (pto, mm, msList, bb, generateHorizon, useIntegerCoordinates, - useAbsolutePathnames); - - ArrayList_delete(components); - BondBall_delete(bb); - MultiMatch_delete(mm); - if ( !streamout ) - fclose(pto); - return 0; -} - + +/* APSCmain.c 06Feb2008 TKSharpless + Single-executable form of AutoPano-sift-C for Hugin 0.7 + Here, GenerateKeys is a subroutine + + * Keypoint file correlation and hugin panorama file creation utility. + * + * (C) Copyright 2004 -- Sebastian Nowozin (no...@cs...) + * + * "The University of British Columbia has applied for a patent on the SIFT + * algorithm in the United States. Commercial applications of this software + * may require a license from the University of British Columbia." + * For more information, see the LICENSE file supplied with the distribution. + * + * This program is free software released under the GNU General Public + * License, which is included in this software package (doc/LICENSE). +*/ + +#include "AutoPanoSift.h" + +void Usage () +{ + WriteLine ("APSC: Generate and Match Keypoints giving Hugin project file\n"); + WriteLine (" Version %s\n", PACKAGE_VERSION); + WriteLine ("usage: APSC.exe [options] output.pto image1 image2 [..]\n"); + WriteLine ("Options"); + WriteLine (" --ransac <on|off|1|0> Switch RANSAC filtration on or off (default: on)"); + WriteLine (" --maxmatches <matches> Use no more than the given number of matches"); + WriteLine (" (default: 16, use zero for unlimited)"); + + WriteLine (" --disable-areafilter Do not use max-area filtration, which is default."); + WriteLine (" See manpage for details."); + WriteLine (" --integer-coordinates Truncate match coordinates to integer numbers."); + WriteLine (" --absolute-pathnames <on|off|1|0> Use the absolute pathname of the image"); + WriteLine (" file in the PTO output file. Disabled by default."); + WriteLine (" --maxdim <integer> input images are repeatedly halfed in size until"); + WriteLine (" both width and height are below 'maxdim' (default: 800)."); + WriteLine (""); + + WriteLine ("Alignment options"); + WriteLine (" --align Automatically pre-align images in PTO file."); + WriteLine (" --bottom-is-left"); + WriteLine (" --bottom-is-right Use in case the automatic algorithm fails."); + WriteLine (" --generate-horizon <c> Generate up to 'c' horizon lines."); + WriteLine (""); + + WriteLine ("Refinement options"); + WriteLine (" --refine Refine the found control points using the"); + WriteLine (" original images."); + WriteLine (" --refine-by-middle Use the best middle point to refine (default)."); + WriteLine (" --refine-by-mean Use the mean of the patches control points."); + WriteLine (" --keep-unrefinable <on|off|1|0>"); + WriteLine (" Keep unrefinable matches (default: on)."); + + WriteLine ("output.pto: The output PTO panorama project file."); + WriteLine (" The filename can be \"-\", then stdout is used"); + WriteLine ("image<n>: input image files (any common format: JPEG, PNG, TIFF, ..)"); + WriteLine ("Notice: for the aligning to work, the input images shall be"); + WriteLine (" 1. All of the same dimension and scale"); + WriteLine (" 2. The first images must be an ordered row. See manpage."); + WriteLine (""); +} + +// subroutine equivalent to GenerateKeys.c +KeypointXMLList * GenerateKeys( char* imgname, int downRes ) +{ + // 1. load the image file + DisplayImage* pic = DisplayImage_new(imgname); + int pW = pic->width; + int pH = pic->height; + ImageMap* picMap; + LoweFeatureDetector* lf; + KeypointXMLList* kpp; + double startScale = 1.0; + + if (downRes > 0) { + startScale = DisplayImage_ScaleWithin(pic, downRes); +// WriteLine ("Scaled picture, starting with scale %0.04f", startScale); + } + picMap = DisplayImage_ConvertToImageMap(pic); + DisplayImage_delete(pic); + + // 2. find the features + lf = LoweFeatureDetector_new0(); + + if (downRes > 0) { + LoweFeatureDetector_DetectFeaturesDownscaled (lf, picMap, 0, 1.0 / startScale); + } else + LoweFeatureDetector_DetectFeatures (lf, picMap); + + /* build the return value + We need a new copy of the list held in lf because lf is about to be deleted. + The following code adapted from LoweFeatureDetector_GlobalNaturalKeypoints() + does that, and also a needed format conversion (lucky this is not C++!) + */ + ArrayList * globalNaturalKeypoints = ArrayList_new0 (KeypointN_delete); + int i; + for(i=0; i < ArrayList_Count(lf->globalKeypoints); i++) { + Keypoint* kp = (Keypoint *) ArrayList_GetItem( lf->globalKeypoints, i ); + ArrayList_AddItem ( globalNaturalKeypoints, KeypointN_new( kp )); + } + // package result as a KeypointXMLList + kpp = KeypointXMLList_new ( imgname, pW, pH, globalNaturalKeypoints ); + + LoweFeatureDetector_delete(lf); + + // disable the patent warning message (for any subsequent images) + LoweFeatureDetector_SetPrintWarning(false); + + return kpp; +} + + +typedef struct Resolution Resolution; +struct Resolution +{ + int x, y; +}; + +Resolution* Resolution_new0() +{ + Resolution* self = (Resolution*)malloc(sizeof(Resolution)); + return self; +} + +Resolution* Resolution_new(int x, int y) +{ + Resolution* self = Resolution_new0(); + self->x = x; + self->y = y; + return self; +} + +void Resolution_delete(Resolution* self) +{ + if (self) { + free(self); + } +} + +int Resolution_CompareTo (Resolution* self, int x, int y) +{ + + if (self->x == x && self->y == y) + return (0); + + return (1); +} + + + + +// The maximum radius to consider around a keypoint that is refined. That +// is, at most a patch of a maximum size of twice this value in both +// horizontal and vertical direction is extracted. +int RefinementRadiusMaximum = 96; +int (*refineHandler)(int index, int total); + + +void RefineKeypoints (ArrayList* msList, + bool selectMiddlePoint, bool neverLosePoints); +DisplayImage* ExtractPatch (DisplayImage* large, + int px, int py, double scale, int* radius); +ArrayList* ExtractKeypoints (DisplayImage* pic); +bool YesNoOption (char* optionName, char* val); + +// selectMiddlePoint: if true, select the middle point in the patch, +// otherwise build the mean +// neverLosePoints: if true, and if we cannot do the refinement, still use +// the control point. +void RefineKeypoints (ArrayList* msList, + bool selectMiddlePoint, bool neverLosePoints) +{ + DisplayImage* pic1 = NULL; + DisplayImage* pic2 = NULL; + char* pic1Name = NULL; + char* pic2Name = NULL; + + /* Keep stats for the refineHandler delegate + */ + int totalRefines = 0; + int doneRefines = 0; + int i; + for(i=0; i<ArrayList_Count(msList); i++) { + MatchSet* ms = (MatchSet*) ArrayList_GetItem(msList, i); + int j; + for(j=0; j<ArrayList_Count(ms->matches); j++) { + ArrayList_GetItem(ms->matches, j); + totalRefines += 1; + } + } + + + for(i=0; i<ArrayList_Count(msList); i++) { + MatchSet* ms = (MatchSet*) ArrayList_GetItem(msList, i); + WriteLine (" between \"%s\" and \"%s\"", + ms->file1, ms->file2); + + if (pic1Name != ms->file1) { + pic1Name = ms->file1; + pic1 = DisplayImage_new (ms->file1); + } + if (pic2Name != ms->file2) { + pic2Name = ms->file2; + pic2 = DisplayImage_new (ms->file2); + } + /*WriteLine ("pair: %s, %s, %d keypoint matches", + ms->file1, ms->file2, ArrayList_Count(ms->Matches));*/ + + ArrayList* refinedMatches = ArrayList_new0 (NULL); + + int j; + for(j=0; j<ArrayList_Count(ms->matches); j++) { + Match* m = (Match*) ArrayList_GetItem(ms->matches, j); + + int p1x = (int) (m->kp1->x + 0.5); + int p1y = (int) (m->kp1->y + 0.5); + int p1radius; + DisplayImage* patch1 = ExtractPatch (pic1, p1x, p1y, + m->kp1->scale, &p1radius); + + int p2x = (int) (m->kp2->x + 0.5); + int p2y = (int) (m->kp2->y + 0.5); + int p2radius; + DisplayImage* patch2 = ExtractPatch (pic2, p2x, p2y, + m->kp2->scale, &p2radius); + + /* Call the refine handler delegate in case there is one to + * inform the callee of a single refining step (for progress + * bar displays and such). + */ + doneRefines += 1; + if (refineHandler != NULL) + refineHandler (doneRefines, totalRefines); + + // Skip over keypoint matches we cannot refine as part of the + // image lies outside. + if (patch1 == NULL || patch2 == NULL) { + if (neverLosePoints) + ArrayList_AddItem(refinedMatches, m); + DisplayImage_delete(patch1); + DisplayImage_delete(patch2); + continue; + } + + // Otherwise, run the SIFT algorithm on both small patches. + ArrayList* p1kp = ExtractKeypoints (patch1); + ArrayList* p2kp = ExtractKeypoints (patch2); + /*WriteLine ("p1kp = %d, p2kp = %d", ArrayList_Count(p1kp), + ArrayList_Count(p2kp));*/ + + // Apply the matching, RANSAC enabled. + MultiMatch* mm = MultiMatch_new0 (); + mm->verbose = false; + + ArrayList* matches = NULL; + matches = MultiMatch_TwoPatchMatch (mm, p1kp, + patch1->width, patch1->height, p2kp, patch2->width, + patch2->height, true); + DisplayImage_delete(patch1); + DisplayImage_delete(patch2); + + /* In case there are less than three keypoints in the + * two patches, we ignore them all. + */ + if (0 /*was exception ???*/ ) { + matches = NULL; + } + + if (matches == NULL || ArrayList_Count(matches) != 1) { + if (neverLosePoints) + ArrayList_AddItem(refinedMatches, m); + + continue; + } + + MatchSet* pSet = (MatchSet*) ArrayList_GetItem(matches, 0); + + // Now get the real new control point coordinates from the + // patches. We have two options and assume all points are + // equal quality-wise: + // a) Select the one that is most in the middle + // (selectMiddlePoint == true) + // b) Build the mean of all the control point matches in the + // patches (selectMiddlePoint == false). + double kp1X = 0.0; + double kp1Y = 0.0; + double kp2X = 0.0; + double kp2Y = 0.0; + double kpMidDist = Double_PositiveInfinity; + + int k; + for(k=0; k<ArrayList_Count(pSet->matches); k++) { + Match* pM = (Match*) ArrayList_GetItem(pSet->matches, k); + if (selectMiddlePoint) { + double dist = sqrt ( + pow (pM->kp1->x - p1radius, 2.0) + + pow (pM->kp1->y - p1radius, 2.0)); + + if (dist < kpMidDist) { + kpMidDist = dist; + + kp1X = pM->kp1->x; + kp1Y = pM->kp1->y; + + kp2X = pM->kp2->x; + kp2Y = pM->kp2->y; + } + } else { + kp1X += pM->kp1->x; + kp1Y += pM->kp1->y; + + kp2X += pM->kp2->x; + kp2Y += pM->kp2->y; + } + + /*WriteLine ("(%g, %g) matches (%g, %g)", + pM->kp1->x, pM->kp1->y, pM->kp2->x, pM->kp2->y);*/ + } + + if (selectMiddlePoint == false) { + kp1X /= (double) ArrayList_Count(pSet->matches); + kp1Y /= (double) ArrayList_Count(pSet->matches); + kp2X /= (double) ArrayList_Count(pSet->matches); + kp2Y /= (double) ArrayList_Count(pSet->matches); + } + + kp1X += p1x - p1radius; + kp1Y += p1y - p1radius; + + kp2X += p2x - p2radius; + kp2Y += p2y - p2radius; + + Match* mn = Match_clone (m); + + // Adjust the original keypoints location to be the mean of + // all the highly precise superresolution points. + mn->kp1->x = kp1X; + mn->kp1->y = kp1Y; + + mn->kp2->x = kp2X; + mn->kp2->y = kp2Y; + + /*WriteLine ("MASTER POINT MATCH: (%g,%g) to (%g,%g)", + kp1X, kp1Y, kp2X, kp2Y);*/ + + ArrayList_AddItem(refinedMatches, mn); + /* + DisplayImage_Save (patch1, "patch-1.jpg"); + DisplayImage_Save (patch2, "patch-2.jpg"); + exit (0); + */ + } + + ms->matches = refinedMatches; + } +} + +/** Extract a small image patch from a larger image, centered at the given + * coordinates. + */ +DisplayImage* ExtractPatch (DisplayImage* large, + int px, int py, double scale, int* radius) +{ + *radius = (int) (9.0 * scale + 0.5); + if (*radius > RefinementRadiusMaximum) + *radius = RefinementRadiusMaximum; + + /*WriteLine ("patch centered at (%d,%d), scale %g, radius = %d", + px, py, scale, *radius);*/ + + int pxe = px + *radius; + int pye = py + *radius; + px -= *radius; + py -= *radius; + + if (px < 0 || py < 0 || pxe >= large->width || pye >= large->height) { + /*WriteLine (" (%d,%d)-(%d,%d) out of (0,0)-(%d,%d)", + px, py, pxe, pye, large->width, large->height);*/ + + return (NULL); + } else { + //WriteLine (" extracting patch"); + } + DisplayImage* patch = DisplayImage_Carve (large, px, py, *radius*2, *radius*2); + + return (patch); +} + +/** Produce keypoints for a small image patch. + */ +ArrayList* ExtractKeypoints (DisplayImage* pic) +{ + ImageMap* picMap = DisplayImage_ConvertToImageMap (pic); + + LoweFeatureDetector* lf = LoweFeatureDetector_new0 (); + LoweFeatureDetector_SetPrintWarning(false); + LoweFeatureDetector_SetVerbose(false); + LoweFeatureDetector_DetectFeatures (lf, picMap); + + ArrayList* res = LoweFeatureDetector_GlobalNaturalKeypoints(lf); + lf->globalNaturalKeypoints = NULL; // Make sure res won't get deleted. + LoweFeatureDetector_delete(lf); + return res; +} + +bool YesNoOption (char* optionName, char* val) +{ + if (strcmp (val, "1") == 0 || strcmp (val, "on") == 0) + return (true); + else if (strcmp (val, "0") == 0 || strcmp (val, "off") == 0) + return (false); + + FatalError ("'%s' is no valid truth value for option '%s'. Please see manpage for help.", + val, optionName); + return false; +} + +void WritePTOFile (FILE* pto, MultiMatch* mm, + ArrayList* msList, BondBall* bb, int generateHorizon, bool integerCoordinates, + bool useAbsolutePathnames) +{ + fprintf(pto, "# Hugin project file\n"); + fprintf(pto, "# automatically generated by autopano-sift, available at\n"); + fprintf(pto, "# http://cs.tu-berlin.de/~nowozin/autopano-sift/\n\n"); + fprintf(pto, "p f2 w3000 h1500 v360 n\"JPEG q90\"\n"); + fprintf(pto, "m g1 i0\n\n"); + + int imageIndex = 0; + HashTable* imageNameTab = HashTable_new0 (NULL, NULL); + ArrayList* resolutions = ArrayList_new0 (Resolution_delete); + int i; + for(i=0; i<ArrayList_Count(mm->keySets); i++) { + KeypointXMLList* kx = (KeypointXMLList*) ArrayList_GetItem(mm->keySets, i); + HashTable_AddItem(imageNameTab, kx->imageFile, (void*)imageIndex); + ArrayList_AddItem(resolutions, Resolution_new (kx->xDim, kx->yDim)); + + char* imageFile = kx->imageFile; + + // If the resolution was already there, use the first image with + // the exact same resolution as reference for camera-related + // values. + + int refIdx; + for (refIdx = 0 ; refIdx < (ArrayList_Count(resolutions) - 1) ; ++refIdx) { + if (Resolution_CompareTo((Resolution*) ArrayList_GetItem(resolutions, refIdx), kx->xDim, kx->yDim) == 0) + break; + } + if (refIdx == (ArrayList_Count(resolutions) - 1)) + refIdx = -1; + + Position* pos = bb == NULL ? NULL : + (Position*) HashTable_GetItem(bb->positions, imageFile); + /* + if (pos != NULL) { + WriteLine ("yaw %g, pitch %g, rotation %g", + pos->yaw, pos->pitch, pos->rotation); + }*/ + + double yaw = 0.0, pitch = 0.0, rotation = 0.0; + if (pos != NULL) { + yaw = pos->yaw; + pitch = pos->pitch; + rotation = pos->rotation; + } + + if (imageIndex == 0 || refIdx == -1) { + fprintf(pto, "i w%d h%d f0 a0 b-0.01 c0 d0 e0 p%g r%g v180 y%g u10 n\"%s\"\n", + kx->xDim, kx->yDim, pitch, rotation, yaw, imageFile); + } else { + fprintf(pto, "i w%d h%d f0 a=%d b=%d c=%d d0 e0 p%g r%g v=%d y%g u10 n\"%s\"\n", + kx->xDim, kx->yDim, refIdx, refIdx, refIdx, pitch, rotation, refIdx, yaw, imageFile); + } + imageIndex += 1; + } + + fprintf(pto, "\nv p1 r1 y1\n\n"); + + fprintf(pto, "# match list automatically generated\n"); + int j; + for(j=0; j<ArrayList_Count(msList); j++) { + MatchSet* ms = (MatchSet*) ArrayList_GetItem(msList, j); + int k; + for(k=0; k<ArrayList_Count(ms->matches); k++) { + Match* m = (Match*) ArrayList_GetItem(ms->matches, k); + if (integerCoordinates == false) { + fprintf(pto, "c n%d N%d x%.6f y%.6f X%.6f Y%.6f t0\n", + (int)HashTable_GetItem(imageNameTab, ms->file1), (int)HashTable_GetItem(imageNameTab, ms->file2), + m->kp1->x, m->kp1->y, m->kp2->x, m->kp2->y); + } else { + fprintf(pto, "c n%d N%d x%d y%d X%d Y%d t0\n", + (int)HashTable_GetItem(imageNameTab, ms->file1), (int)HashTable_GetItem(imageNameTab, ms->file2), + (int) (m->kp1->x + 0.5), (int) (m->kp1->y + 0.5), + (int) (m->kp2->x + 0.5), (int) (m->kp2->y + 0.5)); + } + } + } + + // Generate horizon if we should + if (bb != NULL && generateHorizon > 0) { + WriteLine ("Creating horizon..."); + + int kMain = 2; + int hPoints = generateHorizon; + int horizonPointsMade = 0; + + bool hasGood = true; + while (hPoints > 0 && hasGood) { + hasGood = false; + int kStep = 2 * kMain; + + int p; + for (p = 0 ; hPoints > 0 && p < kMain ; ++p) { + double stepSize = ((double) ArrayList_Count(bb->firstRow)) / ((double) kStep); + double beginIndex = p * stepSize; + double endIndex = (((double) ArrayList_Count(bb->firstRow)) / (double) kMain) + + p * stepSize; + +// Round to next integer and check if their image distance +// is larger than 1. If its not, we skip over this useless +// horizon point. + int bi = (int) (beginIndex + 0.5); + int ei = (int) (endIndex + 0.5); + if ((ei - bi) <= 1) + continue; + + hasGood = true; + + bi %= ArrayList_Count(bb->firstRow); + ei %= ArrayList_Count(bb->firstRow); + fprintf(pto, "c n%s N%s x%d y%d X%d Y%d t2\n", + (char*)HashTable_GetItem(imageNameTab, ArrayList_GetItem(bb->firstRow, bi)), + (char*)HashTable_GetItem(imageNameTab, ArrayList_GetItem(bb->firstRow, ei)), + ((Resolution*) ArrayList_GetItem(resolutions,bi))->x / 2, + ((Resolution*) ArrayList_GetItem(resolutions,bi))->y / 2, + ((Resolution*) ArrayList_GetItem(resolutions,ei))->x / 2, + ((Resolution*) ArrayList_GetItem(resolutions,ei))->y / 2); + + horizonPointsMade += 1; + hPoints -= 1; + } + +// Increase density for next generation lines + kMain *= 2; + } + WriteLine (" made %d horizon lines.\n", horizonPointsMade); + } + + fprintf(pto, "\n# :-)\n\n"); + + WriteLine ("\nYou can now load the output file into hugin."); + WriteLine ("Notice: You absolutely must adjust the field-of-view value for the images"); + + ArrayList_delete(resolutions); + HashTable_delete(imageNameTab); +} + + +int main (int argc, char* argv[]) +{ + WriteLine ("autopano-sift, Automatic panorama generation program\n"); + + if (argc+1 < 3) { + Usage (); + exit (1); + } + + // downscale option for GenerteKeys + int mindim = 800; // default maxdim = 800 + + // output to stdout flag + bool streamout = false; + + // Automatic pre-aligning of images + bool preAlign = false; + int bottomDefault = -1; + int generateHorizon = 0; + + // Use RANSAC algorithm match filtration. + bool useRansac = true; + + // Use area based weighting for final match selection. + bool useAreaFiltration = true; + + // Truncate match coordinates to integer numbers. + bool useIntegerCoordinates = false; + + // Use the absolute pathname of the image files in the output PTO + // file. + bool useAbsolutePathnames = false; + + // Use "keep-best" filtration, keep the maxMatches best. + int maxMatches = 16; // default: 16 + + // Refinement options + bool refine = false; + bool refineMiddle = true; + bool keepUnrefinable = true; + + int optionCount = 0; + int optionN = 1; + while (optionN < argc && + strlen(argv[optionN]) >= 2 + && argv[optionN][0] == '-' + && argv[optionN][1] == '-') + { + char* optionStr = argv[optionN]; + + if (strcmp (optionStr, "--maxdim") == 0) { + mindim = atoi(argv[optionN + 1]); + optionN += 2; + } else if (strcmp (optionStr, "--ransac") == 0) { + useRansac = YesNoOption ("--ransac", argv[optionN + 1]); + optionN += 2; + } else if (strcmp (optionStr, "--maxmatches") == 0) { + if (sscanf(argv[optionN + 1], "%d", &maxMatches) != 1) { + WriteLine ("Parameter to maxmatches option invalid. See the usage help."); + exit (1); + } + if (maxMatches < 0) { + WriteLine ("Maximum number of matches must be positive or zero (unlimited)."); + exit (1); + } + optionN += 2; + } else if (strcmp (optionStr, "--disable-areafilter") == 0) { + useAreaFiltration = false; + optionN += 1; + } else if (strcmp (optionStr, "--integer-coordinates") == 0) { + useIntegerCoordinates = true; + optionN += 1; + } else if (strcmp (optionStr, "--absolute-pathnames") == 0) { + useAbsolutePathnames = YesNoOption ("--absolute-pathnames", argv[optionN + 1]); + optionN += 2; + } else if (strcmp (optionStr, "--align") == 0) { + preAlign = true; + optionN += 1; + } else if (strcmp (optionStr, "--bottom-is-left") == 0) { + bottomDefault = 0; + optionN += 1; + } else if (strcmp (optionStr, "--bottom-is-right") == 0) { + bottomDefault = 1; + optionN += 1; + } else if (strcmp (optionStr, "--generate-horizon") == 0) { + if (sscanf(argv[optionN + 1], "%d", &generateHorizon) != 1) { + WriteLine ("Parameter to generate-horizon option invalid. See the usage help."); + exit (1); + } + if (generateHorizon < 0) { + WriteLine ("The number of horizon lines to generate must be positive."); + exit (1); + } + + optionN += 2; + } else if (strcmp (optionStr, "--refine") == 0) { + refine = true; + optionN += 1; + } else if (strcmp (optionStr, "--refine-by-middle") == 0) { + refineMiddle = true; + optionN += 1; + } else if (strcmp (optionStr, "--refine-by-mean") == 0) { + refineMiddle = false; + optionN += 1; + } else if (strcmp (optionStr, "--keep-unrefinable") == 0) { + keepUnrefinable = YesNoOption ("--keep-unrefinable", argv[optionN + 1]); + optionN += 2; + } else { + WriteLine ("Option error. Run without arguments for help."); + exit (1); + } + } + optionCount = optionN; + // is there an output name and at least one input name? + if( argc - optionN < 2 ){ + WriteLine ("Error. Output name and at least one image name required."); + Usage(); + exit(1); + } + // next arg is either output file name or "-" for stdout + // anything else beginning with '-' is an error + if( argv[optionCount][0] == '-' ){ + if( strcmp( argv[optionCount], "-" ) == 0 )streamout = true; + else { + WriteLine ("Option error. Run without arguments for help."); + exit (1); + } + } + + if (bottomDefault != -1 && preAlign == false) { + WriteLine ("Please enable automatic alignment (\"--align\") before using the"); + WriteLine ("--bottom-is-* options. Run without arguments for help."); + + exit (1); + } + + if (generateHorizon > 0 && preAlign == false) { + WriteLine ("Please enable automatic alignment (\"--align\") before using the"); + WriteLine ("--generate-horizon option. Run without arguments for help."); + + exit (1); + } + + MultiMatch* mm = MultiMatch_new0 (); +//------------ + ArrayList* keylists = ArrayList_new0(NULL); + int i; + for( i=0; i<argc - 1 - optionCount; i++) { + ArrayList_AddItem(keylists, GenerateKeys( argv[i+optionCount+1], mindim ) ); + } + MultiMatch_LoadKeysetsFromMemory (mm, keylists); + // note mm now owns keylists and will delete it when destroyed +//------------- + + WriteLine ("\nMatching...%s", useRansac == true ? " RANSAC enabled" : ""); + ArrayList* msList = MultiMatch_LocateMatchSets (mm, 3, maxMatches, + useRansac, useAreaFiltration); + + // Connected component check + WriteLine ("\nConnected component check..."); + ArrayList* components = MultiMatch_ComponentCheck (mm, msList); + WriteLine ("Connected component identification resulted in %d component%s:", + ArrayList_Count(components), ArrayList_Count(components) > 1 ? "s" : ""); + + int compN = 1; + int j; + for(j=0; j<ArrayList_Count(components); j++) { + Component* comp = (Component*) ArrayList_GetItem(components, j); + char* compstr = Component_ToString(comp); + WriteLine ("component %d: %s", compN++, compstr); + free(compstr); + } + + if (ArrayList_Count(components) > 1) { + WriteLine (""); + WriteLine ("Warning: There is one or more components that are not connected through control"); + WriteLine (" points. An optimization of the resulting PTO will not be possible"); + WriteLine (" without prior adding of control points between the components listed"); + WriteLine (" above. Please see the manual page for autopano(1) for details."); + WriteLine (""); + } else + WriteLine (""); + + // BondBall algorithm + BondBall* bb = NULL; + if (preAlign) { + bb = MultiMatch_BuildBondBall (mm, msList, bottomDefault); + + if (bb == NULL) { + WriteLine ("WARNING: Failed to build bondball as requested. No pre-aligning of images"); + WriteLine (" takes place.\n"); + } + } + + if (refine) { + WriteLine ("Refining keypoints"); + RefineKeypoints (msList, refineMiddle, keepUnrefinable); + } + + FILE* pto; + if ( streamout ) { + pto = stdout; + } else { + WriteLine ("Creating output file \"%s\"", argv[optionCount]); + pto = fopen(argv[optionCount], "w"); + } + + WritePTOFile (pto, mm, msList, bb, generateHorizon, useIntegerCoordinates, + useAbsolutePathnames); + + ArrayList_delete(components); + BondBall_delete(bb); + MultiMatch_delete(mm); + if ( !streamout ) + fclose(pto); + return 0; +} + Modified: autopano-sift-C/trunk/APSCpp/ANN/CMakeLists.txt =================================================================== --- autopano-sift-C/trunk/APSCpp/ANN/CMakeLists.txt 2009-05-29 22:20:37 UTC (rev 3896) +++ autopano-sift-C/trunk/APSCpp/ANN/CMakeLists.txt 2009-05-30 20:16:45 UTC (rev 3897) @@ -1,17 +1,17 @@ -# CMakeLists.txt for APSCpp/ANN 07 Mar 2008 TKS -# -# Note this is a customized version of ANN, see ANN.h -# - -SET(ANN_SRC ANN.cpp brute.cpp kd_tree.cpp kd_util.cpp kd_split.cpp - kd_dump.cpp kd_search.cpp kd_pr_search.cpp kd_fix_rad_search.cpp - bd_tree.cpp bd_search.cpp bd_pr_search.cpp bd_fix_rad_search.cpp - perf.cpp) - -SET(ANN_HEADERS ANN.h ANNperf.h ANNx.h kd_tree.h kd_split.h kd_util.h kd_search.h - kd_pr_search.h kd_fix_rad_search.h perf.h pr_queue.h pr_queue_k.h) - - -add_library(ANN STATIC ${ANN_SRC}) - - +# CMakeLists.txt for APSCpp/ANN 07 Mar 2008 TKS +# +# Note this is a customized version of ANN, see ANN.h +# + +SET(ANN_SRC ANN.cpp brute.cpp kd_tree.cpp kd_util.cpp kd_split.cpp + kd_dump.cpp kd_search.cpp kd_pr_search.cpp kd_fix_rad_search.cpp + bd_tree.cpp bd_search.cpp bd_pr_search.cpp bd_fix_rad_search.cpp + perf.cpp) + +SET(ANN_HEADERS ANN.h ANNperf.h ANNx.h kd_tree.h kd_split.h kd_util.h kd_search.h + kd_pr_search.h kd_fix_rad_search.h perf.h pr_queue.h pr_queue_k.h) + + +add_library(ANN STATIC ${ANN_SRC}) + + Modified: autopano-sift-C/trunk/APSCpp/ANNkd_wrap.cpp =================================================================== --- autopano-sift-C/trunk/APSCpp/ANNkd_wrap.cpp 2009-05-29 22:20:37 UTC (rev 3896) +++ autopano-sift-C/trunk/APSCpp/ANNkd_wrap.cpp 2009-05-30 20:16:45 UTC (rev 3897) @@ -1,43 +1,43 @@ -/** ANNkd_wrap.cpp 08 Mar 2008 TKSharpless - -C-callable wrapper for ANN kd-tree search, for autopano-sift-c -The objective is to allow all legacy code to be compiled as c -because it is full of standards-violating pointer usages (that -MSVC++ doesn't notice). - -**/ - -#include "ANN/ANN.h" - -static ANNkd_tree * pkd = 0; - -extern "C" -void ANNkd_new( int sd, double ** pts, int n, int d ){ - - annMaxPtsVisit( sd ); - - pkd = new ANNkd_tree ( // build from point array - pts, // point array - n, // number of points - d, // dimension - 1, // bucket size - ANN_KD_SUGGEST); // splitting method - - -} - -extern "C" -void ANNkd_search( double * pt, int nnabe, int *indx, double *dist, double nneps ){ - - pkd->annkSearch( pt, nnabe, indx, dist, nneps ); - -} - -extern "C" -void ANNkd_delete( void ){ - - if( pkd ) delete pkd; - pkd = 0; - -} - +/** ANNkd_wrap.cpp 08 Mar 2008 TKSharpless + +C-callable wrapper for ANN kd-tree search, for autopano-sift-c +The objective is to allow all legacy code to be compiled as c +because it is full of standards-violating pointer usages (that +MSVC++ doesn't notice). + +**/ + +#include "ANN/ANN.h" + +static ANNkd_tree * pkd = 0; + +extern "C" +void ANNkd_new( int sd, double ** pts, int n, int d ){ + + annMaxPtsVisit( sd ); + + pkd = new ANNkd_tree ( // build from point array + pts, // point array + n, // number of points + d, // dimension + 1, // bucket size + ANN_KD_SUGGEST); // splitting method + + +} + +extern "C" +void ANNkd_search( double * pt, int nnabe, int *indx, double *dist, double nneps ){ + + pkd->annkSearch( pt, nnabe, indx, dist, nneps ); + +} + +extern "C" +void ANNkd_delete( void ){ + + if( pkd ) delete pkd; + pkd = 0; + +} + Modified: autopano-sift-C/trunk/APSCpp/APSCpp.c =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp.c 2009-05-29 22:20:37 UTC (rev 3896) +++ autopano-sift-C/trunk/APSCpp/APSCpp.c 2009-05-30 20:16:45 UTC (rev 3897) @@ -1,577 +1,577 @@ -/* APSCpp.cpp 04 Mar 2008 TKS - various routines for enhanced autopano-sift-c -*/ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This software 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include "AutoPanoSift.h" -#include "sphereAlign.h" -#include "saInterp.h" -#include <math.h> -#include <tiffio.h> - -// create empty -pDIinfo DIinfo_new0(){ - pDIinfo p = (pDIinfo)malloc(sizeof(DIinfo)); - if( p ) memset( p, 0, sizeof(DIinfo) ); - return p; -} - -// delete -void DIinfo_delete( pDIinfo p ){ - free( p ); -} - - -/* - Get source image info from a panotools project file. - - Adapted from "optimizer script parser" in panotools\parser.c - Should work with panotools, ptasmblr and hugin projects. - Ignores everything except 'i' lines (unless there are none, - when it scans the file again looking for 'o' lines). - - input - project file name - output - adds a DisplayImage struct to DIlist for each "i" or "o" line - with only the following fields set - name - width - height - hfov - format - yaw - pitch - roll - returns - 0 on error else number of image lines found - - Notes - ignores all optimizable params except hfov, y, p, r; - handles back references ("v=n", etc) by copying the value from - the referenced image. - - accepts all format codes verbatim (original checks them) -*/ -#define LINE_LENGTH 512 -#define READ_VAR( fmt, ref ) \ - sscanf( ++li, fmt, ref ); \ - if( *li == '"' ) do ++li; while(*li != '"'); \ - while(*li > ' ') li++; - -int LoadProjectImages( char* script, ArrayList * DIlist ) -{ - DIinfo *im, *ir; // DIlist items - - // Variables used by parser - - char *li, line[LINE_LENGTH], *ch; - int lineNum = 0; - int k; - int numIm = 0; - int baseIdx = ArrayList_Count( DIlist ); // 1st image goes here - - int keychar; - -// setlocale(LC_ALL, "C"); -// loop over 'i', 'o' linestart - for( keychar = 'i';; ){ - FILE * fp = fopen( script, "r" ); - if( !fp ) return 0; - - // Parse script - - while( (ch = fgets(line, LINE_LENGTH, fp)) ) - { - lineNum++; - - if( line[0] == keychar - && isspace( line[1] ) ) - { - // create new Image descriptor - im = DIinfo_new0(); - // fill it from line - li = &(line[1]); - while( *li != 0 && *li != '\n') - { - switch(*li) - { - case 'w': READ_VAR( "%d", &(im->width) ) - break; - case 'h': READ_VAR( "%d", &(im->height)) - break; - case 'v': if( *(li+1) == '=' ){ - // copy referenced value - ++li; - READ_VAR( "%d", &k ) - ir = (DIinfo *)ArrayList_GetItem( DIlist, baseIdx + k ); - im->hfov = ir->hfov; - }else{ - READ_VAR( "%lf", &(im->hfov)); - } - break; - case 'f': - READ_VAR( "%d", &(im->format) ); - break; - case 'y': if( *(li+1) == '=' ){ - // copy referenced value - ++li; - READ_VAR( "%d", &k ) - ir = (DIinfo *)ArrayList_GetItem( DIlist, baseIdx + k ); - im->yaw = ir->yaw; - }else{ - READ_VAR( "%lf", &(im->yaw)); - } - break; - case 'p': if( *(li+1) == '=' ){ - // copy referenced value - ++li; - READ_VAR( "%d", &k ) - ir = (DIinfo *)ArrayList_GetItem( DIlist, baseIdx + k ); - im->pitch = ir->pitch; - }else{ - READ_VAR("%lf", &(im->pitch)); - } - break; - case 'r': if( *(li+1) == '=' ){ - // copy referenced value - ++li; - READ_VAR( "%d", &k ) - ir = (DIinfo *)ArrayList_GetItem( DIlist, baseIdx + k ); - im->roll = ir->roll; - }else{ - READ_VAR("%lf", &(im->roll)); - } - break; - case 'n': // Set filename - { char *p = im->name; - READ_VA... [truncated message content] |
From: <tks...@us...> - 2009-07-19 01:19:29
|
Revision: 4054 http://hugin.svn.sourceforge.net/hugin/?rev=4054&view=rev Author: tksharpless Date: 2009-07-19 01:19:18 +0000 (Sun, 19 Jul 2009) Log Message: ----------- Initial easy steps in a continuing revision of APSCpp (detailed journal in RevisionLog.txt) new version # 2.5.1. corrected antialiasing code removed alignment option & supporting code added 2 stereographic control options Revised some messages and reports. Modified Paths: -------------- autopano-sift-C/trunk/APSCpp/APSCpp.c autopano-sift-C/trunk/APSCpp/APSCpp_main.c autopano-sift-C/trunk/AutoPanoSift.h Added Paths: ----------- autopano-sift-C/trunk/RevisionLog.txt Modified: autopano-sift-C/trunk/APSCpp/APSCpp.c =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp.c 2009-07-18 01:37:42 UTC (rev 4053) +++ autopano-sift-C/trunk/APSCpp/APSCpp.c 2009-07-19 01:19:18 UTC (rev 4054) @@ -253,9 +253,13 @@ 0 for legacy (KDTree) mode -- returns list of KeypointN 1 for ANN mode -- returns list of Keypoint + 18 July 2009 new stgfov argument + <0 forbids reprojection + >=0 allows reprojection when hfov exceeds this value */ -KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, DIinfo * pdi, int mode ) +KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, DIinfo * pdi, + int mode, double stgfov ) { #ifdef _DEBUG_INTERP char tmp[262]; @@ -322,15 +326,18 @@ dwid = (int)(0.5 + pW / Scale ); dhgt = (int)(0.5 + pH / Scale ); Scale = (double) pW / (double) dwid; // exact - WriteLine(" reduce size to %d x %d", dwid, dhgt ); + WriteLine(" reduce size to %d x %d ...", dwid, dhgt ); + // smooth the source for antialiasing + ImageMap* tmp = ImageMap_GaussianConvolution( picMap, 0.75 * Scale ); + ImageMap_delete( picMap ); + picMap = tmp; } // create result map pn = ImageMap_new( dwid, dhgt ); - // smooth the source - //ImageMap_GaussianConvolution( picMap, 0.75 * Scale ); // NO EFFECT. + LoweFeatureDetector_SetPreprocSigma( 0 ); - // set up coordinate mapping - if( pdi ){ // ++ mode + // set up stereographic mapping + if( pdi && stgfov >= 0 && pdi->hfov >= stgfov ){ CamLens * psp, * pdp; // create the projections psp = CamLens_new1( pW, pH, pdi->format, pdi->hfov, 16.0 ); @@ -338,7 +345,7 @@ // create the mapping prm = saRemap_new( psp, pdp ); saRemap_inv ( prm, 0.5 * dwid, 0.5 * dhgt, &Xcen, &Ycen ); - WriteLine(" use stereographic projection"); + WriteLine(" convert to stereographic projection ..."); } // interpolate saInterpSetup((void *)picMap->values, // void * pdata @@ -376,9 +383,11 @@ /* find the features */ + WriteLine(" find keypoints ..." ); lf = LoweFeatureDetector_new0(); nKeys = LoweFeatureDetector_DetectFeaturesDownscaled (lf, picMap, 0, Scale); + WriteLine(" %d keypoints found\n", nKeys ); /* build the return value Modified: autopano-sift-C/trunk/APSCpp/APSCpp_main.c =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp_main.c 2009-07-18 01:37:42 UTC (rev 4053) +++ autopano-sift-C/trunk/APSCpp/APSCpp_main.c 2009-07-19 01:19:18 UTC (rev 4054) @@ -43,7 +43,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ - #include <time.h> #include "AutoPanoSift.h" @@ -51,20 +50,21 @@ // APSCpp.cpp int LoadProjectImages( char* script, ArrayList * DIlist ); -KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, DIinfo * pdi, int mode ); +KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, DIinfo * pdi, int mode, double stgfov ); int MultiMatch_ANN ( MultiMatch* ); void Usage () { WriteLine ("autopano-sift-c: Find control points giving a Hugin project file\n"); - WriteLine (" Version %s for hugin 0.7\n", PACKAGE_VERSION); + WriteLine (" Version %s \n", PACKAGE_VERSION); WriteLine ("autopano-sift-c [options] output.pto image1 image2 [..]"); WriteLine (" hugin project file output.pto gets the results "); WriteLine (" input images can be jpeg, tiff, or other formats.\n"); WriteLine ("autopano-sift-c [options] output.pto projectfile"); - WriteLine (" projectfile: a hugin project or other PT compatible"); - WriteLine (" script with image file names, projections and angular"); - WriteLine (" widths. Enables stereographic projection.\n"); + WriteLine (" projectfile: a Hugin or other PT family project script with"); + WriteLine (" image file names, projections, angular widths and optionally"); + WriteLine (" alignments. Enables the options of stereographic projection"); + WriteLine (" and alignment-aware control point selection.\n"); WriteLine ("Options"); WriteLine (" --ransac <on|off|1|0> Switch RANSAC filtration on or off (default: off)."); @@ -72,22 +72,19 @@ WriteLine (" image pair (default: 25, zero means unlimited)"); WriteLine (" --maxdim <n> Make largest image dimension <= n (default: 1600)."); WriteLine (" --projection <n>,<d> n = PT format code, d = hfov in degrees. These"); - WriteLine (" apply to all images, reprojection is enabled."); + WriteLine (" apply to all images. Enables streographic option."); + WriteLine (" --stereogaphic <on|off|1|0> reprojection on (if enabled) or off. Default on."); + WriteLine (" --stgfov <d> minimum hfov (degrees) for reprojection. Default 65."); WriteLine (" --ANNmatch <on|off|1|0> Use fast keypoint matching tree (default: on)."); WriteLine (" --disable-areafilter Do not use max-area filtration, which is default."); WriteLine (" See manpage for details."); WriteLine (" --integer-coordinates Truncate match coordinates to integer numbers."); WriteLine (" --absolute-pathnames <on|off|1|0> Use the absolute pathname of the image"); WriteLine (" file in the PTO output file. Disabled by default."); + WriteLine (" --align-aware <on|off|1|0> alignment based selection on (if enabled) or off."); + WriteLine (" default off."); WriteLine (""); - WriteLine ("Alignment options"); - WriteLine (" --align Automatically pre-align images in PTO file."); - WriteLine (" --bottom-is-left"); - WriteLine (" --bottom-is-right Use in case the automatic algorithm fails."); - WriteLine (" --generate-horizon <c> Generate up to 'c' horizon lines."); - WriteLine (""); - WriteLine ("Refinement options"); WriteLine (" --refine Refine the found control points using the"); WriteLine (" original images."); @@ -97,11 +94,8 @@ WriteLine (" Keep unrefinable matches (default: on)."); WriteLine ("output.pto: The output PTO panorama project file."); - WriteLine (" The filename can be \"-\", then stdout is used"); + WriteLine (" This filename can be \"-\", then stdout is used"); WriteLine ("image<n>: input image files (any common format: JPEG, PNG, TIFF, ..)"); - WriteLine ("Notice: for the aligning to work, the input images shall be"); - WriteLine (" 1. All of the same dimension and scale"); - WriteLine (" 2. The first images must be an ordered row. See manpage."); WriteLine (""); } @@ -518,57 +512,7 @@ } } } - - // Generate horizon if we should - if (bb != NULL && generateHorizon > 0) { - WriteLine ("Creating horizon..."); - - int kMain = 2; - int hPoints = generateHorizon; - int horizonPointsMade = 0; - bool hasGood = true; - while (hPoints > 0 && hasGood) { - hasGood = false; - int kStep = 2 * kMain; - - int p; - for (p = 0 ; hPoints > 0 && p < kMain ; ++p) { - double stepSize = ((double) ArrayList_Count(bb->firstRow)) / ((double) kStep); - double beginIndex = p * stepSize; - double endIndex = (((double) ArrayList_Count(bb->firstRow)) / (double) kMain) + - p * stepSize; - -// Round to next integer and check if their image distance -// is larger than 1. If its not, we skip over this useless -// horizon point. - int bi = (int) (beginIndex + 0.5); - int ei = (int) (endIndex + 0.5); - if ((ei - bi) <= 1) - continue; - - hasGood = true; - - bi %= ArrayList_Count(bb->firstRow); - ei %= ArrayList_Count(bb->firstRow); - fprintf(pto, "c n%s N%s x%d y%d X%d Y%d t2\n", - (char*)HashTable_GetItem(imageNameTab, ArrayList_GetItem(bb->firstRow, bi)), - (char*)HashTable_GetItem(imageNameTab, ArrayList_GetItem(bb->firstRow, ei)), - ((Resolution*) ArrayList_GetItem(resolutions,bi))->x / 2, - ((Resolution*) ArrayList_GetItem(resolutions,bi))->y / 2, - ((Resolution*) ArrayList_GetItem(resolutions,ei))->x / 2, - ((Resolution*) ArrayList_GetItem(resolutions,ei))->y / 2); - - horizonPointsMade += 1; - hPoints -= 1; - } - -// Increase density for next generation lines - kMain *= 2; - } - WriteLine (" made %d horizon lines.\n", horizonPointsMade); - } - fprintf(pto, "\n# :-)\n\n"); WriteLine ("\nYou can now load the output file into hugin."); @@ -600,17 +544,19 @@ // output to stdout flag bool streamout = false; - // Automatic pre-aligning of images - bool preAlign = false; - int bottomDefault = -1; - int generateHorizon = 0; - // Use ANN kd-tree for keypoint matching bool useANN = true; // Use RANSAC algorithm match filtration. bool useRansac = false; + + // Use stereographic projection if feasible + bool useStereographic = true; + double stgfov = 65; // don't reproject below this hfov + // Use input alignment if feasible + bool useAlignment = false; + // Use area based weighting for final match selection. bool useAreaFiltration = true; @@ -633,7 +579,7 @@ int optionN = 1; int i; - WriteLine ("\nAPSCpp, enhanced Autopano-sift-c"); + WriteLine ("\nAPSCpp, enhanced autopano-sift-c version %s \n", PACKAGE_VERSION); LoweFeatureDetector_SetVerbose(false); // default low chatter @@ -673,6 +619,15 @@ } else if (strcmp (optionStr, "--ANNmatch") == 0) { joptN = 2; useANN = YesNoOption ("--ANNmatch", argv[optionN + 1], &Nerr ); + } else if (strcmp (optionStr, "--stgfov") == 0) { + joptN = 2; + stgfov = atof( argv[optionN + 1] ); + } else if (strcmp (optionStr, "--stereographic") == 0) { + joptN = 2; + useStereographic = YesNoOption ("--stereographic", argv[optionN + 1], &Nerr ); + } else if (strcmp (optionStr, "--align-aware") == 0) { + joptN = 2; + useAlignment = YesNoOption ("--align-aware", argv[optionN + 1], &Nerr ); } else if (strcmp (optionStr, "--maxmatches") == 0) { joptN = 2; if (sscanf(argv[optionN + 1], "%d", &maxMatches) != 1) { @@ -690,22 +645,6 @@ } else if (strcmp (optionStr, "--absolute-pathnames") == 0) { joptN = 2; useAbsolutePathnames = YesNoOption ("--absolute-pathnames", argv[optionN + 1], &Nerr); - } else if (strcmp (optionStr, "--align") == 0) { - preAlign = true; - } else if (strcmp (optionStr, "--bottom-is-left") == 0) { - bottomDefault = 0; - } else if (strcmp (optionStr, "--bottom-is-right") == 0) { - bottomDefault = 1; - } else if (strcmp (optionStr, "--generate-horizon") == 0) { - joptN = 2; - if (sscanf(argv[optionN + 1], "%d", &generateHorizon) != 1) { - WriteLine ("Parameter to generate-horizon option invalid. See the usage help."); - ++Nerr; - } - if (generateHorizon < 0) { - WriteLine ("The number of horizon lines to generate must be positive."); - ++Nerr; - } } else if (strcmp (optionStr, "--refine") == 0) { refine = true; } else if (strcmp (optionStr, "--refine-by-middle") == 0) { @@ -729,18 +668,6 @@ ++Nerr; } - if (bottomDefault != -1 && preAlign == false) { - WriteLine ("Please enable automatic alignment (\"--align\") before using the"); - WriteLine ("--bottom-is-* options."); - ++Nerr; - } - - if (generateHorizon > 0 && preAlign == false) { - WriteLine ("Please enable automatic alignment (\"--align\") before using the"); - WriteLine ("--generate-horizon option. Run without arguments for help."); - ++Nerr; - } - // show usage and quit if commandline errors if (Nerr){ WriteLine ("%d commandline errors.\n", Nerr ); @@ -775,10 +702,13 @@ DIlist = ArrayList_new0( (void *) DIinfo_delete ); } - if( DIlist ) WriteLine(" Stereographic projection enabled."); + if( DIlist && useStereographic ){ + WriteLine(" Stereographic projection enabled for hfov >= %.1f degrees", stgfov ); + } + /** Find keypoints **/ start = clock(); @@ -801,12 +731,13 @@ // process the images for( i = 0; i < ArrayList_Count( DIlist ); i++ ){ pd = (pDIinfo) ArrayList_GetItem( DIlist, i); - ArrayList_AddItem(keylists, GenerateKeyspp( pd->name, maxdim, pd, useANN ) ); + ArrayList_AddItem(keylists, GenerateKeyspp( pd->name, maxdim, pd, useANN, + useStereographic ? stgfov : -1 ) ); } } else { // std mode: image names only from commandline for( i=0; i<argc - 1 - optionCount; i++) { - ArrayList_AddItem(keylists, GenerateKeyspp( argv[i+optionCount+1], maxdim, 0, useANN ) ); + ArrayList_AddItem(keylists, GenerateKeyspp( argv[i+optionCount+1], maxdim, 0, useANN, 0 ) ); } } @@ -836,7 +767,6 @@ time = ((double)finish - (double)start ) / CLOCKS_PER_SEC; WriteLine("\n%.1f seconds to match keypoints", time); - // Connected component check WriteLine ("\nConnected component check..."); ArrayList* components = MultiMatch_ComponentCheck (mm, msList); @@ -854,25 +784,14 @@ if (ArrayList_Count(components) > 1) { WriteLine (""); - WriteLine ("Warning: There is one or more components that are not connected through control"); - WriteLine (" points. An optimization of the resulting PTO will not be possible"); - WriteLine (" without prior adding of control points between the components listed"); + WriteLine ("Warning: One or more components are not connected through control points."); + WriteLine (" Optimization of the resulting PTO will not be possible without"); + WriteLine (" manual addition of control points between the components listed"); WriteLine (" above. Please see the manual page for autopano(1) for details."); WriteLine (""); } else WriteLine (""); - // BondBall algorithm - BondBall* bb = NULL; - if (preAlign) { - bb = MultiMatch_BuildBondBall (mm, msList, bottomDefault); - - if (bb == NULL) { - WriteLine ("WARNING: Failed to build bondball as requested. No pre-aligning of images"); - WriteLine (" takes place.\n"); - } - } - if (refine) { WriteLine ("Refining keypoints"); RefineKeypoints (msList, refineMiddle, keepUnrefinable); @@ -887,11 +806,10 @@ } WritePTOFile (pto, mm, msList, DIlist, - bb, generateHorizon, useIntegerCoordinates, + 0, 0, useIntegerCoordinates, useAbsolutePathnames); ArrayList_delete(components); - BondBall_delete(bb); MultiMatch_delete(mm); if ( !streamout ) fclose(pto); Modified: autopano-sift-C/trunk/AutoPanoSift.h =================================================================== --- autopano-sift-C/trunk/AutoPanoSift.h 2009-07-18 01:37:42 UTC (rev 4053) +++ autopano-sift-C/trunk/AutoPanoSift.h 2009-07-19 01:19:18 UTC (rev 4054) @@ -5,7 +5,7 @@ #ifdef HAS_CONFIG_H #include "config.h" #else -#define PACKAGE_VERSION "2.5.0" +#define PACKAGE_VERSION "2.5.1" #endif // include windows.h here Added: autopano-sift-C/trunk/RevisionLog.txt =================================================================== --- autopano-sift-C/trunk/RevisionLog.txt (rev 0) +++ autopano-sift-C/trunk/RevisionLog.txt 2009-07-19 01:19:18 UTC (rev 4054) @@ -0,0 +1,31 @@ +APSCpp Revision Log started 18 July 2009 TKSharpless + +18 July some quick & easy changes +-- #define PACKAGE_VERSION "2.5.1" in AutoPanoSift.h + TODO: separate APSCpp version no. from gk/ap one +-- correct code for smoothing image before size reduction + 1) delete orignal image and swap the pointers + 2) do it in the if(Scale > 1) block +-- add user controls on stereographic projection + 1) --stereographic off prevents conversion + 2) --stgfov sets minimum hfov for conversion. Show this + in the setup report on stereographic option + implement as new argument stgfov to GenerateKeyspp() + (< 0 prohibits conversion) +-- remove alignment and related options from APSCpp_main.c + 1) delete from usage text + 2) delete corresponding commandline parsing + 3) delete all code that referred to bondball + 4) pass null alignment params to write_pto (as if the + option had been switched off) + TODO: remove references in other files,verify that linker + nolonger loads bondball from libsift. +-- add (dummy) option --align-aware to control proposed + layout-based keypoint selection. +-- revise the usage text and some other explanatory messages + for better clarity. +-- Display revision number in startup banner. +-- Add a couple of status reports to better delineate image + processing stages. +-- verify no cumulative memory loss during keypoint finding. +-- add this file to svn, commit as SVN 4024 \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tks...@us...> - 2009-07-19 13:57:51
|
Revision: 4055 http://hugin.svn.sourceforge.net/hugin/?rev=4055&view=rev Author: tksharpless Date: 2009-07-19 13:57:48 +0000 (Sun, 19 Jul 2009) Log Message: ----------- remove option to use legacy k-d tree change "align-aware" to "use-layout" Modified Paths: -------------- autopano-sift-C/trunk/APSCpp/APSCpp.c autopano-sift-C/trunk/APSCpp/APSCpp_main.c autopano-sift-C/trunk/RevisionLog.txt Modified: autopano-sift-C/trunk/APSCpp/APSCpp.c =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp.c 2009-07-19 01:19:18 UTC (rev 4054) +++ autopano-sift-C/trunk/APSCpp/APSCpp.c 2009-07-19 13:57:48 UTC (rev 4055) @@ -252,6 +252,7 @@ 06 Mar 2008 new mode argument. 0 for legacy (KDTree) mode -- returns list of KeypointN 1 for ANN mode -- returns list of Keypoint + removed 19 July 2009, legacy k-d tree is no longer an option 18 July 2009 new stgfov argument <0 forbids reprojection @@ -259,7 +260,7 @@ */ KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, DIinfo * pdi, - int mode, double stgfov ) + double stgfov ) { #ifdef _DEBUG_INTERP char tmp[262]; @@ -391,7 +392,7 @@ WriteLine(" %d keypoints found\n", nKeys ); /* build the return value - For KDTree mode, a list of KeypointN; for ANN mode a list of Keypoint, + for ANN mode a list of Keypoint, that will be converted to keypointN after matching */ { @@ -399,8 +400,6 @@ ArrayList * globalNaturalKeypoints = 0; int i; - if( mode == 0 ) globalNaturalKeypoints = ArrayList_new0 ((void *) KeypointN_delete); - if( pdi ){ // build remapping function at input scale CamLens * psp, * pdp; psp = CamLens_new1( pW, pH, pdi->format, pdi->hfov, 16.0 ); @@ -416,7 +415,6 @@ &kp->x, &kp->y // remapped coords ); } - if( mode == 0 ) ArrayList_AddItem ( globalNaturalKeypoints, KeypointN_new( kp )); } // package the list @@ -424,14 +422,9 @@ kpp->imageFile = strdup(imgname); kpp->xDim = pW; kpp->yDim = pH; - if( mode == 0 ){ - // return the KeypointN list - kpp->array = globalNaturalKeypoints; - } else { - // return the Keypoint list - kpp->array = lf->globalKeypoints; - lf->globalKeypoints = 0; // don't delete the list! - } + // return the Keypoint list + kpp->array = lf->globalKeypoints; + lf->globalKeypoints = 0; // don't delete the list! } // delete the LoweDetector LoweFeatureDetector_delete(lf); Modified: autopano-sift-C/trunk/APSCpp/APSCpp_main.c =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp_main.c 2009-07-19 01:19:18 UTC (rev 4054) +++ autopano-sift-C/trunk/APSCpp/APSCpp_main.c 2009-07-19 13:57:48 UTC (rev 4055) @@ -15,8 +15,6 @@ The projections are "ideal" (no lens or center point corrections), but the reprojection machinery could handle those if available. - * Keypoint file correlation and hugin panorama file creation utility. - * * (C) Copyright 2004 -- Sebastian Nowozin (no...@cs...) * * "The University of British Columbia has applied for a patent on the SIFT @@ -28,6 +26,8 @@ * License, which is included in this software package (doc/LICENSE). */ /* + * (C) Copyright 2008, 2009 Thomas K Sharpless (tks...@gm...) + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either @@ -50,7 +50,7 @@ // APSCpp.cpp int LoadProjectImages( char* script, ArrayList * DIlist ); -KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, DIinfo * pdi, int mode, double stgfov ); +KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, DIinfo * pdi, double stgfov ); int MultiMatch_ANN ( MultiMatch* ); void Usage () @@ -64,7 +64,7 @@ WriteLine (" projectfile: a Hugin or other PT family project script with"); WriteLine (" image file names, projections, angular widths and optionally"); WriteLine (" alignments. Enables the options of stereographic projection"); - WriteLine (" and alignment-aware control point selection.\n"); + WriteLine (" and layout-guided control point placement.\n"); WriteLine ("Options"); WriteLine (" --ransac <on|off|1|0> Switch RANSAC filtration on or off (default: off)."); @@ -72,17 +72,16 @@ WriteLine (" image pair (default: 25, zero means unlimited)"); WriteLine (" --maxdim <n> Make largest image dimension <= n (default: 1600)."); WriteLine (" --projection <n>,<d> n = PT format code, d = hfov in degrees. These"); - WriteLine (" apply to all images. Enables streographic option."); - WriteLine (" --stereogaphic <on|off|1|0> reprojection on (if enabled) or off. Default on."); + WriteLine (" apply to all images. Enables stereographic option."); + WriteLine (" --stereographic <on|off|1|0> reprojection on (if enabled) or off. Default on."); WriteLine (" --stgfov <d> minimum hfov (degrees) for reprojection. Default 65."); - WriteLine (" --ANNmatch <on|off|1|0> Use fast keypoint matching tree (default: on)."); WriteLine (" --disable-areafilter Do not use max-area filtration, which is default."); WriteLine (" See manpage for details."); WriteLine (" --integer-coordinates Truncate match coordinates to integer numbers."); WriteLine (" --absolute-pathnames <on|off|1|0> Use the absolute pathname of the image"); WriteLine (" file in the PTO output file. Disabled by default."); - WriteLine (" --align-aware <on|off|1|0> alignment based selection on (if enabled) or off."); - WriteLine (" default off."); + WriteLine (" --use-layout <on|off|1|0> image alignment in pto file guides control point"); + WriteLine (" placement; or does not. Default is off."); WriteLine (""); WriteLine ("Refinement options"); @@ -544,9 +543,6 @@ // output to stdout flag bool streamout = false; - // Use ANN kd-tree for keypoint matching - bool useANN = true; - // Use RANSAC algorithm match filtration. bool useRansac = false; @@ -555,8 +551,8 @@ double stgfov = 65; // don't reproject below this hfov // Use input alignment if feasible - bool useAlignment = false; - + bool useLayout = false; + // Use area based weighting for final match selection. bool useAreaFiltration = true; @@ -616,18 +612,15 @@ } else if (strcmp (optionStr, "--ransac") == 0) { joptN = 2; useRansac = YesNoOption ("--ransac", argv[optionN + 1], &Nerr ); - } else if (strcmp (optionStr, "--ANNmatch") == 0) { - joptN = 2; - useANN = YesNoOption ("--ANNmatch", argv[optionN + 1], &Nerr ); } else if (strcmp (optionStr, "--stgfov") == 0) { joptN = 2; stgfov = atof( argv[optionN + 1] ); } else if (strcmp (optionStr, "--stereographic") == 0) { joptN = 2; useStereographic = YesNoOption ("--stereographic", argv[optionN + 1], &Nerr ); - } else if (strcmp (optionStr, "--align-aware") == 0) { + } else if (strcmp (optionStr, "--use-layout") == 0) { joptN = 2; - useAlignment = YesNoOption ("--align-aware", argv[optionN + 1], &Nerr ); + useLayout = YesNoOption ("--use-layout", argv[optionN + 1], &Nerr ); } else if (strcmp (optionStr, "--maxmatches") == 0) { joptN = 2; if (sscanf(argv[optionN + 1], "%d", &maxMatches) != 1) { @@ -731,13 +724,13 @@ // process the images for( i = 0; i < ArrayList_Count( DIlist ); i++ ){ pd = (pDIinfo) ArrayList_GetItem( DIlist, i); - ArrayList_AddItem(keylists, GenerateKeyspp( pd->name, maxdim, pd, useANN, + ArrayList_AddItem(keylists, GenerateKeyspp( pd->name, maxdim, pd, useStereographic ? stgfov : -1 ) ); } } else { // std mode: image names only from commandline for( i=0; i<argc - 1 - optionCount; i++) { - ArrayList_AddItem(keylists, GenerateKeyspp( argv[i+optionCount+1], maxdim, 0, useANN, 0 ) ); + ArrayList_AddItem(keylists, GenerateKeyspp( argv[i+optionCount+1], maxdim, 0, 0 ) ); } } @@ -753,12 +746,13 @@ MultiMatch_LoadKeysetsFromMemory (mm, keylists); // note mm now owns keylists and will delete it when destroyed - WriteLine ("\nMatching; ransac %s, ANNmatch %s...", + WriteLine ("\nMatching; ransac %s, area filter %s, layout %s ...", useRansac == true ? "on" : "off", - useANN == true ? "on" : "off" + useAreaFiltration == true ? "on" : "off", + useLayout == true ? "on" : "off" ); - if( useANN ) MultiMatch_ANN ( mm ); + MultiMatch_ANN ( mm ); ArrayList* msList = MultiMatch_LocateMatchSets (mm, 3, maxMatches, useRansac, useAreaFiltration); Modified: autopano-sift-C/trunk/RevisionLog.txt =================================================================== --- autopano-sift-C/trunk/RevisionLog.txt 2009-07-19 01:19:18 UTC (rev 4054) +++ autopano-sift-C/trunk/RevisionLog.txt 2009-07-19 13:57:48 UTC (rev 4055) @@ -28,4 +28,13 @@ -- Add a couple of status reports to better delineate image processing stages. -- verify no cumulative memory loss during keypoint finding. --- add this file to svn, commit as SVN 4024 \ No newline at end of file +-- add this file to svn, commit as SVN 4054 + +19 July Further Q&D's + +-- change "align-aware" to "use-layout" (clearer) +-- eliminate option to use legacy k-d tree, ANN only. + 1) remove usage line and command parse + 2) remove control var useANN & uses of it + 3) eliminate mode argument to GenerateKeyspp & code + that used it. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tks...@us...> - 2009-07-22 03:35:11
|
Revision: 4082 http://hugin.svn.sourceforge.net/hugin/?rev=4082&view=rev Author: tksharpless Date: 2009-07-22 03:35:07 +0000 (Wed, 22 Jul 2009) Log Message: ----------- Basically working with Hugin, PTGui and PTAsm projects without any "gotcha's". But PTGui circular fisheye fov is incompletely specified, so don't trust that. Added option to set actual fisheye type used for processing the images, independently of source stitcher's opinions (which ain't worh Jack). Reads layout and lens correction data but does not uses them yet. Modified Paths: -------------- autopano-sift-C/trunk/APSCpp/APSCpp.c autopano-sift-C/trunk/APSCpp/APSCpp_main.c autopano-sift-C/trunk/APSCpp/CamLens.c autopano-sift-C/trunk/APSCpp/sphereAlign.h autopano-sift-C/trunk/RevisionLog.txt Modified: autopano-sift-C/trunk/APSCpp/APSCpp.c =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp.c 2009-07-21 23:29:11 UTC (rev 4081) +++ autopano-sift-C/trunk/APSCpp/APSCpp.c 2009-07-22 03:35:07 UTC (rev 4082) @@ -17,12 +17,15 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ + #include "AutoPanoSift.h" #include "sphereAlign.h" #include "saInterp.h" #include <math.h> #include <tiffio.h> +extern double globFov; // hfov if no project file + // create empty pDIinfo DIinfo_new0(){ pDIinfo p = (pDIinfo)malloc(sizeof(DIinfo)); @@ -35,15 +38,23 @@ free( p ); } +bool DIinfo_isDummy( pDIinfo self ){ + return self->name[0] == 0; +} /* Get source image info from a panotools project file. +revised 19 July 2009 to read PTAsm/PTGui file names Adapted from "optimizer script parser" in panotools\parser.c Should work with panotools, ptasmblr and hugin projects. Ignores everything except 'i' lines (unless there are none, - when it scans the file again looking for 'o' lines). + when it scans the file again looking for 'o' lines) and the + structured comment lines (#-imgfile wid hgt "path") used by + PTGui and PTAssembler to hold file names. Such lines precede + the 'i' or 'o' line that holds the image parameters. + input project file name output @@ -73,7 +84,7 @@ if( *li == '"' ) do ++li; while(*li != '"'); \ while(*li > ' ') li++; -int LoadProjectImages( char* script, ArrayList * DIlist ) +int LoadProjectImages( char* script, ArrayList * DIlist, bool equalAngle ) { DIinfo *im, *ir; // DIlist items @@ -84,9 +95,16 @@ int k; int numIm = 0; int baseIdx = ArrayList_Count( DIlist ); // 1st image goes here - + int FNflag; // 0: no #-imgfile line since last i or o + // >0: have read this many + int imwid, imhgt; int keychar; + bool PTGui = false, PTAsm = false, Hugin = false; + char namebuf[300]; + double hfov; + im = 0; // flag: no info read + // setlocale(LC_ALL, "C"); // loop over 'i', 'o' linestart for( keychar = 'i';; ){ @@ -97,9 +115,23 @@ while( (ch = fgets(line, LINE_LENGTH, fp)) ) { + if( !PTGui && !PTAsm && !Hugin ){ + if( !strncmp( line, "# ptGui project file", 20 )) PTGui = true; + else if( !strncmp( line, "# Script file for PTAStitcher", 29 )) PTAsm = true; + else if( !strncmp( line, "# hugin project file", 20 )) Hugin = true; + } lineNum++; - - if( line[0] == keychar + if( !strncmp( line, "#-imgfile ", 10 )){ + if( sscanf( line + 10, "%d %d %s", &imwid, &imhgt, namebuf ) == 3 ){ + ++FNflag; + if( namebuf[0] == '"' ){ + register char * p = namebuf + 1; + while( *p != '"'){ p[-1] = p[0]; ++p; } + p[-1] = 0; + } + } + + } else if( line[0] == keychar && isspace( line[1] ) ) { // create new Image descriptor @@ -110,22 +142,44 @@ { switch(*li) { + case 'a': if( *(li+1) == '=' ){ // copy referenced value + ++li; + READ_VAR( "%d", &k ) + ir = (DIinfo *)ArrayList_GetItem( DIlist, baseIdx + k ); + im->a = ir->a; + } else READ_VAR("%lf", &(im->a)); + break; + case 'b': if( *(li+1) == '=' ){ // copy referenced value + ++li; + READ_VAR( "%d", &k ) + ir = (DIinfo *)ArrayList_GetItem( DIlist, baseIdx + k ); + im->b = ir->b; + } else READ_VAR("%lf", &(im->b)); + break; + case 'c': if( *(li+1) == '=' ){ // copy referenced value + ++li; + READ_VAR( "%d", &k ) + ir = (DIinfo *)ArrayList_GetItem( DIlist, baseIdx + k ); + im->c = ir->c; + } else READ_VAR("%lf", &(im->c)); + break; case 'w': READ_VAR( "%d", &(im->width) ) break; case 'h': READ_VAR( "%d", &(im->height)) break; - case 'v': if( *(li+1) == '=' ){ - // copy referenced value + case 'v': if( *(li+1) == '=' ){ // copy referenced value ++li; READ_VAR( "%d", &k ) ir = (DIinfo *)ArrayList_GetItem( DIlist, baseIdx + k ); - im->hfov = ir->hfov; + hfov = fovdeg( ir->flpix, ir->width, ir->fmtref); }else{ - READ_VAR( "%lf", &(im->hfov)); + READ_VAR( "%lf", &hfov); } break; case 'f': READ_VAR( "%d", &(im->format) ); + // convert PTAsm equal-area fisheye code to local code + im->fmtref = im->format == 29 ? 8 : im->format; break; case 'y': if( *(li+1) == '=' ){ // copy referenced value @@ -157,7 +211,7 @@ READ_VAR("%lf", &(im->roll)); } break; - case 'n': // Set filename + case 'n': // Set filename (Hugin & PTools) { char *p = im->name; READ_VAR( "%s", p ); // strip quotes @@ -180,14 +234,53 @@ if(*li) li++; // skip one nonnull } // EOL + // check name, patch in PTAsm/PTGui file name + if( im && DIinfo_isDummy( im ) ){ + if( FNflag ){ + strcpy( im->name, namebuf ); + im->width = imwid; + im->height = imhgt; + } + FNflag = 0; + } - // add this image to list - numIm++; - ArrayList_AddItem( DIlist, im ); + if( im ){ + /* add this image info to list + but first, post focal length in pixels + and the working format code + PTAsm allows to specify fisheye as either equal angle (format codes 2, + 3)or equal area (code29, which we convert to 8). PTGui assumes all + fisheyes are equal-area, Hugin assumes they are equal-angle. APSCpp + lets you override those assumptions by setting equalAngle true or false. + */ + + int w = im->width; + int fmt = im->fmtref; + /* PTGui circular fisheye fov is crop circle diameter. Since + we don't know what that is in pixels, assume it is equal to + the long image axis.... + */ + if( PTGui && fmt == 2 && im->height > im->width) + w = im->height; + if((fmt == 2 || fmt == 3) ){ // fisheye formats... + if( PTGui ) fmt = 8; // PTGuis assumes equal-area + // post user preferred format for processing + if( !equalAngle ) im->format = 8; + } + else if( im->format == 29 ) im->format = 8; + // compute focal length as originator did + im->flpix = flpix( hfov, w, fmt ); + + // list the image + numIm++; + ArrayList_AddItem( DIlist, im ); + im = 0; // flag: no current info line + } } // end of line } // end of file + FNflag = 0; fclose( fp ); if( numIm > 0 || keychar == 'o' ) break; @@ -258,9 +351,9 @@ <0 forbids reprojection >=0 allows reprojection when hfov exceeds this value */ - +///#define _DEBUG_INTERP KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, DIinfo * pdi, - double stgfov ) + double stgfov, int * KPcount ) { #ifdef _DEBUG_INTERP char tmp[262]; @@ -274,6 +367,7 @@ KeypointXMLList* kpp; double Scale = 1.0; + double hfov = 0; // reduce Lowe prefilter smoothing @@ -284,10 +378,12 @@ DisplayImage* pic = DisplayImage_new(imgname); // (if we get here the image was read OK, and its name printed) if(!pdi) { + hfov = globFov; WriteLine(" width %d height %d", pic->width, pic->height ); } else { - WriteLine(" width %d height %d format %d hfov %g", - pic->width, pic->height, pdi->format, pdi->hfov ); + hfov = fovdeg( pdi->flpix, pic->width, pdi->format ); + WriteLine(" %s width %d height %d hfov %g ", + formatName( pdi->format), pic->width, pic->height, hfov); // put actual image dimensions in the DIinfo, just in case... pdi->width = pic->width; pdi->height = pic->height; } @@ -338,11 +434,11 @@ LoweFeatureDetector_SetPreprocSigma( 0 ); // set up stereographic mapping - if( pdi && stgfov >= 0 && pdi->hfov >= stgfov ){ + if( pdi && stgfov >= 0 && hfov >= stgfov ){ CamLens * psp, * pdp; // create the projections - psp = CamLens_new1( pW, pH, pdi->format, pdi->hfov, 16.0 ); - pdp = CamLens_new1( dwid, dhgt, _stereographic, pdi->hfov, 0 ); + psp = CamLens_new1( pW, pH, pdi->format, hfov, 16.0 ); + pdp = CamLens_new1( dwid, dhgt, _stereographic, hfov, 0 ); // create the mapping prm = saRemap_new( psp, pdp ); saRemap_inv ( prm, 0.5 * dwid, 0.5 * dhgt, &Xcen, &Ycen ); @@ -390,6 +486,7 @@ nKeys = LoweFeatureDetector_DetectFeaturesDownscaled (lf, picMap, 0, Scale); WriteLine(" %d keypoints found\n", nKeys ); + *KPcount = nKeys; /* build the return value for ANN mode a list of Keypoint, @@ -402,8 +499,8 @@ if( pdi ){ // build remapping function at input scale CamLens * psp, * pdp; - psp = CamLens_new1( pW, pH, pdi->format, pdi->hfov, 16.0 ); - pdp = CamLens_new1( pW, pH, _stereographic, pdi->hfov, 0 ); + psp = CamLens_new1( pW, pH, pdi->format, hfov, 16.0 ); + pdp = CamLens_new1( pW, pH, _stereographic, hfov, 0 ); prm = saRemap_new( psp, pdp ); // dest=>src } else prm = 0; @@ -470,7 +567,7 @@ int m = 0; // return value int i, j, k, n, d; - Keypoint * kp; + Keypoint * kp = 0; // count keypoints n = 0; // number of keypoints @@ -495,7 +592,7 @@ kpn[k++] = KeypointN_new( kp ); } } - + if( k < 1 ) return 0; d = kp->featureVectorLength; // # of dimensions // search cutoff depth Modified: autopano-sift-C/trunk/APSCpp/APSCpp_main.c =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp_main.c 2009-07-21 23:29:11 UTC (rev 4081) +++ autopano-sift-C/trunk/APSCpp/APSCpp_main.c 2009-07-22 03:35:07 UTC (rev 4082) @@ -49,10 +49,15 @@ #include "sphereAlign.h" // APSCpp.cpp -int LoadProjectImages( char* script, ArrayList * DIlist ); -KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, DIinfo * pdi, double stgfov ); +int LoadProjectImages( char* script, ArrayList * DIlist, bool equalAngle ); +KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, + DIinfo * pdi, double stgfov, int * KPcount ); int MultiMatch_ANN ( MultiMatch* ); +// globals +double globFov = 0; // width for all images in degrees + + void Usage () { WriteLine ("autopano-sift-c: Find control points giving a Hugin project file\n"); @@ -75,6 +80,8 @@ WriteLine (" apply to all images. Enables stereographic option."); WriteLine (" --stereographic <on|off|1|0> reprojection on (if enabled) or off. Default on."); WriteLine (" --stgfov <d> minimum hfov (degrees) for reprojection. Default 65."); + WriteLine (" --equal-angle-fisheye Set fisheye lens type to equal-angle instead of"); + WriteLine (" equal-area. Ignored for PTAssembler projects."); WriteLine (" --disable-areafilter Do not use max-area filtration, which is default."); WriteLine (" See manpage for details."); WriteLine (" --integer-coordinates Truncate match coordinates to integer numbers."); @@ -420,17 +427,17 @@ DIinfo * pdi = 0; char buffer[262]; - fprintf(pto, "# Hugin project file generated by APSCpp\n\n"); + fprintf(pto, "# Stitcher project file generated by APSCpp version %s\n\n", PACKAGE_VERSION); fprintf(pto, "p f2 w3000 h1500 v360 n\"JPEG q90\"\n"); fprintf(pto, "m g1 i0\n\n"); int imageIndex = 0; HashTable* imageNameTab = HashTable_new0 (NULL, NULL); ArrayList* resolutions = ArrayList_new0 ( (void *) Resolution_delete); - int i; - for(i=0; i<ArrayList_Count(mm->keySets); i++) { - KeypointXMLList* kx = (KeypointXMLList*) ArrayList_GetItem(mm->keySets, i); - HashTable_AddItem(imageNameTab, kx->imageFile, (void*)imageIndex); + int i, iks; + for( iks = 0; iks < ArrayList_Count(mm->keySets); iks++ ) { + KeypointXMLList* kx = (KeypointXMLList*) ArrayList_GetItem(mm->keySets, iks ); + HashTable_AddItem(imageNameTab, kx->imageFile, (void*)imageIndex); ArrayList_AddItem(resolutions, Resolution_new (kx->xDim, kx->yDim)); char* imageFile = kx->imageFile; @@ -465,6 +472,7 @@ }*/ double yaw = 0.0, pitch = 0.0, rotation = 0.0, hfov = 180.0; + double a = 0, b = -0.01, c = 0; int format = 0; if (pos != NULL) { yaw = pos->yaw; @@ -475,12 +483,16 @@ pitch = pdi->pitch; rotation = pdi->roll; format = pdi->format; - hfov = pdi->hfov; + if( format == 8 ) format = 3; + hfov = fovdeg( pdi->flpix, kx->xDim, format ); + a = pdi->a; + b = pdi->b; + c = pdi->c; } if (imageIndex == 0 || refIdx == -1) { - sprintf(buffer, "i w%d h%d f%d a0 b-0.01 c0 d0 e0 p%g r%g v%g y%g u10 n\"%s\"", - kx->xDim, kx->yDim, format, pitch, rotation, hfov, yaw, imageFile); + sprintf(buffer, "i w%d h%d f%d a%g b%g c%g d0 e0 p%g r%g v%g y%g u10 n\"%s\"", + kx->xDim, kx->yDim, format, a, b, c, pitch, rotation, hfov, yaw, imageFile); } else { sprintf(buffer, "i w%d h%d f%d a=%d b=%d c=%d d0 e0 p%g r%g v=%d y%g u10 n\"%s\"", kx->xDim, kx->yDim, format, refIdx, refIdx, refIdx, pitch, rotation, refIdx, yaw, imageFile); @@ -534,7 +546,6 @@ char *projectfile = 0; // "--projection" option sets these for all images int globFmt = -1; // PT format code - double globFov = 0; // width in degrees int Nerr = 0; // counts commandline errors // downscale option = largest allowed image dimension (0: none) @@ -553,6 +564,9 @@ // Use input alignment if feasible bool useLayout = false; + // treat fisheye lens as equal-angle + bool equalAngle = false; + // Use area based weighting for final match selection. bool useAreaFiltration = true; @@ -574,6 +588,7 @@ int optionCount = 0; int optionN = 1; int i; + int totalKPs = 0; WriteLine ("\nAPSCpp, enhanced autopano-sift-c version %s \n", PACKAGE_VERSION); @@ -633,6 +648,8 @@ } } else if (strcmp (optionStr, "--disable-areafilter") == 0) { useAreaFiltration = false; + } else if (strcmp (optionStr, "--equal-angle-fisheye") == 0) { + equalAngle = true; } else if (strcmp (optionStr, "--integer-coordinates") == 0) { useIntegerCoordinates = true; } else if (strcmp (optionStr, "--absolute-pathnames") == 0) { @@ -686,7 +703,7 @@ // enable ++ mode by creating DIlist DIlist = ArrayList_new0( (void *) DIinfo_delete ); // read the proect file image info into DIlist, or die - if( LoadProjectImages( argv[optionCount + 1], DIlist ) ==0 ){ + if( LoadProjectImages( argv[optionCount + 1], DIlist, equalAngle ) == 0 ){ WriteLine ("Error reading project file."); exit(1); } @@ -696,8 +713,14 @@ } - if( DIlist && useStereographic ){ - WriteLine(" Stereographic projection enabled for hfov >= %.1f degrees", stgfov ); + WriteLine(" Default fisheye lens type is %s.", + equalAngle ? "equal-angle" : "equal-area" ); + + if( DIlist ){ + if( useStereographic ) + WriteLine(" Stereographic projection enabled for hfov >= %.1f degrees.", stgfov ); + if( useLayout ) + WriteLine(" Will try to use source image layout to guide CP placement."); } @@ -715,7 +738,7 @@ for( i=0; i<argc - 1 - optionCount; i++) { pd = DIinfo_new0(); pd->format = globFmt; - pd->hfov = globFov; + pd->flpix = 0; strcpy(pd->name, argv[i+optionCount+1] ); // note dimensions are still zero ArrayList_AddItem( DIlist, pd ); @@ -724,13 +747,15 @@ // process the images for( i = 0; i < ArrayList_Count( DIlist ); i++ ){ pd = (pDIinfo) ArrayList_GetItem( DIlist, i); - ArrayList_AddItem(keylists, GenerateKeyspp( pd->name, maxdim, pd, - useStereographic ? stgfov : -1 ) ); + if( !DIinfo_isDummy( pd ) ) + ArrayList_AddItem(keylists, GenerateKeyspp( pd->name, maxdim, pd, + useStereographic ? stgfov : -1, &totalKPs ) ); } } else { // std mode: image names only from commandline for( i=0; i<argc - 1 - optionCount; i++) { - ArrayList_AddItem(keylists, GenerateKeyspp( argv[i+optionCount+1], maxdim, 0, 0 ) ); + ArrayList_AddItem( keylists, GenerateKeyspp( argv[i+optionCount+1], + maxdim, 0, 0, &totalKPs ) ); } } @@ -738,6 +763,11 @@ time = ((double)finish - (double)start ) / CLOCKS_PER_SEC; WriteLine("%.1f seconds to find keypoints", time); + // fail if no keypoints were found + if( totalKPs < 2 ){ + FatalError("No keypoints found!"); + } + /** Find control points **/ start = clock(); Modified: autopano-sift-C/trunk/APSCpp/CamLens.c =================================================================== --- autopano-sift-C/trunk/APSCpp/CamLens.c 2009-07-21 23:29:11 UTC (rev 4081) +++ autopano-sift-C/trunk/APSCpp/CamLens.c 2009-07-22 03:35:07 UTC (rev 4082) @@ -1,6 +1,9 @@ /* CamLens.c 20 Feb 2008 TKS implementaton of CamLens class + + For APSCpp version 2.5.1, accepts format code 29 for equal-area + fisheye, codes 2 or 3 for equal-angle. */ /* @@ -35,6 +38,7 @@ fish any <= K mirr any <= 2 ster <Pi any + equa any any */ static double r2a_rect( double R, double K ){ @@ -53,6 +57,14 @@ return K * sin( A / K ); } +static double r2a_equa( double R, double K ){ + return R / K; +} + +static double a2r_equa( double A, double K ){ + return K * A; +} + static double r2a_mirr( double R, double K ){ return asin( 0.5 * R ); } @@ -70,7 +82,73 @@ return tan(0.5 * A); } +/* compute focal length in pixels from + fov (deg) + dim (pixels full width) + fmt projection type code + NOTE the horizontal function for fmt is used +*/ +double flpix( double fov, int dim, int fmt ){ + double a = 0.5 * DEG2RAD( fov ); + double d = 0.5 * dim; + switch( fmt ){ + case _rectilinear: + return d / a2r_rect( a, 1 ); + break; + case _fisheye_circ: // equal-angle fisheye + case _fisheye_ff: + case _panorama: // cylindrical + case _equirectangular: + case _spherical_cp: + case _spherical_tp: + return d / a ; + break; + case _mirror: + return d / a2r_mirr( a, 1 ); + break; + case _orthographic: // equal area fisheye in APSCpp + return d / a2r_fish( a, 2 ); + break; + case _stereographic: + return d / a2r_ster( a, 1 ); + break; + default: + return 999999; // unsupported format + } +} +/* compute fov in degrees from + flpix + dim (pixels) + fmt +*/ +double fovdeg( double flpix, int dim, int fmt ){ + double r = 0.5 * dim / flpix; + switch( fmt ){ + case _rectilinear: + return 2 * RAD2DEG( r2a_rect( r, 1 ) ); + break; + case _fisheye_circ: // equal-angle fisheye + case _fisheye_ff: + case _panorama: // cylindrical + case _equirectangular: + case _spherical_cp: + case _spherical_tp: + return 2 * RAD2DEG( r ); + break; + case _mirror: + return 2 * RAD2DEG( r2a_mirr( r, 1 )); + break; + case _orthographic: // equal area fisheye in APSCpp + return 2 * RAD2DEG( r2a_fish( r, 2 )); + break; + case _stereographic: + return 2 * RAD2DEG( r2a_ster( r, 1 )); + break; + default: + return 0; // unsupported format + } +} // create empty pCamLens CamLens_new0() @@ -83,7 +161,7 @@ /* initialize with minimal info fmt is a PT format code fails if fmt is not a "camera" projection - hfov is the angle corresponding to wid + flpix is the focal length in pixels flmm should be 0 for an ideal projection, >0 for a real lens other assumptions see CamLens_setProjection() @@ -105,7 +183,7 @@ // focal lengths in pixels R = CamLens_RofA( p, DEG2RAD( 0.5 * hfov ) ); p->hFLpix = p->vFLpix = 0.5 * p->widpix / R; - + // projection center p->hCpix = 0.5 * wid; p->vCpix = 0.5 * hgt; @@ -166,12 +244,12 @@ p->Klens = 1.0; p->lensAxis &= 2; // lens Y only break; - case _fisheye_circ: + case _fisheye_circ: // equal-angle fisheye in APSCpp case _fisheye_ff: - p->R2A = r2a_fish; - p->A2R = a2r_fish; - p->Klens = 2.0; - p->Rref = p->Rcrop = p->Klens; + p->R2A = r2a_equa; + p->A2R = a2r_equa; + p->Klens = 1.0; + p->Rref = p->Rcrop = 2; //p->Klens; break; case _equirectangular: if( p->FLmm ){ @@ -196,10 +274,10 @@ p->A2R = a2r_mirr; p->Klens = 1.0; break; - case _orthographic: + case _orthographic: // equal area fisheye in APSCpp p->R2A = r2a_fish; p->A2R = a2r_fish; - p->Klens = 1.0; + p->Klens = 2.0; p->Rref = p->Rcrop = p->Klens; break; case _stereographic: @@ -250,3 +328,23 @@ return sqrt( dx * dx + dy * dy ); } +const char * formatName( int fmt ){ + static const char * fmtnms[] = { + "rectilinear", + "cylindrical", + "equal-angle fish", + "equal-angle fish", + "equirectangular", + "spherical_cp", + "spherical_tp", + "mirrorball", + "equal-area fish", + "cubic", + "stereographic", + "mercator", + "trans_merc", + "trans_cyli" + }; + if( fmt < 0 || fmt > 13 ) return "->unknown<-"; + return fmtnms[fmt]; +} \ No newline at end of file Modified: autopano-sift-C/trunk/APSCpp/sphereAlign.h =================================================================== --- autopano-sift-C/trunk/APSCpp/sphereAlign.h 2009-07-21 23:29:11 UTC (rev 4081) +++ autopano-sift-C/trunk/APSCpp/sphereAlign.h 2009-07-22 03:35:07 UTC (rev 4082) @@ -59,6 +59,8 @@ }; #endif //ndef PANORAMA_H +const char * formatName( int fmt ); + #ifndef Pi #define Pi 3.1415926535897932384626433832795 #define DEG2RAD( x ) ((x) * Pi/180.0 ) @@ -182,7 +184,7 @@ // create empty pCamLens CamLens_new0(); // create with minimal info -pCamLens CamLens_new1( int wid, int hgt, int fmt, double flpix, double flmm ); +pCamLens CamLens_new1( int wid, int hgt, int fmt, double hfov, double flmm ); // create with database info pCamLens CamLens_new( pCameraInfo pc, pLensInfo pl ); // change projection type @@ -241,25 +243,45 @@ double *xsrc, double *ysrc ); -/* minimal image info for APSC++ - source is project file 'i' lines - (LoadProjectImages() reads this) +/* compute focal length in pixels from + fov (deg) + dim (pixels full width) + fmt projection type code */ +double flpix( double fov, int dim, int fmt ); + +/* compute fov in degrees from + flpix + dim (pixels) + fmt +*/ +double fovdeg( double flpix, int dim, int fmt ); + +/* image info for APSC++, used when source is project file + Rev 2.5.1+ + flpix is set once when project is read, hfov computed + when needed as fovdeg( flpix, width, format). + format and width can change during processing. The + value read from project file is kept in fmtref. +*/ typedef struct DIinfo { // 'i' line input char name[262]; - int width, height; - int format; - double hfov; - double yaw, pitch, roll; + int width, height; // working + int format; // working + int fmtref; // as read + double flpix; // working + double yaw, pitch, roll; // alignment + double a, b, c; // correction poly } DIinfo, * pDIinfo; // create empty pDIinfo DIinfo_new0(); // delete void DIinfo_delete( pDIinfo self ); +// test if is a dummy image (no file) +int DIinfo_isDummy( pDIinfo self ); - #ifdef __cplusplus } #endif Modified: autopano-sift-C/trunk/RevisionLog.txt =================================================================== --- autopano-sift-C/trunk/RevisionLog.txt 2009-07-21 23:29:11 UTC (rev 4081) +++ autopano-sift-C/trunk/RevisionLog.txt 2009-07-22 03:35:07 UTC (rev 4082) @@ -38,3 +38,121 @@ 2) remove control var useANN & uses of it 3) eliminate mode argument to GenerateKeyspp & code that used it. + +Now for project file loading -- APSCpp.c:LoadProjectImages() +-- it already loads y,p,r, now change needed +-- make it parse PTAsm, PTGui style file names... + These are on comment lines of the form +#-imgfile 3522 2348 "_MG_6981.CR2" + rather than on 'i' or 'o' lines. Name may be full path. + +20 July +debugging load pts and ptp projects.. +ptp load ok, but pts has a "dummy image" o-line that makes +trouble. I think it can be handled just by skipping o-lines +that don't have a file name -- must reset FNflag at eof in +case 2 passes. +But it can't, because file o-lines have back references to +dummy image attributes. So we have to support a true dummy +image in the DIinfo list. Grrr. Let's do that by leaving the +file name null and inserting checks for that where needed. + +That seems to work, however a,b,c from the dummy image line +are not making it to the output file (not unsurprising as we +don't read them, but we should). + +Verrrry interesting. +Here's what three PT family stitchers report for the hfov +of two fisheye images, using EXIF data + stitcher FL crop rectilinear fisheye +Canon 15mm + PTAsm 5.0 15 1.6 73.74 85.94 + Hugin 0.8 15 1.6 73.69 85.86 + PTGui 8.1 15 1.587 74.19 91.67 +Sigma 8mm + PTAsm 5.0 8 1.6 109.16 161.14 + Hugin 0.8 8 1.6 109.1 161 + PTGui 8.1 8 1.587 86.77 180 +PTGui recognizes both lenses as fisheyes, PTAsm and Hugin +have to be told. But it gets the crop factor wrong (Hugin +has 1.60149, the value I compute from the 30D EXIF data). +PTGui uses the equal-area formula for fisheyes, the others +use the equal-angle. The big discrepancy on the 8mm fisheye +is because PTGui reports crop circle diameter for "circular" +fisheyes, all other fovs are for the short image dimension. + +Fixed nasty bug in WritePTOFile(): using same index in outer +& inner loops. This could cause some i-lines to disappear. + +To get a,b,c into the output: +--add them to DIinfo and project parser +--write them to output pto + +Now deal with some differences between stitchers +1) PTAsm and PTGui give image dimensions in #-imgfile line, +so have to read those. +2) for circular fisheye, PTGui's hfov is the diameter of the +cropping circle. Hugin & PTAsm give fov for the horizontal +axis, even if that exceed crop circle. This ccould be fixed +at project read time by rescaling PTGui's number to hdim, if +I knew the crop circle diameter in pixels. But that info is +not apparent in the project file. +3) If the EXIF specifies an orientation, PTGui reports image +as oriented that way, regardless of filed orientation. Hugin +and PTAsm use the filed dimensions. This means we have to +check the filed dimentsions against the nominal ones when we +read the images, and adjust hfov if they don't agree. +4) PTAsm lets you specify fisheye type, using format 29 for +equal-area. Hugin treats all fisheyes as equal angle, PTGui +treats all as equal-area. APSCpp should let you choose. + +21 July -- deal with stitcher differences... +-- read PTAsm and PTGui image dims like the file name; +-- adjust hfov at file read if DIinfo dims are transposed + (fatal error if they don't match either way). +-- provisionally assume PTGui's crop circle diameter equals + the long image axis. +TODO: correct this when better informed (have written Joost). +To deal with both fisheye types... +-- command option --equal-angle-fisheye sets default fisheye type +-- make CamLens treat formats 2,3 as equal-angle, 8 as equal-area; +-- make readProject identify Hugin, PTasm & PTGui projects and + accept PTAsm format 29 as equal-area fisheye (convert to 8), + and if not PTAsm, convert formats 2 & 3 to the default, and + adjust hfov if necessary. +-- print name of source format when converting to stg. (code is + already shown, but who knows what that means?) + +Testing... +1) set up Hugin, PTAsm and PTGui projects for 3 circular fisheye +images, and same rotated 90 degrees. Build release APSCpp and +run against all 6 projects (equal area, no ransac) giving 6 pto's. +Load those in Hugin and compare alignments. +2) run same projects with default equal-area fisheye; compare +3) set up Hugin, PTAsm and PTGui projects for a rectilinear +image set, and its rotated form; run & compare alignments. + +Found 2 problems: +1) writing out format 8, should have been put back to 2 or 3. +(how to tell which??) +2) FL reported by Hugin depends on originating stitcher, and +not quite right even when that was Hugin. +So-- +-- at read project, compute fl in pixels & put that in DIinfo + then compute hfov from it where needed (incl. @ output) +-- review all the monkey motion with hfov, delete code where + possible. + + +And maybe someday.... +-- add copy-project option + +This is a goal left over from original revision, that seems +more desirable now: an option to output a copy of the whole +project file, with old CPs commented out and new ones added. + +To comment-out use "#-old-CP " + +Give the output file name the same extension as the input +project, no matter what user enters? + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tks...@us...> - 2009-07-27 11:11:12
|
Revision: 4114 http://hugin.svn.sourceforge.net/hugin/?rev=4114&view=rev Author: tksharpless Date: 2009-07-27 11:11:03 +0000 (Mon, 27 Jul 2009) Log Message: ----------- Usable, needs work. Reads PTGui & PTAsm projects; works with stereographic off; Several command options still to be implemented Modified Paths: -------------- autopano-sift-C/trunk/APSCpp/APSCpp.c autopano-sift-C/trunk/APSCpp/APSCpp_main.c autopano-sift-C/trunk/APSCpp/CamLens.c autopano-sift-C/trunk/APSCpp/sphereAlign.h autopano-sift-C/trunk/LoweDetector.c autopano-sift-C/trunk/RevisionLog.txt Modified: autopano-sift-C/trunk/APSCpp/APSCpp.c =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp.c 2009-07-27 05:30:19 UTC (rev 4113) +++ autopano-sift-C/trunk/APSCpp/APSCpp.c 2009-07-27 11:11:03 UTC (rev 4114) @@ -24,8 +24,6 @@ #include <math.h> #include <tiffio.h> -extern double globFov; // hfov if no project file - // create empty pDIinfo DIinfo_new0(){ pDIinfo p = (pDIinfo)malloc(sizeof(DIinfo)); @@ -350,10 +348,13 @@ 18 July 2009 new stgfov argument <0 forbids reprojection >=0 allows reprojection when hfov exceeds this value + + 26 July 2009 add argument globFov, used when pdi is null. + */ ///#define _DEBUG_INTERP KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, DIinfo * pdi, - double stgfov, int * KPcount ) + double stgfov, int * KPcount, double globFov ) { #ifdef _DEBUG_INTERP char tmp[262]; @@ -367,6 +368,8 @@ KeypointXMLList* kpp; double Scale = 1.0; + double xcen, ycen; // scaled center + double hfov = 0; @@ -390,8 +393,8 @@ pW = pic->width; pH = pic->height; - Xcen = 0.5 * pW; - Ycen = 0.5 * pH; + xcen = Xcen = 0.5 * pW; + ycen = Ycen = 0.5 * pH; // convert to monochrome float and discard input image @@ -409,7 +412,7 @@ also convert to stereographic if pdi is valid */ // prescale factor - if( maxdim > 0) Scale = max( pW, pH ) / (double) maxdim; + if( maxdim > 0) Scale = ( pW > pH ? pW : pH ) / (double) maxdim; if( Scale <= 1 ) Scale = 1; // interpolate if necessary @@ -420,15 +423,19 @@ int dwid = pW, dhgt = pH; // reduced dimensions if( Scale > 1 ){ - dwid = (int)(0.5 + pW / Scale ); - dhgt = (int)(0.5 + pH / Scale ); - Scale = (double) pW / (double) dwid; // exact - WriteLine(" reduce size to %d x %d ...", dwid, dhgt ); + // scaled dimensions + dwid = (int)( pW / Scale ); xcen = 0.5 * dwid; + dhgt = (int)( pH / Scale ); ycen = 0.5 * dhgt; + // exact scale factor + if( pW > pH ) Scale = (double) pW / (double) dwid; + else Scale = (double) pH / (double) dhgt; + WriteLine(" reduce to %d x %d (Scale %.4f)...", dwid, dhgt, Scale ); // smooth the source for antialiasing ImageMap* tmp = ImageMap_GaussianConvolution( picMap, 0.75 * Scale ); ImageMap_delete( picMap ); picMap = tmp; } + // create result map pn = ImageMap_new( dwid, dhgt ); @@ -443,6 +450,8 @@ prm = saRemap_new( psp, pdp ); saRemap_inv ( prm, 0.5 * dwid, 0.5 * dhgt, &Xcen, &Ycen ); WriteLine(" convert to stereographic projection ..."); + CamLens_delete( psp ); + CamLens_delete( pdp ); } // interpolate saInterpSetup((void *)picMap->values, // void * pdata @@ -460,7 +469,10 @@ for( y = 0; y < pn->yDim; y++ ){ X = (double) x; Y = (double) y; if( prm ) saRemap_inv ( prm, X, Y, &X, &Y ); // ++ - else { X *= Scale; Y *= Scale; } // legacy + else { // linear rescale... + // note no need to subtract and re-add center, that just adds noise + X *= Scale; Y *= Scale; + } saInterp_float( &(pd[y]), X, Y ); } } @@ -468,6 +480,7 @@ ImageMap_delete( picMap ); picMap = pn; saRemap_delete( prm ); prm = 0; + #ifdef _DEBUG_INTERP strcpy(tmp, imgname); strcat(tmp,"-MAP-PROJ.TIF"); @@ -479,6 +492,7 @@ /* find the features + Note feature point coords are at source scale */ WriteLine(" find keypoints ..." ); @@ -488,30 +502,33 @@ WriteLine(" %d keypoints found\n", nKeys ); *KPcount = nKeys; - /* build the return value - for ANN mode a list of Keypoint, - that will be converted to keypointN after matching + /* build the return value. For APSCPP this is a list of keypoint (float + feature vector) not of keypointN (char feature vector). The feature + detector returns KP coordinates at source scale, so here all we need + to do is undo the stereographic projection if one was done. */ { ArrayList * globalNaturalKeypoints = 0; int i; - - if( pdi ){ // build remapping function at input scale - CamLens * psp, * pdp; - psp = CamLens_new1( pW, pH, pdi->format, hfov, 16.0 ); - pdp = CamLens_new1( pW, pH, _stereographic, hfov, 0 ); - prm = saRemap_new( psp, pdp ); // dest=>src + if( pdi && stgfov >= 0 && hfov >= stgfov ){ + // build remapping function at source scale + CamLens * psp, * pdp; + psp = CamLens_new1( pW, pH, pdi->format, hfov, 16.0 ); + pdp = CamLens_new1( pW, pH, _stereographic, hfov, 0 ); + prm = saRemap_new( psp, pdp ); // dest=>src + CamLens_delete( psp ); + CamLens_delete( pdp ); } else prm = 0; for(i=0; i < ArrayList_Count(lf->globalKeypoints); i++) { Keypoint* kp = (Keypoint *) ArrayList_GetItem( lf->globalKeypoints, i ); if( prm ){ // remap coordinates to image projection saRemap_inv ( prm, - kp->x , kp->y , // scale to image size - &kp->x, &kp->y // remapped coords + kp->x , kp->y , + &kp->x, &kp->y ); - } + } } // package the list Modified: autopano-sift-C/trunk/APSCpp/APSCpp_main.c =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp_main.c 2009-07-27 05:30:19 UTC (rev 4113) +++ autopano-sift-C/trunk/APSCpp/APSCpp_main.c 2009-07-27 11:11:03 UTC (rev 4114) @@ -43,65 +43,64 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ + +#define APSCPP_VERSION "2.5.2 23July2009" // now separate from package version + #include <time.h> - #include "AutoPanoSift.h" #include "sphereAlign.h" // APSCpp.cpp int LoadProjectImages( char* script, ArrayList * DIlist, bool equalAngle ); KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, - DIinfo * pdi, double stgfov, int * KPcount ); + DIinfo * pdi, double stgfov, + int * KPcount, double globFov ); int MultiMatch_ANN ( MultiMatch* ); -// globals -double globFov = 0; // width for all images in degrees - - void Usage () { WriteLine ("autopano-sift-c: Find control points giving a Hugin project file\n"); - WriteLine (" Version %s \n", PACKAGE_VERSION); + WriteLine (" Version %s \n", APSCPP_VERSION); WriteLine ("autopano-sift-c [options] output.pto image1 image2 [..]"); WriteLine (" hugin project file output.pto gets the results "); WriteLine (" input images can be jpeg, tiff, or other formats.\n"); + WriteLine (" output.pto: The output Hugin project file name, or \"-\" for stdout."); + WriteLine (" image<n>: The input image files (any common format: JPEG, PNG, TIFF,...)"); WriteLine ("autopano-sift-c [options] output.pto projectfile"); - WriteLine (" projectfile: a Hugin or other PT family project script with"); - WriteLine (" image file names, projections, angular widths and optionally"); - WriteLine (" alignments. Enables the options of stereographic projection"); - WriteLine (" and layout-guided control point placement.\n"); - - WriteLine ("Options"); - WriteLine (" --ransac <on|off|1|0> Switch RANSAC filtration on or off (default: off)."); + WriteLine (" projectfile: a Hugin, PTGui, PTAssembler, PTSticher,... project script with"); + WriteLine (" image file names, fields of view, alignments and lens correction"); + WriteLine (" factors. Enables stereographic, lens-correction, layout options."); + WriteLine (""); + WriteLine ("Options that affect image processing"); + WriteLine (" --maxdim <n> Make largest image dimension <= n (default: 1600)."); + WriteLine (" --projection <n>,<d> n = PT format code, d = hfov in degrees, for all images."); + WriteLine (" --equal-angle-fisheye lens type for format codes 2,3. Default is equal-area."); + WriteLine (" --lens-type <1|2|3> set lens type 1: rectlinear ('normal'), 2: equal-area"); + WriteLine (" fisheye (common), 3: equal-angle fisheye (uncommon)."); + WriteLine (" Used instead of format code, for all images."); + WriteLine (" --focal-length <mm>,<cf> mm = lens focal length in mm, cf = camera crop factor."); + WriteLine (" Used instead of hfov, for all images."); + WriteLine (" --stereographic <on|off|1|0> reprojection on (if enabled) or off. Default on."); + WriteLine (" Enabled by project file, --projection, --focal-length."); + WriteLine (" --stgfov <d> minimum hfov (degrees) for reprojection. Default 65."); + WriteLine (" --lens-correction <on|off|1|0> correction on (if enabled) or off. Default off."); + WriteLine (" Enabled if project has lens correction coefficients."); + WriteLine (""); + WriteLine ("Options that affect Control Point processing and output"); + WriteLine (" --use-layout <on|off|1|0> image alignment in pto file guides control point"); + WriteLine (" placement; or does not. Default is off."); WriteLine (" --maxmatches <matches> Output no more that this many control points per"); WriteLine (" image pair (default: 25, zero means unlimited)"); - WriteLine (" --maxdim <n> Make largest image dimension <= n (default: 1600)."); - WriteLine (" --projection <n>,<d> n = PT format code, d = hfov in degrees. These"); - WriteLine (" apply to all images. Enables stereographic option."); - WriteLine (" --stereographic <on|off|1|0> reprojection on (if enabled) or off. Default on."); - WriteLine (" --stgfov <d> minimum hfov (degrees) for reprojection. Default 65."); - WriteLine (" --equal-angle-fisheye Set fisheye lens type to equal-angle instead of"); - WriteLine (" equal-area. Ignored for PTAssembler projects."); - WriteLine (" --disable-areafilter Do not use max-area filtration, which is default."); - WriteLine (" See manpage for details."); + WriteLine (" --ransac <on|off|1|0> Switch RANSAC filtration on or off (default: off)."); WriteLine (" --integer-coordinates Truncate match coordinates to integer numbers."); WriteLine (" --absolute-pathnames <on|off|1|0> Use the absolute pathname of the image"); WriteLine (" file in the PTO output file. Disabled by default."); - WriteLine (" --use-layout <on|off|1|0> image alignment in pto file guides control point"); - WriteLine (" placement; or does not. Default is off."); - WriteLine (""); - - WriteLine ("Refinement options"); - WriteLine (" --refine Refine the found control points using the"); - WriteLine (" original images."); + WriteLine (" --disable-areafilter Do not use max-area filtration, which is default."); + WriteLine (" See manpage for details."); + WriteLine (" --refine Refine control points using the original images."); WriteLine (" --refine-by-middle Use the best middle point to refine (default)."); WriteLine (" --refine-by-mean Use the mean of the patches control points."); - WriteLine (" --keep-unrefinable <on|off|1|0>"); - WriteLine (" Keep unrefinable matches (default: on)."); - - WriteLine ("output.pto: The output PTO panorama project file."); - WriteLine (" This filename can be \"-\", then stdout is used"); - WriteLine ("image<n>: input image files (any common format: JPEG, PNG, TIFF, ..)"); + WriteLine (" --keep-unrefinable <on|off|1|0> Keep unrefinable CPs (default: on)."); WriteLine (""); } @@ -427,7 +426,7 @@ DIinfo * pdi = 0; char buffer[262]; - fprintf(pto, "# Stitcher project file generated by APSCpp version %s\n\n", PACKAGE_VERSION); + fprintf(pto, "# Stitcher project file generated by APSCpp version %s\n\n", APSCPP_VERSION); fprintf(pto, "p f2 w3000 h1500 v360 n\"JPEG q90\"\n"); fprintf(pto, "m g1 i0\n\n"); @@ -544,11 +543,14 @@ // list used in ++ mode only -- image info from pto file ArrayList * DIlist = 0; // item = DIinfo struct. char *projectfile = 0; - // "--projection" option sets these for all images - int globFmt = -1; // PT format code int Nerr = 0; // counts commandline errors - // downscale option = largest allowed image dimension (0: none) +// "--projection" option + int globFmt = -1; // default PT format code + double globFov = 0; // width for all images in degrees + + +// downscale option = largest allowed image dimension (0: none) int maxdim = 1600; // output to stdout flag @@ -560,10 +562,18 @@ // Use stereographic projection if feasible bool useStereographic = true; double stgfov = 65; // don't reproject below this hfov - - // Use input alignment if feasible + + // Lens and camera settings, valid if > 0 + double FLmm = 0, + cropFactor = 0; + int lensType = 0; + + // Use project alignment if feasible bool useLayout = false; + // Use project lens correction fn if feasible + bool lensCorrection = false; + // treat fisheye lens as equal-angle bool equalAngle = false; @@ -590,7 +600,7 @@ int i; int totalKPs = 0; - WriteLine ("\nAPSCpp, enhanced autopano-sift-c version %s \n", PACKAGE_VERSION); + WriteLine ("\nAPSCpp, enhanced autopano-sift-c version %s \n", APSCPP_VERSION); LoweFeatureDetector_SetVerbose(false); // default low chatter @@ -624,6 +634,19 @@ ++Nerr; } + } else if( strcmp (optionStr, "--focal-length") == 0) { + joptN = 2; + char *p = argv[optionN + 1]; + if(sscanf( p, "%g", &FLmm ) != 1 ){ + WriteLine ("Invalid focal-length parameter"); + ++Nerr; + } + p = strchr(p,','); + if( !p || sscanf( p, "%g", &cropFactor ) != 1 ) + { + WriteLine ("Invalid focal-length parameter"); + ++Nerr; + } } else if (strcmp (optionStr, "--ransac") == 0) { joptN = 2; useRansac = YesNoOption ("--ransac", argv[optionN + 1], &Nerr ); @@ -636,6 +659,9 @@ } else if (strcmp (optionStr, "--use-layout") == 0) { joptN = 2; useLayout = YesNoOption ("--use-layout", argv[optionN + 1], &Nerr ); + } else if (strcmp (optionStr, "--lens-correction") == 0) { + joptN = 2; + lensCorrection = YesNoOption ("--lens-correction", argv[optionN + 1], &Nerr ); } else if (strcmp (optionStr, "--maxmatches") == 0) { joptN = 2; if (sscanf(argv[optionN + 1], "%d", &maxMatches) != 1) { @@ -712,19 +738,42 @@ DIlist = ArrayList_new0( (void *) DIinfo_delete ); } + /** set up and report options **/ - WriteLine(" Default fisheye lens type is %s.", + if( !DIlist ){ + lensCorrection = false; + useLayout = false; + if( globFmt < 0 && FLmm == 0 ) useStereographic = false; + } + + if( lensType ){ + WriteLine(" Assuming %s lens type.", + lensType == 1 ? "rectilinear" + : lensType == 2 ? "equal-area fisheye" + : "equal-angle fisheye" ); + } else { + WriteLine(" Default fisheye lens type is %s.", equalAngle ? "equal-angle" : "equal-area" ); + } - if( DIlist ){ - if( useStereographic ) - WriteLine(" Stereographic projection enabled for hfov >= %.1f degrees.", stgfov ); - if( useLayout ) - WriteLine(" Will try to use source image layout to guide CP placement."); + if( FLmm && cropFactor ){ + WriteLine(" Assuming focal length %.2f mm, crop factor %.4f.", + FLmm, cropFactor); + } else { + WriteLine(" Focal length will be computed from hfov."); } + if( useStereographic ) + WriteLine(" Stereographic projection enabled for hfov >= %.1f degrees.", stgfov ); + if( lensCorrection ) + WriteLine(" Lens correction enabled BUT NOT IMPLEMENTED."); + if( useLayout ) + WriteLine(" Layout guided CP placement enabled BUT NOT IMPLEMENTED."); + + + /** Find keypoints **/ start = clock(); @@ -748,14 +797,18 @@ for( i = 0; i < ArrayList_Count( DIlist ); i++ ){ pd = (pDIinfo) ArrayList_GetItem( DIlist, i); if( !DIinfo_isDummy( pd ) ) - ArrayList_AddItem(keylists, GenerateKeyspp( pd->name, maxdim, pd, - useStereographic ? stgfov : -1, &totalKPs ) ); + ArrayList_AddItem( keylists, + GenerateKeyspp( pd->name, maxdim, pd, + useStereographic ? stgfov : -1, + &totalKPs, globFov ) ); } } else { // std mode: image names only from commandline for( i=0; i<argc - 1 - optionCount; i++) { - ArrayList_AddItem( keylists, GenerateKeyspp( argv[i+optionCount+1], - maxdim, 0, 0, &totalKPs ) ); + ArrayList_AddItem( keylists, + GenerateKeyspp( argv[i+optionCount+1], + maxdim, 0, 0, &totalKPs, + globFov ) ); } } Modified: autopano-sift-C/trunk/APSCpp/CamLens.c =================================================================== --- autopano-sift-C/trunk/APSCpp/CamLens.c 2009-07-27 05:30:19 UTC (rev 4113) +++ autopano-sift-C/trunk/APSCpp/CamLens.c 2009-07-27 11:11:03 UTC (rev 4114) @@ -150,6 +150,10 @@ } } +void CamLens_delete( pCamLens self ){ + if( self ) free( self ); +} + // create empty pCamLens CamLens_new0() { Modified: autopano-sift-C/trunk/APSCpp/sphereAlign.h =================================================================== --- autopano-sift-C/trunk/APSCpp/sphereAlign.h 2009-07-27 05:30:19 UTC (rev 4113) +++ autopano-sift-C/trunk/APSCpp/sphereAlign.h 2009-07-27 11:11:03 UTC (rev 4114) @@ -181,6 +181,8 @@ fmt is a Panotools format code flmm should be 0 for ideal projections, else > 0 */ +// delete +void CamLens_delete( pCamLens self ); // create empty pCamLens CamLens_new0(); // create with minimal info Modified: autopano-sift-C/trunk/LoweDetector.c =================================================================== --- autopano-sift-C/trunk/LoweDetector.c 2009-07-27 05:30:19 UTC (rev 4113) +++ autopano-sift-C/trunk/LoweDetector.c 2009-07-27 11:11:03 UTC (rev 4114) @@ -152,12 +152,12 @@ // Print license restriction WriteLine (""); WriteLine ("==============================================================================="); - WriteLine ("The use of this software is restricted by certain conditions."); - WriteLine ("See the \"LICENSE\" file distributed with the program for details."); + WriteLine (" The use of this software is restricted by certain conditions."); + WriteLine (" See the LICENSE file distributed with the program for details."); WriteLine (""); - WriteLine ("The University of British Columbia has applied for a patent on the SIFT"); - WriteLine ("algorithm in the United States. Commercial applications of this software may"); - WriteLine ("require a license from the University of British Columbia."); + WriteLine (" The University of British Columbia has applied for a patent on the SIFT"); + WriteLine (" algorithm in the United States. Commercial applications of this software"); + WriteLine (" may require a license from the University of British Columbia."); WriteLine ("==============================================================================="); WriteLine (""); } Modified: autopano-sift-C/trunk/RevisionLog.txt =================================================================== --- autopano-sift-C/trunk/RevisionLog.txt 2009-07-27 05:30:19 UTC (rev 4113) +++ autopano-sift-C/trunk/RevisionLog.txt 2009-07-27 11:11:03 UTC (rev 4114) @@ -156,3 +156,147 @@ Give the output file name the same extension as the input project, no matter what user enters? +22 July Design for layout-guided CP selection + +The key thing is to match keypoints for one pair of images +at a time. A list of pairs to be processed will be created, +based on overlaps predicted by the layout. + +The overlaps should be evaluated using only (Y,P) and some +kind of average image diameter. Then candidate CPs can be +validated (for each pair) as follows. + +1) map KP coordinates to the sphere (using lens fn, including +correction if known). +2) repeat { + find rotation of one image around optic axis that minimizes + the variance of KP differences (considered as 3-vectors); + discard outlier CPs; +} until( set is pretty compact ); +3) If there are more than maxmatches CPs left, sort them on +position across the line between image centers, divide into +maxmatches groups, and keep the strongest CP in each group. + +If there is no layout, it is more efficient to match KPs for +all images at once, as now; however for really big jobs it +might be necessary to divide the kp's into several groups & +do global matching on those. Anyhow, we should then select +the image pairs having decent numbers of matches and do the +rotational refinement on those. + +It would be possible to construct a complete alignment from +the results of the pairwise alignments. But perhaps just a +consistency check is enough. + +It might be feasible to use a Monte Carlo approach to +build the overlapping pairs list: Match a random selection +of keypoints (equal numbers from each image), count matches +by pair, use the pairs with above average numbers of matches. +This could be a good check for layout errors, too. + +So I need a KP matching subroutine that will support all +these modes. For full generality it should take a list of +KP lists to be loaded into the k-d tree, and a second list +of KP lists to be used as probes, and output a list of CPs +(caller can separate that into lists by image pair). + +And a rotational optimizer that takes a list of CPs for a +single pair of images; the projection specifications; and +maybe a tuning parameter or two, and returns the subset of +good CPs and the relative alignment of the pair. I don't +think this needs to be given an initial alignment. + +Infrastructure--- +I'd like to abandon Nowozin's MultiMatch structure as it +puts all KP data and CP data "in one basket", making it +hard to partition a big job pairwise. That will mean +abandoning his polishing fns too, as they all assume a +MultiMatch. So with this change the "autopano" part of +APSCpp will become a completely different program from +autopano. + +For a performance boost on multicore systems, it would be +good to repackage the KP finder as a task (or a separate +command pgm). + +But first, test whether there are any systematic coordinate +errors in CPs: +-- make project with an image and same rotated 90 degrees; + check optimization errors. +1) Hugin assigns different focal lengths to the 2 images, so +must set them equal by hand. It then stitches them with near +perfect cancellation, either with the 90 deg rotation set at +load, or using CPS from legacy APSCpp. +PFS_093-PFS_093-rot.pto, "8mm crop 1.60149 circular fisheye". +2)Run this thru APSCpp 2.5.2 giving + 93-93r-stg.pto -- maxdim 1600, stg on + Hugin and PTAsm display CP at same spots in both images; + Hugin gets good auto alignment after deleting 2 bad CPS. + PTAsm auto alignment fails. + 93-93r-nostg.pto -- maxdim 1600, stg off + Hug & Pta show CPs not coinciding, + Hug auto alignment very bad. +Clearly I am botching CP rescaling when the stg is off. +-- try re-using the pre-find remapper & (when stg off) inverting +the pre-find scale. Now both stg on & stg off CPs are misplaced! +The relative positions are same in both images, but all are in +the wrong places. +So must review how to prescale & scale back.... tomorrow. + +23 July kp coord scaling tests w/rotated image pairs +-- put stg rescaling back the way it was. Compute true factor + from long image axis instead of width. +Now stg on gives good match w/90 deg rot (1 wild CP), stg off +still gives shifted CP sets. +-- try 180 deg rotation: PFS_093-PFS_093-180.pto +stg on: perfect alignment (1 bad point). +stg off: perfect alignment (2 bad points). + +So it looks like N. code gets coords wrong on 90 deg rot, and +SAremap somehow corrects that?? No, as usual the fault is all +mine: I forgot to make undoing the stereographic mapping +conditional on having done it in the first place. With that +fixed the no-stg 90 deg case aligns perfectly (0 bad pnts) -- +indeed significantly better than with stg enabled, which means +the remapping makes SIFT localization a bit less certain. + +Now that it's working, improve the API some more.... +-- lens-type option to override PT format codes. +-- focal-length + crop factor option to override hfovs. +-- lens-correction option to use a,b,c,d,e from project. + +26 July BUT FIRST -- some more testing + +Test set: L:EOSPix\StFx\IMG_7346-7350.pts. Six 15mm fisheye +pix that stitch well with PTGui. Run APSCpp with ransac on, +maxdim 1600 (2.19x reduction), autoalign with Hugin... + result CPs Avg Worst + PTGui autoalign 200 1.0 7.8 + no stg 245 2.9 35.4 + no stg + refine 249 3.5 307 + stg 222 2.1 17.5 + stg + refine 241 2.7 26.8 +and at full source resolution... + no stg, full rez 334 2.9 20.6 + stg, full rez 296 2.1 19.2 + +Stereographic remapping seems quite worthwhile, and gives +a big payoff per CPU second because it runs very fast. + +Reducing resolution did not degrade CP quality measurably. + +The refine option takes a very long time and makes the result +worse. It is actually an attempt to find SIFT CPs over again +at original resolution, in small patches around the found CPs. +I think I'll drop it, possibly in favor of something like local +correlation, perhaps on patches that have be reprojected to +on-axis rectilinear... + +Anyhow the bottom line is that APSCpp's CPs are still far +worse than PTGui's. And it takes about 5 times longer to +find them. + +BTW ransac does prune some bad points, but not enough, it +needs attention too. + +BTW \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tks...@us...> - 2009-07-27 20:51:55
|
Revision: 4118 http://hugin.svn.sourceforge.net/hugin/?rev=4118&view=rev Author: tksharpless Date: 2009-07-27 20:51:48 +0000 (Mon, 27 Jul 2009) Log Message: ----------- Removed "refine" option and related code. Modified Paths: -------------- autopano-sift-C/trunk/APSCpp/APSCpp_main.c autopano-sift-C/trunk/RevisionLog.txt Modified: autopano-sift-C/trunk/APSCpp/APSCpp_main.c =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp_main.c 2009-07-27 16:20:44 UTC (rev 4117) +++ autopano-sift-C/trunk/APSCpp/APSCpp_main.c 2009-07-27 20:51:48 UTC (rev 4118) @@ -1,20 +1,21 @@ -/* APSCpp_main.c 18 Feb2008 TKSharpless +/* APSCpp_main.c original 18 Feb2008 TKSharpless + revised 27 July 2009 TKSharpless - enhanced version of APSC for Hugin 0.7 that can transform images to - stereographic projection for better keypoint matching. - - The enhanced mode is invoked by giving it a project file in place - of the image files. The project file 'i' lines supply information - about the images' projections, as well as their file names. This - info is stored in DIlist. The keypoint generator (and the refine - keypoints step if used) converts intensity maps to stereographic - projection using info from DIlist. At tne final output-to-pto stage - the control point coordinates get projected back to image space. - - The projections are "ideal" (no lens or center point corrections), but - the reprojection machinery could handle those if available. - + Enhanced version of autopano-sift-c. Notable enchancements: + - All-in-one, runs as a plugin under Hugin, no bulky XML files. + - Uses ANN k-d tree implementation, far faster than original, + and float instead of double feature vectors. + - Can read image specifications from Hugin, PTStitcher, PTGui or + PTAssembler project files. Specs include lens type, field of + view, lens correction coefficients and image alignment angles + as well as the file name and dimensions. These are copied to + the output Hugin project file along with the keypoints. + - When able to compute image angular scale, can reproject: to + stereographic for keypoint finding; to spherical for control + point validation; to aligned stereographic for fine keypoint + adjustment. + * (C) Copyright 2004 -- Sebastian Nowozin (no...@cs...) * * "The University of British Columbia has applied for a patent on the SIFT @@ -74,10 +75,10 @@ WriteLine ("Options that affect image processing"); WriteLine (" --maxdim <n> Make largest image dimension <= n (default: 1600)."); WriteLine (" --projection <n>,<d> n = PT format code, d = hfov in degrees, for all images."); - WriteLine (" --equal-angle-fisheye lens type for format codes 2,3. Default is equal-area."); + WriteLine (" --equal-angle-fisheye change assumed type for format codes 2,3 from equal-area."); WriteLine (" --lens-type <1|2|3> set lens type 1: rectlinear ('normal'), 2: equal-area"); WriteLine (" fisheye (common), 3: equal-angle fisheye (uncommon)."); - WriteLine (" Used instead of format code, for all images."); + WriteLine (" Used instead of format code default, for all images."); WriteLine (" --focal-length <mm>,<cf> mm = lens focal length in mm, cf = camera crop factor."); WriteLine (" Used instead of hfov, for all images."); WriteLine (" --stereographic <on|off|1|0> reprojection on (if enabled) or off. Default on."); @@ -96,11 +97,6 @@ WriteLine (" --absolute-pathnames <on|off|1|0> Use the absolute pathname of the image"); WriteLine (" file in the PTO output file. Disabled by default."); WriteLine (" --disable-areafilter Do not use max-area filtration, which is default."); - WriteLine (" See manpage for details."); - WriteLine (" --refine Refine control points using the original images."); - WriteLine (" --refine-by-middle Use the best middle point to refine (default)."); - WriteLine (" --refine-by-mean Use the mean of the patches control points."); - WriteLine (" --keep-unrefinable <on|off|1|0> Keep unrefinable CPs (default: on)."); WriteLine (""); } @@ -141,263 +137,6 @@ return (1); } - - - -// The maximum radius to consider around a keypoint that is refined. That -// is, at most a patch of a maximum size of twice this value in both -// horizontal and vertical direction is extracted. -int RefinementRadiusMaximum = 96; -int (*refineHandler)(int index, int total); - - -void RefineKeypoints (ArrayList* msList, - bool selectMiddlePoint, bool neverLosePoints); -DisplayImage* ExtractPatch (DisplayImage* large, - int px, int py, double scale, int* radius); -ArrayList* ExtractKeypoints (DisplayImage* pic); -bool YesNoOption (char* optionName, char* val, int * nerr); - -// selectMiddlePoint: if true, select the middle point in the patch, -// otherwise build the mean -// neverLosePoints: if true, and if we cannot do the refinement, still use -// the control point. -void RefineKeypoints (ArrayList* msList, - bool selectMiddlePoint, bool neverLosePoints) -{ - DisplayImage* pic1 = NULL; - DisplayImage* pic2 = NULL; - char* pic1Name = NULL; - char* pic2Name = NULL; - - /* Keep stats for the refineHandler delegate - */ - int totalRefines = 0; - int doneRefines = 0; - int i; - for(i=0; i<ArrayList_Count(msList); i++) { - MatchSet* ms = (MatchSet*) ArrayList_GetItem(msList, i); - int j; - for(j=0; j<ArrayList_Count(ms->matches); j++) { - ArrayList_GetItem(ms->matches, j); - totalRefines += 1; - } - } - - - for(i=0; i<ArrayList_Count(msList); i++) { - MatchSet* ms = (MatchSet*) ArrayList_GetItem(msList, i); - WriteLine (" between \"%s\" and \"%s\"", - ms->file1, ms->file2); - - if (pic1Name != ms->file1) { - pic1Name = ms->file1; - pic1 = DisplayImage_new (ms->file1); - } - if (pic2Name != ms->file2) { - pic2Name = ms->file2; - pic2 = DisplayImage_new (ms->file2); - } - /*WriteLine ("pair: %s, %s, %d keypoint matches", - ms->file1, ms->file2, ArrayList_Count(ms->Matches));*/ - - ArrayList* refinedMatches = ArrayList_new0 (NULL); - - int j; - for(j=0; j<ArrayList_Count(ms->matches); j++) { - Match* m = (Match*) ArrayList_GetItem(ms->matches, j); - - int p1x = (int) (m->kp1->x + 0.5); - int p1y = (int) (m->kp1->y + 0.5); - int p1radius; - DisplayImage* patch1 = ExtractPatch (pic1, p1x, p1y, - m->kp1->scale, &p1radius); - - int p2x = (int) (m->kp2->x + 0.5); - int p2y = (int) (m->kp2->y + 0.5); - int p2radius; - DisplayImage* patch2 = ExtractPatch (pic2, p2x, p2y, - m->kp2->scale, &p2radius); - - /* Call the refine handler delegate in case there is one to - * inform the callee of a single refining step (for progress - * bar displays and such). - */ - doneRefines += 1; - if (refineHandler != NULL) - refineHandler (doneRefines, totalRefines); - - // Skip over keypoint matches we cannot refine as part of the - // image lies outside. - if (patch1 == NULL || patch2 == NULL) { - if (neverLosePoints) - ArrayList_AddItem(refinedMatches, m); - DisplayImage_delete(patch1); - DisplayImage_delete(patch2); - continue; - } - - // Otherwise, run the SIFT algorithm on both small patches. - ArrayList* p1kp = ExtractKeypoints (patch1); - ArrayList* p2kp = ExtractKeypoints (patch2); - /*WriteLine ("p1kp = %d, p2kp = %d", ArrayList_Count(p1kp), - ArrayList_Count(p2kp));*/ - - // Apply the matching, RANSAC enabled. - MultiMatch* mm = MultiMatch_new0 (); - mm->verbose = false; - - ArrayList* matches = NULL; - matches = MultiMatch_TwoPatchMatch (mm, p1kp, - patch1->width, patch1->height, p2kp, patch2->width, - patch2->height, true); - DisplayImage_delete(patch1); - DisplayImage_delete(patch2); - - /* In case there are less than three keypoints in the - * two patches, we ignore them all. - */ - if (0 /*was exception ???*/ ) { - matches = NULL; - } - - if (matches == NULL || ArrayList_Count(matches) != 1) { - if (neverLosePoints) - ArrayList_AddItem(refinedMatches, m); - - continue; - } - - MatchSet* pSet = (MatchSet*) ArrayList_GetItem(matches, 0); - - // Now get the real new control point coordinates from the - // patches. We have two options and assume all points are - // equal quality-wise: - // a) Select the one that is most in the middle - // (selectMiddlePoint == true) - // b) Build the mean of all the control point matches in the - // patches (selectMiddlePoint == false). - double kp1X = 0.0; - double kp1Y = 0.0; - double kp2X = 0.0; - double kp2Y = 0.0; - double kpMidDist = Double_PositiveInfinity; - - int k; - for(k=0; k<ArrayList_Count(pSet->matches); k++) { - Match* pM = (Match*) ArrayList_GetItem(pSet->matches, k); - if (selectMiddlePoint) { - double dist = sqrt ( - pow (pM->kp1->x - p1radius, 2.0) + - pow (pM->kp1->y - p1radius, 2.0)); - - if (dist < kpMidDist) { - kpMidDist = dist; - - kp1X = pM->kp1->x; - kp1Y = pM->kp1->y; - - kp2X = pM->kp2->x; - kp2Y = pM->kp2->y; - } - } else { - kp1X += pM->kp1->x; - kp1Y += pM->kp1->y; - - kp2X += pM->kp2->x; - kp2Y += pM->kp2->y; - } - - /*WriteLine ("(%g, %g) matches (%g, %g)", - pM->kp1->x, pM->kp1->y, pM->kp2->x, pM->kp2->y);*/ - } - - if (selectMiddlePoint == false) { - kp1X /= (double) ArrayList_Count(pSet->matches); - kp1Y /= (double) ArrayList_Count(pSet->matches); - kp2X /= (double) ArrayList_Count(pSet->matches); - kp2Y /= (double) ArrayList_Count(pSet->matches); - } - - kp1X += p1x - p1radius; - kp1Y += p1y - p1radius; - - kp2X += p2x - p2radius; - kp2Y += p2y - p2radius; - - Match* mn = Match_clone (m); - - // Adjust the original keypoints location to be the mean of - // all the highly precise superresolution points. - mn->kp1->x = kp1X; - mn->kp1->y = kp1Y; - - mn->kp2->x = kp2X; - mn->kp2->y = kp2Y; - - /*WriteLine ("MASTER POINT MATCH: (%g,%g) to (%g,%g)", - kp1X, kp1Y, kp2X, kp2Y);*/ - - ArrayList_AddItem(refinedMatches, mn); - /* - DisplayImage_Save (patch1, "patch-1.jpg"); - DisplayImage_Save (patch2, "patch-2.jpg"); - exit (0); - */ - } - - ms->matches = refinedMatches; - } -} - -/** Extract a small image patch from a larger image, centered at the given - * coordinates. - */ -DisplayImage* ExtractPatch (DisplayImage* large, - int px, int py, double scale, int* radius) -{ - *radius = (int) (9.0 * scale + 0.5); - if (*radius > RefinementRadiusMaximum) - *radius = RefinementRadiusMaximum; - - /*WriteLine ("patch centered at (%d,%d), scale %g, radius = %d", - px, py, scale, *radius);*/ - - int pxe = px + *radius; - int pye = py + *radius; - px -= *radius; - py -= *radius; - - if (px < 0 || py < 0 || pxe >= large->width || pye >= large->height) { - /*WriteLine (" (%d,%d)-(%d,%d) out of (0,0)-(%d,%d)", - px, py, pxe, pye, large->width, large->height);*/ - - return (NULL); - } else { - //WriteLine (" extracting patch"); - } - DisplayImage* patch = DisplayImage_Carve (large, px, py, *radius*2, *radius*2); - - return (patch); -} - -/** Produce keypoints for a small image patch. - */ -ArrayList* ExtractKeypoints (DisplayImage* pic) -{ - ImageMap* picMap = DisplayImage_ConvertToImageMap (pic); - - LoweFeatureDetector* lf = LoweFeatureDetector_new0 (); - LoweFeatureDetector_SetPrintWarning(false); - LoweFeatureDetector_SetVerbose(false); - LoweFeatureDetector_DetectFeatures (lf, picMap); - - ArrayList* res = LoweFeatureDetector_GlobalNaturalKeypoints(lf); - lf->globalNaturalKeypoints = NULL; // Make sure res won't get deleted. - LoweFeatureDetector_delete(lf); - return res; -} - // check a commandline truth value // return true or false; increment *nerr if invalid bool YesNoOption (char* optionName, char* val, int * nerr) @@ -590,11 +329,6 @@ // Use "keep-best" filtration, keep the maxMatches best. int maxMatches = 25; // default - // Refinement options - bool refine = false; - bool refineMiddle = true; - bool keepUnrefinable = true; - int optionCount = 0; int optionN = 1; int i; @@ -638,13 +372,13 @@ joptN = 2; char *p = argv[optionN + 1]; if(sscanf( p, "%g", &FLmm ) != 1 ){ - WriteLine ("Invalid focal-length parameter"); + WriteLine ("Invalid focal length"); ++Nerr; } p = strchr(p,','); if( !p || sscanf( p, "%g", &cropFactor ) != 1 ) { - WriteLine ("Invalid focal-length parameter"); + WriteLine ("Invalid crop factor"); ++Nerr; } } else if (strcmp (optionStr, "--ransac") == 0) { @@ -662,10 +396,17 @@ } else if (strcmp (optionStr, "--lens-correction") == 0) { joptN = 2; lensCorrection = YesNoOption ("--lens-correction", argv[optionN + 1], &Nerr ); + } else if (strcmp (optionStr, "--lens-type") == 0) { + joptN = 2; + if( sscanf( argv[optionN + 1], "%d", &lensType) != 1 + || lensType < 1 || lensType > 3 ){ + WriteLine ("Invalid --lens-type."); + ++Nerr; + } } else if (strcmp (optionStr, "--maxmatches") == 0) { joptN = 2; if (sscanf(argv[optionN + 1], "%d", &maxMatches) != 1) { - WriteLine ("Parameter to maxmatches option invalid. See the usage help."); + WriteLine ("Invalid --maxmatches."); ++Nerr; } if (maxMatches < 0) { @@ -681,15 +422,6 @@ } else if (strcmp (optionStr, "--absolute-pathnames") == 0) { joptN = 2; useAbsolutePathnames = YesNoOption ("--absolute-pathnames", argv[optionN + 1], &Nerr); - } else if (strcmp (optionStr, "--refine") == 0) { - refine = true; - } else if (strcmp (optionStr, "--refine-by-middle") == 0) { - refineMiddle = true; - } else if (strcmp (optionStr, "--refine-by-mean") == 0) { - refineMiddle = false; - } else if (strcmp (optionStr, "--keep-unrefinable") == 0) { - joptN = 2; - keepUnrefinable = YesNoOption ("--keep-unrefinable", argv[optionN + 1], &Nerr); } else { WriteLine ("Bad option \"%s\"", optionStr); ++Nerr; @@ -869,11 +601,6 @@ } else WriteLine (""); - if (refine) { - WriteLine ("Refining keypoints"); - RefineKeypoints (msList, refineMiddle, keepUnrefinable); - } - FILE* pto; if ( streamout ) { pto = stdout; Modified: autopano-sift-C/trunk/RevisionLog.txt =================================================================== --- autopano-sift-C/trunk/RevisionLog.txt 2009-07-27 16:20:44 UTC (rev 4117) +++ autopano-sift-C/trunk/RevisionLog.txt 2009-07-27 20:51:48 UTC (rev 4118) @@ -299,4 +299,25 @@ BTW ransac does prune some bad points, but not enough, it needs attention too. -BTW \ No newline at end of file +27 July Let's get on with pairwise matching... + +Set up an image pairs list first, use layout if available, else +list all pairs. Sort the list on 1st member to minimize the no. +of k-d tree builds. Match thru k-d tree giving a CP list for +each pair. + +Do a 'rotational alignment' on each pair to cull out wild CPs. +This uses the kp coords mapped to sphere. Rotate one image around +Z to minimize the variance of the difference vectors across each CP +-- 3d variance is best because all good CPs will be parallel after +alignment. But the rotation is 2d of course. Use L-M unless an +analytic solution presents itself (surely one exists). Throw out +obvious outlier CPs and repeat, until there are no obvious outliers. + +Using the pair alignment just computed, one could then refine kp +positions by remapping a patch around each CP from original images +to panospace and doing correlation (shifts only). Woth a try. + +Finally, review the ransac procedure to see if it could be made to +use pairwise and/or global alignments effectively. + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bru...@us...> - 2009-08-15 12:10:42
|
Revision: 4212 http://hugin.svn.sourceforge.net/hugin/?rev=4212&view=rev Author: brunopostle Date: 2009-08-15 12:10:29 +0000 (Sat, 15 Aug 2009) Log Message: ----------- Bump version to 2.6.0 and update ChangeLog for release candidate Modified Paths: -------------- autopano-sift-C/trunk/CMakeLists.txt autopano-sift-C/trunk/ChangeLog Modified: autopano-sift-C/trunk/CMakeLists.txt =================================================================== --- autopano-sift-C/trunk/CMakeLists.txt 2009-08-15 04:01:15 UTC (rev 4211) +++ autopano-sift-C/trunk/CMakeLists.txt 2009-08-15 12:10:29 UTC (rev 4212) @@ -13,7 +13,7 @@ # version set(V_MAJOR 2) -set(V_MINOR 5) +set(V_MINOR 6) set(V_PATCH 0) set(PACKAGE_VERSION ${V_MAJOR}.${V_MINOR}.${V_PATCH}) Modified: autopano-sift-C/trunk/ChangeLog =================================================================== --- autopano-sift-C/trunk/ChangeLog 2009-08-15 04:01:15 UTC (rev 4211) +++ autopano-sift-C/trunk/ChangeLog 2009-08-15 12:10:29 UTC (rev 4212) @@ -1,3 +1,73 @@ +2009-07-27 20:51 tksharpless + + * APSCpp/APSCpp_main.c, RevisionLog.txt: Removed "refine" option + and related code. + +2009-07-27 11:11 tksharpless + + * APSCpp/APSCpp.c, APSCpp/APSCpp_main.c, APSCpp/CamLens.c, + APSCpp/sphereAlign.h, LoweDetector.c, RevisionLog.txt: Usable, + needs work. + Reads PTGui & PTAsm projects; works with stereographic off; + Several command options still to be implemented + +2009-07-22 03:35 tksharpless + + * APSCpp/APSCpp.c, APSCpp/APSCpp_main.c, APSCpp/CamLens.c, + APSCpp/sphereAlign.h, RevisionLog.txt: Basically working with + Hugin, PTGui and PTAsm projects without any "gotcha's". But PTGui + circular fisheye fov is incompletely specified, so don't trust + that. + Added option to set actual fisheye type used for processing the + images, independently of source stitcher's opinions (which ain't + worh Jack). + Reads layout and lens correction data but does not uses them yet. + +2009-07-19 13:57 tksharpless + + * APSCpp/APSCpp.c, APSCpp/APSCpp_main.c, RevisionLog.txt: remove + option to use legacy k-d tree + change "align-aware" to "use-layout" + +2009-07-19 01:19 tksharpless + + * APSCpp/APSCpp.c, APSCpp/APSCpp_main.c, AutoPanoSift.h, + RevisionLog.txt: Initial easy steps in a continuing revision of + APSCpp (detailed journal in RevisionLog.txt) + new version # 2.5.1. + corrected antialiasing code + removed alignment option & supporting code + added 2 stereographic control options + Revised some messages and reports. + +2009-05-30 20:16 brunopostle + + * APSCmain.c, APSCpp/ANN/CMakeLists.txt, APSCpp/ANNkd_wrap.cpp, + APSCpp/APSCpp.c, APSCpp/APSCpp_main.c, APSCpp/CMakeLists.txt, + APSCpp/CamLens.c, APSCpp/HermiteSpline.h, + APSCpp/README-autopano-sift-c.txt, APSCpp/saInterp.c, + APSCpp/saInterp.h, APSCpp/saRemap.c, APSCpp/sphereAlign.h, + CMakeLists.txt, MatchKeys.c: unify line-endings + +2009-05-29 20:57 brunopostle + + * APSCpp/APSCpp.c: Commented out unused gaussian blur (Scott + Crosby) + +2009-05-29 20:50 brunopostle + + * AutoPanoSift.h, ImageMap.c: Inline ImageMap_SetPixel() and + ImageMap_GetPixel() patch #2798145 (Scott Crosby) + +2009-05-08 23:29 gkohlmeyer + + * CMakeLists.txt: Updated CMake file for wxWidgets 2.8.10 + +2009-03-08 22:16 brunopostle + + * CMakeLists.txt, ChangeLog: fix binary cpack generator (Kornel + Benko) + 2009-03-04 19:04 brunopostle * CMakeLists.txt: cpack stuff required for RPM and DEB generators This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yu...@us...> - 2009-09-30 04:22:49
|
Revision: 4520 http://hugin.svn.sourceforge.net/hugin/?rev=4520&view=rev Author: yuv Date: 2009-09-30 04:22:34 +0000 (Wed, 30 Sep 2009) Log Message: ----------- remove pano12 cruft fix version number to disambiguate from 2.5.1 interim release Modified Paths: -------------- autopano-sift-C/trunk/APSCpp/CamLens.c autopano-sift-C/trunk/AutoPanoSift.h autopano-sift-C/trunk/DisplayImage.c autopano-sift-C/trunk/config.h.in.cmake Modified: autopano-sift-C/trunk/APSCpp/CamLens.c =================================================================== --- autopano-sift-C/trunk/APSCpp/CamLens.c 2009-09-29 22:07:37 UTC (rev 4519) +++ autopano-sift-C/trunk/APSCpp/CamLens.c 2009-09-30 04:22:34 UTC (rev 4520) @@ -2,7 +2,7 @@ implementaton of CamLens class - For APSCpp version 2.5.1, accepts format code 29 for equal-area + For APSCpp version 2.5.1 and later, accepts format code 29 for equal-area fisheye, codes 2 or 3 for equal-angle. */ @@ -351,4 +351,4 @@ }; if( fmt < 0 || fmt > 13 ) return "->unknown<-"; return fmtnms[fmt]; -} \ No newline at end of file +} Modified: autopano-sift-C/trunk/AutoPanoSift.h =================================================================== --- autopano-sift-C/trunk/AutoPanoSift.h 2009-09-29 22:07:37 UTC (rev 4519) +++ autopano-sift-C/trunk/AutoPanoSift.h 2009-09-30 04:22:34 UTC (rev 4520) @@ -5,7 +5,7 @@ #ifdef HAS_CONFIG_H #include "config.h" #else -#define PACKAGE_VERSION "2.5.1" +#define PACKAGE_VERSION "2.5.2" #endif // include windows.h here @@ -29,13 +29,8 @@ # endif #endif -#ifdef HAS_PANO13 #include "pano13/filter.h" #include "pano13/panorama.h" -#else -#include "pano12/filter.h" -#include "pano12/panorama.h" -#endif #include "math.h" Modified: autopano-sift-C/trunk/DisplayImage.c =================================================================== --- autopano-sift-C/trunk/DisplayImage.c 2009-09-29 22:07:37 UTC (rev 4519) +++ autopano-sift-C/trunk/DisplayImage.c 2009-09-30 04:22:34 UTC (rev 4520) @@ -1,7 +1,7 @@ #include "AutoPanoSift.h" /* This is a replacement for the "GUIImage-Drawing.cs" */ -/* the code is wrapping a libpano12 Image structure */ +/* the code is wrapping a libpano Image structure */ DisplayImage* DisplayImage_new0() { DisplayImage* self = (DisplayImage*)malloc(sizeof(DisplayImage)); @@ -15,15 +15,9 @@ if (StringtoFullPath(&filePath, filename) != 0) { FatalError("Syntax error: Not a valid pathname"); } -#ifdef HAS_PANO13 if ( panoImageRead(self, &filePath) == FALSE ) { FatalError("Syntax error: Not a valid image"); } -#else - if( readImage(self, &filePath) != 0) { - FatalError("Syntax error: Not a valid image"); - } -#endif return self; } Modified: autopano-sift-C/trunk/config.h.in.cmake =================================================================== --- autopano-sift-C/trunk/config.h.in.cmake 2009-09-29 22:07:37 UTC (rev 4519) +++ autopano-sift-C/trunk/config.h.in.cmake 2009-09-30 04:22:34 UTC (rev 4520) @@ -13,8 +13,6 @@ #if defined PANO13_FOUND #define HAS_PANO13 1 -#elif defined PANO12_FOUND -#define HAS_PANO12 1 #endif #cmakedefine APPLE This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bru...@us...> - 2010-02-16 22:44:49
|
Revision: 4986 http://hugin.svn.sourceforge.net/hugin/?rev=4986&view=rev Author: brunopostle Date: 2010-02-16 22:44:43 +0000 (Tue, 16 Feb 2010) Log Message: ----------- Fix for broken --projection parameter (Alexandre Duret-Lutz) Modified Paths: -------------- autopano-sift-C/trunk/APSCpp/APSCpp.c autopano-sift-C/trunk/ChangeLog Modified: autopano-sift-C/trunk/APSCpp/APSCpp.c =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp.c 2010-02-16 22:31:47 UTC (rev 4985) +++ autopano-sift-C/trunk/APSCpp/APSCpp.c 2010-02-16 22:44:43 UTC (rev 4986) @@ -377,6 +377,11 @@ hfov = globFov; WriteLine(" width %d height %d", pic->width, pic->height ); } else { + // If globFov is non null, its value was specified by + // the user on the command line, so use that. + if (globFov > 0.0) + hfov = globFov; + else hfov = fovdeg( pdi->flpix, pic->width, pdi->format ); WriteLine(" %s width %d height %d hfov %g ", formatName( pdi->format), pic->width, pic->height, hfov); Modified: autopano-sift-C/trunk/ChangeLog =================================================================== --- autopano-sift-C/trunk/ChangeLog 2010-02-16 22:31:47 UTC (rev 4985) +++ autopano-sift-C/trunk/ChangeLog 2010-02-16 22:44:43 UTC (rev 4986) @@ -1,5 +1,16 @@ +2010-01-06 brunopostle + + * [r4858] README: Remove outdated C# build instructions + +2009-09-30 yuv + + * [r4520] APSCpp/CamLens.c, AutoPanoSift.h, DisplayImage.c, + config.h.in.cmake: remove pano12 cruft + fix version number to disambiguate from 2.5.1 interim release + 2009-09-28 brunopostle + * [r4513] ChangeLog: Switch to slightly different svn2cl format * [r4512] CMakeLists.txt: New ChangeLog regime, update like so: cmake -DUPDATE_CHANGELOG=YES . This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bru...@us...> - 2010-05-23 09:57:10
|
Revision: 5162 http://hugin.svn.sourceforge.net/hugin/?rev=5162&view=rev Author: brunopostle Date: 2010-05-23 09:57:03 +0000 (Sun, 23 May 2010) Log Message: ----------- Break SVN build and point users to HG Modified Paths: -------------- autopano-sift-C/trunk/CMakeLists.txt autopano-sift-C/trunk/ChangeLog Modified: autopano-sift-C/trunk/CMakeLists.txt =================================================================== --- autopano-sift-C/trunk/CMakeLists.txt 2010-05-17 22:20:57 UTC (rev 5161) +++ autopano-sift-C/trunk/CMakeLists.txt 2010-05-23 09:57:03 UTC (rev 5162) @@ -9,6 +9,12 @@ # minimum version set to suppress project developer warning cmake_minimum_required(VERSION 2.4) +IF (NOT BUILD_ANYWAY) + MESSAGE(FATAL_ERROR "Subversion repository is disused, please use the +mercurial repository. Define BUILD_ANYWAY to ignore this message, e.g. + cmake -DBUILD_ANYWAY=1 .") +ENDIF (NOT BUILD_ANYWAY) + project(autopano-sift-C) # version Modified: autopano-sift-C/trunk/ChangeLog =================================================================== --- autopano-sift-C/trunk/ChangeLog 2010-05-17 22:20:57 UTC (rev 5161) +++ autopano-sift-C/trunk/ChangeLog 2010-05-23 09:57:03 UTC (rev 5162) @@ -1,3 +1,23 @@ +2010-05-04 brunopostle + + * [r5143] APSCpp/APSCpp.c: Fix fov output when --projection is used, + patch #2996756 (Felix Hagemann) + +2010-03-11 brunopostle + + * [r5060] APSCpp/APSCpp_main.c: Fix for --focal-length parameter, + patch #2968247 (Felix Hagemann) + +2010-03-02 brunopostle + + * [r5041] APSCpp/APSCpp_main.c: Change reported date from 23July2009 + to 16February2010 + +2010-02-16 brunopostle + + * [r4986] APSCpp/APSCpp.c, ChangeLog: Fix for broken --projection + parameter (Alexandre Duret-Lutz) + 2010-01-06 brunopostle * [r4858] README: Remove outdated C# build instructions This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |