package de.lmu.ifi.dbs.jfeaturelib.features; import de.lmu.ifi.dbs.jfeaturelib.LibProperties; import de.lmu.ifi.dbs.utilities.Arrays2; import ij.gui.Roi; import ij.process.ByteProcessor; import ij.process.ColorProcessor; import java.awt.Color; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import org.junit.Test; import static org.junit.Assert.*; import org.junit.Before; /** * @author Franz */ public class HistogramTest { private volatile Throwable threadException = null; public HistogramTest() { } @Before public void setup() { threadException = null; } @Test public void testRGB2() { try { ColorProcessor processor = new ColorProcessor(ImageIO.read(new File(MyRGBThreadTest.class .getResource("/test.jpg").toURI()))); Histogram histogram = new Histogram(); histogram.type = Histogram.TYPE.RGB; histogram.bins = 128; histogram.run(processor); List<double[]> features = histogram.getFeatures(); } catch (IOException | URISyntaxException ex) { fail(ex.getMessage()); Logger.getLogger(HistogramTest.class.getName()).log(Level.SEVERE, null, ex); } } @Test public void testRGBThreads() throws InterruptedException { int numberOfThreads = 25; List<Thread> l = new ArrayList<>(); for (int i = 0; i < numberOfThreads; i++) { Thread t = new Thread(new Runnable() { @Override public void run() { try { ColorProcessor processor = new ColorProcessor(ImageIO.read( new File(MyRGBThreadTest.class.getResource("/test.jpg").toURI()))); for (int j = 0; j < 200; j++) { Histogram histogram = new Histogram(); histogram.type = Histogram.TYPE.RGB; histogram.bins = 128; histogram.run(processor); histogram.getFeatures(); } } catch (Throwable ex) { threadException = ex; } } }); t.start(); l.add(t); } String message = ""; for (Thread t : l) { t.join(); if (threadException != null) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); threadException.printStackTrace(new PrintStream(baos)); message = baos.toString(); } assertNull(message, threadException); } } @Test public void testRGB() { ColorProcessor cp = new ColorProcessor(3, 1); cp.setColor(Color.red); cp.fill(new Roi(0, 0, 1, 1)); cp.setColor(Color.green); cp.fill(new Roi(1, 0, 2, 1)); cp.setColor(Color.blue); cp.fill(new Roi(2, 0, 3, 1)); Histogram histogram = new Histogram(); histogram.type = Histogram.TYPE.RGB; histogram.bins = 3; histogram.run(cp); List<double[]> features = histogram.getFeatures(); assertEquals(features.get(0).length, 3); assertEquals(3, features.get(0)[0], 0.001); assertEquals(3, features.get(0)[1], 0.001); assertEquals(3, features.get(0)[2], 0.001); } @Test public void testWithoutMasking() { ColorProcessor blackRed = new ColorProcessor(10, 10); blackRed.setColor(Color.black); blackRed.fill(); blackRed.setColor(Color.red); blackRed.fill(new Roi(0, 5, 10, 5)); Histogram histogram = new Histogram(); histogram.type = Histogram.TYPE.Red; histogram.bins = 2; histogram.run(blackRed); List<double[]> features = histogram.getFeatures(); assertEquals(features.get(0).length, 2); assertEquals(50, features.get(0)[0], 0.001); assertEquals(50, features.get(0)[1], 0.001); } @Test public void testWithMasking() { ColorProcessor blackRed = new ColorProcessor(10, 10); blackRed.setColor(Color.red); blackRed.fill(new Roi(0, 0, 10, 1)); ByteProcessor mask = new ByteProcessor(10, 10); mask.setColor(Color.white); mask.fill(new Roi(0, 0, 1, 10)); blackRed.setMask(mask); Histogram histogram = new Histogram(); histogram.type = Histogram.TYPE.Red; histogram.bins = 2; histogram.run(blackRed); double[] features = histogram.getFeatures().get(0); assertEquals(features.length, 2); assertEquals(9, features[0], 0.001); assertEquals(1, features[1], 0.001); // Controll without mask blackRed.setMask(null); histogram = new Histogram(); histogram.type = Histogram.TYPE.Red; histogram.bins = 2; histogram.run(blackRed); features = histogram.getFeatures().get(0); assertEquals(features.length, 2); assertEquals(90, features[0], 0.001); assertEquals(10, features[1], 0.001); } @Test public void testWithMasking_nonBinaryMask() throws IOException { ColorProcessor image = new ColorProcessor(10, 10); image.setColor(Color.red); image.fill(new Roi(0, 0, 10, 1)); ColorProcessor mask = new ColorProcessor(10, 10); mask.setColor(Color.white); mask.fill(new Roi(0, 0, 1, 10)); image.setMask(mask); LibProperties prop = LibProperties.get(); prop.setProperty(LibProperties.HISTOGRAMS_BINS, 2); prop.setProperty(LibProperties.HISTOGRAMS_TYPE, "Red"); Histogram descriptor1 = new Histogram(); descriptor1.setProperties(prop); descriptor1.run(image); List<double[]> features = descriptor1.getFeatures(); assertNotNull(features); assertEquals("one feature vector is expected", 1, features.size()); assertEquals("2 bins are expected", 2, features.get(0).length); } /** * tests array scaling with a scaling factor that is not an integer. I.e: scale 3 to 2 */ @Test public void testScaleInterpolate() { Histogram h = new Histogram(); double[] in, exp; in = new double[]{1d, 1d, 1d}; exp = new double[]{2d, 1d}; assertArrayEquals(exp, h.scale(in, 2), 0.0001); } /** * tests array scalig where the factor between old length and new length is an integer I.e: scale 2 to 1, 4 to 2 or * 4 to 1 */ @Test public void testScaleDirectFit() { Histogram h = new Histogram(); double[] in, exp; in = new double[]{1d, 1d}; exp = new double[]{2d}; assertArrayEquals(exp, h.scale(in, 1), 0.0001); in = new double[]{1d, 1d, 2d, 3d}; exp = new double[]{2d, 5d}; assertArrayEquals(exp, h.scale(in, 2), 0.0001); in = new double[]{1d, 1d, 2d, 3d}; exp = new double[]{7d}; assertArrayEquals(exp, h.scale(in, 1), 0.0001); } }