/* * 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.segmentation; import boofcv.alg.filter.binary.BinaryImageOps; import boofcv.alg.misc.GImageMiscOps; import boofcv.struct.ConnectRule; import boofcv.struct.image.GrayS32; import boofcv.struct.image.GrayU8; import boofcv.struct.image.ImageBase; import boofcv.struct.image.ImageType; import boofcv.testing.BoofTesting; import org.junit.Test; import java.util.Random; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * @author Peter Abeles */ public abstract class GeneralImageSuperpixelsChecks<T extends ImageBase> { ImageType imageTypes[]; Random rand = new Random(234); int width = 20; int height = 30; public GeneralImageSuperpixelsChecks(ImageType... types) { this.imageTypes = types; } public abstract ImageSuperpixels<T> createAlg( ImageType<T> imageType ); /** * Makes sure all pixels with the same label are connected */ @Test public void connectivity() { for( ImageType<T> t : imageTypes ) { // System.out.println("Image type "+t); ImageSuperpixels<T> alg = createAlg(t); T input = t.createImage(width, height); GrayS32 output = new GrayS32(width, height); GImageMiscOps.fillUniform(input, rand, 0, 100); alg.segment(input, output); assertTrue(alg.getTotalSuperpixels() > 4); GrayU8 binary = new GrayU8(width,height); boolean selected[] = new boolean[ alg.getTotalSuperpixels()]; for (int i = 0; i < alg.getTotalSuperpixels(); i++) { selected[i] = true; BinaryImageOps.labelToBinary(output,binary,selected); selected[i] = false; // the number of blobs should always be one ConnectRule rule = alg.getRule(); assertEquals(1,BinaryImageOps.contour(binary,rule,null).size()); } } } /** * Make sure subimages produce the same results */ @Test public void subimage() { for( ImageType<T> t : imageTypes ) { // System.out.println("Image type "+t); ImageSuperpixels<T> alg = createAlg(t); T input = t.createImage(width,height); GrayS32 expected = new GrayS32(width,height); GImageMiscOps.fillUniform(input,rand,0,100); alg.segment(input,expected); // provide an output which is a sub-image GrayS32 found = new GrayS32(width+3,height+2).subimage(2,1,width+2,height+1); alg.segment(input,found); BoofTesting.assertEquals(expected,found,0); // Now make the input image an output input = BoofTesting.createSubImageOf(input); found = new GrayS32(width,height); alg.segment(input,found); BoofTesting.assertEquals(expected,found,0); } } /** * Makes sure that there really are regions 0 N-1 in the output image */ @Test public void sequentialNumbers() { for( ImageType<T> t : imageTypes ) { ImageSuperpixels<T> alg = createAlg(t); T input = t.createImage(width,height); GrayS32 output = new GrayS32(width,height); GImageMiscOps.fillUniform(input,rand,0,100); alg.segment(input,output); int N = alg.getTotalSuperpixels(); assertTrue(N > 2); boolean found[] = new boolean[N]; for( int y = 0; y < height; y++ ) { for( int x = 0; x < width; x++ ) { found[ output.get(x,y) ] = true; } } for( int i = 0; i < N; i++ ) { assertTrue(found[i]); } } } /** /** * Produces the same results when run multiple times */ @Test public void multipleCalls() { for( ImageType<T> t : imageTypes ) { ImageSuperpixels<T> alg = createAlg(t); T input = t.createImage(width,height); GrayS32 output = new GrayS32(width,height); GImageMiscOps.fillUniform(input,rand,0,100); alg.segment(input,output); GrayS32 output2 = new GrayS32(width,height); alg.segment(input,output2); for( int y = 0; y < height; y++ ) { for( int x = 0; x < width; x++ ) { assertEquals(output.get(x,y),output2.get(x,y)); } } } } /** * See if it won't blow up if input image size is changed */ @Test public void changeInImageSize() { for( ImageType<T> t : imageTypes ) { ImageSuperpixels<T> alg = createAlg(t); T input = t.createImage(width/2,height/2); GrayS32 output = new GrayS32(width/2,height/2); GImageMiscOps.fillUniform(input,rand,0,100); alg.segment(input,output); input = t.createImage(width,height); output = new GrayS32(width,height); alg.segment(input,output); } } }