ArrayList* MatchKeys_FilterJoins (ArrayList* matches) { HashTable* ht = HashTable_new0 (NULL, NULL); // Count the references to each keypoint int i; for(i=0; i<ArrayList_Count(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); HashTable_SetItem(ht, m->kp2, (void*)(rI + 1)); } ArrayList* survivors = ArrayList_new0(NULL); int removed = 0; int j; for(j=0; j<ArrayList_Count(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) ArrayList_AddItem(survivors, m); else removed += 1; } HashTable_delete(ht); return (survivors); }
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); }
void testHashTable() { typedef struct { uint64 key; uint64 data; } TestData; int initialCapacity = 1000; int numEntries = 5000; // make hash table HashTable htb = HashTable_make(sizeof(uint64), sizeof(uint64), initialCapacity); // insert data, and some duplicates TestData entries[numEntries]; int i; for (i = 0; i < numEntries; i++) { entries[i].key = rand(); entries[i].data = rand(); HashTable_insert(&htb, &(entries[i].key), &(entries[i].data)); // insert a previous duplicate if (i > 10) { HashTable_insert(&htb, &(entries[i-10].key), &(entries[i-10].data)); } assert(HashTable_size(&htb) == i+1); assert(HashTable_capacity(&htb) > i); } // check data for (i = 0; i < numEntries; i++) { uint64 *data = (uint64*)HashTable_get(&htb, &(entries[i].key)); assert(data != NULL); assert(*data == entries[i].data); } assert(HashTable_size(&htb) == numEntries); assert(HashTable_capacity(&htb) >= numEntries); // remove and re-insert some elements int numRemoved = 0; for (i = 0; i < numEntries; i = i + 2) { HashTable_delete(&htb, &(entries[i].key)); numRemoved++; assert(HashTable_size(&htb) == numEntries - numRemoved); assert(HashTable_get(&htb, &(entries[i].key)) == NULL); } for (i = 0; i < numEntries; i = i + 2) { HashTable_insert(&htb, &(entries[i].key), &(entries[i].data)); numRemoved--; assert(HashTable_size(&htb) == numEntries - numRemoved); assert(HashTable_get(&htb, &(entries[i].key)) != NULL); } // save to file, destroy, and recreate from file char *filename = "/tmp/roomyTestHashTable"; HashTable_fileSave(&htb, filename); HashTable_destroy(&htb); htb = HashTable_makeFromFiles(filename); for (i = 0; i < numEntries; i++) { uint64 *data = (uint64*)HashTable_get(&htb, &(entries[i].key)); assert(data != NULL); assert(*data == entries[i].data); } assert(HashTable_size(&htb) == numEntries); assert(HashTable_capacity(&htb) >= numEntries); HashTable_destroy(&htb); // make using mmap htb = HashTable_makeMapped(filename); for (i = 0; i < numEntries; i++) { uint64 *data = (uint64*)HashTable_get(&htb, &(entries[i].key)); assert(data != NULL); assert(*data == entries[i].data); } assert(HashTable_size(&htb) == numEntries); assert(HashTable_capacity(&htb) >= numEntries); HashTable_destroy(&htb); assert(HashTable_removeFiles(filename) == 0); printf("HASH TABLE PASSED TESTS\n"); }