001/** 002 * This source code file is part of a direct port of Stan Birchfield's implementation 003 * of a Kanade-Lucas-Tomasi feature tracker. The original implementation can be found 004 * here: http://www.ces.clemson.edu/~stb/klt/ 005 * 006 * As per the original code, the source code is in the public domain, available 007 * for both commercial and non-commercial use. 008 */ 009package org.openimaj.video.tracking.klt; 010 011import org.openimaj.image.FImage; 012import org.openimaj.image.processing.convolution.FGaussianConvolve; 013 014/** 015 * A simple Gaussian pyramid 016 * 017 * @author Stan Birchfield 018 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 019 */ 020public class Pyramid { 021 int subsampling; 022 int nLevels; 023 FImage [] img; 024 int [] ncols, nrows; 025 026 /** 027 * @param ncols 028 * @param nrows 029 * @param subsampling 030 * @param nlevels 031 */ 032 public Pyramid(int ncols, int nrows, int subsampling, int nlevels) { 033 if (subsampling != 2 && subsampling != 4 && 034 subsampling != 8 && subsampling != 16 && subsampling != 32) 035 throw new RuntimeException("(_KLTCreatePyramid) Pyramid's subsampling must be either 2, 4, 8, 16, or 32"); 036 037 img = new FImage[nlevels]; 038 this.ncols = new int[nlevels]; 039 this.nrows = new int[nlevels]; 040 041 /* Set parameters */ 042 this.subsampling = subsampling; 043 this.nLevels = nlevels; 044 045 /* Allocate memory for each level of pyramid and assign pointers */ 046 for (int i = 0 ; i < nlevels ; i++) { 047 this.img[i] = new FImage(ncols, nrows); 048 this.ncols[i] = ncols; 049 this.nrows[i] = nrows; 050 ncols /= subsampling; 051 nrows /= subsampling; 052 } 053 } 054 055 /********************************************************************* 056 * 057 */ 058 void computePyramid(FImage img, float sigma_fact) { 059 FImage currimg, tmpimg; 060 int ncols = img.width, nrows = img.height; 061 int subsampling = this.subsampling; 062 int subhalf = subsampling / 2; 063 float sigma = subsampling * sigma_fact; /* empirically determined */ 064 int i, x, y; 065 066 if (subsampling != 2 && subsampling != 4 && 067 subsampling != 8 && subsampling != 16 && subsampling != 32) 068 throw new RuntimeException("(_KLTComputePyramid) Pyramid's subsampling must be either 2, 4, 8, 16, or 32"); 069 070 /* Copy original image to level 0 of pyramid */ 071 this.img[0] = img.clone(); 072 073 currimg = img; 074 for (i = 1 ; i < this.nLevels ; i++) { 075 //tmpimg = FImage(nrows, ncols); 076 //_KLTComputeSmoothedImage(currimg, sigma, tmpimg); 077 tmpimg = currimg.process(new FGaussianConvolve(sigma)); 078 079 /* Subsample */ 080 ncols /= subsampling; nrows /= subsampling; 081 for (y = 0 ; y < nrows ; y++) 082 for (x = 0 ; x < ncols ; x++) 083 this.img[i].pixels[y][x] = tmpimg.pixels[(subsampling*y+subhalf)][(subsampling*x+subhalf)]; 084 085 /* Reassign current image */ 086 currimg = this.img[i]; 087 } 088 } 089}