Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

Diff of /APSCpp/APSCpp.c [f61243] .. [03d2ea] Maximize Restore

  Switch to side-by-side view

--- a/APSCpp/APSCpp.c
+++ b/APSCpp/APSCpp.c
@@ -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,14 +38,22 @@
 	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
@@ -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,8 +95,15 @@
     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
@@ -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
-
-			 // add this image to list
-				numIm++;
-				ArrayList_AddItem( DIlist, im );
-
+			// 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;
+				}
+
+				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