void KLTChangeTCPyramid( KLT_TrackingContext tc, int search_range) { float window_halfwidth; float subsampling; /* Check window size (and correct if necessary) */ if (tc->window_width % 2 != 1) { tc->window_width = tc->window_width+1; KLTWarning("(KLTChangeTCPyramid) Window width must be odd. " "Changing to %d.\n", tc->window_width); } if (tc->window_height % 2 != 1) { tc->window_height = tc->window_height+1; KLTWarning("(KLTChangeTCPyramid) Window height must be odd. " "Changing to %d.\n", tc->window_height); } if (tc->window_width < 3) { tc->window_width = 3; KLTWarning("(KLTChangeTCPyramid) Window width must be at least three. \n" "Changing to %d.\n", tc->window_width); } if (tc->window_height < 3) { tc->window_height = 3; KLTWarning("(KLTChangeTCPyramid) Window height must be at least three. \n" "Changing to %d.\n", tc->window_height); } window_halfwidth = min(tc->window_width,tc->window_height)/2; subsampling = ((float) search_range) / window_halfwidth; if (subsampling < 1.0) { /* 1.0 = 0+1 */ tc->nPyramidLevels = 1; } else if (subsampling <= 3.0) { /* 3.0 = 2+1 */ tc->nPyramidLevels = 2; tc->subsampling = 2; } else if (subsampling <= 5.0) { /* 5.0 = 4+1 */ tc->nPyramidLevels = 2; tc->subsampling = 4; } else if (subsampling <= 9.0) { /* 9.0 = 8+1 */ tc->nPyramidLevels = 2; tc->subsampling = 8; } else { /* The following lines are derived from the formula: search_range = window_halfwidth * \sum_{i=0}^{nPyramidLevels-1} 8^i, which is the same as: search_range = window_halfwidth * (8^nPyramidLevels - 1)/(8 - 1). Then, the value is rounded up to the nearest integer. */ float val = logf(7.0*subsampling+1.0)/logf(8.0); tc->nPyramidLevels = (int) (val + 0.99); tc->subsampling = 8; } }
void pnmReadHeader( FILE *fp, int *magic, int *ncols, int *nrows, int *maxval) { char line[LENGTH]; /* Read magic number */ _getNextString(fp, line); if (line[0] != 'P') KLTError("(pnmReadHeader) Magic number does not begin with 'P', " "but with a '%c'", line[0]); sscanf(line, "P%d", magic); /* Read size, skipping comments */ _getNextString(fp, line); *ncols = atoi(line); _getNextString(fp, line); *nrows = atoi(line); if (*ncols < 0 || *nrows < 0 || *ncols > 10000 || *nrows > 10000) KLTError("(pnmReadHeader) The dimensions %d x %d are unacceptable", *ncols, *nrows); /* Read maxval, skipping comments */ _getNextString(fp, line); *maxval = atoi(line); fread(line, 1, 1, fp); /* Read newline which follows maxval */ if (*maxval != 255) KLTWarning("(pnmReadHeader) Maxval is not 255, but %d", *maxval); }
void point_gradients(register int *ptr, KLT_TrackingContext tc, int *npoints, int nrows, int ncols, _KLT_FloatImage gradx, _KLT_FloatImage grady) { register float gx, gy; register float gxx, gxy, gyy; register int xx, yy; int x, y, i; float val; int window_hw, window_hh; int borderx = tc->borderx; /* Must not touch cols */ int bordery = tc->bordery; /* lost by convolution */ unsigned int limit = 1; window_hw = tc->window_width/2; window_hh = tc->window_height/2; if (borderx < window_hw) borderx = window_hw; if (bordery < window_hh) bordery = window_hh; // Find largest value of an int for (i = 0 ; i < sizeof(int) ; i++) limit *= 256; limit = limit/2 - 1; /* For most of the pixels in the image, do ... */ for (y = bordery ; y < nrows - bordery ; y += tc->nSkippedPixels + 1) for (x = borderx ; x < ncols - borderx ; x += tc->nSkippedPixels + 1) { /* Sum the gradients in the surrounding window */ gxx = 0; gxy = 0; gyy = 0; for (yy = y-window_hh ; yy <= y+window_hh ; yy++){ for (xx = x-window_hw ; xx <= x+window_hw ; xx++) { gx = *(gradx->data + ncols*yy+xx); gy = *(grady->data + ncols*yy+xx); gxx += gx * gx; gxy += gx * gy; gyy += gy * gy; } } /* Store the trackability of the pixel as the minimum of the two eigenvalues */ *ptr++ = x; *ptr++ = y; val = _minEigenvalue(gxx, gxy, gyy); if (val > limit) { KLTWarning("(_KLTSelectGoodFeatures) minimum eigenvalue %f is " "greater than the capacity of an int; setting " "to maximum value", val); val = (float) limit; } *ptr++ = (int) val; *npoints = *npoints + 1; } }
void KLTWriteFeatureListToPPM( KLT_FeatureList featurelist, KLT_PixelType *greyimg, int ncols, int nrows, char *filename) { int nbytes = ncols * nrows * sizeof(char); uchar *redimg, *grnimg, *bluimg; int offset; int x, y, xx, yy; int i; if (KLT_verbose >= 1) fprintf(stderr, "(KLT) Writing %d features to PPM file: '%s'\n", KLTCountRemainingFeatures(featurelist), filename); /* Allocate memory for component images */ redimg = (uchar *) malloc(nbytes); grnimg = (uchar *) malloc(nbytes); bluimg = (uchar *) malloc(nbytes); if (redimg == NULL || grnimg == NULL || bluimg == NULL) KLTError("(KLTWriteFeaturesToPPM) Out of memory\n"); /* Copy grey image to component images */ if (sizeof(KLT_PixelType) != 1) KLTWarning("(KLTWriteFeaturesToPPM) KLT_PixelType is not uchar"); memcpy(redimg, greyimg, nbytes); memcpy(grnimg, greyimg, nbytes); memcpy(bluimg, greyimg, nbytes); /* Overlay features in red */ for (i = 0 ; i < featurelist->nFeatures ; i++) if (featurelist->feature[i]->val >= 0) { x = (int) (featurelist->feature[i]->x + 0.5); y = (int) (featurelist->feature[i]->y + 0.5); for (yy = y - 1 ; yy <= y + 1 ; yy++) for (xx = x - 1 ; xx <= x + 1 ; xx++) if (xx >= 0 && yy >= 0 && xx < ncols && yy < nrows) { offset = yy * ncols + xx; *(redimg + offset) = 255; *(grnimg + offset) = 0; *(bluimg + offset) = 0; } } /* Write to PPM file */ ppmWriteFileRGB(filename, redimg, grnimg, bluimg, ncols, nrows); /* Free memory */ free(redimg); free(grnimg); free(bluimg); }
void _KLTSelectGoodFeatures( KLT_TrackingContext tc, KLT_PixelType *img, int ncols, int nrows, KLT_FeatureList featurelist, selectionMode mode) { // added timer for this function //Timer selectTimer; _KLT_FloatImage floatimg, gradx, grady; int window_hw, window_hh; int *pointlist; int npoints = 0; KLT_BOOL overwriteAllFeatures = (mode == SELECTING_ALL) ? TRUE : FALSE; KLT_BOOL floatimages_created = FALSE; // Initialize times //initTimer(&selectTimer, "select Feature Time"); // Start timer //startTimer(&selectTimer); /* Check window size (and correct if necessary) */ if (tc->window_width % 2 != 1) { tc->window_width = tc->window_width+1; KLTWarning("Tracking context's window width must be odd. " "Changing to %d.\n", tc->window_width); } if (tc->window_height % 2 != 1) { tc->window_height = tc->window_height+1; KLTWarning("Tracking context's window height must be odd. " "Changing to %d.\n", tc->window_height); } if (tc->window_width < 3) { tc->window_width = 3; KLTWarning("Tracking context's window width must be at least three. \n" "Changing to %d.\n", tc->window_width); } if (tc->window_height < 3) { tc->window_height = 3; KLTWarning("Tracking context's window height must be at least three. \n" "Changing to %d.\n", tc->window_height); } window_hw = tc->window_width/2; window_hh = tc->window_height/2; // After windows //stopTimer(&selectTimer); //printf("Time for checking the window size = %f\n", getTime(selectTimer)); // Restart for point list //restartTimer(&selectTimer); /* Create pointlist, which is a simplified version of a featurelist, */ /* for speed. Contains only integer locations and values. */ pointlist = (int *) malloc(ncols * nrows * 3 * sizeof(int)); // stop and print //stopTimer(&selectTimer); //printf("Time for initializing pointlist = %f\n", getTime(selectTimer)); // Restart for point list //restartTimer(&selectTimer); /* Create temporary images, etc. */ if (mode == REPLACING_SOME && tc->sequentialMode && tc->pyramid_last != NULL) { floatimg = ((_KLT_Pyramid) tc->pyramid_last)->img[0]; gradx = ((_KLT_Pyramid) tc->pyramid_last_gradx)->img[0]; grady = ((_KLT_Pyramid) tc->pyramid_last_grady)->img[0]; assert(gradx != NULL); assert(grady != NULL); } else { floatimages_created = TRUE; floatimg = _KLTCreateFloatImage(ncols, nrows); gradx = _KLTCreateFloatImage(ncols, nrows); grady = _KLTCreateFloatImage(ncols, nrows); if (tc->smoothBeforeSelecting) { _KLT_FloatImage tmpimg; tmpimg = _KLTCreateFloatImage(ncols, nrows); _KLTToFloatImage(img, ncols, nrows, tmpimg); _KLTComputeSmoothedImage(tmpimg, _KLTComputeSmoothSigma(tc), floatimg); _KLTFreeFloatImage(tmpimg); } else _KLTToFloatImage(img, ncols, nrows, floatimg); /* Compute gradient of image in x and y direction */ _KLTComputeGradients(floatimg, tc->grad_sigma, gradx, grady); } // stop and print //stopTimer(&selectTimer); //printf("Time for creating temporary mages = %f\n", getTime(selectTimer)); // Restart for point list //restartTimer(&selectTimer); /* Write internal images */ if (tc->writeInternalImages) { _KLTWriteFloatImageToPGM(floatimg, "kltimg_sgfrlf.pgm"); _KLTWriteFloatImageToPGM(gradx, "kltimg_sgfrlf_gx.pgm"); _KLTWriteFloatImageToPGM(grady, "kltimg_sgfrlf_gy.pgm"); } // stop and print //stopTimer(&selectTimer); //printf("Time for writing internal images = %f\n", getTime(selectTimer)); /* Compute trackability of each image pixel as the minimum of the two eigenvalues of the Z matrix */ {register int *ptr; /* register float gx, gy; register float gxx, gxy, gyy; register int xx, yy; float val; unsigned int limit = 1; int borderx = tc->borderx; // Must not touch cols int bordery = tc->bordery; // lost by convolution int x, y; int i; */ /* if (borderx < window_hw) borderx = window_hw; if (bordery < window_hh) bordery = window_hh; // Find largest value of an int for (i = 0 ; i < sizeof(int) ; i++) limit *= 256; limit = limit/2 - 1; */ /* For most of the pixels in the image, do ... */ ptr = pointlist; point_gradients(ptr, tc, &npoints, nrows, ncols, gradx, grady); /* for (y = bordery ; y < nrows - bordery ; y += tc->nSkippedPixels + 1) for (x = borderx ; x < ncols - borderx ; x += tc->nSkippedPixels + 1) { // Sum the gradients in the surrounding window gxx = 0; gxy = 0; gyy = 0; for (yy = y-window_hh ; yy <= y+window_hh ; yy++) for (xx = x-window_hw ; xx <= x+window_hw ; xx++) { gx = *(gradx->data + ncols*yy+xx); gy = *(grady->data + ncols*yy+xx); gxx += gx * gx; gxy += gx * gy; gyy += gy * gy; } // Store the trackability of the pixel as the minimum // of the two eigenvalues *ptr++ = x; *ptr++ = y; val = _minEigenvalue(gxx, gxy, gyy); if (val > limit) { KLTWarning("(_KLTSelectGoodFeatures) minimum eigenvalue %f is " "greater than the capacity of an int; setting " "to maximum value", val); val = (float) limit; } *ptr++ = (int) val; npoints++; } */ } // Restart for point list //restartTimer(&selectTimer); /* Sort the features */ _sortPointList(pointlist, npoints); // printing this loop //stopTimer(&selectTimer); //printf("Time for sorting the pointlist = %f\n", getTime(selectTimer)); // Restart for point list //restartTimer(&selectTimer); /* Check tc->mindist */ if (tc->mindist < 0) { KLTWarning("(_KLTSelectGoodFeatures) Tracking context field tc->mindist " "is negative (%d); setting to zero", tc->mindist); tc->mindist = 0; } // printing this loop //stopTimer(&selectTimer); //printf("Time for checking midlist = %f\n", getTime(selectTimer)); // Restart for point list //restartTimer(&selectTimer); /* Enforce minimum distance between features */ _enforceMinimumDistance( pointlist, npoints, featurelist, ncols, nrows, tc->mindist, tc->min_eigenvalue, overwriteAllFeatures); // printing this loop //stopTimer(&selectTimer); //printf("Time for enforcing minimum distance = %f\n", getTime(selectTimer)); // Restart for point list //restartTimer(&selectTimer); /* Free memory */ free(pointlist); if (floatimages_created) { _KLTFreeFloatImage(floatimg); _KLTFreeFloatImage(gradx); _KLTFreeFloatImage(grady); } // printing this loop //stopTimer(&selectTimer); //printf("Time for freeing stuff = %f\n", getTime(selectTimer)); }
void KLTUpdateTCBorder( KLT_TrackingContext tc) { float val; int pyramid_gauss_hw; int smooth_gauss_hw; int gauss_width, gaussderiv_width; int num_levels = tc->nPyramidLevels; int n_invalid_pixels; int window_hw; int ss = tc->subsampling; int ss_power; int border; int i; /* Check window size (and correct if necessary) */ if (tc->window_width % 2 != 1) { tc->window_width = tc->window_width+1; KLTWarning("(KLTUpdateTCBorder) Window width must be odd. " "Changing to %d.\n", tc->window_width); } if (tc->window_height % 2 != 1) { tc->window_height = tc->window_height+1; KLTWarning("(KLTUpdateTCBorder) Window height must be odd. " "Changing to %d.\n", tc->window_height); } if (tc->window_width < 3) { tc->window_width = 3; KLTWarning("(KLTUpdateTCBorder) Window width must be at least three. \n" "Changing to %d.\n", tc->window_width); } if (tc->window_height < 3) { tc->window_height = 3; KLTWarning("(KLTUpdateTCBorder) Window height must be at least three. \n" "Changing to %d.\n", tc->window_height); } window_hw = max(tc->window_width, tc->window_height)/2; /* Find widths of convolution windows */ _KLTGetKernelWidths(_KLTComputeSmoothSigma(tc), &gauss_width, &gaussderiv_width); smooth_gauss_hw = gauss_width/2; _KLTGetKernelWidths(_pyramidSigma(tc), &gauss_width, &gaussderiv_width); pyramid_gauss_hw = gauss_width/2; /* Compute the # of invalid pixels at each level of the pyramid. n_invalid_pixels is computed with respect to the ith level of the pyramid. So, e.g., if n_invalid_pixels = 5 after the first iteration, then there are 5 invalid pixels in level 1, which translated means 5*subsampling invalid pixels in the original level 0. */ n_invalid_pixels = smooth_gauss_hw; for (i = 1 ; i < num_levels ; i++) { val = ((float) n_invalid_pixels + pyramid_gauss_hw) / ss; n_invalid_pixels = (int) (val + 0.99); /* Round up */ } /* ss_power = ss^(num_levels-1) */ ss_power = 1; for (i = 1 ; i < num_levels ; i++) ss_power *= ss; /* Compute border by translating invalid pixels back into */ /* original image */ border = (n_invalid_pixels + window_hw) * ss_power; tc->borderx = border; tc->bordery = border; }
void KLTTrackFeatures( KLT_TrackingContext tc, KLT_PixelType *img1, KLT_PixelType *img2, int ncols, int nrows, KLT_FeatureList featurelist) { _KLT_FloatImage tmpimg, floatimg1, floatimg2; _KLT_Pyramid pyramid1, pyramid1_gradx, pyramid1_grady, pyramid2, pyramid2_gradx, pyramid2_grady; float subsampling = (float) tc->subsampling; float xloc, yloc, xlocout, ylocout; int val; int indx, r; KLT_BOOL floatimg1_created = FALSE; int i; if (KLT_verbose >= 1) { fprintf(stderr, "(KLT) Tracking %d features in a %d by %d image... ", KLTCountRemainingFeatures(featurelist), ncols, nrows); fflush(stderr); } /* Check window size (and correct if necessary) */ if (tc->window_width % 2 != 1) { tc->window_width = tc->window_width+1; KLTWarning("Tracking context's window width must be odd. " "Changing to %d.\n", tc->window_width); } if (tc->window_height % 2 != 1) { tc->window_height = tc->window_height+1; KLTWarning("Tracking context's window height must be odd. " "Changing to %d.\n", tc->window_height); } if (tc->window_width < 3) { tc->window_width = 3; KLTWarning("Tracking context's window width must be at least three. \n" "Changing to %d.\n", tc->window_width); } if (tc->window_height < 3) { tc->window_height = 3; KLTWarning("Tracking context's window height must be at least three. \n" "Changing to %d.\n", tc->window_height); } /* Create temporary image */ tmpimg = _KLTCreateFloatImage(ncols, nrows); /* Process first image by converting to float, smoothing, computing */ /* pyramid, and computing gradient pyramids */ if (tc->sequentialMode && tc->pyramid_last != NULL) { pyramid1 = (_KLT_Pyramid) tc->pyramid_last; pyramid1_gradx = (_KLT_Pyramid) tc->pyramid_last_gradx; pyramid1_grady = (_KLT_Pyramid) tc->pyramid_last_grady; if (pyramid1->ncols[0] != ncols || pyramid1->nrows[0] != nrows) KLTError("(KLTTrackFeatures) Size of incoming image (%d by %d) " "is different from size of previous image (%d by %d)\n", ncols, nrows, pyramid1->ncols[0], pyramid1->nrows[0]); assert(pyramid1_gradx != NULL); assert(pyramid1_grady != NULL); } else { floatimg1_created = TRUE; floatimg1 = _KLTCreateFloatImage(ncols, nrows); _KLTToFloatImage(img1, ncols, nrows, tmpimg); _KLTComputeSmoothedImage(tmpimg, _KLTComputeSmoothSigma(tc), floatimg1); pyramid1 = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); _KLTComputePyramid(floatimg1, pyramid1, tc->pyramid_sigma_fact); pyramid1_gradx = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); pyramid1_grady = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); for (i = 0 ; i < tc->nPyramidLevels ; i++) _KLTComputeGradients(pyramid1->img[i], tc->grad_sigma, pyramid1_gradx->img[i], pyramid1_grady->img[i]); } /* Do the same thing with second image */ floatimg2 = _KLTCreateFloatImage(ncols, nrows); _KLTToFloatImage(img2, ncols, nrows, tmpimg); _KLTComputeSmoothedImage(tmpimg, _KLTComputeSmoothSigma(tc), floatimg2); pyramid2 = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); _KLTComputePyramid(floatimg2, pyramid2, tc->pyramid_sigma_fact); pyramid2_gradx = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); pyramid2_grady = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); for (i = 0 ; i < tc->nPyramidLevels ; i++) _KLTComputeGradients(pyramid2->img[i], tc->grad_sigma, pyramid2_gradx->img[i], pyramid2_grady->img[i]); /* Write internal images */ if (tc->writeInternalImages) { char fname[80]; for (i = 0 ; i < tc->nPyramidLevels ; i++) { sprintf(fname, "kltimg_tf_i%d.pgm", i); _KLTWriteFloatImageToPGM(pyramid1->img[i], fname); sprintf(fname, "kltimg_tf_i%d_gx.pgm", i); _KLTWriteFloatImageToPGM(pyramid1_gradx->img[i], fname); sprintf(fname, "kltimg_tf_i%d_gy.pgm", i); _KLTWriteFloatImageToPGM(pyramid1_grady->img[i], fname); sprintf(fname, "kltimg_tf_j%d.pgm", i); _KLTWriteFloatImageToPGM(pyramid2->img[i], fname); sprintf(fname, "kltimg_tf_j%d_gx.pgm", i); _KLTWriteFloatImageToPGM(pyramid2_gradx->img[i], fname); sprintf(fname, "kltimg_tf_j%d_gy.pgm", i); _KLTWriteFloatImageToPGM(pyramid2_grady->img[i], fname); } } /* For each feature, do ... */ for (indx = 0 ; indx < featurelist->nFeatures ; indx++) { /* Only track features that are not lost */ if (featurelist->feature[indx]->val >= 0) { xloc = featurelist->feature[indx]->x; yloc = featurelist->feature[indx]->y; /* Transform location to coarsest resolution */ for (r = tc->nPyramidLevels - 1 ; r >= 0 ; r--) { xloc /= subsampling; yloc /= subsampling; } xlocout = xloc; ylocout = yloc; /* Beginning with coarsest resolution, do ... */ for (r = tc->nPyramidLevels - 1 ; r >= 0 ; r--) { /* Track feature at current resolution */ xloc *= subsampling; yloc *= subsampling; xlocout *= subsampling; ylocout *= subsampling; val = _trackFeature(xloc, yloc, &xlocout, &ylocout, pyramid1->img[r], pyramid1_gradx->img[r], pyramid1_grady->img[r], pyramid2->img[r], pyramid2_gradx->img[r], pyramid2_grady->img[r], tc->window_width, tc->window_height, tc->step_factor, tc->max_iterations, tc->min_determinant, tc->min_displacement, tc->max_residue, tc->lighting_insensitive); if (val==KLT_SMALL_DET || val==KLT_OOB) break; } /* Record feature */ if (val == KLT_OOB) { featurelist->feature[indx]->x = -1.0; featurelist->feature[indx]->y = -1.0; featurelist->feature[indx]->val = KLT_OOB; if( featurelist->feature[indx]->aff_img ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img); if( featurelist->feature[indx]->aff_img_gradx ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_gradx); if( featurelist->feature[indx]->aff_img_grady ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_grady); featurelist->feature[indx]->aff_img = NULL; featurelist->feature[indx]->aff_img_gradx = NULL; featurelist->feature[indx]->aff_img_grady = NULL; } else if (_outOfBounds(xlocout, ylocout, ncols, nrows, tc->borderx, tc->bordery)) { featurelist->feature[indx]->x = -1.0; featurelist->feature[indx]->y = -1.0; featurelist->feature[indx]->val = KLT_OOB; if( featurelist->feature[indx]->aff_img ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img); if( featurelist->feature[indx]->aff_img_gradx ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_gradx); if( featurelist->feature[indx]->aff_img_grady ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_grady); featurelist->feature[indx]->aff_img = NULL; featurelist->feature[indx]->aff_img_gradx = NULL; featurelist->feature[indx]->aff_img_grady = NULL; } else if (val == KLT_SMALL_DET) { featurelist->feature[indx]->x = -1.0; featurelist->feature[indx]->y = -1.0; featurelist->feature[indx]->val = KLT_SMALL_DET; if( featurelist->feature[indx]->aff_img ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img); if( featurelist->feature[indx]->aff_img_gradx ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_gradx); if( featurelist->feature[indx]->aff_img_grady ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_grady); featurelist->feature[indx]->aff_img = NULL; featurelist->feature[indx]->aff_img_gradx = NULL; featurelist->feature[indx]->aff_img_grady = NULL; } else if (val == KLT_LARGE_RESIDUE) { featurelist->feature[indx]->x = -1.0; featurelist->feature[indx]->y = -1.0; featurelist->feature[indx]->val = KLT_LARGE_RESIDUE; if( featurelist->feature[indx]->aff_img ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img); if( featurelist->feature[indx]->aff_img_gradx ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_gradx); if( featurelist->feature[indx]->aff_img_grady ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_grady); featurelist->feature[indx]->aff_img = NULL; featurelist->feature[indx]->aff_img_gradx = NULL; featurelist->feature[indx]->aff_img_grady = NULL; } else if (val == KLT_MAX_ITERATIONS) { featurelist->feature[indx]->x = -1.0; featurelist->feature[indx]->y = -1.0; featurelist->feature[indx]->val = KLT_MAX_ITERATIONS; if( featurelist->feature[indx]->aff_img ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img); if( featurelist->feature[indx]->aff_img_gradx ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_gradx); if( featurelist->feature[indx]->aff_img_grady ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_grady); featurelist->feature[indx]->aff_img = NULL; featurelist->feature[indx]->aff_img_gradx = NULL; featurelist->feature[indx]->aff_img_grady = NULL; } else { featurelist->feature[indx]->x = xlocout; featurelist->feature[indx]->y = ylocout; featurelist->feature[indx]->val = KLT_TRACKED; if (tc->affineConsistencyCheck >= 0 && val == KLT_TRACKED) { /*for affine mapping*/ int border = 2; /* add border for interpolation */ #ifdef DEBUG_AFFINE_MAPPING glob_index = indx; #endif if(!featurelist->feature[indx]->aff_img){ /* save image and gradient for each feature at finest resolution after first successful track */ featurelist->feature[indx]->aff_img = _KLTCreateFloatImage((tc->affine_window_width+border), (tc->affine_window_height+border)); featurelist->feature[indx]->aff_img_gradx = _KLTCreateFloatImage((tc->affine_window_width+border), (tc->affine_window_height+border)); featurelist->feature[indx]->aff_img_grady = _KLTCreateFloatImage((tc->affine_window_width+border), (tc->affine_window_height+border)); _am_getSubFloatImage(pyramid1->img[0],xloc,yloc,featurelist->feature[indx]->aff_img); _am_getSubFloatImage(pyramid1_gradx->img[0],xloc,yloc,featurelist->feature[indx]->aff_img_gradx); _am_getSubFloatImage(pyramid1_grady->img[0],xloc,yloc,featurelist->feature[indx]->aff_img_grady); featurelist->feature[indx]->aff_x = xloc - (int) xloc + (tc->affine_window_width+border)/2; featurelist->feature[indx]->aff_y = yloc - (int) yloc + (tc->affine_window_height+border)/2;; }else{ /* affine tracking */ val = _am_trackFeatureAffine(featurelist->feature[indx]->aff_x, featurelist->feature[indx]->aff_y, &xlocout, &ylocout, featurelist->feature[indx]->aff_img, featurelist->feature[indx]->aff_img_gradx, featurelist->feature[indx]->aff_img_grady, pyramid2->img[0], pyramid2_gradx->img[0], pyramid2_grady->img[0], tc->affine_window_width, tc->affine_window_height, tc->step_factor, tc->affine_max_iterations, tc->min_determinant, tc->min_displacement, tc->affine_min_displacement, tc->affine_max_residue, tc->lighting_insensitive, tc->affineConsistencyCheck, tc->affine_max_displacement_differ, &featurelist->feature[indx]->aff_Axx, &featurelist->feature[indx]->aff_Ayx, &featurelist->feature[indx]->aff_Axy, &featurelist->feature[indx]->aff_Ayy ); featurelist->feature[indx]->val = val; if(val != KLT_TRACKED){ featurelist->feature[indx]->x = -1.0; featurelist->feature[indx]->y = -1.0; featurelist->feature[indx]->aff_x = -1.0; featurelist->feature[indx]->aff_y = -1.0; /* free image and gradient for lost feature */ _KLTFreeFloatImage(featurelist->feature[indx]->aff_img); _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_gradx); _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_grady); featurelist->feature[indx]->aff_img = NULL; featurelist->feature[indx]->aff_img_gradx = NULL; featurelist->feature[indx]->aff_img_grady = NULL; }else{ /*featurelist->feature[indx]->x = xlocout;*/ /*featurelist->feature[indx]->y = ylocout;*/ } } } } } } if (tc->sequentialMode) { tc->pyramid_last = pyramid2; tc->pyramid_last_gradx = pyramid2_gradx; tc->pyramid_last_grady = pyramid2_grady; } else { _KLTFreePyramid(pyramid2); _KLTFreePyramid(pyramid2_gradx); _KLTFreePyramid(pyramid2_grady); } /* Free memory */ _KLTFreeFloatImage(tmpimg); if (floatimg1_created) _KLTFreeFloatImage(floatimg1); _KLTFreeFloatImage(floatimg2); _KLTFreePyramid(pyramid1); _KLTFreePyramid(pyramid1_gradx); _KLTFreePyramid(pyramid1_grady); if (KLT_verbose >= 1) { fprintf(stderr, "\n\t%d features successfully tracked.\n", KLTCountRemainingFeatures(featurelist)); if (tc->writeInternalImages) fprintf(stderr, "\tWrote images to 'kltimg_tf*.pgm'.\n"); fflush(stderr); } }