From: <da...@us...> - 2007-05-29 23:51:21
|
Revision: 2029 http://hugin.svn.sourceforge.net/hugin/?rev=2029&view=rev Author: dangelo Date: 2007-05-29 16:51:18 -0700 (Tue, 29 May 2007) Log Message: ----------- moved files to trunk directory Added Paths: ----------- autopano-sift-C/trunk/AreaFilter.c autopano-sift-C/trunk/ArrayList.c autopano-sift-C/trunk/AutoPano.c autopano-sift-C/trunk/AutoPanoSift.h autopano-sift-C/trunk/BondBall.c autopano-sift-C/trunk/ChangeLog autopano-sift-C/trunk/DisplayImage.c autopano-sift-C/trunk/GaussianConvolution.c autopano-sift-C/trunk/GenerateKeys.c autopano-sift-C/trunk/HashTable.c autopano-sift-C/trunk/ImageMap.c autopano-sift-C/trunk/ImageMatchModel.c autopano-sift-C/trunk/KDTree.c autopano-sift-C/trunk/KeypointXML.c autopano-sift-C/trunk/LICENSE autopano-sift-C/trunk/LoweDetector.c autopano-sift-C/trunk/Makefile autopano-sift-C/trunk/MatchKeys.c autopano-sift-C/trunk/RANSAC.c autopano-sift-C/trunk/README autopano-sift-C/trunk/README.1ST autopano-sift-C/trunk/Random.c autopano-sift-C/trunk/ScaleSpace.c autopano-sift-C/trunk/SimpleMatrix.c autopano-sift-C/trunk/TestArray.c autopano-sift-C/trunk/TestKDTree.c autopano-sift-C/trunk/TestRandom.c autopano-sift-C/trunk/Transform.c autopano-sift-C/trunk/Utils.c autopano-sift-C/trunk/autopano-c-complete.sh autopano-sift-C/trunk/doc/ Copied: autopano-sift-C/trunk/AreaFilter.c (from rev 2027, autopano-sift-C/trunk/autopano-sift-C/AreaFilter.c) =================================================================== --- autopano-sift-C/trunk/AreaFilter.c (rev 0) +++ autopano-sift-C/trunk/AreaFilter.c 2007-05-29 23:51:18 UTC (rev 2029) @@ -0,0 +1,208 @@ + +/* autopano-sift, Automatic panorama image creation + * Copyright (C) 2004 -- Sebastian Nowozin + * + * This program is free software released under the GNU General Public + * License, which is included in this software package (doc/LICENSE). + */ + +/* AreaFilter.cs + * + * Area maximizing match filtration using convex hull and polygon-area + * maximization. + * + * (C) Copyright 2004 -- Sebastian Nowozin (no...@cs...) + * + * Convex hull code based on Ken Clarksons original C implementation. + * Polygon area formula by Paul Bourke. + */ + +#include "AutoPanoSift.h" + +#ifdef TEST_MAIN +int main (int argc, char* argv[]) +{ + ArrayList* al = ArrayList_new0 (FilterPoint_delete); + Random* rnd = Random_new0 (); + + int n; + for (n = 0 ; n < 10 ; ++n) { + FilterPoint* p = FilterPoint_new0 (); + + p->x = Random_NextDouble(rnd) * 400.0; + p->y = Random_NextDouble(rnd) * 400.0; + + ArrayList_AddItem(al, p); + } + int i; + for(i=0; i<ArrayList_Count(al); i++) { + FilterPoint* p = ArrayList_GetItem(al, i); + WriteLine ("%f %f # GNUPLOT1", p->x, p->y); + } + + AreaFilter* conv = AreaFilter_new0 (); + ArrayList* hull = AreaFilter_CreateConvexHull(conv, al); + + WriteLine ("\nhull: %d elements", ArrayList_Count(hull)); + int j; + for(j=0; j<ArrayList_Count(hull); j++) { + FilterPoint* p = ArrayList_GetItem(hull, j); + WriteLine ("%f %f # GNUPLOT2", p->x, p->y); + } + + WriteLine ("\npolygon area: %f", AreaFilter_PolygonArea(conv, hull)); + ArrayList_delete(al); + return 0; +} + +#else + +AreaFilter* AreaFilter_new0() +{ + AreaFilter* self = (AreaFilter*)malloc(sizeof(AreaFilter)); + return self; +} + +void AreaFilter_delete(AreaFilter* self) +{ + if (self) { + free(self); + } +} + +// Measure the absolute area of a non self-intersecting polygon. +// Formula by Paul Bourke +// (http://astronomy.swin.edu.au/~pbourke/geometry/polyarea/) +// +// The input points must be ordered (clock- or counter-clockwise). The +// polygon is closed automatically between the first and the last point, +// so there should not be two same points in the polygon point set. +double AreaFilter_PolygonArea (AreaFilter* self, ArrayList* orderedPoints) +{ + double A = 0.0; + + int n; + for (n = 0 ; n < ArrayList_Count(orderedPoints) ; ++n) { + FilterPoint* p0 = ArrayList_GetItem(orderedPoints,n); + FilterPoint* p1 = ArrayList_GetItem(orderedPoints, (n + 1) % ArrayList_Count(orderedPoints)); + + A += p0->x * p1->y - p1->x * p0->y; + } + + A *= 0.5; + + return (abs (A)); +} + +// Create the convex hull of a point set. +ArrayList* AreaFilter_CreateConvexHull (AreaFilter* self, ArrayList* points) +{ + int chn = AreaFilter_CreateHull (self, points); + + ArrayList* hull = ArrayList_new0 (NULL); + int k; + for (k = 0 ; k < chn ; ++k) + ArrayList_AddItem(hull, ArrayList_GetItem (points, k)); + + return (hull); +} + +int AreaFilter_CompareLow (const FilterPoint* p1, const FilterPoint* p2) +{ + + double v = p1->x - p2->x; + if (v > 0) + return (1); + if (v < 0) + return (-1); + + v = p2->y - p1->y; + if (v > 0) + return (1); + if (v < 0) + return (-1); + + // Equal point + return (0); +} + +int AreaFilter_CompareHigh (const FilterPoint* p1, const FilterPoint* p2) +{ + return AreaFilter_CompareLow(p2, p1); +} + + +bool AreaFilter_ccw (ArrayList* points, int i, int j, int k) +{ + double a = ((FilterPoint*)ArrayList_GetItem(points, i))->x - ((FilterPoint*)ArrayList_GetItem(points, j))->x; + double b = ((FilterPoint*)ArrayList_GetItem(points, i))->y - ((FilterPoint*)ArrayList_GetItem(points, j))->y; + double c = ((FilterPoint*)ArrayList_GetItem(points, k))->x - ((FilterPoint*)ArrayList_GetItem(points, j))->x; + double d = ((FilterPoint*)ArrayList_GetItem(points, k))->y - ((FilterPoint*)ArrayList_GetItem(points, j))->y; + + return ((a * d - b * c) <= 0.0); +} + +int AreaFilter_MakeChain (AreaFilter* self, ArrayList* points, int (*comp)(const FilterPoint*, const FilterPoint*)) +{ + IComparator comparator; + comparator.compareTo = (void*)comp; + ArrayList_Sort(points, &comparator); + + int s = 1; + int pCount = ArrayList_Count(points); + int i; + for (i = 2 ; i < pCount ; ++i) { + int j; + for (j = s ; j >= 1 && AreaFilter_ccw (points, i, j, j - 1) ; --j) + ; + + s = j + 1; + + // Swap + FilterPoint* t = ArrayList_GetItem(points, s); + ArrayList_SetItem(points, s, ArrayList_GetItem(points, i)); + ArrayList_SetItem(points, i, t); + } + + return (s); +} + +int AreaFilter_CreateHull (AreaFilter* self, ArrayList* points) +{ + int u = AreaFilter_MakeChain (self, points, AreaFilter_CompareLow); + + if (ArrayList_Count(points) == 0) + return (0); + /* + int k; + for (k = 0 ; k < u ; ++k) + WriteLine ("point %d: %f %f", k, ((FilterPoint*)ArrayList_GetItem(points, k)[k])->x, + ((FilterPoint*)ArrayList_GetItem(points, k)[k])->y); + */ + + ArrayList* pointsHigh = ArrayList_new(ArrayList_Count(points)+1-u, NULL); + //WriteLine ("points.Length = %d, u = %d", ArrayList_Count(points), u); + + ArrayList_Copy (points, u, pointsHigh, 0, ArrayList_Count(points) - u); + ArrayList_SetItem(pointsHigh, ArrayList_Count(pointsHigh) - 1, ArrayList_GetItem(points, 0)); + + int h = AreaFilter_MakeChain (self, pointsHigh, AreaFilter_CompareHigh); + + int p; + for ( p = u ; p < ArrayList_Count(points) ; ++p) { + ArrayList_SetItem(points, p, ArrayList_GetItem(pointsHigh, p-u)); + } + + /* + WriteLine ("h = %d, u = %d", h, u); + int k; + for (k = 0 ; k < (h + u) ; ++k) + WriteLine ("point %d: %f %f", k, ((FilterPoint*)ArrayList_GetItem(points, k)[k])->x, + ((FilterPoint*)ArrayList_GetItem(points, k)[k])->y); + */ + + return (h + u); +} + +#endif + Copied: autopano-sift-C/trunk/ArrayList.c (from rev 2027, autopano-sift-C/trunk/autopano-sift-C/ArrayList.c) =================================================================== --- autopano-sift-C/trunk/ArrayList.c (rev 0) +++ autopano-sift-C/trunk/ArrayList.c 2007-05-29 23:51:18 UTC (rev 2029) @@ -0,0 +1,185 @@ +#include "AutoPanoSift.h" + +/* This is a minimal subset of the C# Container Class ArrayList */ + +void ArrayList_init(ArrayList* self, void* deletefn) +{ + self->count = 0; + self->reserved = 0; + self->items = NULL; + self->deletefn = deletefn; +} + +ArrayList* ArrayList_new0(void* deletefn) +{ + ArrayList* self = (ArrayList*)malloc(sizeof(ArrayList)); + ArrayList_init(self, deletefn); + return self; +} + +ArrayList* ArrayList_new(int dim, void* deletefn) +{ + ArrayList* self = ArrayList_new0(deletefn); + self->count = dim; + self->reserved = dim; + self->items = (void**)malloc(self->reserved * sizeof(void*)); + int index; + for(index=0; index<self->count; index++) { + self->items[index] = NULL; + } + return self; +} + +ArrayList* ArrayList_clone(ArrayList* self) +{ + ArrayList* cl = ArrayList_new0(self->deletefn); + cl->count = self->count; + cl->reserved = self->reserved; + cl->items = (void**)malloc(cl->reserved * sizeof(void*)); + memcpy(cl->items, self->items, self->count * sizeof(void*)); + return cl; +} + +void ArrayList_delete(ArrayList* self) +{ + if (self != NULL) { + if (self->items != NULL) { + if (self->deletefn != NULL) { + int index=0; + void (*_deletefn)(void*) = self->deletefn; + for(index=0; index<self->count; index++) { + if (self->items[index]) { + _deletefn(self->items[index]); + self->items[index] = NULL; + } + } + } + free(self->items); + self->items = NULL; + } + self->count = 0; + self->reserved = 0; + free(self); + } +} + +int ArrayList_Count(ArrayList* self) +{ + return self->count; +} + +void* ArrayList_GetItem(ArrayList* self, int index) +{ + if (index < 0 || index >= self->count) { + FatalError("Array out of bounds"); + return NULL; + } + return self->items[index]; +} + +void ArrayList_SetItem(ArrayList* self, int index, void* item) +{ + if (index < 0 || index >= self->count) { + WriteError("Array out of bounds"); + return; + } + self->items[index] = item; +} + +int ArrayList_IndexOf(ArrayList* self, void* item) +{ + int index; + for(index=0; index<self->count; index++) { + if( self->items[index] == item) { + return index; + } + } + return -1; +} + +bool ArrayList_Contains(ArrayList* self, void* item) +{ + return ArrayList_IndexOf(self, item) >= 0; +} + +void ArrayList_AddItem(ArrayList* self, void* item) +{ + if (self->count+1 > self->reserved) { + void* tmp = self->items; + self->reserved = self->reserved * 5 + 10; + self->items = (void**)malloc(self->reserved * sizeof(void*)); + if (tmp != NULL) { + memcpy(self->items, tmp, self->count * sizeof(void*)); + free(tmp); + } + } + self->items[self->count] = item; + self->count++; +} + +void ArrayList_AddRange(ArrayList* self, ArrayList* list) +{ + if (self->count+list->count > self->reserved) { + void* tmp = self->items; + self->reserved = self->count + list->count + 10; + self->items = (void**)malloc(self->reserved * sizeof(void*)); + if (tmp != NULL) { + memcpy(self->items, tmp, self->count * sizeof(void*)); + free(tmp); + } + } + memcpy(self->items+self->count, list->items, list->count * sizeof(void*)); + self->count += list->count; +} + +void ArrayList_Copy(ArrayList* self, int start, ArrayList* dest, int offset, int len) +{ + if (dest->reserved < len) { + if (dest->reserved>0) { + free(dest->items); + } + dest->reserved = len+10; + dest->items = (void*)malloc(dest->reserved * sizeof(void*)); + } + memcpy(dest->items, self->items+start, len*sizeof(void*)); +} + + +void ArrayList_RemoveItem(ArrayList* self, void* value) +{ + int index; + for(index=0; index<self->count; index++) { + if (self->items[index] == value) { + memmove(self->items+index, self->items+index+1, (self->count-(index+1))*sizeof(void*)); + self->count--; + return; + } + } +} + +void ArrayList_RemoveAt(ArrayList* self, int index) +{ + memmove(self->items+index, self->items+index+1, (self->count-(index+1))*sizeof(void*)); + self->count--; +} + +void ArrayList_RemoveRange(ArrayList* self, int start, int len) +{ + memmove(self->items+start, self->items+start+len, (self->count-(start+len))*sizeof(void*)); + self->count-=len; +} + +IComparator* ArrayList_comparator = NULL; + +int ArrayList_compareTo(const void** obj1, const void** obj2) { + return ArrayList_comparator->compareTo(ArrayList_comparator, *obj1, *obj2); +} + +void ArrayList_Sort(ArrayList* self, IComparator* cmp) { + if (ArrayList_comparator != NULL) { + FatalError("ArrayList_Sort called recursively"); + } + ArrayList_comparator = cmp; + qsort(self->items, self->count, sizeof(void*), ArrayList_compareTo); + ArrayList_comparator = NULL; +} Copied: autopano-sift-C/trunk/AutoPano.c (from rev 2027, autopano-sift-C/trunk/autopano-sift-C/AutoPano.c) =================================================================== --- autopano-sift-C/trunk/AutoPano.c (rev 0) +++ autopano-sift-C/trunk/AutoPano.c 2007-05-29 23:51:18 UTC (rev 2029) @@ -0,0 +1,707 @@ + +/* autopano-sift, Automatic panorama image creation + * Copyright (C) 2004 -- Sebastian Nowozin + * + * This program is free software released under the GNU General Public + * License, which is included in this software package (doc/LICENSE). + */ + +/* Autopano.cs + * + * 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. + */ + +#include "AutoPanoSift.h" + +void Usage () +{ + WriteLine ("usage: autopano.exe [options] output.pto keys1.xml keys2.xml [..]\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 (""); + + 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 ("key<n>.xml: The keypoint input files."); + WriteLine (" The input files can be gzip compressed, but require the \".gz\" extension\n then."); + WriteLine (""); + 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 (""); +} + +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 = 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 = 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 = 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 = 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 = 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 = 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(ArrayList_GetItem(resolutions, refIdx), kx->xDim, kx->yDim) == 0) + break; + } + if (refIdx == (ArrayList_Count(resolutions) - 1)) + refIdx = -1; + + Position* pos = bb == NULL ? NULL : + 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 = ArrayList_GetItem(msList, j); + int k; + for(k=0; k<ArrayList_Count(ms->matches); k++) { + Match* m = 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); + } + + // 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] == '-') + { + char* optionStr = argv[optionN]; + + if (optionStr[1] != '-') { + Usage (); + exit (1); + } + + 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 ("Usage error. Run \"autopano.exe\" without arguments for help."); + exit (1); + } + } + optionCount = optionN; + + if (bottomDefault != -1 && preAlign == false) { + WriteLine ("Please enable automatic alignment (\"--align\") before using the"); + WriteLine ("--bottom-is-* options. Thank you. Run \"autopano.exe\" without"); + WriteLine ("arguments for usage help."); + + exit (1); + } + + if (generateHorizon > 0 && preAlign == false) { + WriteLine ("Please enable automatic alignment (\"--align\") before using the"); + WriteLine ("--generate-horizon option. Thank you. Run \"autopano.exe\" without"); + WriteLine ("arguments for usage help."); + + exit (1); + } + + MultiMatch* mm = MultiMatch_new0 (); + ArrayList* keyfiles = ArrayList_new0(NULL); + int i; + for( i=0; i<argc - 1 - optionCount; i++) { + ArrayList_AddItem(keyfiles, argv[i+optionCount+1]); + } + + WriteLine ("Loading keyfiles"); + MultiMatch_LoadKeysets (mm, keyfiles); + + 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 = 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 (argv[optionCount] == "-") { + 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(keyfiles); + ArrayList_delete(components); + BondBall_delete(bb); + MultiMatch_delete(mm); + if (argv[optionCount] != "-") + fclose(pto); + return 0; +} + Copied: autopano-sift-C/trunk/AutoPanoSift.h (from rev 2027, autopano-sift-C/trunk/autopano-sift-C/AutoPanoSift.h) =================================================================== --- autopano-sift-C/trunk/AutoPanoSift.h (rev 0) +++ autopano-sift-C/trunk/AutoPanoSift.h 2007-05-29 23:51:18 UTC (rev 2029) @@ -0,0 +1,742 @@ +#ifdef __cplusplus +extern "C" { +#endif +#include "pano12/filter.h" +#include "pano12/panorama.h" +#include "math.h" +#ifdef __cplusplus +} +#endif + +#define bool int +#define true 1 +#define false 0 +#define min(x,y) ((x)<(y)?(x):(y)) +#define max(x,y) ((x)>(y)?(x):(y)) +#define abs(x) ((x)>0?(x):(-x)) +#define Double_PositiveInfinity (1e+308) +#define Double_NegativeInfinity (-1e+308) + +void Write(char* fmt, ...); +void WriteLine(char* fmt, ...); +void WriteError(char* fmt, ...); +void FatalError(char* fmt, ...); + +char* FileNameToFullPath(char* filename); +char* FullPathToFileName(char* fullpath); + + +int** IntMap_new(int xDim, int yDim); +void IntMap_delete(int** self); + +double** DoubleMap_new(int xDim, int yDim); +void DoubleMap_delete(double** self); + +void*** PtrMap_new(int xDim, int yDim); +void PtrMap_delete(void*** self, void* deletefn); + +typedef struct Random Random; +struct Random { + int seed; +}; +Random* Random_new0(); +void Random_delete(Random*); +int Random_Next(Random*, int min, int max); +double Random_NextDouble(Random*); + + +typedef struct SimpleMatrix SimpleMatrix; +struct SimpleMatrix { + int xDim; + int yDim; + double** values; +}; +SimpleMatrix* SimpleMatrix_new0(); +SimpleMatrix* SimpleMatrix_new(int,int); +void SimpleMatrix_init(SimpleMatrix* self, int,int); +void SimpleMatrix_delete(SimpleMatrix*); +SimpleMatrix* SimpleMatrix_clone (SimpleMatrix* self); +double SimpleMatrix_GetValue(SimpleMatrix* self, int y, int x); +void SimpleMatrix_SetValue(SimpleMatrix* self, int y, int x, double value ); +SimpleMatrix* SimpleMatrix_Mul(SimpleMatrix* m1, SimpleMatrix* m2); +double SimpleMatrix_Dot (SimpleMatrix* self, SimpleMatrix* m); +void SimpleMatrix_Negate (SimpleMatrix* self); +void SimpleMatrix_Inverse (SimpleMatrix* self); +void SimpleMatrix_SolveLinear (SimpleMatrix* self, SimpleMatrix* vec); +void SimpleMatrix_SwapRow (SimpleMatrix* self, int r1, int r2); +char* SimpleMatrix_ToString (SimpleMatrix* self); + + +typedef struct ArrayList ArrayList; +struct ArrayList { + int count; + int reserved; + void** items; + void* deletefn; + }; +ArrayList* ArrayList_new0(void* deletefn); +void ArrayList_init(ArrayList* self, void* deletefn); +ArrayList* ArrayList_new(int count, void* deletefn); +void ArrayList_delete(ArrayList* self); +ArrayList* ArrayList_clone(ArrayList* self); +int ArrayList_Count(ArrayList* self); +void* ArrayList_GetItem(ArrayList* self, int index); +void ArrayList_SetItem(ArrayList* self, int index, void* value); +void ArrayList_AddItem(ArrayList* self, void* value); +void ArrayList_AddRange(ArrayList* self, ArrayList* list); +void ArrayList_Copy(ArrayList* self, int start, ArrayList* dest, int offset, int len); +void ArrayList_RemoveAt(ArrayList* self, int index); +void ArrayList_RemoveItem(ArrayList* self, void* value); +void ArrayList_RemoveRange(ArrayList* self, int start, int count); +bool ArrayList_Contains(ArrayList* self, void* value); +int ArrayList_IndexOf(ArrayList* self, void* value); +typedef struct IComparator IComparator; +struct IComparator { + int (*compareTo)(IComparator* self, const void*, const void*); +}; +void ArrayList_Sort(ArrayList* self, IComparator*); + + +typedef struct HashTable HashTable; +struct HashTable { + ArrayList* keys; + ArrayList* values; +}; +HashTable* HashTable_new0(void* delete_key, void* delete_value); +void HashTable_delete(HashTable* self); +void HashTable_AddItem(HashTable* self, void* key, void* value); +void* HashTable_GetItem(HashTable* self, void* key); +void HashTable_SetItem(HashTable* self, void* key, void* value); +bool HashTable_Contains(HashTable* self, void* key); + +typedef struct SortedLimitedList SortedLimitedList; +struct SortedLimitedList { + ArrayList base; + int max; + IComparator comparator; + void (*deletefn)(void*); +}; +SortedLimitedList* SortedLimitedList_new0 (); +SortedLimitedList* SortedLimitedList_new (int, void* deletefn); +void SortedLimitedList_delete (SortedLimitedList* self); +void SortedLimitedList_SetItem (SortedLimitedList* self, int idx, void* value); +int SortedLimitedList_Count (SortedLimitedList* self); +void* SortedLimitedList_GetItem (SortedLimitedList* self, int i); +void SortedLimitedList_RemoveAt (SortedLimitedList* self, int i); +int SortedLimitedList_AddItem (SortedLimitedList* self, void* value); + + +typedef struct IKDTreeDomain IKDTreeDomain; +typedef struct KDTreeBestEntry KDTreeBestEntry; +typedef struct KDTreeHREntry KDTreeHREntry; +typedef struct HyperRectangle HyperRectangle; +typedef struct KDTree KDTree; + +// The interface to be implemented by all data elements within the +// kd-tree. As every element is represented in domain space by a +// multidimensional vector, the interface provides readonly methods to +// access into this vector and to get its dimension. + +struct IKDTreeDomain { + int (*getDimensionCount)(IKDTreeDomain* self); + int (*getDimensionElement)(IKDTreeDomain* self, int dim); +}; +int IKDTreeDomain_GetDimensionCount(IKDTreeDomain* self); +int IKDTreeDomain_GetDimensionElement(IKDTreeDomain* self, int dim); + + +struct KDTreeHREntry { + double dist; + HyperRectangle* rect; + IKDTreeDomain* pivot; + KDTree* tree; +}; + +struct HyperRectangle { + int* leftTop; + int* rightBottom; + int dim; + int ref; +}; + +HyperRectangle* HyperRectangle_new0(); +void HyperRectangle_delete(HyperRectangle* self); +HyperRectangle* HyperRectangle_new (int dim); +HyperRectangle* HyperRectangle_clone (HyperRectangle* self); +HyperRectangle* HyperRectangle_ref (HyperRectangle* self); +void HyperRectangle_unref (HyperRectangle* self); +HyperRectangle* HyperRectangle_CreateUniverseRectangle (int dim); +double HyperRectangle_Distance (HyperRectangle* self, IKDTreeDomain* target); +bool HyperRectangle_IsInReach (HyperRectangle* self, IKDTreeDomain* target, double distRad); + +struct KDTreeBestEntry { + // Distance between this neighbour point and the target point. + double distance; + int distanceSq; + bool squared; + // The neighbour. + IKDTreeDomain* neighbour; + +}; +IKDTreeDomain* KDTreeBestEntry_Neighbour(KDTreeBestEntry* self); +void KDTreeBestEntry_delete(KDTreeBestEntry* self); + +struct KDTree { + // The current element + IKDTreeDomain* dr; + + // The splitting dimension for subtrees. + int splitDim; + + // The left and the right kd-subtree. + KDTree* left; + KDTree* right; +}; +int KDTree_DistanceSq (IKDTreeDomain* t1, IKDTreeDomain* t2); +IKDTreeDomain* KDTree_GoodCandidate (ArrayList* exset, int* splitDim); +KDTree* KDTree_CreateKDTree (ArrayList* exset); +KDTree* KDTree_new0 (); +void KDTree_delete (KDTree* self); +IKDTreeDomain* KDTree_NearestNeighbour (KDTree* self, IKDTreeDomain* target, double* resDist); +IKDTreeDomain* KDTree_NearestNeighbourI (KDTree* self, IKDTreeDomain* target, HyperRectangle* hr, + double maxDistSq, double* resDistSq, ArrayList* hrl); +SortedLimitedList* KDTree_NearestNeighbourList (KDTree* self, IKDTreeDomain* target, + double* resDist, int q); +IKDTreeDomain* KDTree_NearestNeighbourListI (KDTree* self, SortedLimitedList* best, + int q, IKDTreeDomain* target, HyperRectangle* hr, double maxDistSq, + double* resDistSq, ArrayList* hrl); +SortedLimitedList* KDTree_NearestNeighbourListBBF (KDTree* self, IKDTreeDomain* target, + int q, int searchSteps); +IKDTreeDomain* KDTree_NearestNeighbourListBBFI (KDTree* self, SortedLimitedList* best, + int q, IKDTreeDomain* target, HyperRectangle* hr, int maxDistSq, + int* resDistSq, SortedLimitedList* searchHr, int* searchSteps, + ArrayList* hrl); + +typedef struct Image DisplayImage; + +struct ImageMap { + int xDim; + int yDim; + double** values; +}; +typedef struct ImageMap ImageMap; + +DisplayImage* DisplayImage_new0(); +DisplayImage* DisplayImage_new(char* filename); +void DisplayImage_delete(Image* self); +double DisplayImage_ScaleWithin(DisplayImage* self, int); +ImageMap* DisplayImage_ConvertToImageMap(DisplayImage*); +DisplayImage* DisplayImage_Carve(DisplayImage* self, int x, int y, int w, int h); + +ImageMap* ImageMap_new0(); +ImageMap* ImageMap_new(int width, int height); +void ImageMap_delete(ImageMap* self); +void ImageMap_Save(ImageMap* self, char* filename, char* comment); +double ImageMap_ScaleWithin(ImageMap* self, int); +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, double 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); + + +typedef struct ConvLinearMask ConvLinearMask; +struct ConvLinearMask { + int Dim; + int Middle; + double* items; + double MaskSum; +}; + +typedef struct GaussianConvolution GaussianConvolution; +struct GaussianConvolution { + ConvLinearMask* mask; +}; + +GaussianConvolution* GaussianConvolution_new0 (); +void GaussianConvolution_delete (GaussianConvolution* ); +GaussianConvolution* GaussianConvolution_new1 (double sigma); +GaussianConvolution* GaussianConvolution_new2 (double sigma, int dim); +ImageMap* GaussianConvolution_Convolve (GaussianConvolution*, ImageMap*); + +ImageMap* ConvolutionFilter_Convolve (ImageMap* img, ConvLinearMask* mask); +void ConvolutionFilter_Convolve1D (ImageMap* dest, ConvLinearMask* mask, + ImageMap* src, int dir); +double ConvolutionFilter_CalculateConvolutionValue1D (ImageMap* src, + ConvLinearMask* mask, int n, int p, int maxN, int maxP, int dir); + + +typedef struct IRANSACModel IRANSACModel; +struct IRANSACModel { + IRANSACModel* (*clone)(IRANSACModel*); + void (*deletefn)(IRANSACModel*); + + // Fit the model to the samples given. The number of samples is equal + // to or larger than the smallest number of points required for a fit + // ('n'). + // Return true if the fit can be done, false otherwise. + bool (*fitModel)(IRANSACModel*, ArrayList*); + + // Return the fitting error of a single point against the current + // model. + double (*fittingErrorSingle)(IRANSACModel*, void*); + + // Threshhold the given fit error of a point. + // Return true if the fitting error is small enough and the point is + // fitting. + // Return false if the point is not fitting. + bool (*threshholdPoint)(IRANSACModel*, double fitError); + + // The overall fitting error of all points in FittingGround. This + // value is calculated by averaging all individual fitting errors of + // the points in the FittingGround. + double (*getFittingErrorSum)(IRANSACModel*); + void (*setFittingErrorSum)(IRANSACModel*, double); + + // All the points used to fit. Has to be set explicitly. + ArrayList* (*getFittingGround)(IRANSACModel*); + void (*setFittingGround)(IRANSACModel*, ArrayList*); + int (*compareTo)(IComparator*, IRANSACModel*, IRANSACModel*); +}; + +bool IRANSACModel_FitModel(IRANSACModel*, ArrayList*); +IRANSACModel* IRANSACModel_clone(IRANSACModel*); +void IRANSACModel_delete(IRANSACModel* self); +double IRANSACModel_FittingErrorSingle(IRANSACModel*, void*); +bool IRANSACModel_ThreshholdPoint (IRANSACModel*, double); +void IRANSACModel_SetFittingErrorSum(IRANSACModel*, double); +double IRANSACModel_GetFittingErrorSum(IRANSACModel*); +void IRANSACModel_SetFittingGround(IRANSACModel*, ArrayList*); +void IRANSACModel_CompareTo(IComparator*, void*, void*); + + +typedef struct RANSAC RANSAC; +struct RANSAC { + // Smallest number of points to be able to fit the model. + int n; + + // The number of iterations required. + int k; +}; +RANSAC* RANSAC_new0(); +RANSAC* RANSAC_new(int n, int k); +void RANSAC_delete(RANSAC* ); +ArrayList* RANSAC_FindModels(RANSAC*, IRANSACModel*, ArrayList*, int); +ArrayList* RANSAC_Sort(RANSAC*); +int RANSAC_GetKFromGoodfraction (int n, double goodFraction, int sdM); + +typedef struct OctavePyramid OctavePyramid; +typedef struct DScaleSpace DScaleSpace; + +struct OctavePyramid { + bool Verbose; + // Holds DScaleSpace objects, ordered by descending image size. + ArrayList* octaves; +}; +OctavePyramid* OctavePyramid_new0(); +void OctavePyramid_delete(OctavePyramid* self); +int OctavePyramid_Count(OctavePyramid* self); +int OctavePyramid_BuildOctaves(OctavePyramid* self, ImageMap*, double, int, double, int); +DScaleSpace* OctavePyramid_GetScaleSpace(OctavePyramid* self, int); + + +struct PointLocalInformation { + // Sub-pixel offset relative from this point. In the range of [-0.5 ; 0.5] + double fineX, fineY; + // Relative scale adjustment to the base image scale + double scaleAdjust; + double dValue; +}; +typedef struct PointLocalInformation PointLocalInformation; +PointLocalInformation* PointLocalInformation_new0 (); +void PointLocalInformation_delete (PointLocalInformation* self); +PointLocalInformation* PointLocalInformation_new3 (double fineS, double fineX, double fineY); + + +// A single point in scale space, used in keypoint creation to describe an +// exact position in scalespace and additional information about that point. +// Should not be used outside. +typedef struct ScalePoint ScalePoint; +struct ScalePoint { + int x; + int y; + int level; + // Sub-pixel level information from the Localization step are put here + PointLocalInformation* local; +}; +ScalePoint* ScalePoint_new0 (); +void ScalePoint_delete (ScalePoint* self); +ScalePoint* ScalePoint_new3 (int x, int y, int level); + + +// A single keypoint, the final result of keypoint creation. Contains the +// keypoint descriptor and position. +typedef struct Keypoint Keypoint; +struct Keypoint { + ImageMap* image; + double y, x; + double imgScale; // The scale of the image the keypoint was found in + // The absolute keypoint scale, where 1.0 is the original input image + double scale; + double orientation; + // The actual keypoint descriptor. + bool hasFV; + double* featureVector; + int featureVectorLength; + int xDim, yDim, oDim; +}; + +Keypoint* Keypoint_new0(); +void Keypoint_delete(Keypoint* self); +Keypoint* Keypoint_new (ImageMap* image, double x, double y, double imgScale, + double kpScale, double orientation); +double Keypoint_FVGet (Keypoint* self, int xI, int yI, int oI); +void Keypoint_FVSet (Keypoint* self, int xI, int yI, int oI, double value); +int Keypoint_FVLinearDim(Keypoint* self); +double Keypoint_FVLinearGet (Keypoint* self, int idx); +void Keypoint_FVLinearSet (Keypoint* self, int idx, double value); +void Keypoint_CreateLinearVector (Keypoint* self, int dim); +void Keypoint_CreateVector (Keypoint* self, int xDim, int yDim, int oDim); + + +// A single normalized and natural number keypoint. Contains the descriptor, +// position and orientation. +typedef struct KeypointN KeypointN; +struct KeypointN { + IKDTreeDomain domain; + double x, y; + double scale; + double orientation; + + int dim; + int* descriptor; +}; +KeypointN* KeypointN_new0(); +void KeypointN_delete(KeypointN* self); +KeypointN* KeypointN_new(Keypoint* kp); +KeypointN* KeypointN_clone(KeypointN* self); +void KeypointN_CreateDescriptor(KeypointN* self); +int KeypointN_GetDimensionCount(KeypointN* self); +int KeypointN_GetDimensionElement(KeypointN* self, int n); + + +struct DScaleSpace { + bool Verbose; + DScaleSpace* Down; + DScaleSpace* Up; + + // The original gaussian blurred source image this level was started with. + // Needed for keypoint generation. + + ImageMap* baseImg; + double basePixScale; + + // The smoothed gaussian images, all the base (lower scale) relative to + // the DoG spaces below. + ArrayList* imgScaled; + + ArrayList* magnitudes; + ArrayList* directions; + + // The DoG spaces. + ArrayList* spaces; +}; +DScaleSpace* DScaleSpace_new0(); +void DScaleSpace_delete(DScaleSpace* self); +ImageMap* DScaleSpace_GetGaussianMap (DScaleSpace* self, int idx); +ImageMap* DScaleSpace_LastGaussianMap(DScaleSpace* self); +int DScaleSpace_Count(DScaleSpace* self); +ImageMap* DScaleSpace_Map(DScaleSpace* self, int idx); +ArrayList* DScaleSpace_GenerateKeypoints(DScaleSpace* self, ArrayList*, int, double); +ArrayList* DScaleSpace_GenerateKeypointSingle (DScaleSpace* self, + double imgScale, ScalePoint* point, + int binCount, double peakRelThresh, int scaleCount, + double octaveSigma); +bool DScaleSpace_InterpolateOrientation (DScaleSpace* self, + double left, double middle, + double right, double* degreeCorrection, double* peakValue); +int DScaleSpace_FindClosestRotationBin (DScaleSpace* self, int binCount, double angle); +void DScaleSpace_AverageWeakBins (DScaleSpace* self, double* bins, int binCount); +ArrayList* DScaleSpace_CreateDescriptors (DScaleSpace* self, + ArrayList* keypoints, + ImageMap* magnitude, ImageMap* direction, + double considerScaleFactor, int descDim, int directionCount, + double fvGradHicap); +void DScaleSpace_CapAndNormalizeFV (DScaleSpace* self, Keypoint* kp, double fvGradHicap); +bool DScaleSpace_IsInCircle (int rX, int rY, int radiusSq); +ArrayList* DScaleSpace_FilterAndLocalizePeaks (DScaleSpace* self, ArrayList* peaks, double edgeRatio, + double dValueLoThresh, double scaleAdjustThresh, int relocationMaximum); +bool DScaleSpace_LocalizeIsWeak (DScaleSpace* self, ScalePoint* point, int steps, int** processed); +bool DScaleSpace_IsTooEdgelike (DScaleSpace* self, ImageMap* space, int x, int y, double r); +SimpleMatrix* DScaleSpace_GetAdjustment (DScaleSpace* self, ScalePoint* point, + int level, int x, int y, double* dp); +ArrayList* DScaleSpace_FindPeaks(DScaleSpace* self, double); +ArrayList* DScaleSpace_FindPeaksThreeLevel (DScaleSpace* self, ImageMap* below, ImageMap* current, + ImageMap* above, int curLev, double dogThresh); +void DScaleSpace_GenerateMagnitudeAndDirectionMaps(DScaleSpace* self); +void DScaleSpace_ClearMagnitudeAndDirectionMaps(DScaleSpace* self); +void DScaleSpace_BuildDiffMaps (DScaleSpace* self); +void DScaleSpace_BuildGaussianMaps (DScaleSpace* self, ImageMap* first, double firstScale, + int scales, double sigma); +void DScaleSpace_CheckMinMax (DScaleSpace* self, ImageMap* layer, double c, int x, int y, + bool* IsMin, bool* IsMax, bool cLayer); + + +typedef struct LoweFeatureDetector LoweFeatureDetector; +struct LoweFeatureDetector { + ArrayList* globalKeypoints; + ArrayList* globalNaturalKeypoints; + OctavePyramid* pyr; +}; + +void LoweFeatureDetector_SetPrintWarning(bool value); +void LoweFeatureDetector_SetVerbose(bool value); + +LoweFeatureDetector* LoweFeatureDetector_new0(); +void LoweFeatureDetector_delete(LoweFeatureDetector* ); +ArrayList* LoweFeatureDetector_GlobalKeypoints(LoweFeatureDetector* ); +ArrayList* LoweFeatureDetector_GlobalNaturalKeypoints(LoweFeatureDetector* ); +int LoweFeatureDetector_DetectFeaturesDownscaled(LoweFeatureDetector* self, ImageMap*, int, double); +int LoweFeatureDetector_DetectFeatures(LoweFeatureDetector* self, ImageMap*); + + +typedef struct KeypointXMLList KeypointXMLList; +struct KeypointXMLList { + char* imageFile; + ArrayList* array; + int xDim; + int yDim; +}; +KeypointXMLList* KeypointXMLList_new0(); +void KeypointXMLList_delete(KeypointXMLList* self); +KeypointXMLList* KeypointXMLList_new (char* imageFile, int xDim, int yDim, ArrayList* list); +KeypointXMLList* KeypointXMLList_new2 (ArrayList* list, int xDim, int yDim); +void KeypointXMLList_Add(KeypointXMLList* self, KeypointN* kp); +KeypointXMLList* KeypointXMLReader_ReadComplete(char*); +KeypointXMLList* KeypointXMLReader_ReadComplete2(char*, bool); +void KeypointXMLWriter_WriteComplete(char*, int, int, char*, ArrayList*); +void KeypointXMLWriter_WriteComplete2(char*, int, int, char*, ArrayList*, bool); + + +typedef struct Match Match; +struct Match { + KeypointN* kp1; + KeypointN* kp2; + double dist1; + double dist2; +}; +Match* Match_new0(); +Match* Match_new(KeypointN* kp1, KeypointN* kp2, double dist1, double dist2); +Match* Match_clone (Match* self); +void Match_delete(Match* self); + +typedef struct MatchWeighter MatchWeighter; +struct MatchWeighter { + IComparator comparator; + double distExp; + double quotExp; +}; +MatchWeighter* MatchWeighter_new0(); +MatchWeighter* MatchWeighter_new(double distExp, double quotExp); +void MatchWeighter_delete(MatchWeighter* self); +int MatchWeighter_CompareTo (MatchWeighter* self, Match* m1, Match* m2); +double MatchWeighter_OverallFitness(MatchWeighter* self, Match* m); + +typedef struct Position Position; +struct Position { + double yaw; + double pitch; + double rotation; +}; +Position* Position_new0(); +void Position_delete(Position* self); +Position* Position_new(double yaw, double pitch, double rotation); +char* Position_ToString (Position* self); + +typedef struct AffineTransform2D AffineTransform2D; +struct AffineTransform2D { + struct SimpleMatrix base; + // The relative angle of both images in the affine transformation. + double rotationAngle; + // The angle between the horizon and the line through the centers of both + // images. + double centerAngle; + double shiftWidth; +}; +AffineTransform2D* AffineTransform2D_new0(); +void AffineTransform2D_delete(AffineTransform2D* self); +AffineTransform2D* AffineTransform2D_clone(AffineTransform2D* self); +int AffineTransform2D_GetShiftWidth(AffineTransform2D* self); +AffineTransform2D* AffineTransform2D_BuildTransformFromTwoPairs(double,double,double,double,double,double,double,double,int,int); + +typedef struct ImageMatchModel ImageMatchModel; +struct ImageMatchModel { + struct IRANSACModel base; + + // The two original matches we build the model on. + Match* m1; + Match* m2; + + double fitThresh; + + // The distance-gratifying factor in the distance relaxing formula. + double distanceFactor; + // The image resolution to calculate the maximum possible distance. + int width, height; + + double fittingErrorSum; + ArrayList* fittingGround; + AffineTransform2D* trans; +}; + +ImageMatchModel* ImageMatchModel_clone(ImageMatchModel* self); +void ImageMatchModel_delete(ImageMatchModel* self); +ImageMatchModel* ImageMatchModel_new (double fitThresh, double distanceFactor, + int width, int height); +char* ImageMatchModel_ToString (ImageMatchModel* self); +ImageMatchModel* MatchDriver_FilterMatchSet (ArrayList* matches, + double distanceFactor, int width, int height); + +typedef struct FilterPoint FilterPoint; +struct FilterPoint +{ + double x, y; + void* user; +}; + +FilterPoint* FilterPoint_new0(); +void FilterPoint_delete(FilterPoint* self); + +typedef struct AreaFilter AreaFilter; +struct AreaFilter { + +}; +AreaFilter* AreaFilter_new0(); +void AreaFilter_delete(AreaFilter* self); +double AreaFilter_PolygonArea(AreaFilter* self, ArrayList* orderedPoints); +ArrayList* AreaFilter_CreateConvexHull (AreaFilter* self, ArrayList* points); +int AreaFilter_CreateHull (AreaFilter* self, ArrayList* points); +int AreaFilter_CompareLow (const FilterPoint* p1, const FilterPoint* p2); +int AreaFilter_CompareHigh (const FilterPoint* p1, const FilterPoint* p2); +bool AreaFilter_ccw (ArrayList* points, int i, int j, int k); +int AreaFilter_MakeChain (AreaFilter* self, ArrayList* points, int (*comp)(const FilterPoint*, const FilterPoint*)); + +typedef struct MultiMatch MultiMatch; +struct MultiMatch { + ArrayList* keySets; // KeypointXMLList[] + // Global k-d tree, containing all keys. + KDTree* globalKeyKD; + // Global key list, containing Keypoint elements + ArrayList* globalKeys; + + // Global match list containing Match objects + ArrayList* globalMatches; + + // Partitioned matches + void*** matchSets; + int imageCount; + + ArrayList* filteredMatchSets; + + bool verbose; +}; + +MultiMatch* MultiMatch_new0(); +void MultiMatch_delete(MultiMatch* self); +void MultiMatch_LoadKeysetsFromMemory (MultiMatch* self, ArrayList* memlist); +void MultiMatch_LoadKeysets(MultiMatch* self, ArrayList* filenames); + + + +// a set of files from the same panorama +typedef struct Component Component; +struct Component { + ArrayList* files; +}; +Component* Component_new0(); +void Component_delete(Component* self); +void Component_AddComponent(Component* self, Component* comp); +bool Component_IsIncluded (Component* self, char* filename); +void Component_AddFile (Component* self, char* filename); +char* Component_ToString (Component* self); + +// Matches between two images +typedef struct MatchSet MatchSet; +struct MatchSet { + MultiMatch* parent; // inner class + char* file1;... [truncated message content] |
From: <da...@us...> - 2008-01-02 14:54:48
|
Revision: 2589 http://hugin.svn.sourceforge.net/hugin/?rev=2589&view=rev Author: dangelo Date: 2008-01-02 06:54:43 -0800 (Wed, 02 Jan 2008) Log Message: ----------- build against pano13 by default Modified Paths: -------------- autopano-sift-C/trunk/AutoPanoSift.h autopano-sift-C/trunk/DisplayImage.c autopano-sift-C/trunk/Makefile Modified: autopano-sift-C/trunk/AutoPanoSift.h =================================================================== --- autopano-sift-C/trunk/AutoPanoSift.h 2008-01-02 09:37:14 UTC (rev 2588) +++ autopano-sift-C/trunk/AutoPanoSift.h 2008-01-02 14:54:43 UTC (rev 2589) @@ -1,8 +1,13 @@ #ifdef __cplusplus extern "C" { #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" #ifdef __cplusplus } Modified: autopano-sift-C/trunk/DisplayImage.c =================================================================== --- autopano-sift-C/trunk/DisplayImage.c 2008-01-02 09:37:14 UTC (rev 2588) +++ autopano-sift-C/trunk/DisplayImage.c 2008-01-02 14:54:43 UTC (rev 2589) @@ -15,9 +15,15 @@ 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/Makefile =================================================================== --- autopano-sift-C/trunk/Makefile 2008-01-02 09:37:14 UTC (rev 2588) +++ autopano-sift-C/trunk/Makefile 2008-01-02 14:54:43 UTC (rev 2589) @@ -1,12 +1,14 @@ # install prefix -PREFIX=/usr/local +PREFIX=/usr # compiler settings +# By default, pano13 is required. To build against pano12, remove +# the -DHAS_PANO13 and change the LDLIBS to link against -lpano12 CC=gcc -CFLAGS=-I/usr/include/libxml2 -Wall -O2 +CFLAGS=-I/usr/include/libxml2 -Wall -O2 -DHAS_PANO13 LDFLAGS= -L. -LDLIBS= -lsift -lpano12 -lxml2 -lm +LDLIBS= -lsift -lpano13 -lxml2 -lm LIBSIFT_SOURCES=LoweDetector.c RANSAC.c GaussianConvolution.c ScaleSpace.c \ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <da...@us...> - 2008-01-15 06:53:25
|
Revision: 2637 http://hugin.svn.sourceforge.net/hugin/?rev=2637&view=rev Author: dangelo Date: 2008-01-14 22:53:24 -0800 (Mon, 14 Jan 2008) Log Message: ----------- Added CMake build system and fixed source, so that it compiles with MSVC. Modified Paths: -------------- autopano-sift-C/trunk/AreaFilter.c autopano-sift-C/trunk/ArrayList.c autopano-sift-C/trunk/AutoPano.c autopano-sift-C/trunk/AutoPanoSift.h autopano-sift-C/trunk/BondBall.c autopano-sift-C/trunk/ChangeLog autopano-sift-C/trunk/GenerateKeys.c autopano-sift-C/trunk/ImageMatchModel.c autopano-sift-C/trunk/KDTree.c autopano-sift-C/trunk/KeypointXML.c autopano-sift-C/trunk/LoweDetector.c autopano-sift-C/trunk/MatchKeys.c autopano-sift-C/trunk/RANSAC.c autopano-sift-C/trunk/README.1ST autopano-sift-C/trunk/ScaleSpace.c autopano-sift-C/trunk/TestArray.c autopano-sift-C/trunk/TestKDTree.c autopano-sift-C/trunk/TestRandom.c autopano-sift-C/trunk/Utils.c autopano-sift-C/trunk/autopano-c-complete.sh Added Paths: ----------- autopano-sift-C/trunk/CMakeLists.txt autopano-sift-C/trunk/CMakeModules/ autopano-sift-C/trunk/CMakeModules/FindJPEG.cmake autopano-sift-C/trunk/CMakeModules/FindLibXml2.cmake autopano-sift-C/trunk/CMakeModules/FindLibraryWithDebug.cmake autopano-sift-C/trunk/CMakeModules/FindPANO13.cmake autopano-sift-C/trunk/CMakeModules/FindPNG.cmake autopano-sift-C/trunk/CMakeModules/FindPackageHandleStandardArgs.cmake autopano-sift-C/trunk/CMakeModules/FindTIFF.cmake autopano-sift-C/trunk/CMakeModules/FindZLIB.cmake autopano-sift-C/trunk/config.h.in.cmake Modified: autopano-sift-C/trunk/AreaFilter.c =================================================================== --- autopano-sift-C/trunk/AreaFilter.c 2008-01-14 21:29:24 UTC (rev 2636) +++ autopano-sift-C/trunk/AreaFilter.c 2008-01-15 06:53:24 UTC (rev 2637) @@ -83,8 +83,8 @@ int n; for (n = 0 ; n < ArrayList_Count(orderedPoints) ; ++n) { - FilterPoint* p0 = ArrayList_GetItem(orderedPoints,n); - FilterPoint* p1 = ArrayList_GetItem(orderedPoints, (n + 1) % ArrayList_Count(orderedPoints)); + FilterPoint* p0 = (FilterPoint*) ArrayList_GetItem(orderedPoints,n); + FilterPoint* p1 = (FilterPoint*) ArrayList_GetItem(orderedPoints, (n + 1) % ArrayList_Count(orderedPoints)); A += p0->x * p1->y - p1->x * p0->y; } @@ -145,7 +145,7 @@ int AreaFilter_MakeChain (AreaFilter* self, ArrayList* points, int (*comp)(const FilterPoint*, const FilterPoint*)) { IComparator comparator; - comparator.compareTo = (void*)comp; + comparator.compareTo = (int ( *)(IComparator *,const void *,const void *)) comp; ArrayList_Sort(points, &comparator); int s = 1; @@ -159,7 +159,7 @@ s = j + 1; // Swap - FilterPoint* t = ArrayList_GetItem(points, s); + FilterPoint* t = (FilterPoint*) ArrayList_GetItem(points, s); ArrayList_SetItem(points, s, ArrayList_GetItem(points, i)); ArrayList_SetItem(points, i, t); } Modified: autopano-sift-C/trunk/ArrayList.c =================================================================== --- autopano-sift-C/trunk/ArrayList.c 2008-01-14 21:29:24 UTC (rev 2636) +++ autopano-sift-C/trunk/ArrayList.c 2008-01-15 06:53:24 UTC (rev 2637) @@ -46,7 +46,7 @@ if (self->items != NULL) { if (self->deletefn != NULL) { int index=0; - void (*_deletefn)(void*) = self->deletefn; + void (*_deletefn)(void*) = (void ( *)(void *)) self->deletefn; for(index=0; index<self->count; index++) { if (self->items[index]) { _deletefn(self->items[index]); @@ -139,7 +139,7 @@ free(dest->items); } dest->reserved = len+10; - dest->items = (void*)malloc(dest->reserved * sizeof(void*)); + dest->items = (void**)malloc(dest->reserved * sizeof(void*)); } memcpy(dest->items, self->items+start, len*sizeof(void*)); } @@ -180,6 +180,6 @@ FatalError("ArrayList_Sort called recursively"); } ArrayList_comparator = cmp; - qsort(self->items, self->count, sizeof(void*), ArrayList_compareTo); + qsort(self->items, self->count, sizeof(void*), (int ( *)(const void *,const void *)) ArrayList_compareTo); ArrayList_comparator = NULL; } Modified: autopano-sift-C/trunk/AutoPano.c =================================================================== --- autopano-sift-C/trunk/AutoPano.c 2008-01-14 21:29:24 UTC (rev 2636) +++ autopano-sift-C/trunk/AutoPano.c 2008-01-15 06:53:24 UTC (rev 2637) @@ -22,6 +22,8 @@ void Usage () { + WriteLine ("Autopano: Match Keypoints generated by generatekeys\n"); + WriteLine (" Version %s\n", PACKAGE_VERSION); WriteLine ("usage: autopano.exe [options] output.pto keys1.xml keys2.xml [..]\n"); WriteLine ("Options"); WriteLine (" --ransac <on|off|1|0> Switch RANSAC filtration on or off (default: on)"); @@ -132,7 +134,7 @@ int doneRefines = 0; int i; for(i=0; i<ArrayList_Count(msList); i++) { - MatchSet* ms = ArrayList_GetItem(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); @@ -142,7 +144,7 @@ for(i=0; i<ArrayList_Count(msList); i++) { - MatchSet* ms = ArrayList_GetItem(msList, i); + MatchSet* ms = (MatchSet*) ArrayList_GetItem(msList, i); WriteLine (" between \"%s\" and \"%s\"", ms->file1, ms->file2); @@ -161,7 +163,7 @@ int j; for(j=0; j<ArrayList_Count(ms->matches); j++) { - Match* m = ArrayList_GetItem(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); @@ -224,7 +226,7 @@ continue; } - MatchSet* pSet = ArrayList_GetItem(matches, 0); + 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 @@ -241,7 +243,7 @@ int k; for(k=0; k<ArrayList_Count(pSet->matches); k++) { - Match* pM = ArrayList_GetItem(pSet->matches, k); + Match* pM = (Match*) ArrayList_GetItem(pSet->matches, k); if (selectMiddlePoint) { double dist = sqrt ( pow (pM->kp1->x - p1radius, 2.0) + @@ -381,7 +383,7 @@ ArrayList* resolutions = ArrayList_new0 (Resolution_delete); int i; for(i=0; i<ArrayList_Count(mm->keySets); i++) { - KeypointXMLList* kx = ArrayList_GetItem(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)); @@ -393,14 +395,14 @@ int refIdx; for (refIdx = 0 ; refIdx < (ArrayList_Count(resolutions) - 1) ; ++refIdx) { - if (Resolution_CompareTo(ArrayList_GetItem(resolutions, refIdx), kx->xDim, kx->yDim) == 0) + 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 : - HashTable_GetItem(bb->positions, imageFile); + (Position*) HashTable_GetItem(bb->positions, imageFile); /* if (pos != NULL) { WriteLine ("yaw %g, pitch %g, rotation %g", @@ -429,10 +431,10 @@ fprintf(pto, "# match list automatically generated\n"); int j; for(j=0; j<ArrayList_Count(msList); j++) { - MatchSet* ms = ArrayList_GetItem(msList, j); + MatchSet* ms = (MatchSet*) ArrayList_GetItem(msList, j); int k; for(k=0; k<ArrayList_Count(ms->matches); k++) { - Match* m = ArrayList_GetItem(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), @@ -653,7 +655,7 @@ int compN = 1; int j; for(j=0; j<ArrayList_Count(components); j++) { - Component* comp = ArrayList_GetItem(components, j); + Component* comp = (Component*) ArrayList_GetItem(components, j); char* compstr = Component_ToString(comp); WriteLine ("component %d: %s", compN++, compstr); free(compstr); Modified: autopano-sift-C/trunk/AutoPanoSift.h =================================================================== --- autopano-sift-C/trunk/AutoPanoSift.h 2008-01-14 21:29:24 UTC (rev 2636) +++ autopano-sift-C/trunk/AutoPanoSift.h 2008-01-15 06:53:24 UTC (rev 2637) @@ -1,6 +1,30 @@ + +#ifndef AUTOPANOS_SIFT_H +#define AUTOPANOS_SIFT_H + +#include "config.h" + +// include windows.h here +// to prevent the global namespace to become polluted with +// badly named Windows macros + + #ifdef __cplusplus extern "C" { #endif + +#if defined(_WIN32) +# define VC_EXTRALEAN +#ifndef NOMINMAX +# define NOMINMAX +#endif +# include <windows.h> +# undef NOMINMAX +# ifdef DIFFERENCE +# undef DIFFERENCE +# endif +#endif + #ifdef HAS_PANO13 #include "pano13/filter.h" #include "pano13/panorama.h" @@ -16,12 +40,23 @@ #define bool int #define true 1 #define false 0 -#define min(x,y) ((x)<(y)?(x):(y)) -#define max(x,y) ((x)>(y)?(x):(y)) -#define abs(x) ((x)>0?(x):(-x)) +#ifndef min + #define min(x,y) ((x)<(y)?(x):(y)) +#endif +#ifndef max + #define max(x,y) ((x)>(y)?(x):(y)) +#endif +#ifndef abs + #define abs(x) ((x)>0?(x):(-x)) +#endif + #define Double_PositiveInfinity (1e+308) #define Double_NegativeInfinity (-1e+308) +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + void Write(char* fmt, ...); void WriteLine(char* fmt, ...); void WriteError(char* fmt, ...); @@ -38,7 +73,7 @@ void DoubleMap_delete(double** self); void*** PtrMap_new(int xDim, int yDim); -void PtrMap_delete(void*** self, void* deletefn); +void PtrMap_delete(void*** self, void (* deletefn)(void*)); typedef struct Random Random; struct Random { @@ -97,7 +132,7 @@ int ArrayList_IndexOf(ArrayList* self, void* value); typedef struct IComparator IComparator; struct IComparator { - int (*compareTo)(IComparator* self, const void*, const void*); + int (*compareTo)(IComparator* self, const void*, const void*); }; void ArrayList_Sort(ArrayList* self, IComparator*); @@ -618,9 +653,11 @@ void FilterPoint_delete(FilterPoint* self); typedef struct AreaFilter AreaFilter; + struct AreaFilter { - + int dummy; // dummy entry required by MSVC 2008 }; + AreaFilter* AreaFilter_new0(); void AreaFilter_delete(AreaFilter* self); double AreaFilter_PolygonArea(AreaFilter* self, ArrayList* orderedPoints); @@ -745,3 +782,4 @@ BondBall* MultiMatch_BuildBondBall (MultiMatch* self, ArrayList* ransacFiltered, int bottomDefault); +#endif // AUTOPANOS_SIFT_H Modified: autopano-sift-C/trunk/BondBall.c =================================================================== --- autopano-sift-C/trunk/BondBall.c 2008-01-14 21:29:24 UTC (rev 2636) +++ autopano-sift-C/trunk/BondBall.c 2008-01-15 06:53:24 UTC (rev 2637) @@ -218,8 +218,8 @@ char* knownFile = image1known ? ms->file1 : ms->file2; //char* unknownFile = image1known ? ms->file2 : ms->file1; - Position* knownPos = HashTable_GetItem(self->positions, knownFile); - ImageMatchModel* fit = ms->bestMatchFit; + Position* knownPos = (Position*) HashTable_GetItem(self->positions, knownFile); + ImageMatchModel* fit = (ImageMatchModel*) ms->bestMatchFit; /* double centerDegree = (fit.CenterAngle / (2.0 * M_PI)) * 360.0; @@ -328,7 +328,7 @@ int xs = 0; int i; for(i=0; i<ArrayList_Count(self->firstRow); i++) { - char* filename = ArrayList_GetItem(self->firstRow, i); + char* filename = (char *) ArrayList_GetItem(self->firstRow, i); double yawCur = xs * self->yawStep; // Roughly align in center for non 360 degree panoramas. @@ -359,7 +359,7 @@ int i; for(i=0; i<ArrayList_Count(keys); i++) { - KeypointN* kp = ArrayList_GetItem(keys, i); + KeypointN* kp = (KeypointN*) ArrayList_GetItem(keys, i); xAccum += kp->x; } Added: autopano-sift-C/trunk/CMakeLists.txt =================================================================== --- autopano-sift-C/trunk/CMakeLists.txt (rev 0) +++ autopano-sift-C/trunk/CMakeLists.txt 2008-01-15 06:53:24 UTC (rev 2637) @@ -0,0 +1,178 @@ +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMakeModules ) + +## global setup +project(autopano-sift-C) + +# version +set(V_MAJOR 2) +set(V_MINOR 4) +set(V_PATCH 1) +set(PACKAGE_VERSION ${V_MAJOR}.${V_MINOR}.${V_PATCH}) + +IF (WIN32) + ## + ## The directory that contains the hugin source root is a good + ## place to look for support packages, so post it in cache. + ## + ## Our FIND_PACKAGE calls modules will search SOURCE_BASE_DIR + ## after the local standard places + ## + # extract pathname from CMAKE_SOURCE_DIR (note result must be a local var) + STRING( REGEX REPLACE "(.*)/[^/]+$" "\\1" work "${CMAKE_SOURCE_DIR}" ) + # create the cache entry + SET( SOURCE_BASE_DIR ${work} CACHE FILEPATH "parent dir of hugin source root" ) + + # 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) +ENDIF(WIN32) + +## +## Graphics libraries +## +# wxWidgets sub-packages will be used if native ones aren't found + +FIND_PACKAGE(TIFF REQUIRED) +INCLUDE_DIRECTORIES(${TIFF_INCLUDE_DIR}) +FIND_PACKAGE(JPEG REQUIRED) +INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR}) +FIND_PACKAGE(PNG REQUIRED) +INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) +INCLUDE_DIRECTORIES(${PNG_INCLUDE_DIR}) + +## +## XML library +## + +FIND_PACKAGE(LIBXML2 REQUIRED) +ADD_DEFINITIONS(${LIBXML2_DEFINITIONS}) +INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR}) + +## +## Panotools +## + +FIND_PACKAGE(PANO13 REQUIRED) +INCLUDE_DIRECTORIES(${PANO13_INCLUDE_DIR}) + + +#BUILD SETUP +IF(NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING + "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." + FORCE) +ENDIF(NOT CMAKE_BUILD_TYPE) + +IF(UNIX) + ADD_DEFINITIONS(-Wall) +ENDIF(UNIX) + +# Setup MSVC +IF (MSVC) + # Stop MSVC8 from bitching about the C library + ADD_DEFINITIONS(/D_CRT_SECURE_NO_DEPRECATE) + # Stop MSVC9 from bitching about possibly invalid STL usage + ADD_DEFINITIONS(/D_SCL_SECURE_NO_WARNINGS) + # 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}) + + # compile as C code as C++ code, required to enable + # variable declarations between statements. + ADD_DEFINITIONS(/TP) +ENDIF(MSVC) + +# create config.h file +configure_file(config.h.in.cmake ${CMAKE_BINARY_DIR}/config.h) +INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}) + + +## +## Finally, rules to build the source code! +## + +SET(LIBSIFT_SOURCES LoweDetector.c RANSAC.c GaussianConvolution.c + ScaleSpace.c KeypointXML.c MatchKeys.c KDTree.c BondBall.c + AreaFilter.c ImageMatchModel.c Transform.c DisplayImage.c ImageMap.c + HashTable.c ArrayList.c Random.c SimpleMatrix.c Utils.c) + +ADD_LIBRARY(libsift STATIC ${LIBSIFT_SOURCES}) + +set(all_libs libsift ${JPEG_LIBRARIES} ${TIFF_LIBRARIES} + ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${PANO13_LIBRARIES} ${LIBXML2_LIBRARIES}) + +add_executable(generatekeys GenerateKeys.c) +TARGET_LINK_LIBRARIES(generatekeys ${all_libs}) + +add_executable(autopano AutoPano.c) +TARGET_LINK_LIBRARIES(autopano ${all_libs}) + +install(TARGETS generatekeys autopano DESTINATION bin) +install(FILES autopano-c-complete.sh DESTINATION bin) + +# man pages +FILE(GLOB MAN_PAGES_1 doc/*.1) +FILE(GLOB MAN_PAGES_7 doc/*.1) +install(FILES ${MAN_PAGES_1} DESTINATION share/man/man1) +install(FILES ${MAN_PAGES_7} DESTINATION share/man/man7) + +## Test exectuables. + +if (BUILD_TESTS) + add_executable(testArray TestArray.c) + TARGET_LINK_LIBRARIES(testArray ${all_libs}) + add_executable(testRandom TestRandom.c) + TARGET_LINK_LIBRARIES(testRandom ${all_libs}) +#add_executable(testSimpleMatrix TestSimpleMatrix.c) +#TARGET_LINK_LIBRARIES(testSimpleMatrix ${all_libs}) +#add_executable(testTransform TestTransform.c) +#TARGET_LINK_LIBRARIES(testTransform ${all_libs}) +#add_executable(testRansac TestRansac.c) +#TARGET_LINK_LIBRARIES(testRansac ${all_libs}) +#add_executable(testAreaFilter TestAreaFilter.c) +#TARGET_LINK_LIBRARIES(testAreaFilter ${all_libs}) + add_executable(testKDTree TestKDTree.c) + TARGET_LINK_LIBRARIES(testKDTree ${all_libs}) +endif(BUILD_TESTS) + + +SET(CPACK_PACKAGE_VERSION_MAJOR "${V_MAJOR}") +SET(CPACK_PACKAGE_VERSION_MINOR "${V_MINOR}") +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_SOURCE_GENERATOR "TGZ") +SET(CPACK_SOURCE_IGNORE_FILES +"/_CPack_Packages/" +"/CMakeCache.txt$" +"\\\\.dir/" +"\\\\.tar\\\\.gz$" +"\\\\.tar\\\\.Z$" +"\\\\.svn/" +"\\\\.cvsignore$" +"\\\\.swp$" +"~$" +"\\\\.#" +"/#" +"/build/" +"/CVS/" +"/\\\\.libs/" +"/\\\\.deps/" +"\\\\.o$" +"\\\\.a$" +"\\\\.lo$" +"\\\\.so$" +"\\\\.so\\\\.0$" +"\\\\.so\\\\.0\\\\.0$" +"\\\\.la$" +"Makefile\\\\.in$" + ) +INCLUDE(CPack) Added: autopano-sift-C/trunk/CMakeModules/FindJPEG.cmake =================================================================== --- autopano-sift-C/trunk/CMakeModules/FindJPEG.cmake (rev 0) +++ autopano-sift-C/trunk/CMakeModules/FindJPEG.cmake 2008-01-15 06:53:24 UTC (rev 2637) @@ -0,0 +1,37 @@ +# - Find JPEG for Hugin 0.7 01Nov2007 TKSharpless +# Added to support Windows build but should work anywhere. +# After looking in UNIX standard places, tries wxWidgets build +# tree, which should have this package. +# +# Call FIND_PACKAGE(wxWidgets REQUIRED) before calling this! +# +# reads cache variables +# wxWidgets_ROOT_DIR +# wxWidgets_LIB_DIR +# defines cache variables +# JPEG_INCLUDE_DIR, where to find headers +# JPEG_LIBRARIES, list of release link libraries +# JPEG_DEBUG_LIBRARIES, list of debug link libraries +# JPEG_FOUND, If != "YES", do not try to use JPEG + +FIND_PATH(JPEG_INCLUDE_DIR jpeglib.h + /usr/local/include + /usr/include + ${wxWidgets_ROOT_DIR}/src/jpeg +) + +include(FindLibraryWithDebug) + +find_library_with_debug(JPEG_LIBRARIES + WIN32_DEBUG_POSTFIX d + NAMES jpeg libjpeg wxjpeg + PATHS /usr/lib /usr/local/lib ${wxWidgets_LIB_DIR} +) + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(JPEG DEFAULT_MSG + JPEG_INCLUDE_DIR JPEG_LIBRARIES) + +MARK_AS_ADVANCED(JPEG_INCLUDE_DIR JPEG_LIBRARIES ) + Added: autopano-sift-C/trunk/CMakeModules/FindLibXml2.cmake =================================================================== --- autopano-sift-C/trunk/CMakeModules/FindLibXml2.cmake (rev 0) +++ autopano-sift-C/trunk/CMakeModules/FindLibXml2.cmake 2008-01-15 06:53:24 UTC (rev 2637) @@ -0,0 +1,48 @@ +# - Try to find LibXml2 +# Once done this will define +# +# LIBXML2_FOUND - system has LibXml2 +# LIBXML2_INCLUDE_DIR - the LibXml2 include directory +# LIBXML2_LIBRARIES - the libraries needed to use LibXml2 +# LIBXML2_DEFINITIONS - Compiler switches required for using LibXml2 + +# Copyright (c) 2006, Alexander Neundorf, <neu...@kd...> +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + + +IF (LIBXML2_INCLUDE_DIR AND LIBXML2_LIBRARIES) + # in cache already + SET(LibXml2_FIND_QUIETLY TRUE) +ENDIF (LIBXML2_INCLUDE_DIR AND LIBXML2_LIBRARIES) + +IF (NOT WIN32) + # use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + INCLUDE(UsePkgConfig) + PKGCONFIG(libxml-2.0 _LibXml2IncDir _LibXml2LinkDir _LibXml2LinkFlags _LibXml2Cflags) + SET(LIBXML2_DEFINITIONS ${_LibXml2Cflags}) +ENDIF (NOT WIN32) + +FIND_PATH(LIBXML2_INCLUDE_DIR libxml/xpath.h + PATHS + ${_LibXml2IncDir} + ${SOURCE_BASE_DIR}/libxml2-2.6.31/include + PATH_SUFFIXES libxml2 + ) + +FIND_LIBRARY(LIBXML2_LIBRARIES NAMES libxml2_a xml2 libxml2 + PATHS + ${_LibXml2LinkDir} + ${SOURCE_BASE_DIR}/libxml2-2.6.31/win32/bin.msvc + ) + +INCLUDE(FindPackageHandleStandardArgs) + +# handle the QUIETLY and REQUIRED arguments and set LIBXML2_FOUND to TRUE if +# all listed variables are TRUE +FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR) + +MARK_AS_ADVANCED(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARIES) + Added: autopano-sift-C/trunk/CMakeModules/FindLibraryWithDebug.cmake =================================================================== --- autopano-sift-C/trunk/CMakeModules/FindLibraryWithDebug.cmake (rev 0) +++ autopano-sift-C/trunk/CMakeModules/FindLibraryWithDebug.cmake 2008-01-15 06:53:24 UTC (rev 2637) @@ -0,0 +1,113 @@ +# +# FIND_LIBRARY_WITH_DEBUG +# -> enhanced FIND_LIBRARY to allow the search for an +# optional debug library with a WIN32_DEBUG_POSTFIX similar +# to CMAKE_DEBUG_POSTFIX when creating a shared lib +# it has to be the second and third argument + +# Copyright (c) 2007, Christian Ehrlicher, <ch....@gm...> +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +MACRO(FIND_LIBRARY_WITH_DEBUG var_name win32_dbg_postfix_name dgb_postfix libname) + + IF(NOT "${win32_dbg_postfix_name}" STREQUAL "WIN32_DEBUG_POSTFIX") + + # no WIN32_DEBUG_POSTFIX -> simply pass all arguments to FIND_LIBRARY + FIND_LIBRARY(${var_name} + ${win32_dbg_postfix_name} + ${dgb_postfix} + ${libname} + ${ARGN} + ) + + ELSE(NOT "${win32_dbg_postfix_name}" STREQUAL "WIN32_DEBUG_POSTFIX") + + IF(NOT WIN32) + # on non-win32 we don't need to take care about WIN32_DEBUG_POSTFIX + + FIND_LIBRARY(${var_name} ${libname} ${ARGN}) + + ELSE(NOT WIN32) + + # 1. get all possible libnames + SET(args ${ARGN}) + SET(newargs "") + SET(libnames_release "") + SET(libnames_debug "") + + LIST(LENGTH args listCount) + + IF("${libname}" STREQUAL "NAMES") + SET(append_rest 0) + LIST(APPEND args " ") + + FOREACH(i RANGE ${listCount}) + LIST(GET args ${i} val) + + IF(append_rest) + LIST(APPEND newargs ${val}) + ELSE(append_rest) + IF("${val}" STREQUAL "PATHS") + LIST(APPEND newargs ${val}) + SET(append_rest 1) + ELSE("${val}" STREQUAL "PATHS") + LIST(APPEND libnames_release "${val}") + LIST(APPEND libnames_debug "${val}${dgb_postfix}") + ENDIF("${val}" STREQUAL "PATHS") + ENDIF(append_rest) + + ENDFOREACH(i) + + ELSE("${libname}" STREQUAL "NAMES") + + # just one name + LIST(APPEND libnames_release "${libname}") + LIST(APPEND libnames_debug "${libname}${dgb_postfix}") + + SET(newargs ${args}) + + ENDIF("${libname}" STREQUAL "NAMES") + + # search the release lib + FIND_LIBRARY(${var_name}_RELEASE + NAMES ${libnames_release} + ${newargs} + ) + + # search the debug lib + FIND_LIBRARY(${var_name}_DEBUG + NAMES ${libnames_debug} + ${newargs} + ) + + IF(${var_name}_RELEASE AND ${var_name}_DEBUG) + + # both libs found + SET(${var_name} optimized ${${var_name}_RELEASE} + debug ${${var_name}_DEBUG}) + + ELSE(${var_name}_RELEASE AND ${var_name}_DEBUG) + + IF(${var_name}_RELEASE) + + # only release found + SET(${var_name} ${${var_name}_RELEASE}) + + ELSE(${var_name}_RELEASE) + + # only debug (or nothing) found + SET(${var_name} ${${var_name}_DEBUG}) + + ENDIF(${var_name}_RELEASE) + + ENDIF(${var_name}_RELEASE AND ${var_name}_DEBUG) + + MARK_AS_ADVANCED(${var_name}_RELEASE) + MARK_AS_ADVANCED(${var_name}_DEBUG) + + ENDIF(NOT WIN32) + + ENDIF(NOT "${win32_dbg_postfix_name}" STREQUAL "WIN32_DEBUG_POSTFIX") + +ENDMACRO(FIND_LIBRARY_WITH_DEBUG) Added: autopano-sift-C/trunk/CMakeModules/FindPANO13.cmake =================================================================== --- autopano-sift-C/trunk/CMakeModules/FindPANO13.cmake (rev 0) +++ autopano-sift-C/trunk/CMakeModules/FindPANO13.cmake 2008-01-15 06:53:24 UTC (rev 2637) @@ -0,0 +1,46 @@ +# - Find PANO13 headers and libraries +# modified for Hugin 0.7 Windows build 02Nov2007 TKSharpless +# reads cache variable +# SOURCE_BASE_DIR -- directory that contains hugin source root +# defines cache vars +# PANO13_INCLUDE_DIR, where to find pano13/panorama.h, etc. +# PANO13_LIBRARIES, release link library list. +# PANO13_DEBUG_LIBRARIES, debug ditto. +# PANO13_FOUND, If != "YES", do not try to use PANO13. + +# In Pablo's Windows setup ${SOURCE_BASE_DIR}/libpano contains pano12 +# and pano13. This code also works if pano13 is in ${SOURCE_BASE_DIR} +## NOTE the form "pano13/panorama.h" is used in #includes in some +## Hugin source files, so we are stuck with that for now. +FIND_PATH(PANO13_INCLUDE_DIR pano13/panorama.h + /usr/local/include + /usr/include + ${SOURCE_BASE_DIR}/libpano + ${SOURCE_BASE_DIR} +) + +# Pablo's Windows setup has the link libs in subdirs Debug +# and Release of libpano/pano13, as "Panotools.lib". This +# code will also find them in pano13 or in pano13/lib, and +# with names pano13 or pano13d. +FIND_LIBRARY(PANO13_LIBRARIES + NAMES pano13 + PATHS /usr/lib /usr/local/lib + ${PANO13_INCLUDE_DIR}/pano13/Release + ${SOURCE_BASE_DIR}/pano13/lib + ${SOURCE_BASE_DIR}/pano13 + ) + +IF(PANO13_INCLUDE_DIR) + IF(PANO13_LIBRARIES) + SET( PANO13_FOUND "YES" ) + FIND_LIBRARY( PANO13_DEBUG_LIBRARIES + NAMES Panotools pano13d pano13 + PATHS /usr/lib /usr/local/lib + ${PANO13_INCLUDE_DIR}/pano13/Debug + ${SOURCE_BASE_DIR}/pano13/lib + ${SOURCE_BASE_DIR}/pano13 + ) + ENDIF(PANO13_LIBRARIES) +ENDIF(PANO13_INCLUDE_DIR) + Added: autopano-sift-C/trunk/CMakeModules/FindPNG.cmake =================================================================== --- autopano-sift-C/trunk/CMakeModules/FindPNG.cmake (rev 0) +++ autopano-sift-C/trunk/CMakeModules/FindPNG.cmake 2008-01-15 06:53:24 UTC (rev 2637) @@ -0,0 +1,43 @@ +# - Find PNG for Hugin 0.7 01Nov2007 TKSharpless +# Added to support Windows build but should work anywhere. +# After looking in UNIX standard places, tries wxWidgets build +# tree, which should have this package. +# +# Call FIND_PACKAGE(wxWidgets REQUIRED) before calling this! +# +# reads cache variables +# wxWidgets_ROOT_DIR +# wxWidgets_LIB_DIR +# defines cache variables +# PNG_INCLUDE_DIR, where to find headers +# PNG_LIBRARIES, list of release link libraries. +# PNG_FOUND, If != "YES", do not try to use PNG. +# None of the above will be defined unless ZLIB can be found + +INCLUDE(FindZLIB) + +include(FindLibraryWithDebug) + +SET(PNG_FOUND "NO") + +IF (ZLIB_FOUND) + FIND_PATH(PNG_INCLUDE_DIR png.h + /usr/local/include + /usr/include + ${wxWidgets_ROOT_DIR}/src/png + ) + + find_library_with_debug(PNG_LIBRARIES + WIN32_DEBUG_POSTFIX d + NAMES png libpng wxpng + PATHS /usr/lib /usr/local/lib ${wxWidgets_LIB_DIR} + ) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(PNG DEFAULT_MSG + PNG_INCLUDE_DIR PNG_LIBRARIES) + + SET(PNG_LIBRARIES ${PNG_LIBRARIES} ${ZLIB_LIBRARIES}) + MARK_AS_ADVANCED(PNG_INCLUDE_DIR PNG_LIBRARIES ) +ENDIF(ZLIB_FOUND) + Added: autopano-sift-C/trunk/CMakeModules/FindPackageHandleStandardArgs.cmake =================================================================== --- autopano-sift-C/trunk/CMakeModules/FindPackageHandleStandardArgs.cmake (rev 0) +++ autopano-sift-C/trunk/CMakeModules/FindPackageHandleStandardArgs.cmake 2008-01-15 06:53:24 UTC (rev 2637) @@ -0,0 +1,58 @@ +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME (DEFAULT_MSG|"Custom failure message") VAR1 ... ) +# This macro is intended to be used in FindXXX.cmake modules files. +# It handles the REQUIRED and QUIET argument to FIND_PACKAGE() and +# it also sets the <UPPERCASED_NAME>_FOUND variable. +# The package is found if all variables listed are TRUE. +# Example: +# +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR) +# +# LibXml2 is considered to be found, if both LIBXML2_LIBRARIES and +# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE. +# If it is not found and REQUIRED was used, it fails with FATAL_ERROR, +# independent whether QUIET was used or not. +# If it is found, the location is reported using the VAR1 argument, so +# here a message "Found LibXml2: /usr/lib/libxml2.so" will be printed out. +# If the second argument is DEFAULT_MSG, the message in the failure case will +# be "Could NOT find LibXml2", if you don't like this message you can specify +# your own custom failure message there. + +MACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FAIL_MSG _VAR1 ) + + IF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") + IF (${_NAME}_FIND_REQUIRED) + SET(_FAIL_MESSAGE "Could not find REQUIRED package ${_NAME}") + ELSE (${_NAME}_FIND_REQUIRED) + SET(_FAIL_MESSAGE "Could not find OPTIONAL package ${_NAME}") + ENDIF (${_NAME}_FIND_REQUIRED) + ELSE("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") + SET(_FAIL_MESSAGE "${_FAIL_MSG}") + ENDIF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") + + STRING(TOUPPER ${_NAME} _NAME_UPPER) + + SET(${_NAME_UPPER}_FOUND TRUE) + IF(NOT ${_VAR1}) + SET(${_NAME_UPPER}_FOUND FALSE) + ENDIF(NOT ${_VAR1}) + + FOREACH(_CURRENT_VAR ${ARGN}) + IF(NOT ${_CURRENT_VAR}) + SET(${_NAME_UPPER}_FOUND FALSE) + ENDIF(NOT ${_CURRENT_VAR}) + ENDFOREACH(_CURRENT_VAR) + + IF (${_NAME_UPPER}_FOUND) + IF (NOT ${_NAME}_FIND_QUIETLY) + MESSAGE(STATUS "Found ${_NAME}: ${${_VAR1}}") + ENDIF (NOT ${_NAME}_FIND_QUIETLY) + ELSE (${_NAME_UPPER}_FOUND) + IF (${_NAME}_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "${_FAIL_MESSAGE}") + ELSE (${_NAME}_FIND_REQUIRED) + IF (NOT ${_NAME}_FIND_QUIETLY) + MESSAGE(STATUS "${_FAIL_MESSAGE}") + ENDIF (NOT ${_NAME}_FIND_QUIETLY) + ENDIF (${_NAME}_FIND_REQUIRED) + ENDIF (${_NAME_UPPER}_FOUND) +ENDMACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS) Added: autopano-sift-C/trunk/CMakeModules/FindTIFF.cmake =================================================================== --- autopano-sift-C/trunk/CMakeModules/FindTIFF.cmake (rev 0) +++ autopano-sift-C/trunk/CMakeModules/FindTIFF.cmake 2008-01-15 06:53:24 UTC (rev 2637) @@ -0,0 +1,42 @@ +# - Find TIFF for Hugin 0.7 01Nov2007 TKSharpless +# Added to support Windows build but should work anywhere. +# After looking in UNIX standard places, tries wxWidgets build +# tree, which should have this package. +# +# Call FIND_PACKAGE(wxWidgets REQUIRED) before calling this! +# +# reads cache variables +# wxWidgets_ROOT_DIR +# wxWidgets_LIB_DIR +# defines cache variables +# TIFF_INCLUDE_DIR, where to find headers +# TIFF_LIBRARIES, list of link libraries for release +# TIFF_DEBUG_LIBRARIES ditto for debug +# TIFF_FOUND, If != "YES", do not try to use TIFF. + +FIND_PATH(TIFF_INCLUDE_DIR tiff.h + /usr/local/include + /usr/include + ${SOURCE_BASE_DIR}/tiff-3.8.2/libtiff + ${SOURCE_BASE_DIR}/tiff-4.0.0alpha/libtiff + ${wxWidgets_ROOT_DIR}/src/tiff +) + +include(FindLibraryWithDebug) + +find_library_with_debug(TIFF_LIBRARIES + WIN32_DEBUG_POSTFIX d + NAMES tiff libtiff wxtiff + PATHS /usr/lib /usr/local/lib + ${SOURCE_BASE_DIR}/tiff-3.8.2/libtiff + ${SOURCE_BASE_DIR}/tiff-4.0.0alpha/libtiff + ${wxWidgets_LIB_DIR} +) + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(TIFF DEFAULT_MSG + TIFF_INCLUDE_DIR TIFF_LIBRARIES) + +MARK_AS_ADVANCED(TIFF_INCLUDE_DIR TIFF_LIBRARIES) + Added: autopano-sift-C/trunk/CMakeModules/FindZLIB.cmake =================================================================== --- autopano-sift-C/trunk/CMakeModules/FindZLIB.cmake (rev 0) +++ autopano-sift-C/trunk/CMakeModules/FindZLIB.cmake 2008-01-15 06:53:24 UTC (rev 2637) @@ -0,0 +1,45 @@ +# - Find zlib +# Find the native ZLIB includes and library +# +# ZLIB_INCLUDE_DIR - where to find zlib.h, etc. +# ZLIB_LIBRARIES - List of libraries when using zlib. +# ZLIB_FOUND - True if zlib found. + +# - Find TIFF for Hugin 0.7 01Nov2007 TKSharpless +# Added to support Windows build but should work anywhere. +# After looking in UNIX standard places, tries wxWidgets build +# tree, which should have this package. +# +# reads cache variables +# wxWidgets_ROOT_DIR +# wxWidgets_LIB_DIR +# + +IF (ZLIB_INCLUDE_DIR) + # Already in cache, be silent + SET(ZLIB_FIND_QUIETLY TRUE) +ENDIF (ZLIB_INCLUDE_DIR) + +FIND_PATH(ZLIB_INCLUDE_DIR zlib.h + /usr/local/include + /usr/include + ${wxWidgets_ROOT_DIR}/src/zlib +) + +include(FindLibraryWithDebug) + +find_library_with_debug(ZLIB_LIBRARIES + WIN32_DEBUG_POSTFIX d + NAMES z zlib wxzlib + PATHS /usr/lib /usr/local/lib ${wxWidgets_LIB_DIR} +) + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(ZLIB DEFAULT_MSG + ZLIB_INCLUDE_DIR ZLIB_LIBRARIES) + +MARK_AS_ADVANCED( + ZLIB_LIBRARIES + ZLIB_INCLUDE_DIR + ) Modified: autopano-sift-C/trunk/ChangeLog =================================================================== --- autopano-sift-C/trunk/ChangeLog 2008-01-14 21:29:24 UTC (rev 2636) +++ autopano-sift-C/trunk/ChangeLog 2008-01-15 06:53:24 UTC (rev 2637) @@ -1,3 +1,11 @@ +2008-01-14 Pablo d'Angelo + + * CMakeLists.txt, CMakeModules: Added CMake based build system, only + tested on windows so far. + + * *.c *.h: fix source for compilation with windows (mainly adding + a lot of explicit casts). + 2008-01-02 Pablo d'Angelo * Makefile, AutoPanoSift.h, DisplayImage.c: build against pano13 Modified: autopano-sift-C/trunk/GenerateKeys.c =================================================================== --- autopano-sift-C/trunk/GenerateKeys.c 2008-01-14 21:29:24 UTC (rev 2636) +++ autopano-sift-C/trunk/GenerateKeys.c 2008-01-15 06:53:24 UTC (rev 2637) @@ -23,7 +23,7 @@ int main (int argc, char* argv[]) { - WriteLine("SIFT Keypoint Generation\n"); + WriteLine("SIFT Keypoint Generation, version %s\n", PACKAGE_VERSION); if ((argc-1) < 2 || (argc-1) > 3) { WriteLine ("usage: generatekeys.exe image output.key [minDim]\n"); Modified: autopano-sift-C/trunk/ImageMatchModel.c =================================================================== --- autopano-sift-C/trunk/ImageMatchModel.c 2008-01-14 21:29:24 UTC (rev 2636) +++ autopano-sift-C/trunk/ImageMatchModel.c 2008-01-15 06:53:24 UTC (rev 2637) @@ -50,8 +50,8 @@ // TODO: least-square match if more than two points are given. // For now, just ignore any further matches. - self->m1 = ArrayList_GetItem(matches, 0); - self->m2 = ArrayList_GetItem(matches, 1); + self->m1 = (Match *) ArrayList_GetItem(matches, 0); + self->m2 = (Match *) ArrayList_GetItem(matches, 1); //WriteLine ("Doing transform building..."); self->trans = AffineTransform2D_BuildTransformFromTwoPairs @@ -111,7 +111,7 @@ pow (self->m1->kp2->y - self->m2->kp2->y, 2)); double distanceTerm = distXA + distXB - distAB; - distanceTerm /= sqrt (pow (self->width, 2) + pow (self->height, 2)); + distanceTerm /= sqrt (pow (self->width, 2.0) + pow (self->height, 2.0)); double distanceReduce = self->distanceFactor * distanceTerm * self->fitThresh; /*WriteLine ("reducing distance %f by %f due to distance term %f, thresh %f", pixDistance, distanceReduce, distanceTerm, fitThresh);*/ @@ -154,16 +154,16 @@ IRANSACModel ImageMatchModel_vtbl = { - ImageMatchModel_clone, - ImageMatchModel_delete, - ImageMatchModel_FitModel, - ImageMatchModel_FittingErrorSingle, - ImageMatchModel_ThreshholdPoint, - ImageMatchModel_GetFittingErrorSum, - ImageMatchModel_SetFittingErrorSum, - ImageMatchModel_GetFittingGround, - ImageMatchModel_SetFittingGround, - ImageMatchModel_CompareTo + (IRANSACModel *( *)(IRANSACModel *)) ImageMatchModel_clone, + (void ( *)(IRANSACModel *))ImageMatchModel_delete, + (int ( *)(IRANSACModel *,ArrayList *)) ImageMatchModel_FitModel, + (double ( *)(IRANSACModel *,void *))ImageMatchModel_FittingErrorSingle, + (int ( *)(IRANSACModel *,double)) ImageMatchModel_ThreshholdPoint, + (double ( *)(IRANSACModel *)) ImageMatchModel_GetFittingErrorSum, + (void ( *)(IRANSACModel *,double)) ImageMatchModel_SetFittingErrorSum, + (ArrayList *( *)(IRANSACModel *)) ImageMatchModel_GetFittingGround, + (void ( *)(IRANSACModel *,ArrayList *)) ImageMatchModel_SetFittingGround, + (int ( *)(IComparator *,IRANSACModel *,IRANSACModel *)) ImageMatchModel_CompareTo }; @@ -246,7 +246,7 @@ return (NULL); } - ImageMatchModel* best = ArrayList_GetItem(models, 0); + ImageMatchModel* best = (ImageMatchModel*) ArrayList_GetItem(models, 0); // Make sure best doesn't get erased by ArrayList_delete below. ArrayList_SetItem(models, 0, NULL); Modified: autopano-sift-C/trunk/KDTree.c =================================================================== --- autopano-sift-C/trunk/KDTree.c 2008-01-14 21:29:24 UTC (rev 2636) +++ autopano-sift-C/trunk/KDTree.c 2008-01-15 06:53:24 UTC (rev 2637) @@ -53,7 +53,7 @@ SortedLimitedList* self = SortedLimitedList_new0(); ArrayList_init((ArrayList*)self, deletefn); self->max = maxElements; - self->deletefn = deletefn; + self->deletefn = (void (*)(void *)) deletefn; return self; } @@ -524,7 +524,7 @@ ArrayList_AddItem(hrl, hr); SortedLimitedList* best = SortedLimitedList_new (q, KDTreeBestEntry_delete); - best->comparator.compareTo = (void*)KDTreeBestEntry_CompareTo; + best->comparator.compareTo = (int ( *)(IComparator *,const void *,const void *))KDTreeBestEntry_CompareTo; /*IKDTreeDomain* nearest = */KDTree_NearestNeighbourListI (self, best, q, target, hr, Double_PositiveInfinity, resDist, hrl); @@ -532,7 +532,7 @@ int i; for(i=0; i<SortedLimitedList_Count(best); i++) { - KDTreeBestEntry* be = SortedLimitedList_GetItem(best, i); + KDTreeBestEntry* be = (KDTreeBestEntry*) SortedLimitedList_GetItem(best, i); be->distance = sqrt (be->distance); } @@ -662,9 +662,9 @@ ArrayList_AddItem(hrl, hr); SortedLimitedList* best = SortedLimitedList_new (q, KDTreeBestEntry_delete); - best->comparator.compareTo = (void*)KDTreeBestEntry_CompareTo; + best->comparator.compareTo = (int ( *)(IComparator *,const void *,const void *)) KDTreeBestEntry_CompareTo; SortedLimitedList* searchHr = SortedLimitedList_new (searchSteps, KDTreeHREntry_delete); - searchHr->comparator.compareTo = (void*)KDTreeHREntry_CompareTo; + searchHr->comparator.compareTo = (int ( *)(IComparator *,const void *,const void *))KDTreeHREntry_CompareTo; int dummyDist; /*IKDTreeDomain* nearest = */KDTree_NearestNeighbourListBBFI (self, best, q, target, hr, @@ -675,8 +675,8 @@ int i; for(i=0; i<SortedLimitedList_Count(best); i++) { - KDTreeBestEntry* be = SortedLimitedList_GetItem(best, i); - be->distance = sqrt (be->distanceSq); + KDTreeBestEntry* be = (KDTreeBestEntry*) SortedLimitedList_GetItem(best, i); + be->distance = sqrt ((double)be->distanceSq); } ArrayList_delete(hrl); @@ -748,7 +748,7 @@ maxDistSq = INT_MAX; if (SortedLimitedList_Count(searchHr) > 0) { - KDTreeHREntry* hre = SortedLimitedList_GetItem(searchHr, 0); + KDTreeHREntry* hre = (KDTreeHREntry*) SortedLimitedList_GetItem(searchHr, 0); SortedLimitedList_RemoveAt (searchHr, 0); furtherHr = hre->rect; @@ -760,7 +760,7 @@ // step 10 *searchSteps -= 1; if (*searchSteps > 0 && - HyperRectangle_IsInReach (furtherHr, target, sqrt (maxDistSq))) + HyperRectangle_IsInReach (furtherHr, target, sqrt ((double)maxDistSq))) { int ptDistSq = KDTree_DistanceSq (pivot, target); if (ptDistSq < distSq) { @@ -810,7 +810,7 @@ IKDTreeDomain* KDTree_GoodCandidate (ArrayList* exset, int* splitDim) { - IKDTreeDomain* first = ArrayList_GetItem(exset, 0); + IKDTreeDomain* first = (IKDTreeDomain*) ArrayList_GetItem(exset, 0); if (first == NULL) { FatalError ("Not of type IKDTreeDomain (TODO: custom exception)"); } @@ -828,7 +828,7 @@ int j; for(j=0; j<ArrayList_Count(exset); j++) { - IKDTreeDomain* dom = ArrayList_GetItem(exset, j); + IKDTreeDomain* dom = (IKDTreeDomain*) ArrayList_GetItem(exset, j); int k; for (k = 0 ; k < dim ; ++k) { double dimE = IKDTreeDomain_GetDimensionElement (dom, k); @@ -866,7 +866,7 @@ int l; for(l=0; l<ArrayList_Count(exset); l++) { - IKDTreeDomain* dom = ArrayList_GetItem(exset, l); + IKDTreeDomain* dom = (IKDTreeDomain*) ArrayList_GetItem(exset, l); double curDiff = abs (IKDTreeDomain_GetDimensionElement (dom, maxDiffDim) - middle); if (curDiff < exemMinDiff) { exemMinDiff = curDiff; @@ -900,7 +900,7 @@ double bound = IKDTreeDomain_GetDimensionElement (cur->dr, cur->splitDim); int i; for(i=0; i<ArrayList_Count(exset); i++) { - IKDTreeDomain* dom = ArrayList_GetItem(exset, i); + IKDTreeDomain* dom = (IKDTreeDomain*) ArrayList_GetItem(exset, i); // ignore the current element if (dom == cur->dr) continue; Modified: autopano-sift-C/trunk/KeypointXML.c =================================================================== --- autopano-sift-C/trunk/KeypointXML.c 2008-01-14 21:29:24 UTC (rev 2636) +++ autopano-sift-C/trunk/KeypointXML.c 2008-01-15 06:53:24 UTC (rev 2637) @@ -25,19 +25,19 @@ static char* String(const xmlChar* str) { char* value; - value = strdup(str); + value = strdup((char *)str); return value; } static int Int(const xmlChar* str) { int value; - sscanf(str, "%d", &value); + sscanf((char *)str, "%d", &value); return value; } static double Double(const xmlChar* str) { double value; - sscanf(str, "%lf", &value); + sscanf((char *)str, "%lf", &value); return value; } @@ -57,89 +57,89 @@ ret = xmlTextReaderRead(reader); while (ret == 1) { name = xmlTextReaderConstName(reader); - if (xmlStrcmp(name, "KeypointXMLList")==0) { + if (xmlStrcmp( name, (xmlChar*) "KeypointXMLList")==0) { kl = KeypointXMLList_new0(); ret = xmlTextReaderRead(reader); while (ret == 1) { name = xmlTextReaderConstName(reader); - if (xmlStrcmp(name, "XDim")==0 && xmlTextReaderNodeType(reader)==1) { + if (xmlStrcmp(name, (xmlChar*) "XDim")==0 && xmlTextReaderNodeType(reader)==1) { ret = xmlTextReaderRead(reader); if (xmlTextReaderHasValue(reader)) kl->xDim = Int(xmlTextReaderConstValue(reader)); - } else if (xmlStrcmp(name, "YDim")==0 && xmlTextReaderNodeType(reader)==1) { + } else if (xmlStrcmp(name, (xmlChar*) "YDim")==0 && xmlTextReaderNodeType(reader)==1) { ret = xmlTextReaderRead(reader); if (xmlTextReaderHasValue(reader)) kl->yDim = Int(xmlTextReaderConstValue(reader)); - } else if (xmlStrcmp(name, "ImageFile")==0 && xmlTextReaderNodeType(reader)==1) { + } else if (xmlStrcmp(name, (xmlChar*) "ImageFile")==0 && xmlTextReaderNodeType(reader)==1) { ret = xmlTextReaderRead(reader); if (xmlTextReaderHasValue(reader) && xmlTextReaderNodeType(reader)==3) kl->imageFile = String(xmlTextReaderConstValue(reader)); - } else if (xmlStrcmp(name, "Arr")==0 && xmlTextReaderNodeType(reader)==1) { + } else if (xmlStrcmp(name, (xmlChar*) "Arr")==0 && xmlTextReaderNodeType(reader)==1) { ret = xmlTextReaderRead(reader); while (ret == 1) { name = xmlTextReaderConstName(reader); - if (xmlStrcmp(name, "KeypointN")==0 && xmlTextReaderNodeType(reader)==1) { + if (xmlStrcmp(name, (xmlChar*) "KeypointN")==0 && xmlTextReaderNodeType(reader)==1) { KeypointN* kp = KeypointN_new0(); ret = xmlTextReaderRead(reader); while (ret == 1) { name = xmlTextReaderConstName(reader); - if (xmlStrcmp(name, "X")==0 && xmlTextReaderNodeType(reader)==1) { + if (xmlStrcmp(name, (xmlChar*) "X")==0 && xmlTextReaderNodeType(reader)==1) { ret = xmlTextReaderRead(reader); if (xmlTextReaderHasValue(reader)) kp->x = Double(xmlTextReaderConstValue(reader)); - } else if (xmlStrcmp(name, "Y")==0 && xmlTextReaderNodeType(reader)==1) { + } else if (xmlStrcmp(name, (xmlChar*) "Y")==0 && xmlTextReaderNodeType(reader)==1) { ret = xmlTextReaderRead(reader); if (xmlTextReaderHasValue(reader)) kp->y = Double(xmlTextReaderConstValue(reader)); - } else if (xmlStrcmp(name, "Scale")==0 && xmlTextReaderNodeType(reader)==1) { + } else if (xmlStrcmp(name, (xmlChar*) "Scale")==0 && xmlTextReaderNodeType(reader)==1) { ret = xmlTextReaderRead(reader); if (xmlTextReaderHasValue(reader)) kp->scale = Double(xmlTextReaderConstValue(reader)); - } else if (xmlStrcmp(name, "Orientation")==0 && xmlTextReaderNodeType(reader)==1) { + } else if (xmlStrcmp(name, (xmlChar*) "Orientation")==0 && xmlTextReaderNodeType(reader)==1) { ret = xmlTextReaderRead(reader); if (xmlTextReaderHasValue(reader)) kp->orientation = Double(xmlTextReaderConstValue(reader)); - } else if (xmlStrcmp(name, "Dim")==0 && xmlTextReaderNodeType(reader)==1) { + } else if (xmlStrcmp(name, (xmlChar*) "Dim")==0 && xmlTextReaderNodeType(reader)==1) { ret = xmlTextReaderRead(reader); if (xmlTextReaderHasValue(reader)) kp->dim = Int(xmlTextReaderConstValue(reader)); - } else if (xmlStrcmp(name, "Descriptor")==0 && xmlTextReaderNodeType(reader)==1) { + } else if (xmlStrcmp(name, (xmlChar*) "Descriptor")==0 && xmlTextReaderNodeType(reader)==1) { KeypointN_CreateDescriptor(kp); int i=0; while (ret == 1) { name = xmlTextReaderConstName(reader); - if (xmlStrcmp(name, "int")==0 && xmlTextReaderNodeType(reader)==1) { + if (xmlStrcmp(name, (xmlChar*) "int")==0 && xmlTextReaderNodeType(reader)==1) { if (xmlTextReaderNodeType(reader)==1) { ret = xmlTextReaderRead(reader); if (xmlTextReaderHasValue(reader)) kp->descriptor[i++] = Int(xmlTextReaderConstValue(reader)); } } - if (strcmp(name, "Descriptor")==0 && xmlTextReaderNodeType(reader)==15) { + if (xmlStrcmp(name, (xmlChar*) "Descriptor")==0 && xmlTextReaderNodeType(reader)==15) { break; } ret = xmlTextReaderRead(reader); } } - if (strcmp(name, "Descriptor")==0 && xmlTextReaderNodeType(reader)==15) { + if (xmlStrcmp(name, (xmlChar*) "Descriptor")==0 && xmlTextReaderNodeType(reader)==15) { break; } ret = xmlTextReaderRead(reader); } KeypointXMLList_Add(kl, kp); - if (strcmp(name, "KeypointN")==0 && xmlTextReaderNodeType(reader)==15) { + if (xmlStrcmp(name, (xmlChar*) "KeypointN")==0 && xmlTextReaderNodeType(reader)==15) { break; } } ret = xmlTextReaderRead(reader); } - if (strcmp(name, "Arr")==0 && xmlTextReaderNodeType(reader)==15) { + if (xmlStrcmp(name, (xmlChar*)"Arr")==0 && xmlTextReaderNodeType(reader)==15) { break; } } ret = xmlTextReaderRead(reader); } - if (strcmp(name, "KeypointXMLList")==0 && xmlTextReaderNodeType(reader)==15) { + if (xmlStrcmp(name, (xmlChar*) "KeypointXMLList")==0 && xmlTextReaderNodeType(reader)==15) { break; } } @@ -212,53 +212,53 @@ writer = xmlNewTextWriterFilename(filename, compressed); if (writer != NULL) { rc = xmlTextWriterSetIndent(writer, 1); - rc = xmlTextWriterSetIndentString(writer, " "); + rc = xmlTextWriterSetIndentString(writer, (xmlChar*) " "); rc = xmlTextWriterStartDocument(writer, NULL, "utf-8", NULL); - rc = xmlTextWriterStartElement(writer, "KeypointXMLList"); + rc = xmlTextWriterStartElement(writer, (xmlChar*)"KeypointXMLList"); - rc = xmlTextWriterStartElement(writer, "XDim"); + rc = xmlTextWriterStartElement(writer, (xmlChar*)"XDim"); rc = xmlTextWriterWriteFormatString(writer, "%d", x); rc = xmlTextWriterEndElement(writer); - rc = xmlTextWriterStartElement(writer, "YDim"); + rc = xmlTextWriterStartElement(writer, (xmlChar*)"YDim"); rc = xmlTextWriterWriteFormatString(writer, "%d", y); rc = xmlTextWriterEndElement(writer); - rc = xmlTextWriterStartElement(writer, "ImageFile"); - rc = xmlTextWriterWriteString(writer, imageFile); + rc = xmlTextWriterStartElement(writer, (xmlChar*)"ImageFile"); + rc = xmlTextWriterWriteString(writer, (xmlChar*)imageFile); rc = xmlTextWriterEndElement(writer); - rc = xmlTextWriterStartElement(writer, "Arr"); + rc = xmlTextWriterStartElement(writer, (xmlChar*)"Arr"); int n; for (n=0; n<ArrayList_Count(list); n++) { - KeypointN* kp = ArrayList_GetItem(list, n); - rc = xmlTextWriterStartElement(writer, "KeypointN"); + KeypointN* kp = (KeypointN*) ArrayList_GetItem(list, n); + rc = xmlTextWriterStartElement(writer, (xmlChar*)"KeypointN"); - rc = xmlTextWriterStartElement(writer, "X"); + rc = xmlTextWriterStartElement(writer, (xmlChar*)"X"); rc = xmlTextWriterWriteFormatString(writer, "%.15g", kp->x); rc = xmlTextWriterEndElement(writer); - rc = xmlTextWriterStartElement(writer, "Y"); + rc = xmlTextWriterStartElement(writer, (xmlChar*)"Y"); rc = xmlTextWriterWriteFormatString(writer, "%.15g", kp->y); rc = xmlTextWriterEndElement(writer); - rc = xmlTextWriterStartElement(writer, "Scale"); + rc = xmlTextWriterStartElement(writer, (xmlChar*)"Scale"); rc = xmlTextWriterWriteFormatString(writer, "%.15g", kp->scale); rc = xmlTextWriterEndElement(writer); - rc = xmlTextWriterStartElement(writer, "Orientation"); + rc = xmlTextWriterStartElement(writer, (xmlChar*)"Orientation"); rc = xmlTextWriterWriteFormatString(writer, "%.15g", kp->orientation); rc = xmlTextWriterEndElement(writer); - rc = xmlTextWriterStartElement(writer, "Dim"); + rc = xmlTextWriterStartElement(writer, (xmlChar*)"Dim"); rc = xmlTextWriterWriteFormatString(writer, "%d", kp->dim); rc = xmlTextWriterEndElement(writer); - rc = xmlTextWriterStartElement(writer, "Descriptor"); + rc = xmlTextWriterStartElement(writer, (xmlChar*)"Descriptor"); int i; for(i=0; i< kp->dim; i++) { - rc = xmlTextWriterStartElement(writer, "int"); + rc = xmlTextWriterStartElement(writer, (xmlChar*)"int"); rc = xmlTextWriterWriteFormatString(writer, "%d", kp->descriptor[i]); rc = xmlTextWriterEndElement(writer); @@ -282,8 +282,8 @@ KeypointN* KeypointN_new0 () { KeypointN* self = (KeypointN*)malloc(sizeof(KeypointN)); - self->domain.getDimensionCount = (void*)KeypointN_GetDimensionCount; - self->domain.getDimensionElement = (void*)KeypointN_GetDimensionElement; + self->domain.getDimensionCount = (int ( *)(IKDTreeDomain *)) KeypointN_GetDimensionCount; + self->domain.getDimensionElement = (int (__cdecl *)(IKDTreeDomain *,int)) KeypointN_GetDimensionElement; self->dim = 0; self->descriptor = NULL; return self; Modified: autopano-sift-C/trunk/LoweDetector.c =================================================================== --- autopano-sift-C/trunk/LoweDetector.c 2008-01-14 21:29:24 UTC (rev 2636) +++ autopano-sift-C/trunk/LoweDetector.c 2008-01-15 06:53:24 UTC (rev 2637) @@ -93,6 +93,8 @@ // The Integer-normalized version of the globalKeypoints. ArrayList* LoweFeatureDetector_GlobalNaturalKeypoints(LoweFeatureDetector* self) { + int i; + if (self->globalNaturalKeypoints != NULL) return (self->globalNaturalKeypoints); @@ -101,9 +103,8 @@ self->globalNaturalKeypoints = ArrayList_new0 (KeypointN_delete); - int i; for(i=0; i<ArrayList_Count(self->globalKeypoints); i++) { - Keypoint* kp = ArrayList_GetItem(self->globalKeypoints, i); + Keypoint* kp = (Keypoint *) ArrayList_GetItem(self->globalKeypoints, i); ArrayList_AddItem (self->globalNaturalKeypoints, KeypointN_new(kp)); } Modified: autopano-sift-C/trunk/MatchKeys.c =================================================================== --- autopano-sift-C/trunk/MatchKeys.c 2008-01-14 21:29:24 UTC (rev 2636) +++ autopano-sift-C/trunk/MatchKeys.c 2008-01-15 06:53:24 UTC (rev 2637) @@ -36,14 +36,14 @@ ArrayList* matches = ArrayList_new0 (Match_delete); int j; for (j=0; j<ArrayList_Count(keys1); j++) { - KeypointN* kp = ArrayList_GetItem(keys1, j); + KeypointN* kp = (KeypointN*) ArrayList_GetItem(keys1, j); ArrayList* kpNNList = (ArrayList*)KDTree_NearestNeighbourListBBF (kd, (IKDTreeDomain*)kp, 2, 40); if (ArrayList_Count(kpNNList) < 2) FatalError ("BUG: less than two neighbours!"); - KDTreeBestEntry* be1 = ArrayList_GetItem(kpNNList, 0); - KDTreeBestEntry* be2 = ArrayList_GetItem(kpNNList, 1); + KDTreeBestEntry* be1 = (KDTreeBestEntry*) ArrayList_GetItem(kpNNList, 0); + KDTreeBestEntry* be2 = (KDTreeBestEntry*) ArrayList_GetItem(kpNNList, 1); if ((be1->distance / be2->distance) > 0.6) continue; @@ -70,7 +70,7 @@ // Count the references to each keypoint int i; for(i=0; i<ArrayList_Count(matches); i++) { - Match* m = ArrayList_GetItem(matches, i); + Match* m = (Match*) ArrayList_GetItem(matches, i); int lI = (HashTable_GetItem(ht, m->kp1) == NULL) ? 0 : (int) HashTable_GetItem(ht, m->kp1); HashTable_SetItem(ht, m->kp1, (void*)(lI + 1)); int rI = (HashTable_GetItem(ht, m->kp2) == NULL) ? 0 : (int) HashTable_GetItem(ht, m->kp2); @@ -81,7 +81,7 @@ int removed = 0; int j; for(j=0; j<ArrayList_Count(matches); j++) { - Match* m = ArrayList_GetItem(matches, j); + Match* m = (Match*) ArrayList_GetItem(matches, j); //WriteLine ("match: %d, %d", (int) HashTable_GetItem(ht, m->kp1), (int) HashTable_GetItem(ht, m->kp2)); if (((int) HashTable_GetItem(ht, m->kp1)) <= 1 && ((int) HashTable_GetItem(ht, m->kp2)) <= 1) @@ -145,7 +145,7 @@ MatchWeighter* MatchWeighter_new0() { MatchWeighter* self = (MatchWeighter*)malloc(sizeof(MatchWeighter)); - self->comparator.compareTo = MatchWeighter_CompareTo; + self->comparator.compareTo = (int ( *)(IComparator *,const void *,const void *)) MatchWeighter_CompareTo; self->distExp = 1.0; self->quotExp = 1.0; return self; @@ -235,7 +235,7 @@ self->keySets = ArrayList_new(self->imageCount, KeypointXMLList_delete); int n; for ( n = 0 ; n < self->imageCount ; ++n) { - char* fn = ArrayList_GetItem(filenames, n); + char* fn = (char *) ArrayList_GetItem(filenames, n); KeypointXMLList* keys = KeypointXMLReader_ReadComplete (fn); if (!keys) FatalError("Failed to load keypoints from %s", fn); @@ -319,7 +319,7 @@ self->filteredMatchSets = ArrayList_new0 (NULL); // The only combination between two matches - MatchSet* ms = self->matchSets[0][1]; + MatchSet* ms = (MatchSet*) self->matchSets[0][1]; if (ms == NULL || ms->matches == NULL) return (NULL); @@ -380,7 +380,7 @@ for ( n0 = 0 ; n0 < self->imageCount ; ++n0) { int n1; for ( n1 = n0 + 1 ; n1 < self->imageCount ; ++n1) { - MatchSet* ms = self->matchSets[n0][n1]; + MatchSet* ms = (MatchSet*) self->matchSets[n0][n1]; if (ms == NULL || ms->matches == NULL) continue; @@ -479,7 +479,7 @@ // Create a point list. int i; for(i=0; i<ArrayList_Count(matches); i++) { - Match* m = ArrayList_GetItem(matches, i); + Match* m = (Match*) ArrayList_GetItem(matches, i); FilterPoint* p = FilterPoint_new0 (); p->x = m->kp1->x; @@ -590,11 +590,11 @@ int i; for(i=0; i<ArrayList_Count(matches); i++) { - Match* m = ArrayList_GetItem(matches, i); + Match* m = (Match*) ArrayList_GetItem(matches, i); bool matchFound = false; int j; for(j=0; j<ArrayList_Count(convexHull); j++) { - FilterPoint* p = ArrayList_GetItem(convexHull, j); + FilterPoint* p = (FilterPoint*) ArrayList_GetItem(convexHull, j); if (p->user != m) continue; @@ -613,7 +613,7 @@ int k; for(k=0; k<ArrayList_Count(convexHull); k++) { - FilterPoint* p = ArrayList_GetItem(convexHull, k); + FilterPoint* p = (FilterPoint*) ArrayList_GetItem(convexHull, k); dist += sqrt (pow (p->x - m->kp1->x, 2.0) + pow (p->y - m->kp1->y, 2.0)); distCount += 1; @@ -640,7 +640,7 @@ ArrayList* filteredMatches = ArrayList_new0 (NULL); int j; for(j=0; j<ArrayList_Count(convexHull); j++) { - FilterPoint* p = ArrayList_GetItem(convexHull, j); + FilterPoint* p = (FilterPoint*) ArrayList_GetItem(convexHull, j); ArrayList_AddItem(filteredMatches, p->user); } @@ -669,10 +669,10 @@ { int i; for(i=0; i<ArrayList_Count(self->keySets); i++) { - KeypointXMLList* list = ArrayList_GetItem(self->keySets, i); + KeypointXMLList* list = (KeypointXMLList*) ArrayList_GetItem(self->keySets, i); int j; for(j=0; j<ArrayList_Count(list->array); j++) { - KeypointN* kp = ArrayList_GetItem(list->array, j); + KeypointN* kp = (KeypointN*) ArrayList_GetItem(list->array, j); ArrayList_AddItem(self->globalKeys, kp); } } @@ -695,7 +695,7 @@ // matches int i; for(i=0; i<ArrayList_Count(self->globalMatches); i++) { - Match* m = ArrayList_GetItem(self->globalMatches, i); + Match* m = (Match*) ArrayList_GetItem(self->globalMatches, i); int l0 = MultiMatch_FindOrigin (self, m->kp1); int l1 = MultiMatch_FindOrigin (self, m->kp2); @@ -711,11 +711,11 @@ continue; if (self->matchSets[l1][l0] != NULL) { - MatchSet* rev = self->matchSets[l1][l0]; + MatchSet* rev = (MatchSet*) self->matchSets[l1][l0]; if (rev != NULL) { int i; for(i=0; i<ArrayList_Count(rev->matches); i++) { - Match* mr = ArrayList_GetItem(rev->matches, i); + Match* mr = (Match*) ArrayList_GetItem(rev->matches, i); if (mr->kp1 == m->kp2 && mr->kp2 == m->kp1) { reverseAlreadyIn = true; @@ -729,8 +729,8 @@ if (self->matchSets[l0][l1] == NULL) { createCount += 1; - KeypointXMLList* k0 = ArrayList_GetItem(self->keySets, l0); - KeypointXMLList* k1 = ArrayList_GetItem(self->keySets, l1); + KeypointXMLList* k0 = (KeypointXMLList*) ArrayList_GetItem(self->keySets, l0); + KeypointXMLList* k1 = (KeypointXMLList*) ArrayList_GetItem(self->keySets, l1); self->matchSets[l0][l1] = MatchSet_new (self, k0->imageFile, k0->xDim, k0->yDim, k1->imageFile, k1->xDim, k1->yDim, @@ -762,7 +762,7 @@ { int ksn; for ( ksn = 0 ; ksn < ArrayList_Count(self->keySets) ; ++ksn) { - KeypointXMLList* list = ArrayList_GetItem(self->keySets, ksn); + KeypointXMLList* list = (KeypointXMLList*) ArrayList_GetItem(self->keySets, ksn); int lIdx = ArrayList_IndexOf (list->array, kp); if (lIdx >= 0) @@ -778,7 +778,7 @@ { int count = 0; double searchDepth = max (130.0, - (log (ArrayList_Count(self->globalKeys)) / log (1000.0)) * 130.0); + (log ((double) ArrayList_Count(self->globalKeys)) / log (1000.0)) * 130.0); int searchDepthI = (int) searchDepth; if (self->verbose) @@ -786,10 +786,10 @@ int i; for(i=0; i<ArrayList_Count(self->globalKeys); i++) { - KeypointN* kp = ArrayList_GetItem(self->globalKeys, i); + KeypointN* kp = (KeypointN*) ArrayList_GetItem(self->globalKeys, i); if (self->verbose) { - if ((count % 25) == 0) + if ((count % 250) == 0) Write ("\r%2.2f%%, %d/%d ", (100 * ((double) count)) / ((double) ArrayList_Count(self->globalKeys)), count, ArrayList_Count(self->globalKeys)); @@ -806,16 +806,16 @@ if (ArrayList_Count(kpNNList) < ... [truncated message content] |
From: <da...@us...> - 2008-01-15 07:19:35
|
Revision: 2638 http://hugin.svn.sourceforge.net/hugin/?rev=2638&view=rev Author: dangelo Date: 2008-01-14 23:19:34 -0800 (Mon, 14 Jan 2008) Log Message: ----------- Fixed compilation with gcc Modified Paths: -------------- autopano-sift-C/trunk/AutoPanoSift.h autopano-sift-C/trunk/CMakeLists.txt autopano-sift-C/trunk/KeypointXML.c Modified: autopano-sift-C/trunk/AutoPanoSift.h =================================================================== --- autopano-sift-C/trunk/AutoPanoSift.h 2008-01-15 06:53:24 UTC (rev 2637) +++ autopano-sift-C/trunk/AutoPanoSift.h 2008-01-15 07:19:34 UTC (rev 2638) @@ -2,7 +2,11 @@ #ifndef AUTOPANOS_SIFT_H #define AUTOPANOS_SIFT_H +#ifdef HAS_CONFIG_H #include "config.h" +#else +#define PACKAGE_VERSION "2.4.1" +#endif // include windows.h here // to prevent the global namespace to become polluted with Modified: autopano-sift-C/trunk/CMakeLists.txt =================================================================== --- autopano-sift-C/trunk/CMakeLists.txt 2008-01-15 06:53:24 UTC (rev 2637) +++ autopano-sift-C/trunk/CMakeLists.txt 2008-01-15 07:19:34 UTC (rev 2638) @@ -44,9 +44,9 @@ ## XML library ## -FIND_PACKAGE(LIBXML2 REQUIRED) -ADD_DEFINITIONS(${LIBXML2_DEFINITIONS}) -INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR}) +FIND_PACKAGE(LIBXML2MY REQUIRED) +ADD_DEFINITIONS(${LIBXML2MY_DEFINITIONS}) +INCLUDE_DIRECTORIES(${LIBXML2MY_INCLUDE_DIR}) ## ## Panotools Modified: autopano-sift-C/trunk/KeypointXML.c =================================================================== --- autopano-sift-C/trunk/KeypointXML.c 2008-01-15 06:53:24 UTC (rev 2637) +++ autopano-sift-C/trunk/KeypointXML.c 2008-01-15 07:19:34 UTC (rev 2638) @@ -283,7 +283,7 @@ { KeypointN* self = (KeypointN*)malloc(sizeof(KeypointN)); self->domain.getDimensionCount = (int ( *)(IKDTreeDomain *)) KeypointN_GetDimensionCount; - self->domain.getDimensionElement = (int (__cdecl *)(IKDTreeDomain *,int)) KeypointN_GetDimensionElement; + self->domain.getDimensionElement = (int ( *)(IKDTreeDomain *,int)) KeypointN_GetDimensionElement; self->dim = 0; self->descriptor = NULL; return self; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bru...@us...> - 2008-01-29 11:49:32
|
Revision: 2729 http://hugin.svn.sourceforge.net/hugin/?rev=2729&view=rev Author: brunopostle Date: 2008-01-29 03:49:27 -0800 (Tue, 29 Jan 2008) Log Message: ----------- Fix line endings, no other changes Modified Paths: -------------- autopano-sift-C/trunk/CMakeLists.txt autopano-sift-C/trunk/CMakeModules/FindJPEG.cmake autopano-sift-C/trunk/CMakeModules/FindLibXml2.cmake autopano-sift-C/trunk/CMakeModules/FindPANO13.cmake autopano-sift-C/trunk/CMakeModules/FindPNG.cmake autopano-sift-C/trunk/CMakeModules/FindTIFF.cmake autopano-sift-C/trunk/CMakeModules/FindZLIB.cmake autopano-sift-C/trunk/config.h.in.cmake Modified: autopano-sift-C/trunk/CMakeLists.txt =================================================================== --- autopano-sift-C/trunk/CMakeLists.txt 2008-01-29 11:44:14 UTC (rev 2728) +++ autopano-sift-C/trunk/CMakeLists.txt 2008-01-29 11:49:27 UTC (rev 2729) @@ -1,184 +1,184 @@ -set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMakeModules ) - -## global setup -project(autopano-sift-C) - -# version -set(V_MAJOR 2) -set(V_MINOR 4) -set(V_PATCH 1) -set(PACKAGE_VERSION ${V_MAJOR}.${V_MINOR}.${V_PATCH}) - -IF (WIN32) - ## - ## The directory that contains the hugin source root is a good - ## place to look for support packages, so post it in cache. - ## - ## Our FIND_PACKAGE calls modules will search SOURCE_BASE_DIR - ## after the local standard places - ## - # extract pathname from CMAKE_SOURCE_DIR (note result must be a local var) - STRING( REGEX REPLACE "(.*)/[^/]+$" "\\1" work "${CMAKE_SOURCE_DIR}" ) - # create the cache entry - SET( SOURCE_BASE_DIR ${work} CACHE FILEPATH "parent dir of hugin source root" ) - - # 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) -ENDIF(WIN32) - -## -## Graphics libraries -## -# wxWidgets sub-packages will be used if native ones aren't found - -FIND_PACKAGE(TIFF REQUIRED) -INCLUDE_DIRECTORIES(${TIFF_INCLUDE_DIR}) -FIND_PACKAGE(JPEG REQUIRED) -INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR}) -FIND_PACKAGE(PNG REQUIRED) -INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) -INCLUDE_DIRECTORIES(${PNG_INCLUDE_DIR}) - -## -## XML library -## -FIND_PACKAGE(LibXml2 REQUIRED) -ADD_DEFINITIONS(${LIBXML2_DEFINITIONS}) -INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR}) - -## -## Panotools -## - -FIND_PACKAGE(PANO13 REQUIRED) -INCLUDE_DIRECTORIES(${PANO13_INCLUDE_DIR}) - - -#BUILD SETUP -IF(NOT CMAKE_BUILD_TYPE) - SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING - "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." - FORCE) -ENDIF(NOT CMAKE_BUILD_TYPE) - -IF(UNIX) - ADD_DEFINITIONS(-Wall) - ADD_DEFINITIONS(-DHAS_PANO13) -ENDIF(UNIX) - -# Setup MSVC -IF (MSVC) - # Stop MSVC8 from bitching about the C library - ADD_DEFINITIONS(/D_CRT_SECURE_NO_DEPRECATE) - # Stop MSVC9 from bitching about possibly invalid STL usage - ADD_DEFINITIONS(/D_SCL_SECURE_NO_WARNINGS) - # 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}) - - # compile as C code as C++ code, required to enable - # variable declarations between statements. - ADD_DEFINITIONS(/TP) - - # yes we DO have pano13 - ADD_DEFINITIONS( /DHAS_PANO13 ) - -ENDIF(MSVC) - -# create config.h file -configure_file(config.h.in.cmake ${CMAKE_BINARY_DIR}/config.h) -INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}) - -## -## Finally, rules to build the source code! -## - -SET(LIBSIFT_SOURCES LoweDetector.c RANSAC.c GaussianConvolution.c - ScaleSpace.c KeypointXML.c MatchKeys.c KDTree.c BondBall.c - AreaFilter.c ImageMatchModel.c Transform.c DisplayImage.c ImageMap.c - HashTable.c ArrayList.c Random.c SimpleMatrix.c Utils.c) - -ADD_LIBRARY(libsift STATIC ${LIBSIFT_SOURCES}) - -set(all_libs libsift ${JPEG_LIBRARIES} ${TIFF_LIBRARIES} - ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${PANO13_LIBRARIES} ${LIBXML2_LIBRARIES}) - -add_executable(generatekeys GenerateKeys.c) -TARGET_LINK_LIBRARIES(generatekeys ${all_libs}) - -add_executable(autopano AutoPano.c) -TARGET_LINK_LIBRARIES(autopano ${all_libs}) - -install(TARGETS generatekeys autopano DESTINATION bin) -install(FILES autopano-c-complete.sh DESTINATION bin) - -# man pages -FILE(GLOB MAN_PAGES_1 doc/*.1) -FILE(GLOB MAN_PAGES_7 doc/*.1) -install(FILES ${MAN_PAGES_1} DESTINATION share/man/man1) -install(FILES ${MAN_PAGES_7} DESTINATION share/man/man7) - -## Test exectuables. - -if (BUILD_TESTS) - add_executable(testArray TestArray.c) - TARGET_LINK_LIBRARIES(testArray ${all_libs}) - add_executable(testRandom TestRandom.c) - TARGET_LINK_LIBRARIES(testRandom ${all_libs}) -#add_executable(testSimpleMatrix TestSimpleMatrix.c) -#TARGET_LINK_LIBRARIES(testSimpleMatrix ${all_libs}) -#add_executable(testTransform TestTransform.c) -#TARGET_LINK_LIBRARIES(testTransform ${all_libs}) -#add_executable(testRansac TestRansac.c) -#TARGET_LINK_LIBRARIES(testRansac ${all_libs}) -#add_executable(testAreaFilter TestAreaFilter.c) -#TARGET_LINK_LIBRARIES(testAreaFilter ${all_libs}) - add_executable(testKDTree TestKDTree.c) - TARGET_LINK_LIBRARIES(testKDTree ${all_libs}) -endif(BUILD_TESTS) - - -SET(CPACK_PACKAGE_VERSION_MAJOR "${V_MAJOR}") -SET(CPACK_PACKAGE_VERSION_MINOR "${V_MINOR}") -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_SOURCE_GENERATOR "TGZ") -SET(CPACK_SOURCE_IGNORE_FILES -"/autopano$" -"/generatekeys$" -"/Makefile$" -"/_CPack_Packages/" -"/CMakeCache.txt$" -"\\\\.dir/" -"\\\\.tar\\\\.gz$" -"\\\\.tar\\\\.Z$" -"\\\\.svn/" -"\\\\.cvsignore$" -"\\\\.swp$" -"~$" -"\\\\.#" -"/#" -"/build/" -"/CVS/" -"/\\\\.libs/" -"/\\\\.deps/" -"\\\\.o$" -"\\\\.a$" -"\\\\.lo$" -"\\\\.so$" -"\\\\.so\\\\.0$" -"\\\\.so\\\\.0\\\\.0$" -"\\\\.la$" -"Makefile\\\\.in$" - ) -INCLUDE(CPack) +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMakeModules ) + +## global setup +project(autopano-sift-C) + +# version +set(V_MAJOR 2) +set(V_MINOR 4) +set(V_PATCH 1) +set(PACKAGE_VERSION ${V_MAJOR}.${V_MINOR}.${V_PATCH}) + +IF (WIN32) + ## + ## The directory that contains the hugin source root is a good + ## place to look for support packages, so post it in cache. + ## + ## Our FIND_PACKAGE calls modules will search SOURCE_BASE_DIR + ## after the local standard places + ## + # extract pathname from CMAKE_SOURCE_DIR (note result must be a local var) + STRING( REGEX REPLACE "(.*)/[^/]+$" "\\1" work "${CMAKE_SOURCE_DIR}" ) + # create the cache entry + SET( SOURCE_BASE_DIR ${work} CACHE FILEPATH "parent dir of hugin source root" ) + + # 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) +ENDIF(WIN32) + +## +## Graphics libraries +## +# wxWidgets sub-packages will be used if native ones aren't found + +FIND_PACKAGE(TIFF REQUIRED) +INCLUDE_DIRECTORIES(${TIFF_INCLUDE_DIR}) +FIND_PACKAGE(JPEG REQUIRED) +INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR}) +FIND_PACKAGE(PNG REQUIRED) +INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) +INCLUDE_DIRECTORIES(${PNG_INCLUDE_DIR}) + +## +## XML library +## +FIND_PACKAGE(LibXml2 REQUIRED) +ADD_DEFINITIONS(${LIBXML2_DEFINITIONS}) +INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR}) + +## +## Panotools +## + +FIND_PACKAGE(PANO13 REQUIRED) +INCLUDE_DIRECTORIES(${PANO13_INCLUDE_DIR}) + + +#BUILD SETUP +IF(NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING + "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." + FORCE) +ENDIF(NOT CMAKE_BUILD_TYPE) + +IF(UNIX) + ADD_DEFINITIONS(-Wall) + ADD_DEFINITIONS(-DHAS_PANO13) +ENDIF(UNIX) + +# Setup MSVC +IF (MSVC) + # Stop MSVC8 from bitching about the C library + ADD_DEFINITIONS(/D_CRT_SECURE_NO_DEPRECATE) + # Stop MSVC9 from bitching about possibly invalid STL usage + ADD_DEFINITIONS(/D_SCL_SECURE_NO_WARNINGS) + # 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}) + + # compile as C code as C++ code, required to enable + # variable declarations between statements. + ADD_DEFINITIONS(/TP) + + # yes we DO have pano13 + ADD_DEFINITIONS( /DHAS_PANO13 ) + +ENDIF(MSVC) + +# create config.h file +configure_file(config.h.in.cmake ${CMAKE_BINARY_DIR}/config.h) +INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}) + +## +## Finally, rules to build the source code! +## + +SET(LIBSIFT_SOURCES LoweDetector.c RANSAC.c GaussianConvolution.c + ScaleSpace.c KeypointXML.c MatchKeys.c KDTree.c BondBall.c + AreaFilter.c ImageMatchModel.c Transform.c DisplayImage.c ImageMap.c + HashTable.c ArrayList.c Random.c SimpleMatrix.c Utils.c) + +ADD_LIBRARY(libsift STATIC ${LIBSIFT_SOURCES}) + +set(all_libs libsift ${JPEG_LIBRARIES} ${TIFF_LIBRARIES} + ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${PANO13_LIBRARIES} ${LIBXML2_LIBRARIES}) + +add_executable(generatekeys GenerateKeys.c) +TARGET_LINK_LIBRARIES(generatekeys ${all_libs}) + +add_executable(autopano AutoPano.c) +TARGET_LINK_LIBRARIES(autopano ${all_libs}) + +install(TARGETS generatekeys autopano DESTINATION bin) +install(FILES autopano-c-complete.sh DESTINATION bin) + +# man pages +FILE(GLOB MAN_PAGES_1 doc/*.1) +FILE(GLOB MAN_PAGES_7 doc/*.1) +install(FILES ${MAN_PAGES_1} DESTINATION share/man/man1) +install(FILES ${MAN_PAGES_7} DESTINATION share/man/man7) + +## Test exectuables. + +if (BUILD_TESTS) + add_executable(testArray TestArray.c) + TARGET_LINK_LIBRARIES(testArray ${all_libs}) + add_executable(testRandom TestRandom.c) + TARGET_LINK_LIBRARIES(testRandom ${all_libs}) +#add_executable(testSimpleMatrix TestSimpleMatrix.c) +#TARGET_LINK_LIBRARIES(testSimpleMatrix ${all_libs}) +#add_executable(testTransform TestTransform.c) +#TARGET_LINK_LIBRARIES(testTransform ${all_libs}) +#add_executable(testRansac TestRansac.c) +#TARGET_LINK_LIBRARIES(testRansac ${all_libs}) +#add_executable(testAreaFilter TestAreaFilter.c) +#TARGET_LINK_LIBRARIES(testAreaFilter ${all_libs}) + add_executable(testKDTree TestKDTree.c) + TARGET_LINK_LIBRARIES(testKDTree ${all_libs}) +endif(BUILD_TESTS) + + +SET(CPACK_PACKAGE_VERSION_MAJOR "${V_MAJOR}") +SET(CPACK_PACKAGE_VERSION_MINOR "${V_MINOR}") +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_SOURCE_GENERATOR "TGZ") +SET(CPACK_SOURCE_IGNORE_FILES +"/autopano$" +"/generatekeys$" +"/Makefile$" +"/_CPack_Packages/" +"/CMakeCache.txt$" +"\\\\.dir/" +"\\\\.tar\\\\.gz$" +"\\\\.tar\\\\.Z$" +"\\\\.svn/" +"\\\\.cvsignore$" +"\\\\.swp$" +"~$" +"\\\\.#" +"/#" +"/build/" +"/CVS/" +"/\\\\.libs/" +"/\\\\.deps/" +"\\\\.o$" +"\\\\.a$" +"\\\\.lo$" +"\\\\.so$" +"\\\\.so\\\\.0$" +"\\\\.so\\\\.0\\\\.0$" +"\\\\.la$" +"Makefile\\\\.in$" + ) +INCLUDE(CPack) Modified: autopano-sift-C/trunk/CMakeModules/FindJPEG.cmake =================================================================== --- autopano-sift-C/trunk/CMakeModules/FindJPEG.cmake 2008-01-29 11:44:14 UTC (rev 2728) +++ autopano-sift-C/trunk/CMakeModules/FindJPEG.cmake 2008-01-29 11:49:27 UTC (rev 2729) @@ -1,37 +1,37 @@ -# - Find JPEG for Hugin 0.7 01Nov2007 TKSharpless -# Added to support Windows build but should work anywhere. -# After looking in UNIX standard places, tries wxWidgets build -# tree, which should have this package. -# -# Call FIND_PACKAGE(wxWidgets REQUIRED) before calling this! -# -# reads cache variables -# wxWidgets_ROOT_DIR -# wxWidgets_LIB_DIR -# defines cache variables -# JPEG_INCLUDE_DIR, where to find headers -# JPEG_LIBRARIES, list of release link libraries -# JPEG_DEBUG_LIBRARIES, list of debug link libraries -# JPEG_FOUND, If != "YES", do not try to use JPEG - -FIND_PATH(JPEG_INCLUDE_DIR jpeglib.h - /usr/local/include - /usr/include - ${wxWidgets_ROOT_DIR}/src/jpeg -) - -include(FindLibraryWithDebug) - -find_library_with_debug(JPEG_LIBRARIES - WIN32_DEBUG_POSTFIX d - NAMES jpeg libjpeg wxjpeg - PATHS /usr/lib /usr/local/lib ${wxWidgets_LIB_DIR} -) - - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(JPEG DEFAULT_MSG - JPEG_INCLUDE_DIR JPEG_LIBRARIES) - -MARK_AS_ADVANCED(JPEG_INCLUDE_DIR JPEG_LIBRARIES ) - +# - Find JPEG for Hugin 0.7 01Nov2007 TKSharpless +# Added to support Windows build but should work anywhere. +# After looking in UNIX standard places, tries wxWidgets build +# tree, which should have this package. +# +# Call FIND_PACKAGE(wxWidgets REQUIRED) before calling this! +# +# reads cache variables +# wxWidgets_ROOT_DIR +# wxWidgets_LIB_DIR +# defines cache variables +# JPEG_INCLUDE_DIR, where to find headers +# JPEG_LIBRARIES, list of release link libraries +# JPEG_DEBUG_LIBRARIES, list of debug link libraries +# JPEG_FOUND, If != "YES", do not try to use JPEG + +FIND_PATH(JPEG_INCLUDE_DIR jpeglib.h + /usr/local/include + /usr/include + ${wxWidgets_ROOT_DIR}/src/jpeg +) + +include(FindLibraryWithDebug) + +find_library_with_debug(JPEG_LIBRARIES + WIN32_DEBUG_POSTFIX d + NAMES jpeg libjpeg wxjpeg + PATHS /usr/lib /usr/local/lib ${wxWidgets_LIB_DIR} +) + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(JPEG DEFAULT_MSG + JPEG_INCLUDE_DIR JPEG_LIBRARIES) + +MARK_AS_ADVANCED(JPEG_INCLUDE_DIR JPEG_LIBRARIES ) + Modified: autopano-sift-C/trunk/CMakeModules/FindLibXml2.cmake =================================================================== --- autopano-sift-C/trunk/CMakeModules/FindLibXml2.cmake 2008-01-29 11:44:14 UTC (rev 2728) +++ autopano-sift-C/trunk/CMakeModules/FindLibXml2.cmake 2008-01-29 11:49:27 UTC (rev 2729) @@ -1,48 +1,48 @@ -# - Try to find LibXml2 -# Once done this will define -# -# LIBXML2_FOUND - system has LibXml2 -# LIBXML2_INCLUDE_DIR - the LibXml2 include directory -# LIBXML2_LIBRARIES - the libraries needed to use LibXml2 -# LIBXML2_DEFINITIONS - Compiler switches required for using LibXml2 - -# Copyright (c) 2006, Alexander Neundorf, <neu...@kd...> -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - - -IF (LIBXML2_INCLUDE_DIR AND LIBXML2_LIBRARIES) - # in cache already - SET(LibXml2_FIND_QUIETLY TRUE) -ENDIF (LIBXML2_INCLUDE_DIR AND LIBXML2_LIBRARIES) - -IF (NOT WIN32) - # use pkg-config to get the directories and then use these values - # in the FIND_PATH() and FIND_LIBRARY() calls - INCLUDE(UsePkgConfig) - PKGCONFIG(libxml-2.0 _LibXml2IncDir _LibXml2LinkDir _LibXml2LinkFlags _LibXml2Cflags) - SET(LIBXML2_DEFINITIONS ${_LibXml2Cflags}) -ENDIF (NOT WIN32) - -FIND_PATH(LIBXML2_INCLUDE_DIR libxml/xpath.h - PATHS - ${_LibXml2IncDir} - ${SOURCE_BASE_DIR}/libxml2-2.6.31/include - PATH_SUFFIXES libxml2 - ) - -FIND_LIBRARY(LIBXML2_LIBRARIES NAMES libxml2_a xml2 libxml2 - PATHS - ${_LibXml2LinkDir} - ${SOURCE_BASE_DIR}/libxml2-2.6.31/win32/bin.msvc - ) - -INCLUDE(FindPackageHandleStandardArgs) - -# handle the QUIETLY and REQUIRED arguments and set LIBXML2_FOUND to TRUE if -# all listed variables are TRUE -FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR) - -MARK_AS_ADVANCED(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARIES) - +# - Try to find LibXml2 +# Once done this will define +# +# LIBXML2_FOUND - system has LibXml2 +# LIBXML2_INCLUDE_DIR - the LibXml2 include directory +# LIBXML2_LIBRARIES - the libraries needed to use LibXml2 +# LIBXML2_DEFINITIONS - Compiler switches required for using LibXml2 + +# Copyright (c) 2006, Alexander Neundorf, <neu...@kd...> +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + + +IF (LIBXML2_INCLUDE_DIR AND LIBXML2_LIBRARIES) + # in cache already + SET(LibXml2_FIND_QUIETLY TRUE) +ENDIF (LIBXML2_INCLUDE_DIR AND LIBXML2_LIBRARIES) + +IF (NOT WIN32) + # use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + INCLUDE(UsePkgConfig) + PKGCONFIG(libxml-2.0 _LibXml2IncDir _LibXml2LinkDir _LibXml2LinkFlags _LibXml2Cflags) + SET(LIBXML2_DEFINITIONS ${_LibXml2Cflags}) +ENDIF (NOT WIN32) + +FIND_PATH(LIBXML2_INCLUDE_DIR libxml/xpath.h + PATHS + ${_LibXml2IncDir} + ${SOURCE_BASE_DIR}/libxml2-2.6.31/include + PATH_SUFFIXES libxml2 + ) + +FIND_LIBRARY(LIBXML2_LIBRARIES NAMES libxml2_a xml2 libxml2 + PATHS + ${_LibXml2LinkDir} + ${SOURCE_BASE_DIR}/libxml2-2.6.31/win32/bin.msvc + ) + +INCLUDE(FindPackageHandleStandardArgs) + +# handle the QUIETLY and REQUIRED arguments and set LIBXML2_FOUND to TRUE if +# all listed variables are TRUE +FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR) + +MARK_AS_ADVANCED(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARIES) + Modified: autopano-sift-C/trunk/CMakeModules/FindPANO13.cmake =================================================================== --- autopano-sift-C/trunk/CMakeModules/FindPANO13.cmake 2008-01-29 11:44:14 UTC (rev 2728) +++ autopano-sift-C/trunk/CMakeModules/FindPANO13.cmake 2008-01-29 11:49:27 UTC (rev 2729) @@ -1,46 +1,46 @@ -# - Find PANO13 headers and libraries -# modified for Hugin 0.7 Windows build 02Nov2007 TKSharpless -# reads cache variable -# SOURCE_BASE_DIR -- directory that contains hugin source root -# defines cache vars -# PANO13_INCLUDE_DIR, where to find pano13/panorama.h, etc. -# PANO13_LIBRARIES, release link library list. -# PANO13_DEBUG_LIBRARIES, debug ditto. -# PANO13_FOUND, If != "YES", do not try to use PANO13. - -# In Pablo's Windows setup ${SOURCE_BASE_DIR}/libpano contains pano12 -# and pano13. This code also works if pano13 is in ${SOURCE_BASE_DIR} -## NOTE the form "pano13/panorama.h" is used in #includes in some -## Hugin source files, so we are stuck with that for now. -FIND_PATH(PANO13_INCLUDE_DIR pano13/panorama.h - /usr/local/include - /usr/include - ${SOURCE_BASE_DIR}/libpano - ${SOURCE_BASE_DIR} -) - -# Pablo's Windows setup has the link libs in subdirs Debug -# and Release of libpano/pano13, as "Panotools.lib". This -# code will also find them in pano13 or in pano13/lib, and -# with names pano13 or pano13d. -FIND_LIBRARY(PANO13_LIBRARIES - NAMES pano13 - PATHS /usr/lib /usr/local/lib - ${PANO13_INCLUDE_DIR}/pano13/Release - ${SOURCE_BASE_DIR}/pano13/lib - ${SOURCE_BASE_DIR}/pano13 - ) - -IF(PANO13_INCLUDE_DIR) - IF(PANO13_LIBRARIES) - SET( PANO13_FOUND "YES" ) - FIND_LIBRARY( PANO13_DEBUG_LIBRARIES - NAMES Panotools pano13d pano13 - PATHS /usr/lib /usr/local/lib - ${PANO13_INCLUDE_DIR}/pano13/Debug - ${SOURCE_BASE_DIR}/pano13/lib - ${SOURCE_BASE_DIR}/pano13 - ) - ENDIF(PANO13_LIBRARIES) -ENDIF(PANO13_INCLUDE_DIR) - +# - Find PANO13 headers and libraries +# modified for Hugin 0.7 Windows build 02Nov2007 TKSharpless +# reads cache variable +# SOURCE_BASE_DIR -- directory that contains hugin source root +# defines cache vars +# PANO13_INCLUDE_DIR, where to find pano13/panorama.h, etc. +# PANO13_LIBRARIES, release link library list. +# PANO13_DEBUG_LIBRARIES, debug ditto. +# PANO13_FOUND, If != "YES", do not try to use PANO13. + +# In Pablo's Windows setup ${SOURCE_BASE_DIR}/libpano contains pano12 +# and pano13. This code also works if pano13 is in ${SOURCE_BASE_DIR} +## NOTE the form "pano13/panorama.h" is used in #includes in some +## Hugin source files, so we are stuck with that for now. +FIND_PATH(PANO13_INCLUDE_DIR pano13/panorama.h + /usr/local/include + /usr/include + ${SOURCE_BASE_DIR}/libpano + ${SOURCE_BASE_DIR} +) + +# Pablo's Windows setup has the link libs in subdirs Debug +# and Release of libpano/pano13, as "Panotools.lib". This +# code will also find them in pano13 or in pano13/lib, and +# with names pano13 or pano13d. +FIND_LIBRARY(PANO13_LIBRARIES + NAMES pano13 + PATHS /usr/lib /usr/local/lib + ${PANO13_INCLUDE_DIR}/pano13/Release + ${SOURCE_BASE_DIR}/pano13/lib + ${SOURCE_BASE_DIR}/pano13 + ) + +IF(PANO13_INCLUDE_DIR) + IF(PANO13_LIBRARIES) + SET( PANO13_FOUND "YES" ) + FIND_LIBRARY( PANO13_DEBUG_LIBRARIES + NAMES Panotools pano13d pano13 + PATHS /usr/lib /usr/local/lib + ${PANO13_INCLUDE_DIR}/pano13/Debug + ${SOURCE_BASE_DIR}/pano13/lib + ${SOURCE_BASE_DIR}/pano13 + ) + ENDIF(PANO13_LIBRARIES) +ENDIF(PANO13_INCLUDE_DIR) + Modified: autopano-sift-C/trunk/CMakeModules/FindPNG.cmake =================================================================== --- autopano-sift-C/trunk/CMakeModules/FindPNG.cmake 2008-01-29 11:44:14 UTC (rev 2728) +++ autopano-sift-C/trunk/CMakeModules/FindPNG.cmake 2008-01-29 11:49:27 UTC (rev 2729) @@ -1,43 +1,43 @@ -# - Find PNG for Hugin 0.7 01Nov2007 TKSharpless -# Added to support Windows build but should work anywhere. -# After looking in UNIX standard places, tries wxWidgets build -# tree, which should have this package. -# -# Call FIND_PACKAGE(wxWidgets REQUIRED) before calling this! -# -# reads cache variables -# wxWidgets_ROOT_DIR -# wxWidgets_LIB_DIR -# defines cache variables -# PNG_INCLUDE_DIR, where to find headers -# PNG_LIBRARIES, list of release link libraries. -# PNG_FOUND, If != "YES", do not try to use PNG. -# None of the above will be defined unless ZLIB can be found - -INCLUDE(FindZLIB) - -include(FindLibraryWithDebug) - -SET(PNG_FOUND "NO") - -IF (ZLIB_FOUND) - FIND_PATH(PNG_INCLUDE_DIR png.h - /usr/local/include - /usr/include - ${wxWidgets_ROOT_DIR}/src/png - ) - - find_library_with_debug(PNG_LIBRARIES - WIN32_DEBUG_POSTFIX d - NAMES png libpng wxpng - PATHS /usr/lib /usr/local/lib ${wxWidgets_LIB_DIR} - ) - - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(PNG DEFAULT_MSG - PNG_INCLUDE_DIR PNG_LIBRARIES) - - SET(PNG_LIBRARIES ${PNG_LIBRARIES} ${ZLIB_LIBRARIES}) - MARK_AS_ADVANCED(PNG_INCLUDE_DIR PNG_LIBRARIES ) -ENDIF(ZLIB_FOUND) - +# - Find PNG for Hugin 0.7 01Nov2007 TKSharpless +# Added to support Windows build but should work anywhere. +# After looking in UNIX standard places, tries wxWidgets build +# tree, which should have this package. +# +# Call FIND_PACKAGE(wxWidgets REQUIRED) before calling this! +# +# reads cache variables +# wxWidgets_ROOT_DIR +# wxWidgets_LIB_DIR +# defines cache variables +# PNG_INCLUDE_DIR, where to find headers +# PNG_LIBRARIES, list of release link libraries. +# PNG_FOUND, If != "YES", do not try to use PNG. +# None of the above will be defined unless ZLIB can be found + +INCLUDE(FindZLIB) + +include(FindLibraryWithDebug) + +SET(PNG_FOUND "NO") + +IF (ZLIB_FOUND) + FIND_PATH(PNG_INCLUDE_DIR png.h + /usr/local/include + /usr/include + ${wxWidgets_ROOT_DIR}/src/png + ) + + find_library_with_debug(PNG_LIBRARIES + WIN32_DEBUG_POSTFIX d + NAMES png libpng wxpng + PATHS /usr/lib /usr/local/lib ${wxWidgets_LIB_DIR} + ) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(PNG DEFAULT_MSG + PNG_INCLUDE_DIR PNG_LIBRARIES) + + SET(PNG_LIBRARIES ${PNG_LIBRARIES} ${ZLIB_LIBRARIES}) + MARK_AS_ADVANCED(PNG_INCLUDE_DIR PNG_LIBRARIES ) +ENDIF(ZLIB_FOUND) + Modified: autopano-sift-C/trunk/CMakeModules/FindTIFF.cmake =================================================================== --- autopano-sift-C/trunk/CMakeModules/FindTIFF.cmake 2008-01-29 11:44:14 UTC (rev 2728) +++ autopano-sift-C/trunk/CMakeModules/FindTIFF.cmake 2008-01-29 11:49:27 UTC (rev 2729) @@ -1,42 +1,42 @@ -# - Find TIFF for Hugin 0.7 01Nov2007 TKSharpless -# Added to support Windows build but should work anywhere. -# After looking in UNIX standard places, tries wxWidgets build -# tree, which should have this package. -# -# Call FIND_PACKAGE(wxWidgets REQUIRED) before calling this! -# -# reads cache variables -# wxWidgets_ROOT_DIR -# wxWidgets_LIB_DIR -# defines cache variables -# TIFF_INCLUDE_DIR, where to find headers -# TIFF_LIBRARIES, list of link libraries for release -# TIFF_DEBUG_LIBRARIES ditto for debug -# TIFF_FOUND, If != "YES", do not try to use TIFF. - -FIND_PATH(TIFF_INCLUDE_DIR tiff.h - /usr/local/include - /usr/include - ${SOURCE_BASE_DIR}/tiff-3.8.2/libtiff - ${SOURCE_BASE_DIR}/tiff-4.0.0alpha/libtiff - ${wxWidgets_ROOT_DIR}/src/tiff -) - -include(FindLibraryWithDebug) - -find_library_with_debug(TIFF_LIBRARIES - WIN32_DEBUG_POSTFIX d - NAMES tiff libtiff wxtiff - PATHS /usr/lib /usr/local/lib - ${SOURCE_BASE_DIR}/tiff-3.8.2/libtiff - ${SOURCE_BASE_DIR}/tiff-4.0.0alpha/libtiff - ${wxWidgets_LIB_DIR} -) - - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(TIFF DEFAULT_MSG - TIFF_INCLUDE_DIR TIFF_LIBRARIES) - -MARK_AS_ADVANCED(TIFF_INCLUDE_DIR TIFF_LIBRARIES) - +# - Find TIFF for Hugin 0.7 01Nov2007 TKSharpless +# Added to support Windows build but should work anywhere. +# After looking in UNIX standard places, tries wxWidgets build +# tree, which should have this package. +# +# Call FIND_PACKAGE(wxWidgets REQUIRED) before calling this! +# +# reads cache variables +# wxWidgets_ROOT_DIR +# wxWidgets_LIB_DIR +# defines cache variables +# TIFF_INCLUDE_DIR, where to find headers +# TIFF_LIBRARIES, list of link libraries for release +# TIFF_DEBUG_LIBRARIES ditto for debug +# TIFF_FOUND, If != "YES", do not try to use TIFF. + +FIND_PATH(TIFF_INCLUDE_DIR tiff.h + /usr/local/include + /usr/include + ${SOURCE_BASE_DIR}/tiff-3.8.2/libtiff + ${SOURCE_BASE_DIR}/tiff-4.0.0alpha/libtiff + ${wxWidgets_ROOT_DIR}/src/tiff +) + +include(FindLibraryWithDebug) + +find_library_with_debug(TIFF_LIBRARIES + WIN32_DEBUG_POSTFIX d + NAMES tiff libtiff wxtiff + PATHS /usr/lib /usr/local/lib + ${SOURCE_BASE_DIR}/tiff-3.8.2/libtiff + ${SOURCE_BASE_DIR}/tiff-4.0.0alpha/libtiff + ${wxWidgets_LIB_DIR} +) + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(TIFF DEFAULT_MSG + TIFF_INCLUDE_DIR TIFF_LIBRARIES) + +MARK_AS_ADVANCED(TIFF_INCLUDE_DIR TIFF_LIBRARIES) + Modified: autopano-sift-C/trunk/CMakeModules/FindZLIB.cmake =================================================================== --- autopano-sift-C/trunk/CMakeModules/FindZLIB.cmake 2008-01-29 11:44:14 UTC (rev 2728) +++ autopano-sift-C/trunk/CMakeModules/FindZLIB.cmake 2008-01-29 11:49:27 UTC (rev 2729) @@ -1,45 +1,45 @@ -# - Find zlib -# Find the native ZLIB includes and library -# -# ZLIB_INCLUDE_DIR - where to find zlib.h, etc. -# ZLIB_LIBRARIES - List of libraries when using zlib. -# ZLIB_FOUND - True if zlib found. - -# - Find TIFF for Hugin 0.7 01Nov2007 TKSharpless -# Added to support Windows build but should work anywhere. -# After looking in UNIX standard places, tries wxWidgets build -# tree, which should have this package. -# -# reads cache variables -# wxWidgets_ROOT_DIR -# wxWidgets_LIB_DIR -# - -IF (ZLIB_INCLUDE_DIR) - # Already in cache, be silent - SET(ZLIB_FIND_QUIETLY TRUE) -ENDIF (ZLIB_INCLUDE_DIR) - -FIND_PATH(ZLIB_INCLUDE_DIR zlib.h - /usr/local/include - /usr/include - ${wxWidgets_ROOT_DIR}/src/zlib -) - -include(FindLibraryWithDebug) - -find_library_with_debug(ZLIB_LIBRARIES - WIN32_DEBUG_POSTFIX d - NAMES z zlib wxzlib - PATHS /usr/lib /usr/local/lib ${wxWidgets_LIB_DIR} -) - - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(ZLIB DEFAULT_MSG - ZLIB_INCLUDE_DIR ZLIB_LIBRARIES) - -MARK_AS_ADVANCED( - ZLIB_LIBRARIES - ZLIB_INCLUDE_DIR - ) +# - Find zlib +# Find the native ZLIB includes and library +# +# ZLIB_INCLUDE_DIR - where to find zlib.h, etc. +# ZLIB_LIBRARIES - List of libraries when using zlib. +# ZLIB_FOUND - True if zlib found. + +# - Find TIFF for Hugin 0.7 01Nov2007 TKSharpless +# Added to support Windows build but should work anywhere. +# After looking in UNIX standard places, tries wxWidgets build +# tree, which should have this package. +# +# reads cache variables +# wxWidgets_ROOT_DIR +# wxWidgets_LIB_DIR +# + +IF (ZLIB_INCLUDE_DIR) + # Already in cache, be silent + SET(ZLIB_FIND_QUIETLY TRUE) +ENDIF (ZLIB_INCLUDE_DIR) + +FIND_PATH(ZLIB_INCLUDE_DIR zlib.h + /usr/local/include + /usr/include + ${wxWidgets_ROOT_DIR}/src/zlib +) + +include(FindLibraryWithDebug) + +find_library_with_debug(ZLIB_LIBRARIES + WIN32_DEBUG_POSTFIX d + NAMES z zlib wxzlib + PATHS /usr/lib /usr/local/lib ${wxWidgets_LIB_DIR} +) + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(ZLIB DEFAULT_MSG + ZLIB_INCLUDE_DIR ZLIB_LIBRARIES) + +MARK_AS_ADVANCED( + ZLIB_LIBRARIES + ZLIB_INCLUDE_DIR + ) Modified: autopano-sift-C/trunk/config.h.in.cmake =================================================================== --- autopano-sift-C/trunk/config.h.in.cmake 2008-01-29 11:44:14 UTC (rev 2728) +++ autopano-sift-C/trunk/config.h.in.cmake 2008-01-29 11:49:27 UTC (rev 2729) @@ -1,21 +1,21 @@ - -#ifndef APSIFT_CONFIG_H -#define APSIFT_CONFIG_H - -#define VERSION_MAJOR ${V_MAJOR} -#define VERSION_MINOR ${V_MINOR} -#define VERSION_PATCH ${V_PATCH} - -#define PACKAGE_VERSION "${PACKAGE_VERSION}" - -/* Define if PANO13 should be used */ -#cmakedefine PANO13_FOUND 1 - -#if defined PANO13_FOUND -#define HAS_PANO13 1 -#elif defined PANO12_FOUND -#define HAS_PANO12 1 -#endif - -#endif // APSIFT_CONFIG_H - + +#ifndef APSIFT_CONFIG_H +#define APSIFT_CONFIG_H + +#define VERSION_MAJOR ${V_MAJOR} +#define VERSION_MINOR ${V_MINOR} +#define VERSION_PATCH ${V_PATCH} + +#define PACKAGE_VERSION "${PACKAGE_VERSION}" + +/* Define if PANO13 should be used */ +#cmakedefine PANO13_FOUND 1 + +#if defined PANO13_FOUND +#define HAS_PANO13 1 +#elif defined PANO12_FOUND +#define HAS_PANO12 1 +#endif + +#endif // APSIFT_CONFIG_H + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <da...@us...> - 2008-02-01 16:44:57
|
Revision: 2759 http://hugin.svn.sourceforge.net/hugin/?rev=2759&view=rev Author: dangelo Date: 2008-02-01 08:44:55 -0800 (Fri, 01 Feb 2008) Log Message: ----------- Corrected possible crash when many images are used. Modified Paths: -------------- autopano-sift-C/trunk/ChangeLog autopano-sift-C/trunk/MatchKeys.c Modified: autopano-sift-C/trunk/ChangeLog =================================================================== --- autopano-sift-C/trunk/ChangeLog 2008-02-01 10:25:58 UTC (rev 2758) +++ autopano-sift-C/trunk/ChangeLog 2008-02-01 16:44:55 UTC (rev 2759) @@ -1,3 +1,8 @@ +2008-02-01 Pablo d'Angelo + + * MatchKeys.c: Corrected possible buffer overflow when many images + are used. + 2008-01-14 Pablo d'Angelo * CMakeLists.txt, CMakeModules: Added CMake based build system, only Modified: autopano-sift-C/trunk/MatchKeys.c =================================================================== --- autopano-sift-C/trunk/MatchKeys.c 2008-02-01 10:25:58 UTC (rev 2758) +++ autopano-sift-C/trunk/MatchKeys.c 2008-02-01 16:44:55 UTC (rev 2759) @@ -948,23 +948,35 @@ char* Component_ToString (Component* self) { - char buffer[1024]=""; + char *buffer; bool first = true; int cCount = 0; int i; + int buflen=256; + buffer = (char *) malloc(buflen); + for(i=0; i<ArrayList_Count(self->files); i++) { char* filename = (char*) ArrayList_GetItem(self->files, i); if (first) { first = false; } else { + if (strlen(buffer) + 2 + 1< buflen) { + buflen += buflen; + buffer = (char*) realloc(buffer, buflen); + } strcat(buffer, ", "); cCount += 2; } char* justFile = FullPathToFileName(filename); - strcat(buffer, justFile); + if (strlen(buffer) + strlen(justFile) + 1 < buflen -1) { + if (buflen + 1 < strlen(justFile) ) buflen += strlen(justFile) + 1; + else buflen += buflen; + buffer = (char*) realloc(buffer, buflen); + } + strcat(buffer, justFile); cCount += strlen(justFile); free(justFile); @@ -975,7 +987,7 @@ } } - return strdup(buffer); + return buffer; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <se...@us...> - 2008-02-02 17:09:30
|
Revision: 2768 http://hugin.svn.sourceforge.net/hugin/?rev=2768&view=rev Author: sebpz Date: 2008-02-02 09:09:26 -0800 (Sat, 02 Feb 2008) Log Message: ----------- Create gzip compressed key files Modified Paths: -------------- autopano-sift-C/trunk/Makefile autopano-sift-C/trunk/autopano-c-complete.sh Modified: autopano-sift-C/trunk/Makefile =================================================================== --- autopano-sift-C/trunk/Makefile 2008-02-02 16:42:11 UTC (rev 2767) +++ autopano-sift-C/trunk/Makefile 2008-02-02 17:09:26 UTC (rev 2768) @@ -10,6 +10,7 @@ CC=gcc ifndef CFLAGS CFLAGS=-Wall -O2 +#CFLAGS=-Wall -g -O0 endif CFLAGS+= -I/usr/include/libxml2 -DHAS_PANO13 LDFLAGS= -L. Modified: autopano-sift-C/trunk/autopano-c-complete.sh =================================================================== --- autopano-sift-C/trunk/autopano-c-complete.sh 2008-02-02 16:42:11 UTC (rev 2767) +++ autopano-sift-C/trunk/autopano-c-complete.sh 2008-02-02 17:09:26 UTC (rev 2768) @@ -76,7 +76,7 @@ KEYFILES="" for arg do - FILENAME=$(basename "$arg").key + FILENAME=$(basename "$arg").key.gz KEYFILES="$KEYFILES $FILENAME" if [ -f $FILENAME ]; then if [ $CLEAN -ne 0 ]; then This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <se...@us...> - 2008-02-02 17:31:43
|
Revision: 2769 http://hugin.svn.sourceforge.net/hugin/?rev=2769&view=rev Author: sebpz Date: 2008-02-02 09:31:39 -0800 (Sat, 02 Feb 2008) Log Message: ----------- Reverting previous change - gzip not supported by autopano Modified Paths: -------------- autopano-sift-C/trunk/Makefile autopano-sift-C/trunk/autopano-c-complete.sh Modified: autopano-sift-C/trunk/Makefile =================================================================== --- autopano-sift-C/trunk/Makefile 2008-02-02 17:09:26 UTC (rev 2768) +++ autopano-sift-C/trunk/Makefile 2008-02-02 17:31:39 UTC (rev 2769) @@ -10,7 +10,6 @@ CC=gcc ifndef CFLAGS CFLAGS=-Wall -O2 -#CFLAGS=-Wall -g -O0 endif CFLAGS+= -I/usr/include/libxml2 -DHAS_PANO13 LDFLAGS= -L. Modified: autopano-sift-C/trunk/autopano-c-complete.sh =================================================================== --- autopano-sift-C/trunk/autopano-c-complete.sh 2008-02-02 17:09:26 UTC (rev 2768) +++ autopano-sift-C/trunk/autopano-c-complete.sh 2008-02-02 17:31:39 UTC (rev 2769) @@ -76,7 +76,7 @@ KEYFILES="" for arg do - FILENAME=$(basename "$arg").key.gz + FILENAME=$(basename "$arg").key KEYFILES="$KEYFILES $FILENAME" if [ -f $FILENAME ]; then if [ $CLEAN -ne 0 ]; then This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <se...@us...> - 2008-02-02 19:51:00
|
Revision: 2770 http://hugin.svn.sourceforge.net/hugin/?rev=2770&view=rev Author: sebpz Date: 2008-02-02 11:50:57 -0800 (Sat, 02 Feb 2008) Log Message: ----------- Adding gz output for keyfiles Modified Paths: -------------- autopano-sift-C/trunk/KeypointXML.c autopano-sift-C/trunk/MatchKeys.c autopano-sift-C/trunk/autopano-c-complete.sh Modified: autopano-sift-C/trunk/KeypointXML.c =================================================================== --- autopano-sift-C/trunk/KeypointXML.c 2008-02-02 17:31:39 UTC (rev 2769) +++ autopano-sift-C/trunk/KeypointXML.c 2008-02-02 19:50:57 UTC (rev 2770) @@ -45,8 +45,6 @@ { xmlTextReaderPtr reader; reader = xmlReaderForFile(filename, NULL, 0); - if (compressed) - FatalError("compressed keypoint files not suported"); KeypointXMLList* kl = NULL; Modified: autopano-sift-C/trunk/MatchKeys.c =================================================================== --- autopano-sift-C/trunk/MatchKeys.c 2008-02-02 17:31:39 UTC (rev 2769) +++ autopano-sift-C/trunk/MatchKeys.c 2008-02-02 19:50:57 UTC (rev 2770) @@ -956,6 +956,7 @@ int buflen=256; buffer = (char *) malloc(buflen); + strcpy(buffer,""); for(i=0; i<ArrayList_Count(self->files); i++) { char* filename = (char*) ArrayList_GetItem(self->files, i); Modified: autopano-sift-C/trunk/autopano-c-complete.sh =================================================================== --- autopano-sift-C/trunk/autopano-c-complete.sh 2008-02-02 17:31:39 UTC (rev 2769) +++ autopano-sift-C/trunk/autopano-c-complete.sh 2008-02-02 19:50:57 UTC (rev 2770) @@ -76,7 +76,7 @@ KEYFILES="" for arg do - FILENAME=$(basename "$arg").key + FILENAME=$(basename "$arg").key.gz KEYFILES="$KEYFILES $FILENAME" if [ -f $FILENAME ]; then if [ $CLEAN -ne 0 ]; then This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tks...@us...> - 2008-02-07 01:44:08
|
Revision: 2799 http://hugin.svn.sourceforge.net/hugin/?rev=2799&view=rev Author: tksharpless Date: 2008-02-06 17:44:05 -0800 (Wed, 06 Feb 2008) Log Message: ----------- Add APSC, which combines generatekeys and autopano in one executable. fflush stdout writes in utils.c Modified Paths: -------------- autopano-sift-C/trunk/CMakeLists.txt autopano-sift-C/trunk/Utils.c Added Paths: ----------- autopano-sift-C/trunk/APSCmain.c Added: autopano-sift-C/trunk/APSCmain.c =================================================================== --- autopano-sift-C/trunk/APSCmain.c (rev 0) +++ autopano-sift-C/trunk/APSCmain.c 2008-02-07 01:44:05 UTC (rev 2799) @@ -0,0 +1,763 @@ + +/* 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'."); + 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 = 0; + + // 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] == '-') + { + char* optionStr = argv[optionN]; + + if (optionStr[1] != '-') { + Usage (); + exit (1); + } + + 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 ("Usage error. Run \"autopano.exe\" without arguments for help."); + exit (1); + } + } + optionCount = optionN; + + if (bottomDefault != -1 && preAlign == false) { + WriteLine ("Please enable automatic alignment (\"--align\") before using the"); + WriteLine ("--bottom-is-* options. Thank you. Run \"autopano.exe\" without"); + WriteLine ("arguments for usage help."); + + exit (1); + } + + if (generateHorizon > 0 && preAlign == false) { + WriteLine ("Please enable automatic alignment (\"--align\") before using the"); + WriteLine ("--generate-horizon option. Thank you. Run \"autopano.exe\" without"); + WriteLine ("arguments for usage 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 (argv[optionCount] == "-") { + 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 (argv[optionCount] != "-") + fclose(pto); + return 0; +} + Modified: autopano-sift-C/trunk/CMakeLists.txt =================================================================== --- autopano-sift-C/trunk/CMakeLists.txt 2008-02-06 22:39:58 UTC (rev 2798) +++ autopano-sift-C/trunk/CMakeLists.txt 2008-02-07 01:44:05 UTC (rev 2799) @@ -121,7 +121,11 @@ add_executable(autopano AutoPano.c) TARGET_LINK_LIBRARIES(autopano ${all_libs}) +add_executable(APSC APSCmain.c) +TARGET_LINK_LIBRARIES(APSC ${all_libs}) + install(TARGETS generatekeys autopano DESTINATION bin) +install(TARGETS APSC DESTINATION bin) if (WIN32) install(PROGRAMS autopano-c-complete.vbs DESTINATION bin) else (WIN32) Modified: autopano-sift-C/trunk/Utils.c =================================================================== --- autopano-sift-C/trunk/Utils.c 2008-02-06 22:39:58 UTC (rev 2798) +++ autopano-sift-C/trunk/Utils.c 2008-02-07 01:44:05 UTC (rev 2799) @@ -35,6 +35,7 @@ vprintf(fmt, ap); va_end(ap); printf("\n"); + fflush(stdout); } void WriteError(char* fmt, ...) { @@ -44,6 +45,7 @@ vfprintf(stderr, fmt, ap); va_end(ap); fprintf(stderr, "\n"); + fflush(stderr); } void FatalError(char* fmt, ...) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tks...@us...> - 2008-02-07 16:02:05
|
Revision: 2800 http://hugin.svn.sourceforge.net/hugin/?rev=2800&view=rev Author: tksharpless Date: 2008-02-07 08:02:03 -0800 (Thu, 07 Feb 2008) Log Message: ----------- Made the "-" option work. Anyone who uses it must donate 1 Euro to the hugin project :) Modified Paths: -------------- autopano-sift-C/trunk/APSCmain.c autopano-sift-C/trunk/AutoPano.c Modified: autopano-sift-C/trunk/APSCmain.c =================================================================== --- autopano-sift-C/trunk/APSCmain.c 2008-02-07 01:44:05 UTC (rev 2799) +++ autopano-sift-C/trunk/APSCmain.c 2008-02-07 16:02:03 UTC (rev 2800) @@ -568,6 +568,9 @@ // downscale option for GenerteKeys int mindim = 0; + // output to stdout flag + bool streamout = false; + // Automatic pre-aligning of images bool preAlign = false; int bottomDefault = -1; @@ -597,15 +600,12 @@ int optionCount = 0; int optionN = 1; while (optionN < argc && - strlen(argv[optionN]) >= 2 && argv[optionN][0] == '-') + strlen(argv[optionN]) >= 2 + && argv[optionN][0] == '-' + && argv[optionN][1] == '-') { char* optionStr = argv[optionN]; - if (optionStr[1] != '-') { - Usage (); - exit (1); - } - if (strcmp (optionStr, "--maxdim") == 0) { mindim = atoi(argv[optionN + 1]); optionN += 2; @@ -664,24 +664,37 @@ keepUnrefinable = YesNoOption ("--keep-unrefinable", argv[optionN + 1]); optionN += 2; } else { - WriteLine ("Usage error. Run \"autopano.exe\" without arguments for help."); + 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. Thank you. Run \"autopano.exe\" without"); - WriteLine ("arguments for usage help."); + 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. Thank you. Run \"autopano.exe\" without"); - WriteLine ("arguments for usage help."); + WriteLine ("--generate-horizon option. Run without arguments for help."); exit (1); } @@ -743,7 +756,7 @@ } FILE* pto; - if (argv[optionCount] == "-") { + if ( streamout ) { pto = stdout; } else { WriteLine ("Creating output file \"%s\"", argv[optionCount]); @@ -756,7 +769,7 @@ ArrayList_delete(components); BondBall_delete(bb); MultiMatch_delete(mm); - if (argv[optionCount] != "-") + if ( !streamout ) fclose(pto); return 0; } Modified: autopano-sift-C/trunk/AutoPano.c =================================================================== --- autopano-sift-C/trunk/AutoPano.c 2008-02-07 01:44:05 UTC (rev 2799) +++ autopano-sift-C/trunk/AutoPano.c 2008-02-07 16:02:03 UTC (rev 2800) @@ -517,6 +517,9 @@ exit (1); } + // output to stdout flag + bool streamout = false; + // Automatic pre-aligning of images bool preAlign = false; int bottomDefault = -1; @@ -546,15 +549,12 @@ int optionCount = 0; int optionN = 1; while (optionN < argc && - strlen(argv[optionN]) >= 2 && argv[optionN][0] == '-') + strlen(argv[optionN]) >= 2 + && argv[optionN][0] == '-' + && argv[optionN][1] == '-') { char* optionStr = argv[optionN]; - if (optionStr[1] != '-') { - Usage (); - exit (1); - } - if (strcmp (optionStr, "--ransac") == 0) { useRansac = YesNoOption ("--ransac", argv[optionN + 1]); optionN += 2; @@ -615,7 +615,22 @@ } } 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. Thank you. Run \"autopano.exe\" without"); @@ -688,7 +703,7 @@ } FILE* pto; - if (argv[optionCount] == "-") { + if ( streamout ) { pto = stdout; } else { WriteLine ("Creating output file \"%s\"", argv[optionCount]); @@ -702,7 +717,7 @@ ArrayList_delete(components); BondBall_delete(bb); MultiMatch_delete(mm); - if (argv[optionCount] != "-") + if ( !streamout ) fclose(pto); return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <da...@us...> - 2008-02-17 23:33:03
|
Revision: 2881 http://hugin.svn.sourceforge.net/hugin/?rev=2881&view=rev Author: dangelo Date: 2008-02-17 15:33:01 -0800 (Sun, 17 Feb 2008) Log Message: ----------- #define HAVE_MALLOC on OSX, it seems to fix an out of memory situation due to the use of realloc. Modified Paths: -------------- autopano-sift-C/trunk/CMakeLists.txt autopano-sift-C/trunk/config.h.in.cmake Modified: autopano-sift-C/trunk/CMakeLists.txt =================================================================== --- autopano-sift-C/trunk/CMakeLists.txt 2008-02-17 23:05:37 UTC (rev 2880) +++ autopano-sift-C/trunk/CMakeLists.txt 2008-02-17 23:33:01 UTC (rev 2881) @@ -70,6 +70,10 @@ ADD_DEFINITIONS(-DHAS_PANO13) ENDIF(UNIX) +IF(APPLE) + SET(HAVE_MALLOC 1) +ENDIF(APPLE) + # Setup MSVC IF (MSVC) # Stop MSVC8 from bitching about the C library @@ -127,7 +131,6 @@ install(TARGETS generatekeys autopano DESTINATION bin) install(TARGETS autopano-sift-c DESTINATION bin) if (WIN32) - install(PROGRAMS autopano-c-complete.vbs DESTINATION bin) else (WIN32) install(PROGRAMS autopano-c-complete.sh DESTINATION bin) endif (WIN32) Modified: autopano-sift-C/trunk/config.h.in.cmake =================================================================== --- autopano-sift-C/trunk/config.h.in.cmake 2008-02-17 23:05:37 UTC (rev 2880) +++ autopano-sift-C/trunk/config.h.in.cmake 2008-02-17 23:33:01 UTC (rev 2881) @@ -16,6 +16,8 @@ #elif defined PANO12_FOUND #define HAS_PANO12 1 #endif + +#cmakedefine HAVE_MALLOC #endif // APSIFT_CONFIG_H This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tks...@us...> - 2008-03-01 02:58:46
|
Revision: 2914 http://hugin.svn.sourceforge.net/hugin/?rev=2914&view=rev Author: tksharpless Date: 2008-02-29 18:58:39 -0800 (Fri, 29 Feb 2008) Log Message: ----------- 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. Modified Paths: -------------- autopano-sift-C/trunk/AutoPanoSift.h autopano-sift-C/trunk/CMakeLists.txt autopano-sift-C/trunk/DisplayImage.c autopano-sift-C/trunk/ImageMap.c autopano-sift-C/trunk/LoweDetector.c autopano-sift-C/trunk/ScaleSpace.c autopano-sift-C/trunk/Utils.c Added Paths: ----------- autopano-sift-C/trunk/APSCpp/ 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/HermiteSpline.c autopano-sift-C/trunk/APSCpp/HermiteSpline.h autopano-sift-C/trunk/APSCpp/README-autopano-sift-c.txt autopano-sift-C/trunk/APSCpp/cmakelists.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 Added: autopano-sift-C/trunk/APSCpp/APSCpp.c =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp.c (rev 0) +++ autopano-sift-C/trunk/APSCpp/APSCpp.c 2008-03-01 02:58:39 UTC (rev 2914) @@ -0,0 +1,448 @@ +/* APSCpp.c 15 Feb 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 ); +} + + + +// set up remapping once basic info is read +// Scale > 0 is the ratio of source to destination dimensions +// returns 1 OK, 0 fail +saRemap * DIinfo_setRm( pDIinfo p, double Scale ){ + CamLens * pcs, * pcd; + saRemap * prm; + int destwid, desthgt; + if( p->width < 1 || p->height < 1 ) return 0; + // destination dimensions + destwid = (int)(0.5 + p->width / Scale); + desthgt = (int)(0.5 + p->height / Scale); + // projection descriptors + pcs = CamLens_new1( p->width, p->height, p->format, p->hfov, 16.0 ); + pcd = CamLens_new1( destwid, desthgt, _stereographic, p->hfov, 0 ); + // remapping functions + prm = saRemap_new( pcs, pcd ); + + free( pcs ); free( pcd ); + + return prm; + +} + + +/* + 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_VAR( "%s", p ); + // strip quotes + if( *p == '"' ){ + while( p[1] != '"' ){ + p[0] = p[1]; + ++p; + } + *p = 0; + } + } + break; + default: + break; + } + while( *li > ' ' ){ // skip next "word" + if( *li == '"' ) do ++li; while( *li != '"' ); // quoted strings + ++li; + } + if(*li) li++; // skip one nonnull + + } // EOL + + // add this image to list + numIm++; + ArrayList_AddItem( DIlist, im ); + + } // end of line + } // end of file + + fclose( fp ); + + if( numIm > 0 || keychar == 'o' ) break; + keychar = 'o'; // try again... + } + + + return numIm; + +} + +/* Dump an ImagMap to a tiff file + return success or failure +*/ +int ImageMap_toTIFF( ImageMap * p, char * name ) +{ + int i, ok; + +// create tiff file + TIFF * tp = TIFFOpen( name, "w" ); + if( !tp ) return 0; + +// set tiff tags + TIFFSetField( tp, TIFFTAG_IMAGEWIDTH, p->yDim ); + TIFFSetField( tp, TIFFTAG_IMAGELENGTH, p->xDim ); + TIFFSetField( tp, TIFFTAG_PLANARCONFIG, 1 ); // packed pixels + TIFFSetField( tp, TIFFTAG_ROWSPERSTRIP, 1 ); // separate rows + TIFFSetField( tp, TIFFTAG_COMPRESSION, 1 ); // uncompressed + TIFFSetField( tp, TIFFTAG_SAMPLESPERPIXEL, 1 ); // monochrome + TIFFSetField( tp, TIFFTAG_PHOTOMETRIC, 1 ); // greyscale + TIFFSetField( tp, TIFFTAG_BITSPERSAMPLE, 32 ); + TIFFSetField( tp, TIFFTAG_SAMPLEFORMAT, 3 ); // IEEE float + +// write the data rowwise + for( i = 0; i < p->xDim; i++ ){ + if((ok = TIFFWriteScanline( tp, p->values[i], i, 0 )) != 1 ) break; + } + +// done + TIFFClose( tp ); + return ok; + +} + +/* subroutine equivalent to GenerateKeys.c + + for APSC++, new argumnent pdi -> DIinfo struct with the input + projection format and angular width into needed to set up a + remapping to stereographic format. If pdi is 0, behaves like + GenerateKeys() with these exceptions. + + 1) it sets the Lowe routine's prefilter sigma to 0.5 if the image stays + at original size, or to 0 (no further smoothing) if it is reduced here. + + 2) it always reduces image size (when maxdim < largest input dimension) + by a smooth interpolation rather than simple decimation. + + 3) it never invokes the Lowe detector's option to expand the image 2x. + + + returns 0 for failure + +*/ + +KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, DIinfo * pdi ) +{ +#ifdef _DEBUG_INTERP + char tmp[262]; +#endif + int nKeys; + int pW, pH; + double Xcen, Ycen; + saRemap *prm = 0; + ImageMap* picMap = 0; + LoweFeatureDetector* lf; + KeypointXMLList* kpp; + + double Scale = 1.0; + + +// reduce Lowe prefilter smoothing + double savesigma = LoweFeatureDetector_SetPreprocSigma( 0.5 ); + +/* read the image */ + + DisplayImage* pic = DisplayImage_new(imgname); + // (if we get here the image was read OK, and its name printed) + if(!pdi) { + 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 ); + // put actual image dimensions in the DIinfo, just in case... + pdi->width = pic->width; pdi->height = pic->height; + } + + pW = pic->width; + pH = pic->height; + Xcen = 0.5 * pW; + Ycen = 0.5 * pH; + + +// convert to monochrome float and discard input image + picMap = DisplayImage_ConvertToImageMap( pic ); + DisplayImage_delete(pic); + +#ifdef _DEBUG_INTERP + strcpy(tmp, imgname); + strcat(tmp,"-MAP.TIF"); + ImageMap_toTIFF( picMap, tmp ); +#endif + +/* reduce size if required + by interpolating in smoothed map + also convert to stereographic if pdi is valid +*/ + // prescale factor + if( maxdim > 0) Scale = max( pW, pH ) / (double) maxdim; + if( Scale <= 1 ) Scale = 1; + + // interpolate if necessary + if( pdi || Scale > 1 ){ + ImageMap * pn; + int x, y; + double X, Y; + 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 ); + } + // create result map + pn = ImageMap_new( dwid, dhgt ); + // smooth the source + ImageMap_GaussianConvolution( picMap, 0.75 * Scale ); + LoweFeatureDetector_SetPreprocSigma( 0 ); + // set up coordinate mapping + if( pdi ){ // ++ mode + 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 ); + // create the mapping + prm = saRemap_new( psp, pdp ); + saRemap_inv ( prm, 0.5 * dwid, 0.5 * dhgt, &Xcen, &Ycen ); + WriteLine(" use stereographic projection"); + } + // interpolate + saInterpSetup((void *)picMap->values, // void * pdata + 2, // format is column vectors + picMap->xDim, // int wid, + picMap->yDim, // int hgt, + 1, // samples per pixel + picMap->xDim, // pixels per row + 0, // char wrap, // required + 0, // char * pmask, + 0, 0, 0 // mask params + ); + for( x = 0; x < pn->xDim; x++ ){ + float * pd = pn->values[x]; + 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 + saInterp_float( &(pd[y]), X, Y ); + } + } + // swap + ImageMap_delete( picMap ); + picMap = pn; + saRemap_delete( prm ); prm = 0; +#ifdef _DEBUG_INTERP + strcpy(tmp, imgname); + strcat(tmp,"-MAP-PROJ.TIF"); + ImageMap_toTIFF( picMap, tmp ); + WriteLine("ImageMap dumped to %s", tmp ); + exit(0); +#endif + } + + +/* find the features +*/ + + lf = LoweFeatureDetector_new0(); + nKeys = LoweFeatureDetector_DetectFeaturesDownscaled (lf, picMap, 0, Scale); + WriteLine(" %d keypoints found\n", nKeys ); + + /* 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; + + 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 ); + prm = saRemap_new( psp, pdp ); // dest=>src + } 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 + ); + } + ArrayList_AddItem ( globalNaturalKeypoints, KeypointN_new( kp )); + } + // package result as a KeypointXMLList + kpp = KeypointXMLList_new ( imgname, pW, pH, globalNaturalKeypoints ); + } + + LoweFeatureDetector_delete(lf); + + // restore the default Lowe prefilter + LoweFeatureDetector_SetPreprocSigma( savesigma ); + // disable the patent warning message (for any subsequent images) + LoweFeatureDetector_SetPrintWarning(false); + + return kpp; +} + + Added: autopano-sift-C/trunk/APSCpp/APSCpp_main.c =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp_main.c (rev 0) +++ autopano-sift-C/trunk/APSCpp/APSCpp_main.c 2008-03-01 02:58:39 UTC (rev 2914) @@ -0,0 +1,878 @@ + +/* APSCpp_main.c 18 Feb2008 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. + + * 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). +*/ +/* + * 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" + +// APSCpp.c +int LoadProjectImages( char* script, ArrayList * DIlist ); +KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, DIinfo * pdi ); + +void Usage () +{ + WriteLine ("APSCpp: Generate and Match Keypoints giving Hugin project file\n"); + WriteLine (" Version %s\n", PACKAGE_VERSION); + WriteLine ("usage: APSCpp.exe [options] output.pto image1 image2 [..]"); + WriteLine (" or: APSCpp.exe [options] output.pto projectfile"); + WriteLine (" projectfile is a PT compatible script giving image"); + WriteLine (" file names, projections and angular widths. Enables"); + WriteLine (" reprojection to stereographic format.\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 <n> Reduce image size so that largest dimension <= n."); + WriteLine (" --projection <n>,<d> n = PT format code, d = hfov in degrees. These"); + WriteLine (" apply to all images, reprojection is enabled."); + 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 (""); +} + + +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; +} + +/* mods for APSCpp + new arg DIlist gets * the image info list (++mode) or == 0 (legacy mode) + if ++ mode, copies this info to the output 'i' lines + +*/ +void WritePTOFile (FILE* pto, MultiMatch* mm, + ArrayList* msList, ArrayList * DIlist, + BondBall* bb, int generateHorizon, bool integerCoordinates, + bool useAbsolutePathnames) +{ + DIinfo * pdi = 0; + char buffer[262]; + + fprintf(pto, "# Hugin project file generated by APSCpp\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; + // get corresponding DIlist record + if( DIlist ){ + for( i = 0; i < ArrayList_Count( DIlist ); i++ ){ + pdi = (pDIinfo)ArrayList_GetItem( DIlist, i ); + if( !strcmp( pdi->name, imageFile ) ) break; + } + if( i >= ArrayList_Count( DIlist ) ) + pdi = 0; // NOT FOUND!! + } + + // 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, hfov = 180.0; + int format = 0; + if (pos != NULL) { + yaw = pos->yaw; + pitch = pos->pitch; + rotation = pos->rotation; + } else if( pdi ){ + yaw = pdi->yaw; + pitch = pdi->pitch; + rotation = pdi->roll; + format = pdi->format; + hfov = pdi->hfov; + } + + 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); + } 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); + } + fprintf( pto, "%s\n", buffer ); +//// WriteLine("%s", buffer ); + imageIndex += 1; + } + + fprintf(pto, "\nv p1 r1 y1\n\n"); + + fprintf(pto, "# automatically generated control points\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."); + if( DIlist == 0 ){ + WriteLine ("Notice: guessed image format and field-of-view, please check and adjust."); + } + + ArrayList_delete(resolutions); + HashTable_delete(imageNameTab); +} + + +int main (int argc, char* argv[]) +{ + // 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 + double globFov = 0; // width in degrees + int Nerr = 0; // counts commandline errors + + // downscale option = largest allowed image dimension + int maxdim = 0; + + // 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 = 25; // default + + // Refinement options + bool refine = false; + bool refineMiddle = true; + bool keepUnrefinable = true; + + int optionCount = 0; + int optionN = 1; + int i; + + WriteLine ("\nAPSCpp, enhanced Autopano-sift-c"); + + LoweFeatureDetector_SetVerbose(false); // default low chatter + + if (argc+1 < 3) { // can't be legal commandline + Usage (); + exit (1); + } + + while (optionN < argc && + strlen(argv[optionN]) >= 2 + && argv[optionN][0] == '-' + && argv[optionN][1] == '-') + { + char* optionStr = argv[optionN]; + + if (strcmp (optionStr, "--maxdim") == 0) { + maxdim = atoi(argv[optionN + 1]); + optionN += 2; + } else if( strcmp (optionStr, "--projection") == 0) { + char *p = argv[optionN + 1]; + if(sscanf( p, "%d", &globFmt ) != 1 ){ + WriteLine ("Parameter to projection option invalid. See the usage help."); + ++Nerr; + } + p = strchr(p,','); + if( p ) globFov = atof(p+1); + else { + WriteLine ("Parameter to projection option invalid. See the usage help."); + ++Nerr; + } + + 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."); + ++Nerr; + } + if (maxMatches < 0) { + WriteLine ("Maximum number of matches must be positive or zero (unlimited)."); + ++Nerr; + } + 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."); + ++Nerr; + } + if (generateHorizon < 0) { + WriteLine ("The number of horizon lines to generate must be positive."); + ++Nerr; + } + + 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."); + ++Nerr; + } + } + 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 more name required."); + ++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 ); + 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 ("Misplaced option '%s'.\n", argv[optionCount] ); + Usage(); + exit (1); + } + } + /* next arg is either a script name or the first of 2 or more image file names + */ + if( argc - optionCount == 2 ){ + projectfile = argv[optionCount + 1]; + WriteLine("Reading project file %s", projectfile ); + // enable ++ mode by creating DIlist + DIlist = ArrayList_new0( DIinfo_delete ); + // read the proect file image info into DIlist, or die + if( LoadProjectImages( argv[optionCount + 1], DIlist ) ==0 ){ + WriteLine ("Error reading project file."); + exit(1); + } + } else if( globFmt >= 0 && globFov > 0 ){ + // enable ++ mode + DIlist = ArrayList_new0( DIinfo_delete ); + } + + if( DIlist ) WriteLine(" Stereographic projection enabled."); + + + MultiMatch* mm = MultiMatch_new0 (); + +/** Find keypoints **/ + + + ArrayList* keylists = ArrayList_new0(NULL); + + if( DIlist ){ + // ++ mode: image info from DIlist + pDIinfo pd; + // build it first if only a global projection was given + if( globFmt >= 0 ){ + for( i=0; i<argc - 1 - optionCount; i++) { + pd = DIinfo_new0(); + pd->format = globFmt; + pd->hfov = globFov; + strcpy(pd->name, argv[i+optionCount+1] ); + // note dimensions are still zero + ArrayList_AddItem( DIlist, pd ); + } + } + // 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) ); + } + } 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) ); + } + } + +/** Find control points **/ + + 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]); + if( DIlist ){ + WriteLine ("with image info from \"%s\"", projectfile); + } + pto = fopen(argv[optionCount], "w"); + } + + WritePTOFile (pto, mm, msList, DIlist, + bb, generateHorizon, useIntegerCoordinates, + useAbsolutePathnames); + + ArrayList_delete(components); + BondBall_delete(bb); + MultiMatch_delete(mm); + if ( !streamout ) + fclose(pto); + + + return 0; +} + Added: autopano-sift-C/trunk/APSCpp/CamLens.c =================================================================== --- autopano-sift-C/trunk/APSCpp/CamLens.c (rev 0) +++ autopano-sift-C/trunk/APSCpp/CamLens.c 2008-03-01 02:58:39 UTC (rev 2914) @@ -0,0 +1,252 @@ +/* CamLens.c 20 Feb 2008 TKS + + implementaton of CamLens class + +*/ +/* + * 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 "sphereAlign.h" +#include <stdlib.h> +#include <memory.h> +#include <math.h> + +/* radius <=> angle functions for lens projections + R is noramlized image radius + K is an adjustable parameter + A is angle in radians + NOTE no error checks, pass only reasonable values! + |A| |R| + rect <Pi/2 any + fish any <= K + mirr any <= 2 + ster <Pi any +*/ + +static double r2a_rect( double R, double K ){ + return atan( R ); +} + +static double a2r_rect( double A, double K ){ + return tan( A ); +} + +static double r2a_fish( double R, double K ){ + return K * asin( R / K ); +} + +static double a2r_fish( double A, double K ){ + return K * sin( A / K ); +} + +static double r2a_mirr( double R, double K ){ + return asin( 0.5 * R ); +} + +static double a2r_mirr( double A, double K ){ + return sin( 0.5 * A ); +} + + +static double r2a_ster( double R, double K ){ + return 2 * atan( R ); +} + +static double a2r_ster( double A, double K ){ + return tan(0.5 * A); +} + + + +// create empty +pCamLens CamLens_new0() +{ + pCamLens p = (pCamLens) malloc(sizeof(CamLens)); + if( p ) memset(p, 0, sizeof(CamLens)); + return p; +} + +/* 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 + flmm should be 0 for an ideal projection, >0 for a real lens + other assumptions see CamLens_setProjection() + +*/ +pCamLens CamLens_new1( int wid, int hgt, int fmt, double hfov, double flmm ) +{ + pCamLens p; + double R, x, y; + + if( fmt < _rectilinear || fmt > _stereographic ) return 0; + p = CamLens_new0(); + p->FLmm = flmm; + if( CamLens_setProjection( p, fmt )){ + + p->widpix = wid; + p->hgtpix = hgt; + p->FLmm = flmm; + + // 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; + + // default crop radius circumscribes raster + x = y = 0; + p->Rcrop = CamLens_getR( p, x, y ); + + // reference radius inscribed in raster + if( p->hFLpix * p->vCpix > p->vFLpix * p->hCpix ) + y = p->vCpix; // wid < hgt + else x = p->hCpix; // wid >= hgt + p->Rref = CamLens_getR( p, x, y ); + + } + + if( p->widpix < 1 || p->hgtpix < 1 + || p->hFLpix == 0 ){ + free(p); + p = 0; + } + + return p; +} + +/* set projection format + + fmt is an image format code defined in panorama.h + + returns 0 for unsupported format + 1 for OK + + Assumes -- + ideal projection if FLmm == 0, else lens projection + equal-area fisheye lens for _equirectangular (the + ideal is equal-angle) + lens projects Y of cylindrical and equirectangular + and both axes of the elliptical formats + +*/ +int CamLens_setProjection( pCamLens p, int fmt ) +{ // null format + p->PT_fmt = -1; + p->R2A = 0; + p->A2R = 0; + p->Klens = 0; + p->lensAxis = (p->FLmm ? 3 : 0 ); // elliptical + p->Rref = p->Rcrop = 0; // no limit + switch( fmt ){ + case _rectilinear: + p->R2A = r2a_rect; + p->A2R = a2r_rect; + p->Klens = 1.0; + break; + case _panorama: + p->R2A = r2a_rect; + p->A2R = a2r_rect; + p->Klens = 1.0; + p->lensAxis &= 2; // lens Y only + break; + case _fisheye_circ: + case _fisheye_ff: + p->R2A = r2a_fish; + p->A2R = a2r_fish; + p->Klens = 2.0; + p->Rref = p->Rcrop = p->Klens; + break; + case _equirectangular: + if( p->FLmm ){ + p->R2A = r2a_fish; + p->A2R = a2r_fish; + p->Klens = 2.0; + p->Rref = p->Rcrop = p->Klens; + p->lensAxis = 2; // Y only + } + break; + case _spherical_cp: + case _spherical_tp: + if( p->FLmm ){ + p->R2A = r2a_fish; + p->A2R = a2r_fish; + p->Klens = 500.0; + p->Rref = p->Rcrop = p->Klens; + } + break; + case _mirror: + p->R2A = r2a_mirr; + p->A2R = a2r_mirr; + p->Klens = 1.0; + break; + case _orthographic: + p->R2A = r2a_fish; + p->A2R = a2r_fish; + p->Klens = 1.0; + p->Rref = p->Rcrop = p->Klens; + break; + case _stereographic: + p->R2A = r2a_ster; + p->A2R = a2r_ster; + p->Klens = 1.0; + break; + + default: + p->lensAxis = 0; + return 0; // unsupported format + + } + // OK + p->PT_fmt = fmt; + return 1; // OK +} + +// initialize with full info +pCamLens CamLens_new( pCameraInfo pc, pLensInfo pl ) +{ + return 0; /// TBD /// +} + +// normalized radius to angle in radians +double CamLens_AofR( pCamLens p, double R ){ + if( p->R2A == 0 ) return R; + return (p->R2A)( R, p->Klens ); +} + +// angle in radians to normalized radius +double CamLens_RofA( pCamLens p, double A ){ + if( p->A2R == 0 ) return A; + return (p->A2R)( A, p->Klens ); +} + +// get largest valid normalized radius +double CamLens_Rmax( pCamLens p ){ + return p->Rcrop; +} + + +/* pixel coordinates to normalized radius */ +double CamLens_getR( CamLens *p, double x, double y ) +{ + double dx = ( x - p->hCpix ) / p->hFLpix; + double dy = ( y - p->vCpix ) / p->vFLpix; + return sqrt( dx * dx + dy * dy ); +} + Added: autopano-sift-C/trunk/APSCpp/HermiteSpline.c =================================================================== --- autopano-sift-C/trunk/APSCpp/HermiteSpline.c (rev 0) +++ autopano-sift-C/trunk/APSCpp/HermiteSpline.c 2008-03-01 02:58:39 UTC (rev 2914) @@ -0,0 +1,353 @@ + +/* HermiteSpline.c 16 Feb 2008 TKS + + Hermite Spline Interpolation Routines + adapted from John Burkardt's collection at + http://people.scs.fsu.edu/~burkardt/cpp_src/spline/spline.html + NOTE FORTRAN style 1-origin array indexing in some places + +*/ +/* + * 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 <stdlib.h> +#include <math.h> +#include "HermiteSpline.h" + +/* some functions below test monotonicity by checking that + the differece across n >= 2 intervals is >= n * fIEPS + (the difference across a single interval can be 0) +*/ +#define fIEPS 1.e-11 // tolerance for nonzero difference + + /** Tabulate coefficients for Hermit Spline Interpolation **/ + +double *spline_hermite_set ( int ndata, double tdata[], double ydata[], + double ypdata[] ) + +//****************************************************************************80 +// +// Purpose: +// +// SPLINE_HERMITE_SET sets up a piecewise cubic Hermite interpolant. +// +// Discussion: +// +// Once the array C is computed, then in the interval +// (TDATA(I), TDATA(I+1)), the interpolating Hermite polynomial +// is given by +// +// SVAL(TVAL) = C(1,I) +// + ( TVAL - TDATA(I) ) * ( C(2,I) +// + ( TVAL - TDATA(I) ) * ( C(3,I) +// + ( TVAL - TDATA(I) ) * C(4,I) ) ) +// +// This is algorithm CALCCF from Conte and deBoor. +// +// Modified: +// +// 11 February 2004 +// +// Author: +// +// John Burkardt +// +// Reference: +// +// Samuel Conte, Carl deBoor, +// Elementary Numerical Analysis, +// Second Edition, +// McGraw Hill, 1972, +// ISBN: 07-012446-4. +// +// Parameters: +// +// Input, int NDATA, the number of data points. +// NDATA must be at least 2. +// +// Input, double TDATA[NDATA], the abscissas of the data points. +// The entries of TDATA are assumed to be strictly increasing. +// +// Input, double Y[NDATA], YP[NDATA], the value of the +// function and its derivative at TDATA(1:NDATA). +// +// Output, double SPLINE_HERMITE_SET[4*NDATA], the coefficients of +// the Hermite polynomial. We will refer to this array as "C". +// C(1,1:NDATA) = Y(1:NDATA) and C(2,1:NDATA) = YP(1:NDATA). +// C(3,1:NDATA-1) and C(4,1:NDATA-1) are the quadratic and cubic +// coefficients. +// +{ + double *c; + double divdif1; + double divdif3; + double dt; + int i; + int j; + + // c = new double[4*ndata]; + c = (double *)malloc(4*ndata*sizeof(double)); + + for ( j = 0; j < ndata; j++ ) + { + c[0+j*4] = ydata[j]; + } + + for ( j = 0; j < ndata; j++ ) + { + c[1+j*4] = ypdata[j]; + } + + for ( i = 1; i <= ndata-1; i++ ) + { + dt = tdata[i] - tdata[i-1]; + divdif1 = ( c[0+i*4] - c[0+(i-1)*4] ) / dt; + divdif3 = c[1+(i-1)*4] + c[1+i*4] - 2.0 * divdif1; + c[2+(i-1)*4] = ( divdif1 - c[1+(i-1)*4] - divdif3 ) / dt; + c[3+(i-1)*4] = divdif3 / ( dt * dt ); + } + + c[2+(ndata-1)*4] = 0.0; + c[3+(ndata-1)*4] = 0.0; + + return c; +} +//****************************************************************************80 + + + /** Compute a Hermite Spline Interpolation **/ + +int spline_hermite_val ( int ndata, double tdata[], double c[], double tval, + double *sval, double *spval ) + +//****************************************************************************80 +// +// Purpose: +// +// SPLINE_HERMITE_VAL evaluates a piecewise cubic Hermite interpolant. +// +// Discussion: +// +// SPLINE_HERMITE_SET must be called first, to set up the +// spline data from the raw function and derivative data. +// +// In the interval (TDATA(I), TDATA(I+1)), the interpolating +// Hermite polynomial is given by +// +// SVAL(TVAL) = C(1,I) +// + ( TVAL - TDATA(I) ) * ( C(2,I) +// + ( TVAL - TDATA(I) ) * ( C(3,I) +// + ( TVAL - TDATA(I) ) * C(4,I) ) ) +// +// and +// +// SVAL'(TVAL) = C(2,I) +// + ( TVAL - TDATA(I) ) * ( 2 * C(3,I) +// + ( TVAL - TDATA(I) ) * 3 * C(4,I) ) +// +// This is algorithm PCUBIC from Conte and deBoor. +// +// Modified: +// +// 24 February 2004 +// +// Author: +// +// John Burkardt +// +// Reference: +// +// Samuel Conte, Carl deBoor, +// Elementary Numerical Analysis, +// Second Edition, +// McGraw Hill, 1972, +// ISBN: 07-012446-4. +// +// Parameters: +// +// Input, int NDATA, the number of data points. +// NDATA is assumed to be at least 2. +// +// Input, double TDATA[NDATA], the abscissas of the data points. +// The entries of TDATA are assumed to be strictly increasing. +// +// Input, double C[4*NDATA], the coefficient data computed by +// SPLINE_HERMITE_SET. +// +// Input, double TVAL, the point where the interpolant is to +// be evaluated. +// +// Output, double *SVAL, *SPVAL, the value of the interpolant +// and its derivative at TVAL. +// +/** TKS mods Feb 2008 + add a return value: 0 failure, 1 success + use interpolating interval search; fail if arg out of range + don't compute derivative if spval is null + declare local vars register +**/ +{ + register double dt; + register int left; + + left = findInterval( ndata, tdata, tval ); + if( left < 0 ) return 0; +// +// Evaluate the cubic polynomial. +// + dt = tval - tdata[left]; + + *sval = c[0+(left)*4] + + dt * ( c[1+(left)*4] + + dt * ( c[2+(left)*4] + + dt * c[3+(left)*4] ) ); + + if( spval ) + *spval = c[1+(left)*4] + + dt * ( 2.0 * c[2+(left)*4] + + dt * 3.0 * c[3+(left)*4] ); + + return 1; +} + +/* Compute array of tangents for a tabulated function + to serve as derivatives for setting up a Hermite spline. + + t values must be strictly monotonic (no zero differences) + but need not be equally spaced. + If y is monotonic, the tangents will be adjusted to ensure that + interpolated values are monotonic, too; else no adjustment. + + Input: + ndata, tdata[ndata], ydata[ndata] as above + ypd[ndata] -- receives the tangents + Output: + returns 0 if tdata[] is not monotonic or ndata < 2 (fail) + 1 if y is monotonic (tangents set) + -1 if y is not monotonic (tangents set) + + Method: + divided differences, suitable for unequally spaced data + (the spline 1st derivative may not be perfectly smooth) + + References: + Wikipedia: "Cubic Hermite spline" + Wikipedia: "Monotone cubic interpolation" + +*/ +int spline_tangents_set( int ndata, double tdata[], double ydata[], double ypd[] ){ + int i, mono; + double d, *del = 0; +// check t + if( ndata < 2 ) return 0; + d = (tdata[ndata-1] - tdata[0]) / (ndata - 1); // avg t difference + if( fabs(d) < fIEPS ) return 0; // implausibly small! + if( d < 0 ){ + for( i = 1; i < ndata; i++ ) if( tdata[i] - tdata[i-1] >= 0 ) return 0; + } else { + for( i = 1; i < ndata; i++ ) if( tdata[i] - tdata[i-1] <= 0 ) return 0; + } + +// allocate temp array or die + del = (double *)malloc(ndata*sizeof(double)); + if( !del ) return 0; + +// compute divided y differences, test monotonicity + mono = 1; + d = 0; // previous difference + for( i = 1; i < ndata; i++ ){ + register double yd = ydata[i] - ydata[i-1]; + if( yd * d < 0 ) mono = 0; // not monotone + d = yd; + del[i] = yd / (tdata[i] - tdata[i-1]); + } + if( mono ){ + if( fabs( ydata[ndata - 1] - ydata[0] ) < ndata * fIEPS ){ + mono = 0; + } + } + +// compute tangents + ypd[0] = del[1]; + ypd[ndata-1] = del[ndata-1]; + for( i = 1; i < ndata - 1; i++ ){ + ypd[i] = 0.5 * (del[i] + del[i+1]); + } + +// adjust for monotonicity + if( mono ){ + register double a, b, c; + for( i = 1; i < ndata; i++ ){ + if( fabs(del[i]) < 1.e-11 ){ + ypd[i-1] = ypd[i] = 0; + } else { + a = ypd[i-1] / del[i]; + b = ypd[i] / del[i]; + c = a * a + b * b; + if( c > 9.0 ){ // adjust... + c = 3.0 / sqrt( c ); + ypd[i-1] *= c; + ypd[i] *= c; + } + } + } + } + + free( del ); + return ( mono ? 1 : -1 ); +} + +/* Find the interval (if any) in t[n] that contains x + t[] must be monotonic ascending or descending + (isolated intervals with zero difference OK) + returns i if x == t[i] + returns index (0:n-2) of the left end of the interval, or + -1 if x is out of range + -2 if t is not monotonic + method: binary search intialized with secant +*/ + +int findInterval( int n, double t[], double x ) +{ int l, r, s; + double d; + + if ( n < 2 ) return -2; // no data + + l = 0; r = n-1; + d = t[r] - t[l]; + if( fabs( d ) < fIEPS ) return -2; // insufficient slope + s = (int) ((x - t[0]) / d); // splitting idex + if( s < l || s > r ) return -1; // out of range + + if( d > 0 ){ + while ( r - l > 1 ){ + if( x < t[s] ) r = s; + else l = s; + s = ( r + l ) / 2; + } + } else { + while ( r - l > 1 ){ + if( x > t[s] ) r = s; + else l = s; + s = ( r + l ) / 2; + } + } + + return l; +} + Added: autopano-sift-C/trunk/APSCpp/HermiteSpline.h =================================================================== --- autopano-sift-C/trunk/APSCpp/HermiteSpline.h (rev 0) +++ autopano-sift-C/trunk/APSCpp/HermiteSpline.h 2008-03-01 02:58:39 UTC (rev 2914) @@ -0,0 +1,80 @@ +/* HermiteSpline.h 16 Feb 2008 TKS + + Hermite Spline Interpolation Routines + lifted & adapted from John Burkardt's collection at + http://people.scs.fsu.edu/~burkardt/cpp_src/spline/spline.html + NOTE FORTRAN style 1-origin array indexing + +*/ +/* + * 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... [truncated message content] |
From: <da...@us...> - 2008-03-03 09:10:04
|
Revision: 2925 http://hugin.svn.sourceforge.net/hugin/?rev=2925&view=rev Author: dangelo Date: 2008-03-03 01:10:01 -0800 (Mon, 03 Mar 2008) Log Message: ----------- Enable compilation with gcc Modified Paths: -------------- autopano-sift-C/trunk/APSCpp/sphereAlign.h autopano-sift-C/trunk/AutoPanoSift.h Modified: autopano-sift-C/trunk/APSCpp/sphereAlign.h =================================================================== --- autopano-sift-C/trunk/APSCpp/sphereAlign.h 2008-03-03 09:06:38 UTC (rev 2924) +++ autopano-sift-C/trunk/APSCpp/sphereAlign.h 2008-03-03 09:10:01 UTC (rev 2925) @@ -254,7 +254,7 @@ // delete void DIinfo_delete( pDIinfo self ); // set up remapping once basic info is read -int DIinfo_setRm( pDIinfo self ); +saRemap * DIinfo_setRm( pDIinfo self, double Scale ); #endif // ndef _SPHEREALIGN_H Modified: autopano-sift-C/trunk/AutoPanoSift.h =================================================================== --- autopano-sift-C/trunk/AutoPanoSift.h 2008-03-03 09:06:38 UTC (rev 2924) +++ autopano-sift-C/trunk/AutoPanoSift.h 2008-03-03 09:10:01 UTC (rev 2925) @@ -2,11 +2,7 @@ #ifndef AUTOPANOS_SIFT_H #define AUTOPANOS_SIFT_H -#ifdef HAS_CONFIG_H #include "config.h" -#else -#define PACKAGE_VERSION "2.4.1" -#endif // include windows.h here // to prevent the global namespace to become polluted with This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tks...@us...> - 2008-03-07 18:18:55
|
Revision: 2933 http://hugin.svn.sourceforge.net/hugin/?rev=2933&view=rev Author: tksharpless Date: 2008-03-07 10:18:51 -0800 (Fri, 07 Mar 2008) Log Message: ----------- 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 Modified Paths: -------------- 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/HermiteSpline.h autopano-sift-C/trunk/APSCpp/README-autopano-sift-c.txt 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/AutoPanoSift.h autopano-sift-C/trunk/CMakeLists.txt autopano-sift-C/trunk/MatchKeys.c autopano-sift-C/trunk/README.1ST Modified: autopano-sift-C/trunk/APSCpp/APSCpp.c =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp.c 2008-03-07 15:44:25 UTC (rev 2932) +++ autopano-sift-C/trunk/APSCpp/APSCpp.c 2008-03-07 18:18:51 UTC (rev 2933) @@ -1,22 +1,22 @@ /* APSCpp.c 15 Feb 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 - * - */ +/* + * 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" @@ -274,12 +274,15 @@ 3) it never invokes the Lowe detector's option to expand the image 2x. - returns 0 for failure + mode argument should be + 0 for legacy (KDTree) mode -- returns list of KeypointN + 1 for ANN mode -- returns list of Keypoint + */ -KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, DIinfo * pdi ) +KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, DIinfo * pdi, int mode ) { #ifdef _DEBUG_INTERP char tmp[262]; @@ -406,14 +409,16 @@ WriteLine(" %d keypoints found\n", nKeys ); /* 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++!) + For KDTree mode, a list of KeypointN; for ANN mode a list of Keypoint, + that will be converted to keypointN after matching */ { - ArrayList * globalNaturalKeypoints = ArrayList_new0 (KeypointN_delete); + + ArrayList * globalNaturalKeypoints = 0; int i; + if( mode == 0 ) globalNaturalKeypoints = ArrayList_new0 (KeypointN_delete); + if( pdi ){ // build remapping function at input scale CamLens * psp, * pdp; psp = CamLens_new1( pW, pH, pdi->format, pdi->hfov, 16.0 ); @@ -429,17 +434,28 @@ &kp->x, &kp->y // remapped coords ); } - ArrayList_AddItem ( globalNaturalKeypoints, KeypointN_new( kp )); + if( mode == 0 ) ArrayList_AddItem ( globalNaturalKeypoints, KeypointN_new( kp )); } - // package result as a KeypointXMLList - kpp = KeypointXMLList_new ( imgname, pW, pH, globalNaturalKeypoints ); + + // package the list + kpp = KeypointXMLList_new0(); + 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! + } } - + // delete the LoweDetector LoweFeatureDetector_delete(lf); - // restore the default Lowe prefilter LoweFeatureDetector_SetPreprocSigma( savesigma ); - // disable the patent warning message (for any subsequent images) + // disable the patent warning message for any subsequent images LoweFeatureDetector_SetPrintWarning(false); return kpp; Modified: autopano-sift-C/trunk/APSCpp/APSCpp_main.c =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp_main.c 2008-03-07 15:44:25 UTC (rev 2932) +++ autopano-sift-C/trunk/APSCpp/APSCpp_main.c 2008-03-07 18:18:51 UTC (rev 2933) @@ -44,13 +44,15 @@ * */ +#include <ctime> #include "AutoPanoSift.h" #include "sphereAlign.h" -// APSCpp.c +// APSCpp.cpp int LoadProjectImages( char* script, ArrayList * DIlist ); -KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, DIinfo * pdi ); +KeypointXMLList * GenerateKeyspp( char * imgname, int maxdim, DIinfo * pdi, int mode ); +int MultiMatch_ANN ( MultiMatch* ); void Usage () { @@ -75,7 +77,9 @@ WriteLine (" --maxdim <n> Make largest image dimension <= n (default: full size)."); WriteLine (" --projection <n>,<d> n = PT format code, d = hfov in degrees. These"); WriteLine (" apply to all images, reprojection is enabled."); + WriteLine (" --ANNmatch <on|off|1|0> Enable faster keypoint matching (default: off)."); WriteLine (""); + WriteLine (""); WriteLine ("Alignment options"); WriteLine (" --align Automatically pre-align images in PTO file."); @@ -579,6 +583,9 @@ int main (int argc, char* argv[]) { + clock_t start,finish; + double time; + // list used in ++ mode only -- image info from pto file ArrayList * DIlist = 0; // item = DIinfo struct. char *projectfile = 0; @@ -597,6 +604,9 @@ bool preAlign = false; int bottomDefault = -1; int generateHorizon = 0; + + // Use ANN kd-tree for keypoint matching + bool useANN = false; // Use RANSAC algorithm match filtration. bool useRansac = true; @@ -660,6 +670,9 @@ } 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, "--maxmatches") == 0) { joptN = 2; if (sscanf(argv[optionN + 1], "%d", &maxMatches) != 1) { @@ -765,11 +778,10 @@ if( DIlist ) WriteLine(" Stereographic projection enabled."); - MultiMatch* mm = MultiMatch_new0 (); /** Find keypoints **/ + start = clock(); - ArrayList* keylists = ArrayList_new0(NULL); if( DIlist ){ @@ -789,24 +801,42 @@ // 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) ); + ArrayList_AddItem(keylists, GenerateKeyspp( pd->name, maxdim, pd, useANN ) ); } } 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) ); + ArrayList_AddItem(keylists, GenerateKeyspp( argv[i+optionCount+1], maxdim, 0, useANN ) ); } } + finish = clock(); + time = (double(finish)-double(start))/CLOCKS_PER_SEC; + WriteLine("%.1f seconds to find keypoints", time); + /** Find control points **/ + start = clock(); + + MultiMatch* mm = MultiMatch_new0 (); MultiMatch_LoadKeysetsFromMemory (mm, keylists); // note mm now owns keylists and will delete it when destroyed - WriteLine ("\nMatching...%s", useRansac == true ? " RANSAC enabled" : ""); + WriteLine ("\nMatching; ransac %s, ANNmatch %s...", + useRansac == true ? "on" : "off", + useANN == true ? "on" : "off" + ); + + if( useANN ) MultiMatch_ANN ( mm ); + ArrayList* msList = MultiMatch_LocateMatchSets (mm, 3, maxMatches, useRansac, useAreaFiltration); + finish = clock(); + time = (double(finish)-double(start))/CLOCKS_PER_SEC; + WriteLine("%.1f seconds to match keypoints", time); + + // Connected component check WriteLine ("\nConnected component check..."); ArrayList* components = MultiMatch_ComponentCheck (mm, msList); Modified: autopano-sift-C/trunk/APSCpp/CMakeLists.txt =================================================================== --- autopano-sift-C/trunk/APSCpp/CMakeLists.txt 2008-03-07 15:44:25 UTC (rev 2932) +++ autopano-sift-C/trunk/APSCpp/CMakeLists.txt 2008-03-07 18:18:51 UTC (rev 2933) @@ -1,7 +1,22 @@ -#cmakelists.txt for subdirectory APSCpp -#note executable is named autopano-sift-c, as Pablo prefers it +#cmakelists.txt for subdirectory APSCpp 07 Mar 2008 TKSharpless +# +# Builds autopano-sift-c aka APSC++ +# +# Uses the ANN kd-tree implementation. Builds a static ANN library from +# source in subdirectory ANN. Note ANN.h has been customized for APSCpp. +# +# ANN needs this to satisfy #include "ANN/xxx" +INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ) + +add_subdirectory( ANN ) -add_executable(autopano-sift-c APSCpp_main.c APSCpp.c CamLens.c HermiteSpline.c saInterp.c saRemap.c ) -TARGET_LINK_LIBRARIES(autopano-sift-c ${all_libs}) +# source files that must be compiled as C +SET( C_Sources CamLens.c HermiteSpline.c saInterp.c saRemap.c ) + +# the build target +add_executable( autopano-sift-c APSCpp_main.cpp APSCpp.cpp ${C_Sources}) + +TARGET_LINK_LIBRARIES( autopano-sift-c ANN ${all_libs} ) + install(TARGETS autopano-sift-c DESTINATION bin) -install(FILES README-autopano-sift-c.txt DESTINATION . ) \ No newline at end of file +install(FILES README-autopano-sift-c.txt DESTINATION . ) Modified: autopano-sift-C/trunk/APSCpp/HermiteSpline.h =================================================================== --- autopano-sift-C/trunk/APSCpp/HermiteSpline.h 2008-03-07 15:44:25 UTC (rev 2932) +++ autopano-sift-C/trunk/APSCpp/HermiteSpline.h 2008-03-07 18:18:51 UTC (rev 2933) @@ -1,80 +1,89 @@ -/* HermiteSpline.h 16 Feb 2008 TKS - - Hermite Spline Interpolation Routines - lifted & adapted from John Burkardt's collection at - http://people.scs.fsu.edu/~burkardt/cpp_src/spline/spline.html - NOTE FORTRAN style 1-origin array indexing - -*/ -/* - * 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 - * - */ - -#ifndef _HERMITESPLINE_H -#define _HERMITESPLINE_H - -/* tabulate coefficients for Hermite spline interpolation of y(t) - tdata[ndata], ydata[ndata] are tabulated y{t} values - ypdata[ndata] are its 1st derivatives at same t's (how you set - these determines the curviness of the spline) - Note t values must be monotonic but intervals can vary - Returns pointer to a new array c[4*ndata] of coefficients - Note c[] is allocated with malloc() -*/ -double *spline_hermite_set ( int ndata, double tdata[], double ydata[], double ypdata[] ); - -/* compute hermite spline interpolation - tdata[ndata] = tabulated t values; c[4*ndata] = coefficients - tval = interpolation point - sval -> returned interpolated y value - spval -> returned derivative at that point (0: no derivative computed) - returns 0: bad input or 1: sucess -*/ -int spline_hermite_val ( int ndata, double tdata[], double c[], - double tval, double * sval, double * spval ); - -/* set tangents (1st divided differences) for a tabulated function - whose tabulation interval need not be uniform. - these can serve as the derivatives for setting up a spline. - - Input: ndata, tdata[ndata], ydata[ndata] as above. - ypdata[ndata] -- place for the result - - returns 0 if tdata[] is not monotonic or ndata < 2 or the - range of t or y is < 1e-11, else - 1 if ydata[] is monotonic, else - -1 if ydata[] is not monotonic - - If y is monotonic, the tangents are adjusted to ensure that all - interpolated values will be monotonic as well. - -*/ -int spline_tangents_set( int ndata, double tdata[], double ydata[], double ypdata[] ); - -/* Find the interval (if any) in t[n] that contains x - t[] must be monotonic ascending or descending - returns i if x == t[i] - returns index (0:n-2) of the left end of the interval, or - -1 if x is out of range - -2 if t is not monotonic - method: linear interpolation search -*/ -int findInterval( int n, double t[], double x ); - - -#endif //ndef _HERMITESPLINE_H - - +/* HermiteSpline.h 16 Feb 2008 TKS + + Hermite Spline Interpolation Routines + lifted & adapted from John Burkardt's collection at + http://people.scs.fsu.edu/~burkardt/cpp_src/spline/spline.html + NOTE FORTRAN style 1-origin array indexing + +*/ +/* + * 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 + * + */ + +#ifndef _HERMITESPLINE_H +#define _HERMITESPLINE_H + + +#ifdef __cplusplus +extern "C" { +#endif + +/* tabulate coefficients for Hermite spline interpolation of y(t) + tdata[ndata], ydata[ndata] are tabulated y{t} values + ypdata[ndata] are its 1st derivatives at same t's (how you set + these determines the curviness of the spline) + Note t values must be monotonic but intervals can vary + Returns pointer to a new array c[4*ndata] of coefficients + Note c[] is allocated with malloc() +*/ +double *spline_hermite_set ( int ndata, double tdata[], double ydata[], double ypdata[] ); + +/* compute hermite spline interpolation + tdata[ndata] = tabulated t values; c[4*ndata] = coefficients + tval = interpolation point + sval -> returned interpolated y value + spval -> returned derivative at that point (0: no derivative computed) + returns 0: bad input or 1: sucess +*/ +int spline_hermite_val ( int ndata, double tdata[], double c[], + double tval, double * sval, double * spval ); + +/* set tangents (1st divided differences) for a tabulated function + whose tabulation interval need not be uniform. + these can serve as the derivatives for setting up a spline. + + Input: ndata, tdata[ndata], ydata[ndata] as above. + ypdata[ndata] -- place for the result + + returns 0 if tdata[] is not monotonic or ndata < 2 or the + range of t or y is < 1e-11, else + 1 if ydata[] is monotonic, else + -1 if ydata[] is not monotonic + + If y is monotonic, the tangents are adjusted to ensure that all + interpolated values will be monotonic as well. + +*/ +int spline_tangents_set( int ndata, double tdata[], double ydata[], double ypdata[] ); + +/* Find the interval (if any) in t[n] that contains x + t[] must be monotonic ascending or descending + returns i if x == t[i] + returns index (0:n-2) of the left end of the interval, or + -1 if x is out of range + -2 if t is not monotonic + method: linear interpolation search +*/ +int findInterval( int n, double t[], double x ); + + +#ifdef __cplusplus +} +#endif + +#endif //ndef _HERMITESPLINE_H + + Modified: autopano-sift-C/trunk/APSCpp/README-autopano-sift-c.txt =================================================================== --- autopano-sift-C/trunk/APSCpp/README-autopano-sift-c.txt 2008-03-07 15:44:25 UTC (rev 2932) +++ autopano-sift-C/trunk/APSCpp/README-autopano-sift-c.txt 2008-03-07 18:18:51 UTC (rev 2933) @@ -1,8 +1,10 @@ -APSCpp == enhanced autopano-sift-c 29 Feb 2008 TKSharpless +APSCpp == enhanced autopano-sift-c 29 Feb 2008 : 07 Mar 2008 TKSharpless +This is a major upgrade of autopano-sift-c and has version 2.5.0. + New executable autopano-sift-c combines keypoint finding and matching in one program. It is built on the autopano-sift-c codebase, and basically delivers -the same functionality as generatekeys + autopano, but adds a few new options. +the same functionality as generatekeys + autopano, plus some new options. The most important are the ability to run under hugin as an alternate control point finder, and the option of converting to stereographic projection before @@ -27,25 +29,34 @@ The output is a .pto file that can be loaded into hugin. In stereographic mode this file has the format and hfov information. -There is one other commandline difference from generatekeys: the limit on the -larger image dimension is --maxdim, not --mindim. +Autopano-sift-c uses a smoother method for reducing image size, which leads to +somewhat more stable control point positions (it also takes a little longer). -The APSCpp extension adds several new source files and a few improvements to the -existing libsift code. Besides bug fixes, there is one major change: most of -the internal image data are now stored as floats rather than doubles. This allows -processing of significantly larger images on any given machine. +Finally, it uses the much faster ANN kd-tree implementation for keypoint matching +(with the option of using the original code instead, for comparison). -The new program also uses a better method of reducing image size, which leads to -somewhat more stable control point positions. +Some notable differences in options from generatekeys/autopano +* the limit on the larger image dimension is --maxdim, not --mindim, and + its default value is 1600 instead of 800. +* the default maximum number of control points per image pair is 25 not 16. +* RANSAC filtering is off by default instead of on +* the default kd-tree implementation is ANN. "--ANNmatch off" can be + used to switch back to the original code, +Please see the usage message, obtained by running autopano-sift-c without +arguments, for details on all the options. + +There are also some improvements to the existing libsift code. Besides bug fixes, +the major change is that most internal image data are now stored as floats rather +than doubles. This just about halves the memory demand of the keypoint finder and +allows processing significantly larger images on any given machine. + + TODO -- --- find out why the kd-tree keypoint matching runs 20x slower than Jenney's, and -fix or replace it. - -- find out why enabling RANSAC seems to make the alignments worse, when the opposite would be expected, and fix that too. --- when a project file is input, output a full copy of it with just the conttrol -points replaced. +-- when a hugin project file is input, output a full copy of it with just the +conttrol points replaced. Modified: autopano-sift-C/trunk/APSCpp/saInterp.h =================================================================== --- autopano-sift-C/trunk/APSCpp/saInterp.h 2008-03-07 15:44:25 UTC (rev 2932) +++ autopano-sift-C/trunk/APSCpp/saInterp.h 2008-03-07 18:18:51 UTC (rev 2933) @@ -53,6 +53,10 @@ #ifndef _SAINTERP_H #define _SAINTERP_H +#ifdef __cplusplus +extern "C" { +#endif + int saInterpSetup( void * ps, // -> source data or pointers int vfmt, // 0: contig 1: row vector 2: col vector int wid, // valid pixels per row @@ -70,6 +74,9 @@ double Xpos, double Ypos ); +#ifdef __cplusplus +} +#endif #endif //ndef _SAINTERP_H Modified: autopano-sift-C/trunk/APSCpp/saRemap.c =================================================================== --- autopano-sift-C/trunk/APSCpp/saRemap.c 2008-03-07 15:44:25 UTC (rev 2932) +++ autopano-sift-C/trunk/APSCpp/saRemap.c 2008-03-07 18:18:51 UTC (rev 2933) @@ -27,22 +27,22 @@ that circle can be remapped. */ -/* - * 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 - * - */ +/* + * 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 "sphereAlign.h" Modified: autopano-sift-C/trunk/APSCpp/sphereAlign.h =================================================================== --- autopano-sift-C/trunk/APSCpp/sphereAlign.h 2008-03-07 15:44:25 UTC (rev 2932) +++ autopano-sift-C/trunk/APSCpp/sphereAlign.h 2008-03-07 18:18:51 UTC (rev 2933) @@ -28,6 +28,11 @@ #ifndef _SPHEREALIGN_H #define _SPHEREALIGN_H + +#ifdef __cplusplus +extern "C" { +#endif + ////#include "pano13\panorama.h" #ifndef PANORAMA_H enum @@ -253,8 +258,10 @@ pDIinfo DIinfo_new0(); // delete void DIinfo_delete( pDIinfo self ); -// set up remapping once basic info is read -saRemap * DIinfo_setRm( pDIinfo self, double Scale ); +#ifdef __cplusplus +} +#endif + #endif // ndef _SPHEREALIGN_H Modified: autopano-sift-C/trunk/AutoPanoSift.h =================================================================== --- autopano-sift-C/trunk/AutoPanoSift.h 2008-03-07 15:44:25 UTC (rev 2932) +++ autopano-sift-C/trunk/AutoPanoSift.h 2008-03-07 18:18:51 UTC (rev 2933) @@ -2,7 +2,11 @@ #ifndef AUTOPANOS_SIFT_H #define AUTOPANOS_SIFT_H +#ifdef HAS_CONFIG_H #include "config.h" +#else +#define PACKAGE_VERSION "2.5.0" +#endif // include windows.h here // to prevent the global namespace to become polluted with @@ -169,93 +173,104 @@ void SortedLimitedList_RemoveAt (SortedLimitedList* self, int i); int SortedLimitedList_AddItem (SortedLimitedList* self, void* value); - typedef struct IKDTreeDomain IKDTreeDomain; -typedef struct KDTreeBestEntry KDTreeBestEntry; -typedef struct KDTreeHREntry KDTreeHREntry; -typedef struct HyperRectangle HyperRectangle; -typedef struct KDTree KDTree; // The interface to be implemented by all data elements within the // kd-tree. As every element is represented in domain space by a // multidimensional vector, the interface provides readonly methods to // access into this vector and to get its dimension. +// kept for APSCpp as KeyPointN uses it struct IKDTreeDomain { int (*getDimensionCount)(IKDTreeDomain* self); - int (*getDimensionElement)(IKDTreeDomain* self, int dim); + int (*getDimensionElement)(IKDTreeDomain* self, int dim); }; -int IKDTreeDomain_GetDimensionCount(IKDTreeDomain* self); -int IKDTreeDomain_GetDimensionElement(IKDTreeDomain* self, int dim); -struct KDTreeHREntry { - double dist; - HyperRectangle* rect; - IKDTreeDomain* pivot; - KDTree* tree; -}; +#ifdef APSCpp_useANN // declarations for using ANN kd-tree -struct HyperRectangle { - int* leftTop; - int* rightBottom; - int dim; - int ref; -}; + typedef void KDTree; + void KDTree_delete (KDTree* self); -HyperRectangle* HyperRectangle_new0(); -void HyperRectangle_delete(HyperRectangle* self); -HyperRectangle* HyperRectangle_new (int dim); -HyperRectangle* HyperRectangle_clone (HyperRectangle* self); -HyperRectangle* HyperRectangle_ref (HyperRectangle* self); -void HyperRectangle_unref (HyperRectangle* self); -HyperRectangle* HyperRectangle_CreateUniverseRectangle (int dim); -double HyperRectangle_Distance (HyperRectangle* self, IKDTreeDomain* target); -bool HyperRectangle_IsInReach (HyperRectangle* self, IKDTreeDomain* target, double distRad); +#else // declarations for using Nowozin KDTree -struct KDTreeBestEntry { - // Distance between this neighbour point and the target point. - double distance; - int distanceSq; - bool squared; - // The neighbour. - IKDTreeDomain* neighbour; - -}; -IKDTreeDomain* KDTreeBestEntry_Neighbour(KDTreeBestEntry* self); -void KDTreeBestEntry_delete(KDTreeBestEntry* self); + int IKDTreeDomain_GetDimensionCount(IKDTreeDomain* self); + int IKDTreeDomain_GetDimensionElement(IKDTreeDomain* self, int dim); -struct KDTree { - // The current element - IKDTreeDomain* dr; - // The splitting dimension for subtrees. - int splitDim; + typedef struct KDTreeBestEntry KDTreeBestEntry; + typedef struct KDTreeHREntry KDTreeHREntry; + typedef struct HyperRectangle HyperRectangle; + typedef struct KDTree KDTree; + struct KDTreeHREntry { + double dist; + HyperRectangle* rect; + IKDTreeDomain* pivot; + KDTree* tree; + }; - // The left and the right kd-subtree. - KDTree* left; - KDTree* right; -}; -int KDTree_DistanceSq (IKDTreeDomain* t1, IKDTreeDomain* t2); -IKDTreeDomain* KDTree_GoodCandidate (ArrayList* exset, int* splitDim); -KDTree* KDTree_CreateKDTree (ArrayList* exset); -KDTree* KDTree_new0 (); -void KDTree_delete (KDTree* self); -IKDTreeDomain* KDTree_NearestNeighbour (KDTree* self, IKDTreeDomain* target, double* resDist); -IKDTreeDomain* KDTree_NearestNeighbourI (KDTree* self, IKDTreeDomain* target, HyperRectangle* hr, - double maxDistSq, double* resDistSq, ArrayList* hrl); -SortedLimitedList* KDTree_NearestNeighbourList (KDTree* self, IKDTreeDomain* target, - double* resDist, int q); -IKDTreeDomain* KDTree_NearestNeighbourListI (KDTree* self, SortedLimitedList* best, - int q, IKDTreeDomain* target, HyperRectangle* hr, double maxDistSq, - double* resDistSq, ArrayList* hrl); -SortedLimitedList* KDTree_NearestNeighbourListBBF (KDTree* self, IKDTreeDomain* target, - int q, int searchSteps); -IKDTreeDomain* KDTree_NearestNeighbourListBBFI (KDTree* self, SortedLimitedList* best, - int q, IKDTreeDomain* target, HyperRectangle* hr, int maxDistSq, - int* resDistSq, SortedLimitedList* searchHr, int* searchSteps, - ArrayList* hrl); + struct HyperRectangle { + int* leftTop; + int* rightBottom; + int dim; + int ref; + }; + HyperRectangle* HyperRectangle_new0(); + void HyperRectangle_delete(HyperRectangle* self); + HyperRectangle* HyperRectangle_new (int dim); + HyperRectangle* HyperRectangle_clone (HyperRectangle* self); + HyperRectangle* HyperRectangle_ref (HyperRectangle* self); + void HyperRectangle_unref (HyperRectangle* self); + HyperRectangle* HyperRectangle_CreateUniverseRectangle (int dim); + double HyperRectangle_Distance (HyperRectangle* self, IKDTreeDomain* target); + bool HyperRectangle_IsInReach (HyperRectangle* self, IKDTreeDomain* target, double distRad); + + struct KDTreeBestEntry { + // Distance between this neighbour point and the target point. + double distance; + int distanceSq; + bool squared; + // The neighbour. + IKDTreeDomain* neighbour; + + }; + IKDTreeDomain* KDTreeBestEntry_Neighbour(KDTreeBestEntry* self); + void KDTreeBestEntry_delete(KDTreeBestEntry* self); + + struct KDTree { + // The current element + IKDTreeDomain* dr; + + // The splitting dimension for subtrees. + int splitDim; + + // The left and the right kd-subtree. + KDTree* left; + KDTree* right; + }; + void KDTree_delete (KDTree* self); + int KDTree_DistanceSq (IKDTreeDomain* t1, IKDTreeDomain* t2); + IKDTreeDomain* KDTree_GoodCandidate (ArrayList* exset, int* splitDim); + KDTree* KDTree_CreateKDTree (ArrayList* exset); + KDTree* KDTree_new0 (); + IKDTreeDomain* KDTree_NearestNeighbour (KDTree* self, IKDTreeDomain* target, double* resDist); + IKDTreeDomain* KDTree_NearestNeighbourI (KDTree* self, IKDTreeDomain* target, HyperRectangle* hr, + double maxDistSq, double* resDistSq, ArrayList* hrl); + SortedLimitedList* KDTree_NearestNeighbourList (KDTree* self, IKDTreeDomain* target, + double* resDist, int q); + IKDTreeDomain* KDTree_NearestNeighbourListI (KDTree* self, SortedLimitedList* best, + int q, IKDTreeDomain* target, HyperRectangle* hr, double maxDistSq, + double* resDistSq, ArrayList* hrl); + SortedLimitedList* KDTree_NearestNeighbourListBBF (KDTree* self, IKDTreeDomain* target, + int q, int searchSteps); + IKDTreeDomain* KDTree_NearestNeighbourListBBFI (KDTree* self, SortedLimitedList* best, + int q, IKDTreeDomain* target, HyperRectangle* hr, int maxDistSq, + int* resDistSq, SortedLimitedList* searchHr, int* searchSteps, + ArrayList* hrl); + +#endif //ndef APSCpp_useANN // end of kd-tree declarations + typedef struct Image DisplayImage; struct ImageMap { Modified: autopano-sift-C/trunk/CMakeLists.txt =================================================================== --- autopano-sift-C/trunk/CMakeLists.txt 2008-03-07 15:44:25 UTC (rev 2932) +++ autopano-sift-C/trunk/CMakeLists.txt 2008-03-07 18:18:51 UTC (rev 2933) @@ -1,39 +1,40 @@ -set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMakeModules ) +### +# CMakeLists.txt for autopano-sift-c +# +# Major upgrade March 2008 by TKSharpless +# adds sterographic projection and fast keypoint matching +# I have assigned it version mumber 2.5.0 +### -## global setup project(autopano-sift-C) # version set(V_MAJOR 2) -set(V_MINOR 4) -set(V_PATCH 1) +set(V_MINOR 5) +set(V_PATCH 0) set(PACKAGE_VERSION ${V_MAJOR}.${V_MINOR}.${V_PATCH}) +#use local CMake modules +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMakeModules ) + +# Put source root on the include search list +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) + +# The parent of root directory, for package searches +GET_FILENAME_COMPONENT( SOURCE_BASE_DIR ${CMAKE_SOURCE_DIR} PATH CACHE ) + IF (WIN32) # install into place in build-dir SET( CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/INSTALL/FILES CACHE FILEPATH "install prefix" FORCE) - ## - ## The directory that contains the hugin source root is a good - ## place to look for support packages, so post it in cache. - ## - ## Our FIND_PACKAGE calls modules will search SOURCE_BASE_DIR - ## after the local standard places - ## - # extract pathname from CMAKE_SOURCE_DIR (note result must be a local var) - STRING( REGEX REPLACE "(.*)/[^/]+$" "\\1" work "${CMAKE_SOURCE_DIR}" ) - # create the cache entry - SET( SOURCE_BASE_DIR ${work} CACHE FILEPATH "parent dir of hugin source root" ) - # 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) ENDIF(WIN32) ## -## Graphics libraries +## External libraries ## -# wxWidgets sub-packages will be used if native ones aren't found FIND_PACKAGE(TIFF REQUIRED) INCLUDE_DIRECTORIES(${TIFF_INCLUDE_DIR}) @@ -57,10 +58,6 @@ FIND_PACKAGE(PANO13 REQUIRED) INCLUDE_DIRECTORIES(${PANO13_INCLUDE_DIR}) -# now there is a source code in a subdirectory -# so put this one on the include search list -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) - #BUILD SETUP IF(NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING @@ -95,10 +92,6 @@ STRING(REPLACE /MD /MT CMAKE_C_FLAGS_MINSIZEREL ${CMAKE_C_FLAGS_MINSIZEREL}) STRING(REPLACE /MD /MT CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELWITHDEBINFO}) - # compile C code as C++ code. Allows variable declarations between statements, - # but CAUTION breaks modules whose headers declare them with extern "C"{} - ADD_DEFINITIONS(/TP) - # yes we DO have pano13 ADD_DEFINITIONS( /DHAS_PANO13 ) @@ -128,19 +121,30 @@ add_executable(autopano AutoPano.c) TARGET_LINK_LIBRARIES(autopano ${all_libs}) +# Nowozin's code has to be compiled as C++ with MSVC +# This used to be global, but now APSCpp has real C files +if ( MSVC ) + SET_TARGET_PROPERTIES( libsift generatekeys autopano + PROPERTIES COMPILE_FLAGS /TP + ) +endif (MSVC ) + install(TARGETS generatekeys autopano DESTINATION bin) # the code and cmake script for autopano-sift-c are in subdirectory APSCpp add_subdirectory( APSCpp ) - +# scripts to run the 2-part version under hugin +# (historical interest only) if (WIN32) + install(PROGRAMS autopano-c-complete.vbs DESTINATION bin) else (WIN32) install(PROGRAMS autopano-c-complete.sh DESTINATION bin) endif (WIN32) -# man pages +# documentation +install(FILES README README.1ST DESTINATION . ) FILE(GLOB MAN_PAGES_1 doc/*.1) FILE(GLOB MAN_PAGES_7 doc/*.7) install(FILES ${MAN_PAGES_1} DESTINATION share/man/man1) Modified: autopano-sift-C/trunk/MatchKeys.c =================================================================== --- autopano-sift-C/trunk/MatchKeys.c 2008-03-07 15:44:25 UTC (rev 2932) +++ autopano-sift-C/trunk/MatchKeys.c 2008-03-07 18:18:51 UTC (rev 2933) @@ -368,8 +368,11 @@ int minimumMatches, int bestMatches, bool useRANSAC, bool useAreaFiltration) { - MultiMatch_BuildGlobalKD (self); - MultiMatch_BuildGlobalMatchList (self); +// mod 06 Mar 2008 TKS to allow alternative primary matchers + if( ArrayList_Count( self->globalMatches ) == 0 ) { + MultiMatch_BuildGlobalKD (self); + MultiMatch_BuildGlobalMatchList (self); + } MultiMatch_PartitionMatches (self); Modified: autopano-sift-C/trunk/README.1ST =================================================================== --- autopano-sift-C/trunk/README.1ST 2008-03-07 15:44:25 UTC (rev 2932) +++ autopano-sift-C/trunk/README.1ST 2008-03-07 18:18:51 UTC (rev 2933) @@ -17,3 +17,27 @@ These files have suddenly appeared on the hugin patches page. It has been uploaded by an anonymous person. Thank you! +-------------------------- + +Upgrade to v. 2.5 March 2008 by TKSharpless (tks...@gm...) + +Internal image data changed from double to float, cutting memory +demand in the keypoint finder by almost half. + +New executable autopano-sift-c both finds and matches keypoints +without generating XML files. It can run under hugin 0.7 as an +alternate control point finder. When run from the command line it +can read image information from any PanoTools compatible script. + +If projection formats and angular sizes of the image are specified, +it converts to stereographic projection, which gives better results +with wide-angle lenses. + +Autopano-sift-c uses the much faster ANN kd-tree for keypoint matching +(but retains the option to use Nowozin's KDTree code for comparison). + +See README-autopano-sift-c.txt for details. + +The manpages in share/man are now quite out of date, but are still +installed in hopes someone will be moved to update them. + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: Jean-Luc C. (f5ibh) <jea...@gm...> - 2008-03-07 18:29:21
|
Le 07.03.2008 19:18:51, tks...@us... a écrit : >Revision: 2933 > http://hugin.svn.sourceforge.net/hugin/?rev=2933&view=rev >Author: tksharpless >Date: 2008-03-07 10:18:51 -0800 (Fri, 07 Mar 2008) > >Log Message: >----------- >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 > Doesnt build on Linux, many warnings and some errors: ... /usr/local/src/autopano-sift-c/autopano-sift-c-2.4/APSCpp/ APSCpp_main.cpp:105: warning: deprecated conversion from string constant to ‘char*’ /usr/local/src/autopano-sift-c/autopano-sift-c-2.4/APSCpp/ APSCpp_main.cpp: In function ‘void RefineKeypoints(ArrayList*, int, int)’: /usr/local/src/autopano-sift-c/autopano-sift-c-2.4/APSCpp/ APSCpp_main.cpp:192: warning: deprecated conversion from string constant to ‘char*’ /usr/local/src/autopano-sift-c/autopano-sift-c-2.4/APSCpp/ APSCpp_main.cpp: In function ‘int YesNoOption(char*, char*, int*)’: /usr/local/src/autopano-sift-c/autopano-sift-c-2.4/APSCpp/ APSCpp_main.cpp:412: warning: deprecated conversion from string constant to ‘char*’ /usr/local/src/autopano-sift-c/autopano-sift-c-2.4/APSCpp/ APSCpp_main.cpp: In function ‘void WritePTOFile(FILE*, MultiMatch*, ArrayList*, ArrayList*, BondBall*, int, int, int)’: /usr/local/src/autopano-sift-c/autopano-sift-c-2.4/APSCpp/ APSCpp_main.cpp:436: error: invalid conversion from ‘void (*) (Resolution*)’ to ‘void*’ /usr/local/src/autopano-sift-c/autopano-sift-c-2.4/APSCpp/ APSCpp_main.cpp:436: error: initializing argument 1 of ‘ArrayList* ArrayList_new0(void*)’ /usr/local/src/autopano-sift-c/autopano-sift-c-2.4/APSCpp/ APSCpp_main.cpp:511: error: cast from ‘void*’ to ‘int’ loses precision /usr/local/src/autopano-sift-c/autopano-sift-c-2.4/APSCpp/ APSCpp_main.cpp:511: error: cast from ‘void*’ to ‘int’ loses precision /usr/local/src/autopano-sift-c/autopano-sift-c-2.4/APSCpp/ APSCpp_main.cpp:515: error: cast from ‘void*’ to ‘int’ loses precision /usr/local/src/autopano-sift-c/autopano-sift-c-2.4/APSCpp/ APSCpp_main.cpp:515: error: cast from ‘void*’ to ‘int’ loses precision /usr/local/src/autopano-sift-c/autopano-sift-c-2.4/APSCpp/ APSCpp_main.cpp:524: warning: deprecated conversion from string constant to ‘char*’ /usr/local/src/autopano-sift-c/autopano-sift-c-2.4/APSCpp/ APSCpp_main.cpp:569: warning: deprecated conversion from string constant to ‘char*’ Regards Jean-Luc |
From: <tks...@us...> - 2008-03-08 16:16:02
|
Revision: 2937 http://hugin.svn.sourceforge.net/hugin/?rev=2937&view=rev Author: tksharpless Date: 2008-03-08 08:16:00 -0800 (Sat, 08 Mar 2008) Log Message: ----------- fixes for C++ compile errors on Linux Modified Paths: -------------- autopano-sift-C/trunk/APSCpp/APSCpp.cpp autopano-sift-C/trunk/APSCpp/APSCpp_main.cpp autopano-sift-C/trunk/AutoPanoSift.h autopano-sift-C/trunk/Utils.c Modified: autopano-sift-C/trunk/APSCpp/APSCpp.cpp =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp.cpp 2008-03-08 14:55:26 UTC (rev 2936) +++ autopano-sift-C/trunk/APSCpp/APSCpp.cpp 2008-03-08 16:16:00 UTC (rev 2937) @@ -392,7 +392,7 @@ ArrayList * globalNaturalKeypoints = 0; int i; - if( mode == 0 ) globalNaturalKeypoints = ArrayList_new0 (KeypointN_delete); + if( mode == 0 ) globalNaturalKeypoints = ArrayList_new0 ((void *) KeypointN_delete); if( pdi ){ // build remapping function at input scale CamLens * psp, * pdp; Modified: autopano-sift-C/trunk/APSCpp/APSCpp_main.cpp =================================================================== --- autopano-sift-C/trunk/APSCpp/APSCpp_main.cpp 2008-03-08 14:55:26 UTC (rev 2936) +++ autopano-sift-C/trunk/APSCpp/APSCpp_main.cpp 2008-03-08 16:16:00 UTC (rev 2937) @@ -433,7 +433,7 @@ int imageIndex = 0; HashTable* imageNameTab = HashTable_new0 (NULL, NULL); - ArrayList* resolutions = ArrayList_new0 (Resolution_delete); + 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); @@ -764,7 +764,7 @@ projectfile = argv[optionCount + 1]; WriteLine("Reading project file %s", projectfile ); // enable ++ mode by creating DIlist - DIlist = ArrayList_new0( DIinfo_delete ); + DIlist = ArrayList_new0( (void *) DIinfo_delete ); // read the proect file image info into DIlist, or die if( LoadProjectImages( argv[optionCount + 1], DIlist ) ==0 ){ WriteLine ("Error reading project file."); @@ -772,7 +772,7 @@ } } else if( globFmt >= 0 && globFov > 0 ){ // enable ++ mode - DIlist = ArrayList_new0( DIinfo_delete ); + DIlist = ArrayList_new0( (void *) DIinfo_delete ); } if( DIlist ) WriteLine(" Stereographic projection enabled."); @@ -900,3 +900,4 @@ return 0; } + Modified: autopano-sift-C/trunk/AutoPanoSift.h =================================================================== --- autopano-sift-C/trunk/AutoPanoSift.h 2008-03-08 14:55:26 UTC (rev 2936) +++ autopano-sift-C/trunk/AutoPanoSift.h 2008-03-08 16:16:00 UTC (rev 2937) @@ -38,9 +38,6 @@ #endif #include "math.h" -#ifdef __cplusplus -} -#endif #define bool int #define true 1 @@ -62,10 +59,10 @@ #define M_PI 3.14159265358979323846 #endif -void Write(char* fmt, ...); -void WriteLine(char* fmt, ...); -void WriteError(char* fmt, ...); -void FatalError(char* fmt, ...); +void Write(const char* fmt, ...); +void WriteLine(const char* fmt, ...); +void WriteError(const char* fmt, ...); +void FatalError(const char* fmt, ...); char* FileNameToFullPath(char* filename); char* FullPathToFileName(char* fullpath); @@ -122,7 +119,7 @@ void** items; void* deletefn; }; -ArrayList* ArrayList_new0(void* deletefn); +ArrayList* ArrayList_new0(void *); void ArrayList_init(ArrayList* self, void* deletefn); ArrayList* ArrayList_new(int count, void* deletefn); void ArrayList_delete(ArrayList* self); @@ -802,4 +799,7 @@ BondBall* MultiMatch_BuildBondBall (MultiMatch* self, ArrayList* ransacFiltered, int bottomDefault); +#ifdef __cplusplus +} +#endif #endif // AUTOPANOS_SIFT_H Modified: autopano-sift-C/trunk/Utils.c =================================================================== --- autopano-sift-C/trunk/Utils.c 2008-03-08 14:55:26 UTC (rev 2936) +++ autopano-sift-C/trunk/Utils.c 2008-03-08 16:16:00 UTC (rev 2937) @@ -19,7 +19,7 @@ #endif -void Write(char* fmt, ...) { +void Write(const char* fmt, ...) { va_list ap; va_start(ap, fmt); @@ -28,7 +28,7 @@ fflush(stdout); } -void WriteLine(char* fmt, ...) { +void WriteLine(const char* fmt, ...) { va_list ap; va_start(ap, fmt); @@ -38,7 +38,7 @@ fflush(stdout); } -void WriteError(char* fmt, ...) { +void WriteError(const char* fmt, ...) { va_list ap; va_start(ap, fmt); @@ -48,7 +48,7 @@ fflush(stderr); } -void FatalError(char* fmt, ...) { +void FatalError(const char* fmt, ...) { va_list ap; va_start(ap, fmt); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bru...@us...> - 2008-04-24 21:00:20
|
Revision: 3036 http://hugin.svn.sourceforge.net/hugin/?rev=3036&view=rev Author: brunopostle Date: 2008-04-24 14:00:17 -0700 (Thu, 24 Apr 2008) Log Message: ----------- Don't try and install a file called /usr/README Modified Paths: -------------- autopano-sift-C/trunk/APSCpp/CMakeLists.txt autopano-sift-C/trunk/CMakeLists.txt Modified: autopano-sift-C/trunk/APSCpp/CMakeLists.txt =================================================================== --- autopano-sift-C/trunk/APSCpp/CMakeLists.txt 2008-04-24 18:50:51 UTC (rev 3035) +++ autopano-sift-C/trunk/APSCpp/CMakeLists.txt 2008-04-24 21:00:17 UTC (rev 3036) @@ -29,4 +29,3 @@ TARGET_LINK_LIBRARIES( autopano-sift-c ANN ${all_libs} ) install(TARGETS autopano-sift-c DESTINATION bin) -install(FILES README-autopano-sift-c.txt DESTINATION . ) Modified: autopano-sift-C/trunk/CMakeLists.txt =================================================================== --- autopano-sift-C/trunk/CMakeLists.txt 2008-04-24 18:50:51 UTC (rev 3035) +++ autopano-sift-C/trunk/CMakeLists.txt 2008-04-24 21:00:17 UTC (rev 3036) @@ -144,7 +144,6 @@ # documentation -install(FILES README README.1ST DESTINATION . ) FILE(GLOB MAN_PAGES_1 doc/*.1) FILE(GLOB MAN_PAGES_7 doc/*.7) install(FILES ${MAN_PAGES_1} DESTINATION share/man/man1) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |