001: /*
002: * @(#) $Header: /cvs/jai-operators/src/tests/ca/forklabs/media/jai/opimage/MedianCollectionOpImageTest.java,v 1.2 2007/07/05 18:30:09 forklabs Exp $
003: *
004: * Copyright (C) 2006 DIRO Daniel Léonard
005: */
006:
007: package ca.forklabs.media.jai.opimage;
008:
009: import java.awt.Rectangle;
010: import java.awt.image.BufferedImage;
011: import java.awt.image.ColorModel;
012: import java.awt.image.ComponentSampleModel;
013: import java.awt.image.DataBuffer;
014: import java.awt.image.Raster;
015: import java.awt.image.RenderedImage;
016: import java.awt.image.renderable.ParameterBlock;
017: import java.io.InputStream;
018: import java.util.Arrays;
019: import java.util.LinkedList;
020: import java.util.List;
021: import java.util.Locale;
022: import javax.media.jai.CollectionImage;
023: import javax.media.jai.JAI;
024: import javax.media.jai.RasterAccessor;
025: import javax.media.jai.RasterFormatTag;
026: import javax.media.jai.RenderedOp;
027: import com.sun.media.jai.codec.ForwardSeekableStream;
028: import junit.framework.TestCase;
029: import ca.forklabs.baselib.util.Algorithm;
030: import ca.forklabs.baselib.util.Iterators;
031: import ca.forklabs.baselib.util.UnaryFunction;
032: import ca.forklabs.media.jai.RasterAdapter;
033: import ca.forklabs.media.jai.SimpleCollectionImage;
034: import ca.forklabs.media.jai.opimage.MedianCollectionOpImage;
035:
036: /**
037: * Class {@code MedianCollectionOpImageTest} tests class
038: * {@link MedianCollectionOpImage}.
039: *
040: * @author <a href="mailto:forklabs at dev.java.net?subject=ca.forklabs.media.jai.opimage.MedianCollectionOpImageTest">Daniel Léonard</a>
041: * @version $Revision: 1.2 $
042: */
043: @SuppressWarnings("nls")
044: public class MedianCollectionOpImageTest extends TestCase {
045:
046: //---------------------------
047: // Constructors
048: //---------------------------
049:
050: /**
051: * Constructor.
052: * @param name the name of this test.
053: */
054: public MedianCollectionOpImageTest(String name) {
055: super (name);
056: }
057:
058: //---------------------------
059: // Test methods
060: //---------------------------
061:
062: /**
063: * Tests the median algorithm.
064: */
065: public void testMedian() {
066: double[][] values = new double[][] {
067: new double[] { 2.0, 3.0, 1.0, },
068: new double[] { 2.0, 4.0, 3.0, 1.0, }, };
069:
070: double[] expected = new double[] { 2.0, 2.5, };
071:
072: assertEquals(expected.length, values.length);
073:
074: CollectionImage sources = new SimpleCollectionImage();
075: sources
076: .add(new BufferedImage(1, 1,
077: BufferedImage.TYPE_INT_ARGB));
078:
079: MedianCollectionOpImage op_image = new MedianCollectionOpImage(
080: sources, null, null);
081:
082: for (int i = 0; i < expected.length; i++) {
083: double median = op_image.computeMedian(values[i]);
084: assertEquals(expected[i], median, 10e-6);
085: }
086: }
087:
088: /**
089: * Tests the normal behaviour of the <em>MedianCollection</em> operation
090: * using the JAI architecture. It tests the algorithm itself as well as the
091: * presence and consistency (for rendered images) of the registration file
092: * {@code META-INF/registryFile.jai}.
093: * <p>
094: * Each of the three image is 4 x 4 pixels. The first and third images have
095: * the same pixels, a red [255 0 0] border and a purple [255 0 255] center
096: * while the second image is the reverse, a purple border and a red center.
097: */
098: public void testNormalBehaviour() {
099: Class<?> clazz = this .getClass();
100: InputStream[] sources = new InputStream[] {
101: clazz
102: .getResourceAsStream("/ca/forklabs/media/jai/opimage/median_collection_test_pic1.png"),
103: clazz
104: .getResourceAsStream("/ca/forklabs/media/jai/opimage/median_collection_test_pic2.png"),
105: clazz
106: .getResourceAsStream("/ca/forklabs/media/jai/opimage/median_collection_test_pic3.png"), };
107:
108: List<RenderedImage> test_pics = new LinkedList<RenderedImage>();
109: Algorithm.transform(Iterators.asIterator(sources), Iterators
110: .backInserter(test_pics),
111: new UnaryFunction<RenderedImage, InputStream>() {
112: public RenderedImage invoke(InputStream is) {
113: RenderedOp image = JAI.create("stream",
114: new ParameterBlock()
115: .add(new ForwardSeekableStream(
116: is)));
117: return image;
118: }
119: });
120:
121: RenderedOp median = JAI.create("mediancollection",
122: new ParameterBlock().addSource(test_pics));
123: Raster raster = median.getData();
124:
125: assertEquals(0, raster.getMinX());
126: assertEquals(0, raster.getMinY());
127: assertEquals(4, raster.getWidth());
128: assertEquals(4, raster.getHeight());
129: assertEquals(3, raster.getNumBands());
130:
131: int[] red = new int[] { 255, 0, 0 };
132: int[] purple = new int[] { 255, 0, 255 };
133: int[] pixels = new int[3];
134:
135: assertTrue(Arrays.equals(red, raster.getPixel(0, 0, pixels)));
136: assertTrue(Arrays.equals(red, raster.getPixel(1, 0, pixels)));
137: assertTrue(Arrays.equals(red, raster.getPixel(2, 0, pixels)));
138: assertTrue(Arrays.equals(red, raster.getPixel(3, 0, pixels)));
139:
140: assertTrue(Arrays.equals(red, raster.getPixel(0, 1, pixels)));
141: assertTrue(Arrays.equals(purple, raster.getPixel(1, 1, pixels)));
142: assertTrue(Arrays.equals(purple, raster.getPixel(2, 1, pixels)));
143: assertTrue(Arrays.equals(red, raster.getPixel(3, 1, pixels)));
144:
145: assertTrue(Arrays.equals(red, raster.getPixel(0, 2, pixels)));
146: assertTrue(Arrays.equals(purple, raster.getPixel(1, 2, pixels)));
147: assertTrue(Arrays.equals(purple, raster.getPixel(2, 2, pixels)));
148: assertTrue(Arrays.equals(red, raster.getPixel(3, 2, pixels)));
149:
150: assertTrue(Arrays.equals(red, raster.getPixel(0, 3, pixels)));
151: assertTrue(Arrays.equals(red, raster.getPixel(1, 3, pixels)));
152: assertTrue(Arrays.equals(red, raster.getPixel(2, 3, pixels)));
153: assertTrue(Arrays.equals(red, raster.getPixel(3, 3, pixels)));
154: }
155:
156: /**
157: * Tests the algorithm on two PFM images.
158: * @throws Exception if anything goes wrong.
159: */
160: public void testFloatData() throws Exception {
161: int cols = 2;
162: int rows = 2;
163: float[][] pixels = new float[][] {
164: new float[] { 1.0f, 4.0f, 7.0f, 10.0f, },
165: new float[] { 2.0f, 5.0f, 8.0f, 11.0f, },
166: new float[] { 3.0f, 6.0f, 9.0f, 12.0f, }, };
167: RenderedImage source = RasterAdapter.buildFloatImage(pixels,
168: cols, rows);
169:
170: RenderedOp median = JAI.create("mediancollection",
171: new ParameterBlock().addSource(source)
172: .addSource(source));
173: Raster raster = median.getData();
174:
175: assertEquals(0, raster.getMinX());
176: assertEquals(0, raster.getMinY());
177: assertEquals(2, raster.getWidth());
178: assertEquals(2, raster.getHeight());
179: assertEquals(3, raster.getNumBands());
180:
181: int[] pixel = new int[3];
182: assertTrue(Arrays.equals(new int[] { 1, 2, 3, }, raster
183: .getPixel(0, 0, pixel)));
184: assertTrue(Arrays.equals(new int[] { 4, 5, 6, }, raster
185: .getPixel(1, 0, pixel)));
186: assertTrue(Arrays.equals(new int[] { 7, 8, 9, }, raster
187: .getPixel(0, 1, pixel)));
188: assertTrue(Arrays.equals(new int[] { 10, 11, 12, }, raster
189: .getPixel(1, 1, pixel)));
190: }
191:
192: /**
193: * Tests an image with double pixels.
194: */
195: public void testDoubleData() {
196: double[][] image_as_double_1 = new double[][] {
197: new double[] { 1, 5, 9, 13, },
198: new double[] { 2, 6, 10, 14, },
199: new double[] { 3, 7, 11, 15, },
200: new double[] { 4, 8, 12, 16, }, };
201:
202: double[][] image_as_double_2 = new double[][] {
203: new double[] { 2, 6, 10, 14, },
204: new double[] { 3, 7, 11, 15, },
205: new double[] { 4, 8, 12, 16, },
206: new double[] { 5, 9, 13, 17, }, };
207:
208: RenderedImage[] images = new RenderedImage[] {
209: RasterAdapter.buildDoubleImage(image_as_double_1, 2, 2),
210: RasterAdapter.buildDoubleImage(image_as_double_2, 2, 2), };
211:
212: RenderedOp median = JAI.create("mediancollection",
213: new ParameterBlock().addSource(Arrays.asList(images)));
214: Raster raster = median.getData();
215:
216: assertEquals(0, raster.getMinX());
217: assertEquals(0, raster.getMinY());
218: assertEquals(2, raster.getWidth());
219: assertEquals(2, raster.getHeight());
220: assertEquals(4, raster.getNumBands());
221:
222: double[] pixels = new double[4];
223: assertTrue(Arrays.equals(new double[] { 1.5, 2.5, 3.5, 4.5, },
224: raster.getPixel(0, 0, pixels)));
225: assertTrue(Arrays.equals(new double[] { 5.5, 6.5, 7.5, 8.5, },
226: raster.getPixel(1, 0, pixels)));
227: assertTrue(Arrays.equals(
228: new double[] { 9.5, 10.5, 11.5, 12.5, }, raster
229: .getPixel(0, 1, pixels)));
230: assertTrue(Arrays.equals(
231: new double[] { 13.5, 14.5, 15.5, 16.5, }, raster
232: .getPixel(1, 1, pixels)));
233: }
234:
235: /**
236: * Tests an image with integer pixels.
237: */
238: public void testIntData() {
239: int[][] image_as_int_1 = new int[][] {
240: new int[] { 1, 4, 7, 10, }, new int[] { 2, 5, 8, 11, },
241: new int[] { 3, 6, 9, 12, }, };
242:
243: int[][] image_as_int_2 = new int[][] {
244: new int[] { 3, 6, 9, 12, },
245: new int[] { 4, 7, 10, 13, },
246: new int[] { 5, 8, 11, 14, }, };
247:
248: RenderedImage[] images = new RenderedImage[] {
249: RasterAdapter.buildIntImage(image_as_int_1, 2, 2),
250: RasterAdapter.buildIntImage(image_as_int_2, 2, 2), };
251:
252: RenderedOp median = JAI.create("mediancollection",
253: new ParameterBlock().addSource(Arrays.asList(images)));
254: Raster raster = median.getData();
255:
256: assertEquals(0, raster.getMinX());
257: assertEquals(0, raster.getMinY());
258: assertEquals(2, raster.getWidth());
259: assertEquals(2, raster.getHeight());
260: assertEquals(3, raster.getNumBands());
261:
262: int[] pixels = new int[3];
263:
264: assertTrue(Arrays.equals(new int[] { 2, 3, 4, }, raster
265: .getPixel(0, 0, pixels)));
266: assertTrue(Arrays.equals(new int[] { 5, 6, 7, }, raster
267: .getPixel(1, 0, pixels)));
268: assertTrue(Arrays.equals(new int[] { 8, 9, 10, }, raster
269: .getPixel(0, 1, pixels)));
270: assertTrue(Arrays.equals(new int[] { 11, 12, 13, }, raster
271: .getPixel(1, 1, pixels)));
272: }
273:
274: /**
275: * Tests an image with short pixels.
276: */
277: public void testShortData() {
278: short[][] image_as_int_1 = new short[][] {
279: new short[] { 1, 4, 7, 10, },
280: new short[] { 2, 5, 8, 11, },
281: new short[] { 3, 6, 9, 12, }, };
282:
283: short[][] image_as_int_2 = new short[][] {
284: new short[] { 3, 6, 9, 12, },
285: new short[] { 4, 7, 10, 13, },
286: new short[] { 5, 8, 11, 14, }, };
287:
288: RenderedImage[] images = new RenderedImage[] {
289: RasterAdapter.buildShortImage(image_as_int_1, 2, 2),
290: RasterAdapter.buildShortImage(image_as_int_2, 2, 2), };
291:
292: RenderedOp median = JAI.create("mediancollection",
293: new ParameterBlock().addSource(Arrays.asList(images)));
294: Raster raster = median.getData();
295:
296: assertEquals(0, raster.getMinX());
297: assertEquals(0, raster.getMinY());
298: assertEquals(2, raster.getWidth());
299: assertEquals(2, raster.getHeight());
300: assertEquals(3, raster.getNumBands());
301:
302: int[] pixels = new int[3];
303: assertTrue(Arrays.equals(new int[] { 2, 3, 4, }, raster
304: .getPixel(0, 0, pixels)));
305: assertTrue(Arrays.equals(new int[] { 5, 6, 7, }, raster
306: .getPixel(1, 0, pixels)));
307: assertTrue(Arrays.equals(new int[] { 8, 9, 10, }, raster
308: .getPixel(0, 1, pixels)));
309: assertTrue(Arrays.equals(new int[] { 11, 12, 13, }, raster
310: .getPixel(1, 1, pixels)));
311: }
312:
313: /**
314: * Tests an image with unsigned short pixels.
315: */
316: public void testUShortData() {
317: short[][] image_as_int_1 = new short[][] {
318: new short[] { 1, 4, 7, 10, },
319: new short[] { 2, 5, 8, 11, },
320: new short[] { 3, 6, 9, 12, }, };
321:
322: short[][] image_as_int_2 = new short[][] {
323: new short[] { 3, 6, 9, 12, },
324: new short[] { 4, 7, 10, 13, },
325: new short[] { 5, 8, 11, 14, }, };
326:
327: RenderedImage[] images = new RenderedImage[] {
328: RasterAdapter.buildUShortImage(image_as_int_1, 2, 2),
329: RasterAdapter.buildUShortImage(image_as_int_2, 2, 2), };
330:
331: RenderedOp median = JAI.create("mediancollection",
332: new ParameterBlock().addSource(Arrays.asList(images)));
333: Raster raster = median.getData();
334:
335: assertEquals(0, raster.getMinX());
336: assertEquals(0, raster.getMinY());
337: assertEquals(2, raster.getWidth());
338: assertEquals(2, raster.getHeight());
339: assertEquals(3, raster.getNumBands());
340:
341: int[] pixels = new int[3];
342: assertTrue(Arrays.equals(new int[] { 2, 3, 4, }, raster
343: .getPixel(0, 0, pixels)));
344: assertTrue(Arrays.equals(new int[] { 5, 6, 7, }, raster
345: .getPixel(1, 0, pixels)));
346: assertTrue(Arrays.equals(new int[] { 8, 9, 10, }, raster
347: .getPixel(0, 1, pixels)));
348: assertTrue(Arrays.equals(new int[] { 11, 12, 13, }, raster
349: .getPixel(1, 1, pixels)));
350: }
351:
352: /**
353: * Make sure that if the data type is unknown that the exception is thrown in
354: * {@link MedianCollectionOpImage#computeMedian(double[])}.
355: */
356: public void testUnknowDataType() {
357: // all this is to have a raster accessor
358: BufferedImage image = new BufferedImage(1, 1,
359: BufferedImage.TYPE_3BYTE_BGR);
360:
361: RasterFormatTag tag = new RasterFormatTag(
362: new ComponentSampleModel(DataBuffer.TYPE_DOUBLE, 1, 1,
363: 1, 1, new int[] { 0, }), 0);
364: ColorModel color_model = new ColorModel(8) {
365: @Override
366: @SuppressWarnings("unused")
367: public int getAlpha(int pixel) {
368: return 0;
369: }
370:
371: @Override
372: @SuppressWarnings("unused")
373: public int getBlue(int pixel) {
374: return 0;
375: }
376:
377: @Override
378: @SuppressWarnings("unused")
379: public int getGreen(int pixel) {
380: return 0;
381: }
382:
383: @Override
384: @SuppressWarnings("unused")
385: public int getRed(int pixel) {
386: return 0;
387: }
388: };
389: RasterAccessor sink = new RasterAccessor(image.getData(),
390: new Rectangle(0, 0, 1, 1), tag, color_model) {
391: @Override
392: public int getDataType() {
393: return 42;
394: }
395: };
396:
397: try {
398: CollectionImage images = new SimpleCollectionImage();
399: images.add(image);
400: MedianCollectionOpImage op_image = new MedianCollectionOpImage(
401: images, null, null);
402: op_image.computeMedian(null, sink);
403: fail("did not throw IllegalStateException");
404: } catch (IllegalStateException ise) {
405: // normal behaviour
406: }
407: }
408:
409: /**
410: * Tests the English messages.
411: */
412: public void testEnglishMessages() {
413: Locale locale = Locale.getDefault();
414: Locale.setDefault(Locale.ENGLISH);
415:
416: try {
417: String[] expected = new String[] { "The pixel type (10) is unknown", };
418:
419: CollectionImage sources = new SimpleCollectionImage();
420: sources.add(new BufferedImage(1, 1,
421: BufferedImage.TYPE_INT_ARGB));
422: MedianCollectionOpImage op_image = new MedianCollectionOpImage(
423: sources, null, null);
424: String[] got = new String[] { op_image
425: .getUnknownDataTypeErrorMessage(10), };
426:
427: assertEquals(expected.length, got.length);
428:
429: for (int i = 0; i < expected.length; i++) {
430: assertEquals("[" + i + "]", expected[i], got[i]);
431: }
432: } finally {
433: Locale.setDefault(locale);
434: }
435: }
436:
437: /**
438: * Tests the French messages.
439: */
440: public void testFrenchMessages() {
441: Locale locale = Locale.getDefault();
442: Locale.setDefault(Locale.FRENCH);
443:
444: try {
445: String[] expected = new String[] { "Type de pixel inconnu (10)", };
446:
447: CollectionImage sources = new SimpleCollectionImage();
448: sources.add(new BufferedImage(1, 1,
449: BufferedImage.TYPE_INT_ARGB));
450: MedianCollectionOpImage op_image = new MedianCollectionOpImage(
451: sources, null, null);
452: String[] got = new String[] { op_image
453: .getUnknownDataTypeErrorMessage(10), };
454:
455: assertEquals(expected.length, got.length);
456:
457: for (int i = 0; i < expected.length; i++) {
458: assertEquals("[" + i + "]", expected[i], got[i]);
459: }
460: } finally {
461: Locale.setDefault(locale);
462: }
463: }
464:
465: //---------------------------
466: // Class methods
467: //---------------------------
468:
469: /**
470: * Runs only this test.
471: * @param args ignored.
472: */
473: public static void main(String... args) {
474: junit.swingui.TestRunner.run(MedianCollectionOpImageTest.class);
475: }
476:
477: }
478:
479: /*
480: * $Log: MedianCollectionOpImageTest.java,v $
481: * Revision 1.2 2007/07/05 18:30:09 forklabs
482: * Now uses CollectionImage instead of lists.
483: *
484: * Revision 1.1 2007/06/13 18:56:36 forklabs
485: * Operator mediancollection.
486: *
487: */
|