001: /*
002: * @(#) $Header: /cvs/jai-operators/src/main/ca/forklabs/media/jai/operator/SpectralHomomorphicDescriptor.java,v 1.2 2007/07/17 16:40:25 forklabs Exp $
003: *
004: * Copyright (C) 2007 Forklabs Daniel Léonard
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: */
020:
021: package ca.forklabs.media.jai.operator;
022:
023: import java.awt.RenderingHints;
024: import java.awt.image.RenderedImage;
025: import java.awt.image.renderable.RenderableImage;
026: import java.util.Collection;
027: import javax.media.jai.CollectionImage;
028: import javax.media.jai.JAI;
029: import javax.media.jai.OperationDescriptor;
030: import javax.media.jai.ParameterBlockJAI;
031: import javax.media.jai.ParameterListDescriptor;
032: import javax.media.jai.RenderableOp;
033: import javax.media.jai.RenderedOp;
034: import javax.media.jai.registry.CollectionRegistryMode;
035: import javax.media.jai.registry.RenderableRegistryMode;
036: import javax.media.jai.registry.RenderedRegistryMode;
037: import ca.forklabs.media.jai.CollectionDescriptor;
038: import ca.forklabs.media.jai.FormatDataType;
039: import ca.forklabs.media.jai.SpectralFilter2D;
040: import ca.forklabs.media.jai.SpectralFilter3D;
041:
042: /**
043: * Class {@code SpectralHomomorphicDescriptor} is an {@link OperationDescriptor}
044: * describing the <em>spectralhomomorphic</em> operation. This composite
045: * operation consists of these eight steps :
046: * <blockquote>
047: * format -> addconst(+1) -> log -> fft -> filter -> ifft -> exp -> subtractconst(+1)
048: * </blockquote>
049: * The <em>SpectralHomomorphic</em> operation takes two parameters, the filter
050: * and the data type for the format operation :
051: * <dl>
052: * <dt>filter</dt>
053: * <dd>This argument will provide the filter image to multiply to the Fourier
054: * transform.</dd>
055: * <dt>data type</dt>
056: * <dd>This argument is the type for the format operation. Data format can be
057: * found in enum {@link FormatDataType}. The default value is
058: * {@link FormatDataType#FLOAT}.</dd>
059: * </dl>
060: * <p>
061: * Here is a description of each step :
062: * <dl>
063: * <dt>format</dt>
064: * <dd>The format step change the type of the image pixel. Its behaviour can
065: * be controlled with the data type parameter.</dd>
066: * <dt>addconst(+1)</dt>
067: * <dd>This step adds one to each pixel so that when the log step is applied,
068: * there are no zero-valued pixels.</dd>
069: * <dt>log</dt>
070: * <dd>This step calculates the logarithm value of each pixel.</dd>
071: * <dt>fft</dt>
072: * <dd>This step calculates the Fourier Transform, using no scaling.</dd>
073: * <dt>filter</dt>
074: * <dd>The filter image will be generated and multiplied to the Fourier
075: * transform.</dd>
076: * <dt>ifft</dt>
077: * <dd>This step calculates the Inverse Fourier Transform, using the
078: * dimension scaling.</dd>
079: * <dt>exp</dt>
080: * <dd>This step calculates the exponential value of each pixel, it is the
081: * reverse of the <em>log</em> operation</dd>
082: * <dt>subtractconst(+1)</dt>
083: * <dd>This step subtracts one from each pixel value, it is the reverse of
084: * the <em>addconst(+1)</em> step.</dd>
085: * </dl>
086: * <p>
087: *
088: * <table border=1>
089: * <caption>Resource List</caption>
090: * <tr><th>Name</th> <th>Value</th></tr>
091: * <tr><td>GlobalName</td> <td>SpectralHomomorphic</td></tr>
092: * <tr><td>LocalName</td> <td>SpectralHomomorphic</td></tr>
093: * <tr><td>Vendor</td> <td>ca.umontreal.iro.image.arcticice</td></tr>
094: * <tr><td>Description</td> <td>Spectral Homomorphic Filter</td></tr>
095: * <tr><td>DocURL</td> <td>n/a</td></tr>
096: * <tr><td>Version</td> <td>$Version$</td></tr>
097: * <tr><td>Arg0Desct</td> <td>The spectral filter</td></tr>
098: * <tr><td>Arg1Desct</td> <td>The data type for the format operation</td></tr>
099: * </table>
100: *
101: * <table border=1>
102: * <caption>Parameter List for the <em>rendered</em> and <em>renderable</em> modes</caption>
103: * <tr><th>Name</th> <th>Class Type</th> <th>Default Value</th></tr>
104: * <tr><td>filter</td> <td>SpectralFilter2D</td> <td>NO_PARAMETER_DEFAULT</td>
105: * <tr><td>type</td> <td>FormatDataType</td> <td>FormatDataType.FLOAT</td>
106: * </table>
107: * <table border=1>
108: * <caption>Parameter List for the <em>collection</em> mode</caption>
109: * <tr><th>Name</th> <th>Class Type</th> <th>Default Value</th></tr>
110: * <tr><td>filter</td> <td>SpectralFilter3D</td> <td>NO_PARAMETER_DEFAULT</td>
111: * <tr><td>type</td> <td>FormatDataType</td> <td>FormatDataType.FLOAT</td>
112: * </table>
113: *
114: * @author <a href="mailto:daniel.leonard at umontreal.ca?subject=ca.umontreal.iro.image.arcticice.media.jai.operator.SpectralHomomorphicDescriptor">Daniel Léonard</a>
115: * @version $Revision: 1.2 $
116: */
117: public class SpectralHomomorphicDescriptor extends CollectionDescriptor {
118:
119: //---------------------------
120: // Class variables
121: //---------------------------
122:
123: /** <em>serialVersionUID</em>. */
124: private static final long serialVersionUID = 6861785573739619522L;
125:
126: /** The name of this operator. */
127: @SuppressWarnings("nls")
128: public static final String NAME = "SpectralHomomorphic";
129:
130: /** The name of the filter parameter. */
131: @SuppressWarnings("nls")
132: public static final String FILTER_PARAMETER_NAME = "filter";
133: /** The name of the initial format type parameter. */
134: @SuppressWarnings("nls")
135: public static final String TYPE_PARAMETER_NAME = "type";
136:
137: /** The index in the parameter block of the filter parameter. */
138: public static final int FILTER_PARAMETER_INDEX = 0;
139: /** The index in the parameter block of the data type parameter. */
140: public static final int TYPE_PARAMETER_INDEX = 1;
141:
142: /**
143: * The resource strings that provide the general documentation and specify
144: * the parameter list for this operation.
145: */
146: @SuppressWarnings("nls")
147: private static final String[][] RESOURCES = {
148: { "GlobalName", SpectralHomomorphicDescriptor.NAME, },
149: { "LocalName", SpectralHomomorphicDescriptor.NAME, },
150: { "Vendor", "ca.umontreal.iro.image.arcticice", },
151: { "Description",
152: SpectralHomomorphicDescriptor.getDescription(), },
153: { "DocURL", "n/a", },
154: { "Version", "$Version$", },
155: { "arg0Desc",
156: SpectralHomomorphicDescriptor.getArg0Description(), },
157: { "arg1Desc",
158: SpectralHomomorphicDescriptor.getArg1Description(), }, };
159:
160: /** The supported modes. */
161: private static final String[] SUPPORTED_MODES = {
162: RenderedRegistryMode.MODE_NAME,
163: RenderableRegistryMode.MODE_NAME,
164: CollectionRegistryMode.MODE_NAME, };
165:
166: /** The name of the source, use default. */
167: private static final String[] SOURCE_NAMES = null;
168:
169: /** The type of source for each mode. */
170: private static final Class<?>[][] SOURCE_CLASSES = new Class<?>[][] {
171: { Collection.class, }, { Collection.class, },
172: { Collection.class, }, };
173:
174: protected static class SpectralHomomorphicParameterListDescriptor
175: extends CollectionDescriptor.EmptyParameterListDescriptor {
176:
177: /**
178: * Gets the number of parameters for this operator.
179: * @return always <em>2</em>.
180: */
181: @Override
182: public int getNumParameters() {
183: int num_parameters = 2;
184: return num_parameters;
185: }
186:
187: /**
188: * {@inheritDoc}
189: */
190: @Override
191: @SuppressWarnings({"static-access","synthetic-access"})
192: public Object getParamDefaultValue(String name) {
193: int index;
194: if (SpectralHomomorphicDescriptor.FILTER_PARAMETER_NAME
195: .equals(name)) {
196: index = SpectralHomomorphicDescriptor.FILTER_PARAMETER_INDEX;
197: } else if (SpectralHomomorphicDescriptor.TYPE_PARAMETER_NAME
198: .equals(name)) {
199: index = SpectralHomomorphicDescriptor.TYPE_PARAMETER_INDEX;
200: } else {
201: // this call throws an exception
202: return super .getParamDefaultValue(name);
203: }
204:
205: Object[] values = this .getParamDefaults();
206: Object value = values[index];
207: return value;
208: }
209:
210: /**
211: * Gets the default values.
212: * @return no default value for the filter, type float for the data
213: * type.
214: */
215: @Override
216: public Object[] getParamDefaults() {
217: Object[] defaults = new Object[] {
218: // TODO : make a default filter with all 1s for real values and all 0s for imaginary values - watch for type SpectralFilter2D and SpectralFilter3D
219: OperationDescriptor.NO_PARAMETER_DEFAULT,
220: FormatDataType.FLOAT, };
221: return defaults;
222: }
223:
224: /**
225: * {@inheritDoc}
226: */
227: @Override
228: public String[] getParamNames() {
229: String[] names = {
230: SpectralHomomorphicDescriptor.FILTER_PARAMETER_NAME,
231: SpectralHomomorphicDescriptor.TYPE_PARAMETER_NAME, };
232: return names;
233: }
234:
235: /**
236: * Determines if the value is valid.
237: * @return {@code true} if the value is not {@code null},
238: * {@code false} otherwise.
239: */
240: @Override
241: public boolean isParameterValueValid(String name, Object value) {
242: // each parameter is an array, check that it is not null
243: // and nothing more
244: boolean is_valid = (null != value);
245: return is_valid;
246: }
247:
248: }
249:
250: /** The parameter list descriptor for the rendered and renderable modes. */
251: private static final ParameterListDescriptor RENDERED_AND_RENDERABLE_PARAMETER_LIST_DESCRIPTOR = new SpectralHomomorphicParameterListDescriptor() {
252:
253: @Override
254: public Class<?>[] getParamClasses() {
255: Class<?>[] clazzes = new Class<?>[] {
256: SpectralFilter2D.class, FormatDataType.class, };
257: return clazzes;
258: }
259:
260: };
261:
262: /** The parameter list descriptor for the collection mode. */
263: private static final ParameterListDescriptor COLLECTION_PARAMETER_LIST_DESCRIPTOR = new SpectralHomomorphicParameterListDescriptor() {
264:
265: @Override
266: public Class<?>[] getParamClasses() {
267: Class<?>[] clazzes = new Class<?>[] {
268: SpectralFilter3D.class, FormatDataType.class, };
269: return clazzes;
270: }
271:
272: };
273:
274: /** Description of the parameters. */
275: private static final ParameterListDescriptor[] PARAMETER_LIST_DESCRIPTORS = new ParameterListDescriptor[] {
276: SpectralHomomorphicDescriptor.RENDERED_AND_RENDERABLE_PARAMETER_LIST_DESCRIPTOR,
277: SpectralHomomorphicDescriptor.RENDERED_AND_RENDERABLE_PARAMETER_LIST_DESCRIPTOR,
278: SpectralHomomorphicDescriptor.COLLECTION_PARAMETER_LIST_DESCRIPTOR, };
279:
280: //---------------------------
281: // Constructor
282: //---------------------------
283:
284: /**
285: * Constructor.
286: */
287: public SpectralHomomorphicDescriptor() {
288: super (RESOURCES, SUPPORTED_MODES, SOURCE_NAMES, SOURCE_CLASSES,
289: PARAMETER_LIST_DESCRIPTORS);
290: }
291:
292: //---------------------------
293: // Class methods
294: //---------------------------
295:
296: /**
297: * Creates and fills a new parameter block.
298: * @param mode the rendering mode (usually rendered or renderable).
299: * @param source the source image.
300: * @param filter the filter
301: * @param type the data type for the format operation.
302: * @return a new parameter block.
303: */
304: public static ParameterBlockJAI createParameterBlock(String mode,
305: Object source, SpectralFilter2D filter, FormatDataType type) {
306: String name = SpectralHomomorphicDescriptor.NAME;
307: ParameterBlockJAI pb = new ParameterBlockJAI(name, mode);
308: pb.addSource(source);
309: pb.setParameter(
310: SpectralHomomorphicDescriptor.FILTER_PARAMETER_NAME,
311: filter);
312: pb
313: .setParameter(
314: SpectralHomomorphicDescriptor.TYPE_PARAMETER_NAME,
315: type);
316: return pb;
317: }
318:
319: /**
320: * Creates and fills a new parameter block.
321: * @param mode the rendering mode (usually collection).
322: * @param source the source image.
323: * @param filter the filter
324: * @param type the data type for the format operation.
325: * @return a new parameter block.
326: */
327: public static ParameterBlockJAI createParameterBlock(String mode,
328: Object source, SpectralFilter3D filter, FormatDataType type) {
329: String name = SpectralHomomorphicDescriptor.NAME;
330: ParameterBlockJAI pb = new ParameterBlockJAI(name, mode);
331: pb.addSource(source);
332: pb.setParameter(
333: SpectralHomomorphicDescriptor.FILTER_PARAMETER_NAME,
334: filter);
335: pb
336: .setParameter(
337: SpectralHomomorphicDescriptor.TYPE_PARAMETER_NAME,
338: type);
339: return pb;
340: }
341:
342: /**
343: * Creates and fills a new parameter block for the rendered mode.
344: * @param source the source image.
345: * @param filter the filter.
346: * @param type the data type for the format operation.
347: * @return a new parameter block.
348: */
349: public static ParameterBlockJAI createParameterBlock(
350: RenderedImage source, SpectralFilter2D filter,
351: FormatDataType type) {
352: String mode = RenderedRegistryMode.MODE_NAME;
353: ParameterBlockJAI pb = SpectralHomomorphicDescriptor
354: .createParameterBlock(mode, source, filter, type);
355: return pb;
356: }
357:
358: /**
359: * Creates and fills a new parameter block for the renderable mode.
360: * @param source the source image.
361: * @param filter the filter.
362: * @param type the data type for the format operation.
363: * @return a new parameter block.
364: */
365: public static ParameterBlockJAI createParameterBlock(
366: RenderableImage source, SpectralFilter2D filter,
367: FormatDataType type) {
368: String mode = RenderedRegistryMode.MODE_NAME;
369: ParameterBlockJAI pb = SpectralHomomorphicDescriptor
370: .createParameterBlock(mode, source, filter, type);
371: return pb;
372: }
373:
374: /**
375: * Creates and fills a new parameter block for the collection mode.
376: * @param source the source image.
377: * @param filter the filter.
378: * @param type the data type for the format operation.
379: * @return a new parameter block.
380: */
381: public static ParameterBlockJAI createParameterBlock(
382: CollectionImage source, SpectralFilter3D filter,
383: FormatDataType type) {
384: String mode = CollectionRegistryMode.MODE_NAME;
385: ParameterBlockJAI pb = SpectralHomomorphicDescriptor
386: .createParameterBlock(mode, source, filter, type);
387: return pb;
388: }
389:
390: /**
391: * Performs the spatial homomorphic filter operation on a rendered image.
392: * @param source the image to enhance.
393: * @param filter the filter.
394: * @param type the data type for the initial format.
395: * @param hints the rendering hints, may be {@code null}.
396: * @return the rendered result image.
397: */
398: public static RenderedOp create(RenderedImage source,
399: SpectralFilter2D filter, FormatDataType type,
400: RenderingHints hints) {
401: String operation = SpectralHomomorphicDescriptor.NAME;
402: ParameterBlockJAI pb = SpectralHomomorphicDescriptor
403: .createParameterBlock(source, filter, type);
404: RenderedOp image = JAI.create(operation, pb, hints);
405: return image;
406: }
407:
408: /**
409: * Performs the spatial homomorphic filter operation on a renderable image.
410: * @param source the image to enhance.
411: * @param filter the filter.
412: * @param type the data type for the initial format.
413: * @param hints the rendering hints, may be {@code null}.
414: * @return the rendered result image.
415: */
416: public static RenderableOp createRenderable(RenderableImage source,
417: SpectralFilter2D filter, FormatDataType type,
418: RenderingHints hints) {
419: String operation = SpectralHomomorphicDescriptor.NAME;
420: ParameterBlockJAI pb = SpectralHomomorphicDescriptor
421: .createParameterBlock(source, filter, type);
422: RenderableOp image = JAI.createRenderable(operation, pb, hints);
423: return image;
424: }
425:
426: /**
427: * Performs the spatial homomorphic filter operation on a rendered image.
428: * @param source the image to enhance.
429: * @param filter the filter.
430: * @param type the data type for the initial format.
431: * @param hints the rendering hints, may be {@code null}.
432: * @return the rendered result image.
433: */
434: public static CollectionImage createCollection(
435: CollectionImage source, SpectralFilter3D filter,
436: FormatDataType type, RenderingHints hints) {
437: String operation = SpectralHomomorphicDescriptor.NAME;
438: ParameterBlockJAI pb = SpectralHomomorphicDescriptor
439: .createParameterBlock(source, filter, type);
440: CollectionImage image = (CollectionImage) JAI.createCollection(
441: operation, pb, hints);
442: return image;
443: }
444:
445: //---------------------------
446: // External resources methods
447: //---------------------------
448:
449: /**
450: * Gets the description of this operation.
451: * @return the description message.
452: */
453: protected static String getDescription() {
454: String key = Resources.SPECTRAL_HOMOMORPHIC_DESCRIPTION;
455: String message = Resources.getLocalizedString(key);
456: return message;
457: }
458:
459: /**
460: * Gets the description for the first argument, the spectral filter.
461: * @return the description message.
462: */
463: protected static String getArg0Description() {
464: String key = Resources.SPECTRAL_HOMOMORPHIC_ARG0_DESCRIPTION;
465: String message = Resources.getLocalizedString(key);
466: return message;
467: }
468:
469: /**
470: * Gets the description for the second argument, the format data type.
471: * @return the description message.
472: */
473: protected static String getArg1Description() {
474: String key = Resources.SPECTRAL_HOMOMORPHIC_ARG1_DESCRIPTION;
475: String message = Resources.getLocalizedString(key);
476: return message;
477: }
478:
479: }
480:
481: /*
482: * $Log: SpectralHomomorphicDescriptor.java,v $
483: * Revision 1.2 2007/07/17 16:40:25 forklabs
484: * clean up.
485: *
486: * Revision 1.1 2007/07/05 18:31:30 forklabs
487: * Operator spectralhomomorphic.
488: *
489: */
|