/* * Copyright (c) 2011-2016, 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.impl; import boofcv.alg.filter.convolve.ConvolveWithBorder; import boofcv.alg.misc.GImageMiscOps; import boofcv.alg.transform.ii.GIntegralImageOps; import boofcv.alg.transform.ii.IntegralKernel; import boofcv.core.image.FactoryGImageGray; import boofcv.core.image.GConvertImage; import boofcv.core.image.GImageGray; import boofcv.core.image.GeneralizedImageOps; import boofcv.core.image.border.FactoryImageBorderAlgs; import boofcv.core.image.border.ImageBorder_S32; import boofcv.struct.ImageRectangle; import boofcv.struct.convolve.Kernel2D_I32; import boofcv.struct.image.GrayS32; import boofcv.struct.image.GrayU8; import boofcv.struct.image.ImageGray; import boofcv.testing.BoofTesting; import org.junit.Assert; import org.junit.Test; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Random; import static org.junit.Assert.assertEquals; /** * @author Peter Abeles */ public class TestImplIntegralImageOps { Random rand = new Random(234); int width = 20; int height = 30; @Test public void transform() { int numFound = BoofTesting.findMethodThenCall(this,"transform",ImplIntegralImageOps.class,"transform"); Assert.assertEquals(5, numFound); } public void transform( Method m ) { Class paramType[] = m.getParameterTypes(); Class inputType = paramType[0]; Class outputType = paramType[1]; ImageGray input = GeneralizedImageOps.createSingleBand(inputType, width, height); ImageGray integral = GeneralizedImageOps.createSingleBand(outputType, width, height); GImageMiscOps.fillUniform(input, rand, 0, 100); BoofTesting.checkSubImage(this,"checkTransformResults",true,m,input,integral); } public void checkTransformResults(Method m , ImageGray a, ImageGray b) throws InvocationTargetException, IllegalAccessException { m.invoke(null,a,b); GImageGray aa = FactoryGImageGray.wrap(a); GImageGray bb = FactoryGImageGray.wrap(b); for( int y = 0; y < height; y++ ) { for( int x = 0; x < width; x++ ) { double total = 0; for( int i = 0; i <= y; i++ ) { for( int j = 0; j <= x; j++ ) { total += aa.get(j,i).doubleValue(); } } Assert.assertEquals(x+" "+y,total,bb.get(x,y).doubleValue(),1e-1); } } } @Test public void convolve() { int numFound = BoofTesting.findMethodThenCall(this,"convolve",ImplIntegralImageOps.class,"convolve"); assertEquals(4, numFound); } public void convolve( Method m ) throws InvocationTargetException, IllegalAccessException { Kernel2D_I32 kernel = new Kernel2D_I32(3, new int[]{1,1,1,2,2,2,1,1,1}); GrayU8 input = new GrayU8(width,height); GrayS32 expected = new GrayS32(width,height); GImageMiscOps.fillUniform(input, rand, 0, 10); ImageBorder_S32 border = FactoryImageBorderAlgs.value( input, 0); ConvolveWithBorder.convolve(kernel,input,expected,border); Class paramType[] = m.getParameterTypes(); Class inputType = paramType[0]; Class outputType = paramType[2]; ImageGray inputII = GeneralizedImageOps.createSingleBand(inputType, width, height); ImageGray integral = GeneralizedImageOps.createSingleBand(outputType, width, height); ImageGray expectedII = GeneralizedImageOps.createSingleBand(outputType, width, height); ImageGray found = GeneralizedImageOps.createSingleBand(outputType, width, height); GConvertImage.convert(input,inputII); GConvertImage.convert(expected,expectedII); GIntegralImageOps.transform(inputII, integral); IntegralKernel kernelII = new IntegralKernel(2); kernelII.blocks[0] = new ImageRectangle(-2,-2,1,1); kernelII.blocks[1] = new ImageRectangle(-2,-1,1,0); kernelII.scales = new int[]{1,1}; m.invoke(null,integral,kernelII,found); BoofTesting.assertEqualsRelative(expected, found, 1e-4f); } @Test public void convolveBorder() { int numFound = BoofTesting.findMethodThenCall(this,"convolveBorder",ImplIntegralImageOps.class,"convolveBorder"); assertEquals(4,numFound); } public void convolveBorder( Method m ) throws InvocationTargetException, IllegalAccessException { Kernel2D_I32 kernel = new Kernel2D_I32(3, new int[]{1,1,1,2,2,2,1,1,1}); GrayU8 input = new GrayU8(width,height); GrayS32 expected = new GrayS32(width,height); GImageMiscOps.fillUniform(input, rand, 0, 10); ImageBorder_S32 border = FactoryImageBorderAlgs.value( input, 0); ConvolveWithBorder.convolve(kernel,input,expected,border); Class paramType[] = m.getParameterTypes(); Class inputType = paramType[0]; Class outputType = paramType[2]; ImageGray inputII = GeneralizedImageOps.createSingleBand(inputType, width, height); ImageGray integral = GeneralizedImageOps.createSingleBand(outputType, width, height); ImageGray expectedII = GeneralizedImageOps.createSingleBand(outputType, width, height); ImageGray found = GeneralizedImageOps.createSingleBand(outputType, width, height); GConvertImage.convert(input,inputII); GConvertImage.convert(expected,expectedII); GIntegralImageOps.transform(inputII, integral); IntegralKernel kernelII = new IntegralKernel(2); kernelII.blocks[0] = new ImageRectangle(-2,-2,1,1); kernelII.blocks[1] = new ImageRectangle(-2,-1,1,0); kernelII.scales = new int[]{1,1}; m.invoke(null,integral,kernelII,found,4,5); BoofTesting.assertEqualsBorder(expected,found,1e-4f,4,5); } @Test public void convolveSparse() { int numFound = BoofTesting.findMethodThenCall(this,"convolveSparse",ImplIntegralImageOps.class,"convolveSparse"); assertEquals(4,numFound); } public void convolveSparse( Method m ) throws InvocationTargetException, IllegalAccessException { Class paramType[] = m.getParameterTypes(); Class inputType = paramType[0]; ImageGray integral = GeneralizedImageOps.createSingleBand(inputType, width, height); GImageMiscOps.fillUniform(integral, rand, 0, 1000); ImageGray expected = GeneralizedImageOps.createSingleBand(inputType, width, height); IntegralKernel kernel = new IntegralKernel(2); kernel.blocks[0] = new ImageRectangle(-2,-2,1,1); kernel.blocks[1] = new ImageRectangle(-2,-1,1,0); kernel.scales = new int[]{1,2}; GIntegralImageOps.convolve(integral,kernel,expected); GImageGray e = FactoryGImageGray.wrap(expected); double found0 = ((Number)m.invoke(null,integral,kernel,0,0)).doubleValue(); double found1 = ((Number)m.invoke(null,integral,kernel,10,12)).doubleValue(); double found2 = ((Number)m.invoke(null,integral,kernel,19,29)).doubleValue(); assertEquals(e.get(0,0).doubleValue(),found0,1e-4f); assertEquals(e.get(10,12).doubleValue(),found1,1e-4f); assertEquals(e.get(19,29).doubleValue(),found2,1e-4f); } @Test public void block_unsafe() { int numFound = BoofTesting.findMethodThenCall(this,"block_unsafe",ImplIntegralImageOps.class,"block_unsafe"); assertEquals(4,numFound); } public void block_unsafe( Method m ) throws InvocationTargetException, IllegalAccessException { Class paramType[] = m.getParameterTypes(); Class inputType = paramType[0]; Class origType = inputType == GrayS32.class ? GrayU8.class : inputType; ImageGray input = GeneralizedImageOps.createSingleBand(origType, width, height); ImageGray integral = GeneralizedImageOps.createSingleBand(inputType, width, height); GImageMiscOps.fill(input,1); GIntegralImageOps.transform(input,integral); double found0 = ((Number)m.invoke(null,integral,4,5,8,8)).doubleValue(); assertEquals(12, found0, 1e-4f); } @Test public void block_zero() { int numFound = BoofTesting.findMethodThenCall(this,"block_zero",ImplIntegralImageOps.class,"block_zero"); assertEquals(4, numFound); } public void block_zero( Method m ) throws InvocationTargetException, IllegalAccessException { Class paramType[] = m.getParameterTypes(); Class inputType = paramType[0]; Class origType = inputType == GrayS32.class ? GrayU8.class : inputType; ImageGray input = GeneralizedImageOps.createSingleBand(origType, width, height); ImageGray integral = GeneralizedImageOps.createSingleBand(inputType, width, height); GImageMiscOps.fill(input,1); GIntegralImageOps.transform(input,integral); double found = ((Number)m.invoke(null,integral,4,5,8,8)).doubleValue(); assertEquals(12,found,1e-4f); found = ((Number)m.invoke(null,integral,-1,-2,2,3)).doubleValue(); assertEquals(12,found,1e-4f); found = ((Number)m.invoke(null,integral,width-2,height-3,width+1,height+3)).doubleValue(); assertEquals(2,found,1e-4f); found = ((Number)m.invoke(null,integral,3,-4,-1,-1)).doubleValue(); assertEquals(0,found,1e-4f); found = ((Number)m.invoke(null,integral,width+1,height+2,width+6,height+8)).doubleValue(); assertEquals(0,found,1e-4f); } }