use of boofcv.struct.sparse.GradientValue in project BoofCV by lessthanoptimal.
the class DescribePointSurfMod method features.
/**
* <p>
* An improved SURF descriptor as presented in CenSurE paper. The sub-regions now overlap and more
* points are sampled in the sub-region to allow overlap.
* </p>
*
* @param c_x Center of the feature x-coordinate.
* @param c_y Center of the feature y-coordinate.
* @param c cosine of the orientation
* @param s sine of the orientation
* @param scale The scale of the wavelets.
* @param features Where the features are written to. Must be 4*(widthLargeGrid*widthSubRegion)^2 large.
*/
public void features(double c_x, double c_y, double c, double s, double scale, SparseImageGradient gradient, double[] features) {
int regionSize = widthLargeGrid * widthSubRegion;
int totalSampleWidth = widthSubRegion + overLap * 2;
int regionR = regionSize / 2;
int regionEnd = regionSize - regionR;
int sampleGridWidth = regionSize + 2 * overLap;
int regionIndex = 0;
// when computing the pixel coordinates it is more precise to round to the nearest integer
// since pixels are always positive round() is equivalent to adding 0.5 and then converting
// to an int, which floors the variable.
c_x += 0.5;
c_y += 0.5;
// first sample the whole grid at once to avoid sampling overlapping regions twice
int index = 0;
for (int rY = -regionR - overLap; rY < regionEnd + overLap; rY++) {
double regionY = rY * scale;
for (int rX = -regionR - overLap; rX < regionEnd + overLap; rX++, index++) {
double regionX = rX * scale;
// rotate the pixel along the feature's direction
int pixelX = (int) (c_x + c * regionX - s * regionY);
int pixelY = (int) (c_y + s * regionX + c * regionY);
GradientValue g = gradient.compute(pixelX, pixelY);
samplesX[index] = g.getX();
samplesY[index] = g.getY();
}
}
// compute descriptor using precomputed samples
int indexGridWeight = 0;
for (int rY = -regionR; rY < regionEnd; rY += widthSubRegion) {
for (int rX = -regionR; rX < regionEnd; rX += widthSubRegion) {
double sum_dx = 0, sum_dy = 0, sum_adx = 0, sum_ady = 0;
// compute and sum up the response inside the sub-region
for (int i = 0; i < totalSampleWidth; i++) {
index = (rY + regionR + i) * sampleGridWidth + rX + regionR;
for (int j = 0; j < totalSampleWidth; j++, index++) {
double w = weightSub.get(j, i);
double dx = w * samplesX[index];
double dy = w * samplesY[index];
// align the gradient along image patch
// note the transform is transposed
double pdx = c * dx + s * dy;
double pdy = -s * dx + c * dy;
sum_dx += pdx;
sum_adx += Math.abs(pdx);
sum_dy += pdy;
sum_ady += Math.abs(pdy);
}
}
double w = weightGrid.data[indexGridWeight++];
features[regionIndex++] = w * sum_dx;
features[regionIndex++] = w * sum_adx;
features[regionIndex++] = w * sum_dy;
features[regionIndex++] = w * sum_ady;
}
}
}
use of boofcv.struct.sparse.GradientValue in project BoofCV by lessthanoptimal.
the class GeneralGradientSparse method compareToFullImage_noBorder.
@Test
public void compareToFullImage_noBorder() {
createGradient().process(image, derivX, derivY);
SparseImageGradient alg = createAlg(null);
alg.setImage(image);
for (int i = 0; i < image.height; i++) {
for (int j = 0; j < image.width; j++) {
if (i >= -lower && j >= -lower && i < image.height - upper && j < image.width - upper) {
assertTrue(j + " " + i, image.isInBounds(j, i));
GradientValue g = alg.compute(j, i);
double expectedX = GeneralizedImageOps.get(derivX, j, i);
double expectedY = GeneralizedImageOps.get(derivY, j, i);
assertEquals(expectedX, g.getX(), 1e-4f);
assertEquals(j + " " + i, expectedY, g.getY(), 1e-4f);
} else {
assertFalse(j + " " + i, alg.isInBounds(j, i));
}
}
}
}
use of boofcv.struct.sparse.GradientValue in project BoofCV by lessthanoptimal.
the class GeneralGradientSparse method compareToFullImage_Border.
@Test
public void compareToFullImage_Border() {
ImageBorder border = FactoryImageBorder.single(imageType, BorderType.EXTENDED);
ImageGradient gradient = createGradient();
gradient.setBorderType(BorderType.EXTENDED);
gradient.process(image, derivX, derivY);
SparseImageGradient alg = createAlg(border);
alg.setImage(image);
for (int i = 0; i < image.height; i++) {
for (int j = 0; j < image.width; j++) {
assertTrue(j + " " + i, image.isInBounds(j, i));
GradientValue g = alg.compute(j, i);
double expectedX = GeneralizedImageOps.get(derivX, j, i);
double expectedY = GeneralizedImageOps.get(derivY, j, i);
assertEquals(expectedX, g.getX(), 1e-4f);
assertEquals(expectedY, g.getY(), 1e-4f);
}
}
}
use of boofcv.struct.sparse.GradientValue in project BoofCV by lessthanoptimal.
the class ImplOrientationSlidingWindowIntegral method computeGradient.
private void computeGradient(double tl_x, double tl_y, double samplePeriod) {
// add 0.5 to c_x and c_y to have it round when converted to an integer pixel
// this is faster than the straight forward method
tl_x += 0.5;
tl_y += 0.5;
total = 0;
for (int y = 0; y < sampleWidth; y++) {
for (int x = 0; x < sampleWidth; x++, total++) {
int xx = (int) (tl_x + x * samplePeriod);
int yy = (int) (tl_y + y * samplePeriod);
if (g.isInBounds(xx, yy)) {
GradientValue deriv = g.compute(xx, yy);
double dx = deriv.getX();
double dy = deriv.getY();
derivX[total] = dx;
derivY[total] = dy;
} else {
derivX[total] = 0;
derivY[total] = 0;
}
}
}
}
use of boofcv.struct.sparse.GradientValue in project BoofCV by lessthanoptimal.
the class BenchmarkSurfDescribeOps method timeGradient_Sample.
/**
* Sample the gradient using SparseImageGradient instead of the completely
* unrolled code
*/
public int timeGradient_Sample(int reps) {
for (int i = 0; i < reps; i++) {
double tl_x = this.tl_x + 0.5;
double tl_y = this.tl_y + 0.5;
int j = 0;
for (int y = 0; y < regionSize; y++) {
for (int x = 0; x < regionSize; x++, j++) {
int xx = (int) (tl_x + x * period);
int yy = (int) (tl_y + y * period);
GradientValue deriv = g.compute(xx, yy);
derivX[j] = deriv.getX();
derivY[j] = deriv.getY();
}
}
}
return 0;
}
Aggregations