/* * 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.interpolate; import boofcv.alg.misc.ImageMiscOps; import boofcv.core.image.FactoryGImageGray; import boofcv.struct.image.GrayU8; import org.junit.Before; import org.junit.Test; import static java.lang.Math.sqrt; import static org.junit.Assert.*; /** * @author Peter Abeles */ public class TestImageLineIntegral { ImageLineIntegral alg; double tol = 1e-6; @Before public void init() { alg = new ImageLineIntegral(); } /** * The same two points are passed in for the end points */ @Test public void zeroLengthLine() { GrayU8 img = new GrayU8(10,15); img.set(6,6,100); alg.setImage(FactoryGImageGray.wrap(img)); checkSolution(6,6,6,6, 0); checkSolution(6.1,6.1,6.1,6.1, 0); } /** * Tests an integral inside a single pixel where x or y slope is zero */ @Test public void inside_SlopeZero() { GrayU8 img = new GrayU8(10,15); img.set(6,6,100); alg.setImage(FactoryGImageGray.wrap(img)); checkSolution(6.5, 6, 6.5, 7, 100); checkSolution(6.5, 6, 6.5, 6.9, 0.9 * 100); checkSolution(6.5, 6.1, 6.5, 7.0, 0.9 * 100); checkSolution(6, 6.5, 7, 6.5, 100); checkSolution(6, 6.5, 6.9, 6.5, 0.9 * 100); checkSolution(6.1, 6.5, 7, 6.5, 0.9 * 100); } /** * Test cases where the slope for x or y is zero across multiple pixels */ @Test public void across_SlopeZero() { GrayU8 img = new GrayU8(10,15); img.set(6,6,100); img.set(6,7,50); img.set(6,8,10); img.set(7,6,50); img.set(8,6,10); alg.setImage(FactoryGImageGray.wrap(img)); checkSolution(6.5, 6, 6.5, 8, 150); checkSolution(6.5, 6, 6.5, 7.5, 125); checkSolution(6.5, 6.5, 6.5, 8, 100); checkSolution(6.5, 6.5, 6.5, 7.5, 75); checkSolution(6.5, 6, 6.5, 8.5, 155); checkSolution(6, 6.5, 8 , 6.5, 150); checkSolution(6, 6.5, 7.5, 6.5, 125); checkSolution(6.5, 6.5, 8 , 6.5, 100); checkSolution(6.5, 6.5, 7.5, 6.5, 75); checkSolution(6, 6.5, 8.5, 6.5, 155); } /** * Test cases where the slope for x or y is zero across multiple pixels and sampling is done near the image * border */ @Test public void nearBorder_SlopeZero() { GrayU8 img = new GrayU8(10,15); img.set(0,0,100); img.set(9,14,120); alg.setImage(FactoryGImageGray.wrap(img)); checkSolution(0.5, 0, 0.5, 0.5, 50); checkSolution(9.5, 14.5, 9.5, 15, 0.5*120); checkSolution(0, 0.5, 0.5, 0.5, 50); checkSolution(9.5, 14.5, 10.0, 14.5, 0.5*120); } /** * See if it calculates the integral correctly inside a single pixel */ @Test public void inside_nonZero() { GrayU8 img = new GrayU8(10,15); ImageMiscOps.fill(img,255); img.set(6,6,100); alg.setImage(FactoryGImageGray.wrap(img)); // entirely inside double r = Math.sqrt(0.1*0.1 + 0.2*0.2); checkSolution(6.1, 6.2, 6.2, 6.4, r*100); checkSolution(6.2, 6.1, 6.4, 6.2, r*100); // one entire diagonal checkSolution(6, 6, 7, 7, sqrt(2) * 100); checkSolution(6, 7, 7, 6, sqrt(2) * 100); } /** * Move across multiple squares */ @Test public void across_nonZero() { GrayU8 img = new GrayU8(10,15); ImageMiscOps.fill(img, 255); img.set(6,6,100); img.set(6,7,200); img.set(6,8,140); img.set(7,6,150); img.set(8,6,175); img.set(7,7,50); alg.setImage(FactoryGImageGray.wrap(img)); // two entire diagonal at 45 degrees checkSolution(6, 6, 8, 8, sqrt(2) * (100+50)); checkSolution(6, 8, 8, 6, sqrt(2) * (200+150)); // two squares horizontal and vertical double r = Math.sqrt(1+4)/2; checkSolution(6, 6, 8, 7, r * (100+150)); checkSolution(6, 6, 7, 8, r * (100+200)); // three squares horizontal and vertical r = Math.sqrt(1+9)/3; checkSolution(6, 6, 9, 7, r * (100+150+175)); checkSolution(6, 6, 7, 9, r * (100+200+140)); // now try some which don't start and stop at a corner double dy = 0.5/3; checkSolution(6.5, 6+dy, 8.5, 7-dy, (r/2)*100+r*150+(r/2)*175); checkSolution(6+dy, 6.5, 7-dy, 8.5, (r/2)*100+r*200+(r/2)*140); } /** * See if it handles borders correctly with both slopes are not zero */ @Test public void nearBorder_nonZero() { GrayU8 img = new GrayU8(2,2); img.set(0,0,100); img.set(0,1,200); img.set(1,0,140); img.set(1,1,150); alg.setImage(FactoryGImageGray.wrap(img)); checkSolution(0, 0, 2, 2, sqrt(2) * (100+150)); checkSolution(2, 0, 0, 2, sqrt(2) * (200+140)); // two squares horizontal and vertical double r = Math.sqrt(1+4)/2; checkSolution(0, 0, 2, 1, r * (100+140)); checkSolution(0, 0, 1, 2, r * (100+200)); } @Test public void isInside() { GrayU8 img = new GrayU8(12,14); alg.setImage(FactoryGImageGray.wrap(img)); assertTrue(alg.isInside(0,0)); assertTrue(alg.isInside(12,14)); assertTrue(alg.isInside(12,0)); assertTrue(alg.isInside(0,14)); assertFalse(alg.isInside(-0.0001, 0)); assertFalse(alg.isInside(0, -0.00001)); assertFalse(alg.isInside(12.000001, 14)); assertFalse(alg.isInside(12, 14.0001)); assertFalse(alg.isInside(12.0001, 0)); assertFalse(alg.isInside(0, 14.00001)); } private void checkSolution(double x0, double y0, double x1, double y1, double expected) { // ind solution in the orward direction double found = alg.compute(x0, y0, x1, y1); assertEquals(expected,found,tol); // should be the same in the reverse direction found = alg.compute(x1, y1, x0, y0); assertEquals(expected,found,tol); } }