boofcv.alg.transform.ii.DerivativeIntegralImage Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of boofcv-ip Show documentation
Show all versions of boofcv-ip Show documentation
BoofCV is an open source Java library for real-time computer vision and robotics applications.
/*
* Copyright (c) 2011-2017, 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.transform.ii;
import boofcv.struct.image.GrayF32;
/**
* @author Peter Abeles
*/
public class DerivativeIntegralImage {
/**
* Creates a kernel for a symmetric box derivative.
*
* @param r Radius of the box. width is 2*r+1
* @return Kernel Kernel for derivative.
*/
public static IntegralKernel kernelDerivX( int r , IntegralKernel ret ) {
if( ret == null )
ret = new IntegralKernel(2);
ret.blocks[0].set(-r-1,-r-1,-1,r);
ret.blocks[1].set(0,-r-1,r,r);
ret.scales[0] = -1;
ret.scales[1] = 1;
return ret;
}
/**
* Creates a kernel for a symmetric box derivative.
*
* @param r Radius of the box. width is 2*r+1
* @return Kernel Kernel for derivative.
*/
public static IntegralKernel kernelDerivY( int r , IntegralKernel ret ) {
if( ret == null )
ret = new IntegralKernel(2);
ret.blocks[0].set(-r-1,-r-1,r,-1);
ret.blocks[1].set(-r-1,0,r,r);
ret.scales[0] = -1;
ret.scales[1] = 1;
return ret;
}
/**
* Creates a kernel for the Haar wavelet "centered" around the target pixel.
*
* @param r Radius of the box. width is 2*r
* @return Kernel for a Haar x-axis wavelet.
*/
public static IntegralKernel kernelHaarX( int r , IntegralKernel ret) {
if( ret == null )
ret = new IntegralKernel(2);
ret.blocks[0].set(-r, -r, 0, r);
ret.blocks[1].set(0,-r,r,r);
ret.scales[0] = -1;
ret.scales[1] = 1;
return ret;
}
/**
* Creates a kernel for the Haar wavelet "centered" around the target pixel.
*
* @param r Radius of the box. width is 2*r
* @return Kernel for a Haar y-axis wavelet.
*/
public static IntegralKernel kernelHaarY( int r , IntegralKernel ret) {
if( ret == null )
ret = new IntegralKernel(2);
ret.blocks[0].set(-r,-r,r,0);
ret.blocks[1].set(-r,0,r,r);
ret.scales[0] = -1;
ret.scales[1] = 1;
return ret;
}
public static IntegralKernel kernelDerivXX( int size , IntegralKernel ret ) {
if( ret == null )
ret = new IntegralKernel(2);
// lobe size
int blockW = size/3;
// horizontal band size
int blockH = size-blockW-1;
int r1 = blockW/2;
int r2 = blockW+r1;
int r3 = blockH/2;
ret.blocks[0].set(-r2-1,-r3-1,r2,r3);
ret.blocks[1].set(-r1 - 1, -r3 - 1, r1, r3);
ret.scales[0] = 1;
ret.scales[1] = -3;
return ret;
}
public static IntegralKernel kernelDerivYY( int size , IntegralKernel ret ) {
if( ret == null )
ret = new IntegralKernel(2);
int blockW = size/3;
int blockH = size-blockW-1;
int r1 = blockW/2;
int r2 = blockW+r1;
int r3 = blockH/2;
ret.blocks[0].set(-r3-1,-r2-1,r3,r2);
ret.blocks[1].set(-r3-1,-r1-1,r3,r1);
ret.scales[0] = 1;
ret.scales[1] = -3;
return ret;
}
public static IntegralKernel kernelDerivXY( int size , IntegralKernel ret ) {
if( ret == null )
ret = new IntegralKernel(4);
int block = size/3;
ret.blocks[0].set(-block-1,-block-1,-1,-1);
ret.blocks[1].set(0,-block-1,block,-1);
ret.blocks[2].set(0, 0, block, block);
ret.blocks[3].set(-block-1,0,-1,block);
ret.scales[0] = 1;
ret.scales[1] = -1;
ret.scales[2] = 1;
ret.scales[3] = -1;
return ret;
}
public static void derivXX(GrayF32 input , GrayF32 output , int size )
{
int blockW = size/3;
int blockH = size-blockW-1;
int radiusW = size/2;
int radiusH = blockH/2;
int blockW2 = 2*blockW;
int blockW3 = 3*blockW;
int endY = input.height - radiusH;
int endX = input.width - radiusW;
for( int y = radiusH+1; y < endY; y++ ) {
int indexTop = input.startIndex + (y-radiusH-1)*input.stride;
int indexBottom = indexTop + (blockH)*input.stride;
int indexDst = output.startIndex + y*output.stride+radiusW+1;
for( int x = radiusW+1; x < endX; x++ , indexTop++,indexBottom++,indexDst++) {
float sum = input.data[indexBottom+blockW3] - input.data[indexTop+blockW3] - input.data[indexBottom] + input.data[indexTop];
sum -= 3*(input.data[indexBottom+blockW2] - input.data[indexTop+blockW2] - input.data[indexBottom+blockW] + input.data[indexTop+blockW]);
output.data[indexDst] = sum;
}
}
}
public static void derivYY(GrayF32 input , GrayF32 output , int size )
{
int blockH = size/3;
int blockW = size-blockH-1;
int radiusH = size/2;
int radiusW = blockW/2;
int rowOff1 = blockH*input.stride;
int rowOff2 = 2*rowOff1;
int rowOff3 = 3*rowOff1;
int endY = input.height - radiusH;
int endX = input.width - radiusW;
for( int y = radiusH+1; y < endY; y++ ) {
int indexL = input.startIndex + (y-radiusH-1)*input.stride;
int indexR = indexL + blockW;
int indexDst = output.startIndex + y*output.stride+radiusW+1;
for( int x = radiusW+1; x < endX; x++ , indexL++,indexR++,indexDst++) {
float sum = input.data[indexR+rowOff3] - input.data[indexL+rowOff3] - input.data[indexR] + input.data[indexL];
sum -= 3*(input.data[indexR+rowOff2] - input.data[indexL+rowOff2] - input.data[indexR+rowOff1] + input.data[indexL+rowOff1]);
output.data[indexDst] = sum;
}
}
}
public static void derivXY(GrayF32 input , GrayF32 output , int size )
{
int block = size/3;
int endY = input.height - block;
int endX = input.width - block;
for( int y = block+1; y < endY; y++ ) {
int indexY1 = input.startIndex + (y-block-1)*input.stride;
int indexY2 = indexY1 + block*input.stride;
int indexY3 = indexY2 + input.stride;
int indexY4 = indexY3 + block*input.stride;
int indexDst = output.startIndex + y*output.stride+block+1;
for( int x = block+1; x < endX; x++ , indexY1++,indexY2++,indexY3++,indexY4++,indexDst++) {
int x3 = block+1;
int x4 = x3+block;
float sum = input.data[indexY2+block] - input.data[indexY1+block] - input.data[indexY2] + input.data[indexY1];
sum -= input.data[indexY2+x4] - input.data[indexY1+x4] - input.data[indexY2+x3] + input.data[indexY1+x3];
sum += input.data[indexY4+x4] - input.data[indexY3+x4] - input.data[indexY4+x3] + input.data[indexY3+x3];
sum -= input.data[indexY4+block] - input.data[indexY3+block] - input.data[indexY4] + input.data[indexY3];
output.data[indexDst] = sum;
}
}
}
}