/* * 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.abst.feature.detdesc; import boofcv.alg.misc.GImageMiscOps; import boofcv.core.image.GeneralizedImageOps; import boofcv.struct.feature.TupleDesc; import boofcv.struct.image.ImageGray; import boofcv.testing.BoofTesting; import georegression.struct.point.Point2D_F64; import org.junit.Test; import java.util.Random; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * Very basic tests which check for conformance to {@link boofcv.abst.feature.detdesc.DetectDescribePoint}. * * @author Peter Abeles */ public abstract class GenericTestsDetectDescribeMulti<T extends ImageGray, TD extends TupleDesc> { int width = 100; int height = 120; Random rand = new Random(234); T image; Class<T> imageType; Class<TD> descType; protected GenericTestsDetectDescribeMulti(Class<T> imageType, Class<TD> descType) { this.imageType = imageType; this.descType = descType; image = GeneralizedImageOps.createSingleBand(imageType,width,height); GImageMiscOps.fillUniform(image, rand, 0, 100); } public void allTests() { detectFeatures(); checkSubImage(); checkMultipleCalls(); } public abstract DetectDescribeMulti<T, TD> createDetDesc(); /** * Detects features inside the image and checks to see if it is in compliance of its reported capabilities */ @Test public void detectFeatures() { DetectDescribeMulti<T, TD> alg = createDetDesc(); alg.process(image); for( int n = 0; n < alg.getNumberOfSets(); n++ ) { PointDescSet<TD> set = alg.getFeatureSet(n); int N = set.getNumberOfFeatures(); assertTrue(N>5); for( int i = 0; i < N; i++ ) { Point2D_F64 p = set.getLocation(i); TD desc = set.getDescription(i); assertTrue(desc!=null); assertTrue(p.x != 0 && p.y != 0); assertTrue(p.x >= 0 && p.y >= 0 && p.x < image.width && p.y < image.height ); } } } /** * Make sure sub-images are correctly handled by having it process one and see if it produces the * same results */ @Test public void checkSubImage() { DetectDescribeMulti<T, TD> alg1 = createDetDesc(); DetectDescribeMulti<T, TD> alg2 = createDetDesc(); T imageSub = BoofTesting.createSubImageOf(image); alg1.process(image); alg2.process(imageSub); checkIdenticalResponse(alg1, alg2); } /** * Make sure everything has been reset correctly and that multiple calls to the same input * produce the same output */ @Test public void checkMultipleCalls() { DetectDescribeMulti<T, TD> alg1 = createDetDesc(); DetectDescribeMulti<T, TD> alg2 = createDetDesc(); // call twice alg1.process(image); alg1.process(image); // call once alg2.process(image); checkIdenticalResponse(alg1, alg2); } @Test public void getDescriptorType() { DetectDescribeMulti<T, TD> alg = createDetDesc(); assertTrue(descType==alg.getDescriptionType()); } private void checkIdenticalResponse(DetectDescribeMulti<T, TD> alg1, DetectDescribeMulti<T, TD> alg2) { for( int n = 0; n < alg1.getNumberOfSets(); n++ ) { PointDescSet<TD> set1 = alg1.getFeatureSet(n); PointDescSet<TD> set2 = alg2.getFeatureSet(n); int N = set1.getNumberOfFeatures(); assertTrue(N > 1); assertEquals(N,set2.getNumberOfFeatures()); for( int i = 0; i < N; i++ ) { Point2D_F64 p1 = set1.getLocation(i); Point2D_F64 p2 = set2.getLocation(i); assertTrue(p1.isIdentical(p2,1e-16)); TD desc1 = set1.getDescription(i); TD desc2 = set2.getDescription(i); for( int j = 0; j < desc1.size(); j++ ) { assertTrue(desc1.getDouble(j) == desc2.getDouble(j)); } } } } }