All Downloads are FREE. Search and download functionalities are using the official Maven repository.

boofcv.alg.feature.detect.intensity.impl.ImplIntegralImageFeatureIntensity Maven / Gradle / Ivy

Go to download

BoofCV is an open source Java library for real-time computer vision and robotics applications.

There is a newer version: 1.1.7
Show newest version
/*
 * Copyright (c) 2011-2019, Peter Abeles. All Rights Reserved.
 *
 * This file is part of BoofCV (http://boofcv.org).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package boofcv.alg.feature.detect.intensity.impl;

import boofcv.alg.transform.ii.DerivativeIntegralImage;
import boofcv.alg.transform.ii.IntegralImageOps;
import boofcv.alg.transform.ii.IntegralKernel;
import boofcv.struct.image.GrayF32;
import boofcv.struct.image.GrayS32;


/**
 * 

* Routines for computing the intensity of the fast hessian features in an image. *

* *

* DO NOT MODIFY: Generated by {@link GenerateImplIntegralImageFeatureIntensity}. *

* * @author Peter Abeles */ @SuppressWarnings("Duplicates") public class ImplIntegralImageFeatureIntensity { /** * Brute force approach which is easy to validate through visual inspection. */ public static void hessianNaive(GrayF32 integral, int skip , int size , GrayF32 intensity) { final int w = intensity.width; final int h = intensity.height; // get convolution kernels for the second order derivatives IntegralKernel kerXX = DerivativeIntegralImage.kernelDerivXX(size,null); IntegralKernel kerYY = DerivativeIntegralImage.kernelDerivYY(size,null); IntegralKernel kerXY = DerivativeIntegralImage.kernelDerivXY(size,null); float norm = 1.0f/(size*size); for( int y = 0; y < h; y++ ) { for( int x = 0; x < w; x++ ) { int xx = x*skip; int yy = y*skip; computeHessian(integral, intensity, kerXX, kerYY, kerXY, norm, y, yy, x, xx); } } } /** * Only computes the fast hessian along the border using a brute force approach */ public static void hessianBorder(GrayF32 integral, int skip , int size , GrayF32 intensity) { final int w = intensity.width; final int h = intensity.height; // get convolution kernels for the second order derivatives IntegralKernel kerXX = DerivativeIntegralImage.kernelDerivXX(size,null); IntegralKernel kerYY = DerivativeIntegralImage.kernelDerivYY(size,null); IntegralKernel kerXY = DerivativeIntegralImage.kernelDerivXY(size,null); int radiusFeature = size/2; final int borderOrig = radiusFeature+ 1 + (skip-(radiusFeature+1)%skip); final int border = borderOrig/skip; float norm = 1.0f/(size*size); for( int y = 0; y < h; y++ ) { int yy = y*skip; for( int x = 0; x < border; x++ ) { int xx = x*skip; computeHessian(integral, intensity, kerXX, kerYY, kerXY, norm, y, yy, x, xx); } for( int x = w-border; x < w; x++ ) { int xx = x*skip; computeHessian(integral, intensity, kerXX, kerYY, kerXY, norm, y, yy, x, xx); } } for( int x = border; x < w-border; x++ ) { int xx = x*skip; for( int y = 0; y < border; y++ ) { int yy = y*skip; computeHessian(integral, intensity, kerXX, kerYY, kerXY, norm, y, yy, x, xx); } for( int y = h-border; y < h; y++ ) { int yy = y*skip; computeHessian(integral, intensity, kerXX, kerYY, kerXY, norm, y, yy, x, xx); } } } public static void computeHessian(GrayF32 integral, GrayF32 intensity, IntegralKernel kerXX, IntegralKernel kerYY, IntegralKernel kerXY, float norm, int y, int yy, int x, int xx) { float Dxx = IntegralImageOps.convolveSparse(integral,kerXX,xx,yy); float Dyy = IntegralImageOps.convolveSparse(integral,kerYY,xx,yy); float Dxy = IntegralImageOps.convolveSparse(integral,kerXY,xx,yy); Dxx *= norm; Dxy *= norm; Dyy *= norm; float det = Dxx*Dyy-0.81f*Dxy*Dxy; intensity.set(x,y,det); } /** * Optimizes intensity for the inner image. */ public static void hessianInner(GrayF32 integral, int skip , int size , GrayF32 intensity) { final int w = intensity.width; final int h = intensity.height; float norm = 1.0f/(size*size); int blockSmall = size/3; int blockLarge = size-blockSmall-1; int radiusFeature = size/2; int radiusSkinny = blockLarge/2; int blockW2 = 2*blockSmall; int blockW3 = 3*blockSmall; int rowOff1 = blockSmall*integral.stride; int rowOff2 = 2*rowOff1; int rowOff3 = 3*rowOff1; // make sure it starts on the correct pixel final int borderOrig = radiusFeature+ 1 + (skip-(radiusFeature+1)%skip); final int border = borderOrig/skip; final int lostPixel = borderOrig - radiusFeature-1; final int endY = h - border; final int endX = w - border; for( int y = border; y < endY; y++ ) { // pixel location in original input image int yy = y*skip; // index for output int indexDst = intensity.startIndex + y*intensity.stride+border; // indexes for Dxx int indexTop = integral.startIndex + (yy-radiusSkinny-1)*integral.stride+lostPixel; int indexBottom = indexTop + (blockLarge)*integral.stride; // indexes for Dyy int indexL = integral.startIndex + (yy-radiusFeature-1)*integral.stride + (radiusFeature-radiusSkinny)+lostPixel; int indexR = indexL + blockLarge; // indexes for Dxy int indexY1 = integral.startIndex + (yy-blockSmall-1)*integral.stride + (radiusFeature-blockSmall)+lostPixel; int indexY2 = indexY1 + blockSmall*integral.stride; int indexY3 = indexY2 + integral.stride; int indexY4 = indexY3 + blockSmall*integral.stride; for( int x = border; x < endX; x++ , indexDst++) { float Dxx = integral.data[indexBottom+blockW3] - integral.data[indexTop+blockW3] - integral.data[indexBottom] + integral.data[indexTop]; Dxx -= 3*(integral.data[indexBottom+blockW2] - integral.data[indexTop+blockW2] - integral.data[indexBottom+blockSmall] + integral.data[indexTop+blockSmall]); float Dyy = integral.data[indexR+rowOff3] - integral.data[indexL+rowOff3] - integral.data[indexR] + integral.data[indexL]; Dyy -= 3*(integral.data[indexR+rowOff2] - integral.data[indexL+rowOff2] - integral.data[indexR+rowOff1] + integral.data[indexL+rowOff1]); int x3 = blockSmall+1; int x4 = x3+blockSmall; float Dxy = integral.data[indexY2+blockSmall] - integral.data[indexY1+blockSmall] - integral.data[indexY2] + integral.data[indexY1]; Dxy -= integral.data[indexY2+x4] - integral.data[indexY1+x4] - integral.data[indexY2+x3] + integral.data[indexY1+x3]; Dxy += integral.data[indexY4+x4] - integral.data[indexY3+x4] - integral.data[indexY4+x3] + integral.data[indexY3+x3]; Dxy -= integral.data[indexY4+blockSmall] - integral.data[indexY3+blockSmall] - integral.data[indexY4] + integral.data[indexY3]; Dxx *= norm; Dxy *= norm; Dyy *= norm; intensity.data[indexDst] = Dxx*Dyy-0.81f*Dxy*Dxy; indexTop += skip; indexBottom += skip; indexL += skip; indexR += skip; indexY1 += skip; indexY2 += skip; indexY3 += skip; indexY4 += skip; } } } /** * Brute force approach which is easy to validate through visual inspection. */ public static void hessianNaive(GrayS32 integral, int skip , int size , GrayF32 intensity) { final int w = intensity.width; final int h = intensity.height; // get convolution kernels for the second order derivatives IntegralKernel kerXX = DerivativeIntegralImage.kernelDerivXX(size,null); IntegralKernel kerYY = DerivativeIntegralImage.kernelDerivYY(size,null); IntegralKernel kerXY = DerivativeIntegralImage.kernelDerivXY(size,null); float norm = 1.0f/(size*size); for( int y = 0; y < h; y++ ) { for( int x = 0; x < w; x++ ) { int xx = x*skip; int yy = y*skip; computeHessian(integral, intensity, kerXX, kerYY, kerXY, norm, y, yy, x, xx); } } } /** * Only computes the fast hessian along the border using a brute force approach */ public static void hessianBorder(GrayS32 integral, int skip , int size , GrayF32 intensity) { final int w = intensity.width; final int h = intensity.height; // get convolution kernels for the second order derivatives IntegralKernel kerXX = DerivativeIntegralImage.kernelDerivXX(size,null); IntegralKernel kerYY = DerivativeIntegralImage.kernelDerivYY(size,null); IntegralKernel kerXY = DerivativeIntegralImage.kernelDerivXY(size,null); int radiusFeature = size/2; final int borderOrig = radiusFeature+ 1 + (skip-(radiusFeature+1)%skip); final int border = borderOrig/skip; float norm = 1.0f/(size*size); for( int y = 0; y < h; y++ ) { int yy = y*skip; for( int x = 0; x < border; x++ ) { int xx = x*skip; computeHessian(integral, intensity, kerXX, kerYY, kerXY, norm, y, yy, x, xx); } for( int x = w-border; x < w; x++ ) { int xx = x*skip; computeHessian(integral, intensity, kerXX, kerYY, kerXY, norm, y, yy, x, xx); } } for( int x = border; x < w-border; x++ ) { int xx = x*skip; for( int y = 0; y < border; y++ ) { int yy = y*skip; computeHessian(integral, intensity, kerXX, kerYY, kerXY, norm, y, yy, x, xx); } for( int y = h-border; y < h; y++ ) { int yy = y*skip; computeHessian(integral, intensity, kerXX, kerYY, kerXY, norm, y, yy, x, xx); } } } public static void computeHessian(GrayS32 integral, GrayF32 intensity, IntegralKernel kerXX, IntegralKernel kerYY, IntegralKernel kerXY, float norm, int y, int yy, int x, int xx) { float Dxx = IntegralImageOps.convolveSparse(integral,kerXX,xx,yy); float Dyy = IntegralImageOps.convolveSparse(integral,kerYY,xx,yy); float Dxy = IntegralImageOps.convolveSparse(integral,kerXY,xx,yy); Dxx *= norm; Dxy *= norm; Dyy *= norm; float det = Dxx*Dyy-0.81f*Dxy*Dxy; intensity.set(x,y,det); } /** * Optimizes intensity for the inner image. */ public static void hessianInner(GrayS32 integral, int skip , int size , GrayF32 intensity) { final int w = intensity.width; final int h = intensity.height; float norm = 1.0f/(size*size); int blockSmall = size/3; int blockLarge = size-blockSmall-1; int radiusFeature = size/2; int radiusSkinny = blockLarge/2; int blockW2 = 2*blockSmall; int blockW3 = 3*blockSmall; int rowOff1 = blockSmall*integral.stride; int rowOff2 = 2*rowOff1; int rowOff3 = 3*rowOff1; // make sure it starts on the correct pixel final int borderOrig = radiusFeature+ 1 + (skip-(radiusFeature+1)%skip); final int border = borderOrig/skip; final int lostPixel = borderOrig - radiusFeature-1; final int endY = h - border; final int endX = w - border; for( int y = border; y < endY; y++ ) { // pixel location in original input image int yy = y*skip; // index for output int indexDst = intensity.startIndex + y*intensity.stride+border; // indexes for Dxx int indexTop = integral.startIndex + (yy-radiusSkinny-1)*integral.stride+lostPixel; int indexBottom = indexTop + (blockLarge)*integral.stride; // indexes for Dyy int indexL = integral.startIndex + (yy-radiusFeature-1)*integral.stride + (radiusFeature-radiusSkinny)+lostPixel; int indexR = indexL + blockLarge; // indexes for Dxy int indexY1 = integral.startIndex + (yy-blockSmall-1)*integral.stride + (radiusFeature-blockSmall)+lostPixel; int indexY2 = indexY1 + blockSmall*integral.stride; int indexY3 = indexY2 + integral.stride; int indexY4 = indexY3 + blockSmall*integral.stride; for( int x = border; x < endX; x++ , indexDst++) { float Dxx = integral.data[indexBottom+blockW3] - integral.data[indexTop+blockW3] - integral.data[indexBottom] + integral.data[indexTop]; Dxx -= 3*(integral.data[indexBottom+blockW2] - integral.data[indexTop+blockW2] - integral.data[indexBottom+blockSmall] + integral.data[indexTop+blockSmall]); float Dyy = integral.data[indexR+rowOff3] - integral.data[indexL+rowOff3] - integral.data[indexR] + integral.data[indexL]; Dyy -= 3*(integral.data[indexR+rowOff2] - integral.data[indexL+rowOff2] - integral.data[indexR+rowOff1] + integral.data[indexL+rowOff1]); int x3 = blockSmall+1; int x4 = x3+blockSmall; float Dxy = integral.data[indexY2+blockSmall] - integral.data[indexY1+blockSmall] - integral.data[indexY2] + integral.data[indexY1]; Dxy -= integral.data[indexY2+x4] - integral.data[indexY1+x4] - integral.data[indexY2+x3] + integral.data[indexY1+x3]; Dxy += integral.data[indexY4+x4] - integral.data[indexY3+x4] - integral.data[indexY4+x3] + integral.data[indexY3+x3]; Dxy -= integral.data[indexY4+blockSmall] - integral.data[indexY3+blockSmall] - integral.data[indexY4] + integral.data[indexY3]; Dxx *= norm; Dxy *= norm; Dyy *= norm; intensity.data[indexDst] = Dxx*Dyy-0.81f*Dxy*Dxy; indexTop += skip; indexBottom += skip; indexL += skip; indexR += skip; indexY1 += skip; indexY2 += skip; indexY3 += skip; indexY4 += skip; } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy