/* * 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.scene; import boofcv.abst.feature.dense.DescribeImageDense; import boofcv.struct.feature.TupleDesc; import boofcv.struct.feature.TupleDesc_F64; import boofcv.struct.image.GrayU8; import boofcv.struct.image.ImageBase; import boofcv.struct.image.ImageType; import georegression.struct.point.Point2D_I32; import org.ddogleg.nn.NearestNeighbor; import org.ddogleg.nn.NnData; import org.ddogleg.struct.FastQueue; import org.junit.Test; import java.util.ArrayList; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * @author Peter Abeles */ public class TestClassifierKNearestNeighborsBow { public final static int NUM_WORDS = 3; public final static int FEATURES_IN_IMAGE = 46; @Test public void basicTest() { DummyNN nn = new DummyNN(); DummyDense features = new DummyDense(); DummyToWord toWords = new DummyToWord(); List<HistogramScene> memory = new ArrayList<>(); for (int i = 0; i < 12; i++) { memory.add(new HistogramScene(NUM_WORDS)); } ClassifierKNearestNeighborsBow bow = new ClassifierKNearestNeighborsBow(nn,features,toWords); bow.setNumNeighbors(6); bow.setClassificationData(memory, 3); assertEquals(2, bow.classify(new GrayU8(2, 3))); assertEquals(NUM_WORDS, nn.initDimension); assertTrue(nn.setPoints); assertEquals(1, toWords.numReset); assertEquals(FEATURES_IN_IMAGE, toWords.numAddFeature); assertEquals(1, toWords.numProcess); // call one more time and see if stuff blows up assertEquals(2, bow.classify(new GrayU8(2, 3))); assertEquals(NUM_WORDS, nn.initDimension); assertTrue(nn.setPoints); assertEquals(2, toWords.numReset); assertEquals(FEATURES_IN_IMAGE*2, toWords.numAddFeature); assertEquals(2, toWords.numProcess); } protected class DummyNN implements NearestNeighbor<HistogramScene> { public boolean setPoints = false; public int initDimension=-1; @Override public void init(int pointDimension) { this.initDimension = pointDimension; } @Override public void setPoints(List<double[]> points, List<HistogramScene> data) { setPoints = true; } @Override public boolean findNearest(double[] point, double maxDistance, NnData<HistogramScene> result) { throw new RuntimeException("Wasn't expecting this to be called!"); } @Override public void findNearest(double[] point, double maxDistance, int numNeighbors, FastQueue<NnData<HistogramScene>> result) { assertTrue(result.size() == 0); for (int i = 0; i < numNeighbors; i++) { NnData<HistogramScene> d = result.grow(); d.data = new HistogramScene(NUM_WORDS); d.data.type = 2; } } } protected class DummyDense implements DescribeImageDense { List<TupleDesc> descriptions = new ArrayList<>(); @Override public void process(ImageBase input) { descriptions.clear(); for (int i = 0; i < FEATURES_IN_IMAGE; i++) { descriptions.add(createDescription()); } } @Override public List getDescriptions() { return descriptions; } @Override public List<Point2D_I32> getLocations() { return null; } @Override public ImageType getImageType() { return null; } @Override public TupleDesc createDescription() { return new TupleDesc_F64(5); } @Override public Class getDescriptionType() { return TupleDesc_F64.class; } } protected class DummyToWord implements FeatureToWordHistogram { int numReset = 0; int numAddFeature = 0; int numProcess = 0; @Override public void reset() { numReset++; } @Override public void addFeature(TupleDesc feature) { numAddFeature++; } @Override public void process() { numProcess++; } @Override public double[] getHistogram() { return new double[]{0.5,0.3,0.2}; } @Override public int getTotalWords() { return NUM_WORDS; } } }