001/*----------------------------------------------------------------------------*/
002/* Copyright (c) FIRST 2008-2012. All Rights Reserved.                        */
003/* Open Source Software - may be modified and shared by FRC teams. The code   */
004/* must be accompanied by the FIRST BSD license file in the root directory of */
005/* the project.                                                               */
006/*----------------------------------------------------------------------------*/
007package edu.wpi.first.wpilibj.image;
008
009import com.ni.vision.NIVision;
010
011/**
012 * A class representing a color image.
013 *
014 * @author dtjones
015 */
016public abstract class ColorImage extends ImageBase {
017
018    ColorImage(NIVision.ImageType type) throws NIVisionException {
019        super(type);
020    }
021
022    ColorImage(ColorImage sourceImage) {
023        super(sourceImage);
024    }
025
026    private BinaryImage threshold(NIVision.ColorMode colorMode,
027                                  int low1, int high1,
028                                  int low2, int high2,
029                                  int low3, int high3) throws NIVisionException {
030        BinaryImage res = new BinaryImage();
031        NIVision.Range range1 = new NIVision.Range(low1, high1);
032        NIVision.Range range2 = new NIVision.Range(low2, high2);
033        NIVision.Range range3 = new NIVision.Range(low3, high3);
034        NIVision.imaqColorThreshold(res.image, image, 1, colorMode, range1, range2, range3);
035        res.free();
036        range1.free();
037        range2.free();
038        range3.free();
039        return res;
040    }
041
042    /**
043     * Return a mask of the areas of the image that fall within the given ranges for color values
044     *
045     * @param redLow    The lower red limit.
046     * @param redHigh   The upper red limit.
047     * @param greenLow  The lower green limit.
048     * @param greenHigh The upper green limit.
049     * @param blueLow   The lower blue limit.
050     * @param blueHigh  The upper blue limit.
051     * @return A BinaryImage masking the areas which match the given thresholds.
052     */
053    public BinaryImage thresholdRGB(int redLow, int redHigh, int greenLow, int greenHigh, int blueLow, int blueHigh) throws NIVisionException {
054        return threshold(NIVision.ColorMode.RGB, redLow, redHigh, greenLow, greenHigh, blueLow, blueHigh);
055    }
056
057    /**
058     * Return a mask of the areas of the image that fall within the given ranges for color values
059     *
060     * @param hueLow         The lower hue limit.
061     * @param hueHigh        The upper hue limit.
062     * @param saturationLow  The lower saturation limit.
063     * @param saturationHigh The upper saturation limit.
064     * @param luminenceLow   The lower luminence limit.
065     * @param luminenceHigh  The upper luminence limit.
066     * @return A BinaryImage masking the areas which match the given thresholds.
067     */
068    public BinaryImage thresholdHSL(int hueLow, int hueHigh, int saturationLow, int saturationHigh, int luminenceLow, int luminenceHigh) throws NIVisionException {
069        return threshold(NIVision.ColorMode.HSL, hueLow, hueHigh, saturationLow, saturationHigh, luminenceLow, luminenceHigh);
070    }
071
072    /**
073     * Return a mask of the areas of the image that fall within the given ranges for color values
074     *
075     * @param hueLow         The lower hue limit.
076     * @param hueHigh        The upper hue limit.
077     * @param saturationLow  The lower saturation limit.
078     * @param saturationHigh The upper saturation limit.
079     * @param valueHigh      The lower value limit.
080     * @param valueLow       The upper value limit.
081     * @return A BinaryImage masking the areas which match the given thresholds.
082     */
083    public BinaryImage thresholdHSV(int hueLow, int hueHigh, int saturationLow, int saturationHigh, int valueLow, int valueHigh) throws NIVisionException {
084        return threshold(NIVision.ColorMode.HSV, hueLow, hueHigh, saturationLow, saturationHigh, valueLow, valueHigh);
085    }
086
087    /**
088     * Return a mask of the areas of the image that fall within the given ranges for color values
089     *
090     * @param hueLow         The lower hue limit.
091     * @param hueHigh        The upper hue limit.
092     * @param saturationLow  The lower saturation limit.
093     * @param saturationHigh The upper saturation limit.
094     * @param intansityLow   The lower intensity limit.
095     * @param intensityHigh  The upper intensity limit.
096     * @return A BinaryImage masking the areas which match the given thresholds.
097     */
098    public BinaryImage thresholdHSI(int hueLow, int hueHigh, int saturationLow, int saturationHigh, int intansityLow, int intensityHigh) throws NIVisionException {
099        return threshold(NIVision.ColorMode.HSI, hueLow, hueHigh, saturationLow, saturationHigh, intansityLow, intensityHigh);
100    }
101
102    MonoImage extractFirstColorPlane(NIVision.ColorMode mode) throws NIVisionException {
103        MonoImage result = new MonoImage();
104        NIVision.imaqExtractColorPlanes(image, mode, result.image, null, null);
105        result.free();
106        return result;
107    }
108
109    MonoImage extractSecondColorPlane(NIVision.ColorMode mode) throws NIVisionException {
110        MonoImage result = new MonoImage();
111        NIVision.imaqExtractColorPlanes(image, mode, null, result.image, null);
112        result.free();
113        return result;
114    }
115
116    MonoImage extractThirdColorPlane(NIVision.ColorMode mode) throws NIVisionException {
117        MonoImage result = new MonoImage();
118        NIVision.imaqExtractColorPlanes(image, mode, null, null, result.image);
119        result.free();
120        return result;
121    }
122
123    /**
124     * Get the red color plane from the image when represented in RGB color space.
125     *
126     * @return The red color plane from the image.
127     */
128    public MonoImage getRedPlane() throws NIVisionException {
129        return extractFirstColorPlane(NIVision.ColorMode.RGB);
130    }
131
132    /**
133     * Get the green color plane from the image when represented in RGB color space.
134     *
135     * @return The green color plane from the image.
136     */
137    public MonoImage getGreenPlane() throws NIVisionException {
138        return extractSecondColorPlane(NIVision.ColorMode.RGB);
139    }
140
141    /**
142     * Get the blue color plane from the image when represented in RGB color space.
143     *
144     * @return The blue color plane from the image.
145     */
146    public MonoImage getBluePlane() throws NIVisionException {
147        return extractThirdColorPlane(NIVision.ColorMode.RGB);
148    }
149
150    /**
151     * Get the hue color plane from the image when represented in HSL color space.
152     *
153     * @return The hue color plane from the image.
154     */
155    public MonoImage getHSLHuePlane() throws NIVisionException {
156        return extractFirstColorPlane(NIVision.ColorMode.HSL);
157    }
158
159    /**
160     * Get the hue color plane from the image when represented in HSV color space.
161     *
162     * @return The hue color plane from the image.
163     */
164    public MonoImage getHSVHuePlane() throws NIVisionException {
165        return extractFirstColorPlane(NIVision.ColorMode.HSV);
166    }
167
168    /**
169     * Get the hue color plane from the image when represented in HSI color space.
170     *
171     * @return The hue color plane from the image.
172     */
173    public MonoImage getHSIHuePlane() throws NIVisionException {
174        return extractFirstColorPlane(NIVision.ColorMode.HSI);
175    }
176
177    /**
178     * Get the saturation color plane from the image when represented in HSL color space.
179     *
180     * @return The saturation color plane from the image.
181     */
182    public MonoImage getHSLSaturationPlane() throws NIVisionException {
183        return extractSecondColorPlane(NIVision.ColorMode.HSL);
184    }
185
186    /**
187     * Get the saturation color plane from the image when represented in HSV color space.
188     *
189     * @return The saturation color plane from the image.
190     */
191    public MonoImage getHSVSaturationPlane() throws NIVisionException {
192        return extractSecondColorPlane(NIVision.ColorMode.HSV);
193    }
194
195    /**
196     * Get the saturation color plane from the image when represented in HSI color space.
197     *
198     * @return The saturation color plane from the image.
199     */
200    public MonoImage getHSISaturationPlane() throws NIVisionException {
201        return extractSecondColorPlane(NIVision.ColorMode.HSI);
202    }
203
204    /**
205     * Get the luminance color plane from the image when represented in HSL color space.
206     *
207     * @return The luminance color plane from the image.
208     */
209    public MonoImage getLuminancePlane() throws NIVisionException {
210        return extractThirdColorPlane(NIVision.ColorMode.HSL);
211    }
212
213    /**
214     * Get the value color plane from the image when represented in HSV color space.
215     *
216     * @return The value color plane from the image.
217     */
218    public MonoImage getValuePlane() throws NIVisionException {
219        return extractThirdColorPlane(NIVision.ColorMode.HSV);
220    }
221
222    /**
223     * Get the intensity color plane from the image when represented in HSI color space.
224     *
225     * @return The intensity color plane from the image.
226     */
227    public MonoImage getIntensityPlane() throws NIVisionException {
228        return extractThirdColorPlane(NIVision.ColorMode.HSI);
229    }
230
231    ColorImage replaceFirstColorPlane(NIVision.ColorMode mode, MonoImage plane) throws NIVisionException {
232        NIVision.imaqReplaceColorPlanes(image, image, mode, plane.image, null, null);
233        return this;
234    }
235
236    ColorImage replaceSecondColorPlane(NIVision.ColorMode mode, MonoImage plane) throws NIVisionException {
237        NIVision.imaqReplaceColorPlanes(image, image, mode, null, plane.image, null);
238        return this;
239    }
240
241    ColorImage replaceThirdColorPlane(NIVision.ColorMode mode, MonoImage plane) throws NIVisionException {
242        NIVision.imaqReplaceColorPlanes(image, image, mode, null, null, plane.image);
243        return this;
244    }
245
246    /**
247     * Set the red color plane from the image when represented in RGB color space.
248     * This does not create a new image, but modifies this one instead. Create a
249     * copy before hand if you need to continue using the original.
250     *
251     * @param plane The MonoImage representing the new color plane.
252     * @return The resulting image.
253     */
254    public ColorImage replaceRedPlane(MonoImage plane) throws NIVisionException {
255        return replaceFirstColorPlane(NIVision.ColorMode.RGB, plane);
256    }
257
258    /**
259     * Set the green color plane from the image when represented in RGB color space.
260     * This does not create a new image, but modifies this one instead. Create a
261     * copy before hand if you need to continue using the original.
262     *
263     * @param plane The MonoImage representing the new color plane.
264     * @return The resulting image.
265     */
266    public ColorImage replaceGreenPlane(MonoImage plane) throws NIVisionException {
267        return replaceSecondColorPlane(NIVision.ColorMode.RGB, plane);
268    }
269
270    /**
271     * Set the blue color plane from the image when represented in RGB color space.
272     * This does not create a new image, but modifies this one instead. Create a
273     * copy before hand if you need to continue using the original.
274     *
275     * @param plane The MonoImage representing the new color plane.
276     * @return The resulting image.
277     */
278    public ColorImage replaceBluePlane(MonoImage plane) throws NIVisionException {
279        return replaceThirdColorPlane(NIVision.ColorMode.RGB, plane);
280    }
281
282    /**
283     * Set the hue color plane from the image when represented in HSL color space.
284     * This does not create a new image, but modifies this one instead. Create a
285     * copy before hand if you need to continue using the original.
286     *
287     * @param plane The MonoImage representing the new color plane.
288     * @return The resulting image.
289     */
290    public ColorImage replaceHSLHuePlane(MonoImage plane) throws NIVisionException {
291        return replaceFirstColorPlane(NIVision.ColorMode.HSL, plane);
292    }
293
294    /**
295     * Set the hue color plane from the image when represented in HSV color space.
296     * This does not create a new image, but modifies this one instead. Create a
297     * copy before hand if you need to continue using the original.
298     *
299     * @param plane The MonoImage representing the new color plane.
300     * @return The resulting image.
301     */
302    public ColorImage replaceHSVHuePlane(MonoImage plane) throws NIVisionException {
303        return replaceFirstColorPlane(NIVision.ColorMode.HSV, plane);
304    }
305
306    /**
307     * Set the hue color plane from the image when represented in HSI color space.
308     * This does not create a new image, but modifies this one instead. Create a
309     * copy before hand if you need to continue using the original.
310     *
311     * @param plane The MonoImage representing the new color plane.
312     * @return The resulting image.
313     */
314    public ColorImage replaceHSIHuePlane(MonoImage plane) throws NIVisionException {
315        return replaceFirstColorPlane(NIVision.ColorMode.HSI, plane);
316    }
317
318    /**
319     * Set the saturation color plane from the image when represented in HSL color space.
320     * This does not create a new image, but modifies this one instead. Create a
321     * copy before hand if you need to continue using the original.
322     *
323     * @param plane The MonoImage representing the new color plane.
324     * @return The resulting image.
325     */
326    public ColorImage replaceHSLSaturationPlane(MonoImage plane) throws NIVisionException {
327        return replaceSecondColorPlane(NIVision.ColorMode.HSL, plane);
328    }
329
330    /**
331     * Set the saturation color plane from the image when represented in HSV color space.
332     * This does not create a new image, but modifies this one instead. Create a
333     * copy before hand if you need to continue using the original.
334     *
335     * @param plane The MonoImage representing the new color plane.
336     * @return The resulting image.
337     */
338    public ColorImage replaceHSVSaturationPlane(MonoImage plane) throws NIVisionException {
339        return replaceSecondColorPlane(NIVision.ColorMode.HSV, plane);
340    }
341
342    /**
343     * Set the saturation color plane from the image when represented in HSI color space.
344     * This does not create a new image, but modifies this one instead. Create a
345     * copy before hand if you need to continue using the original.
346     *
347     * @param plane The MonoImage representing the new color plane.
348     * @return The resulting image.
349     */
350    public ColorImage replaceHSISaturationPlane(MonoImage plane) throws NIVisionException {
351        return replaceSecondColorPlane(NIVision.ColorMode.HSI, plane);
352    }
353
354    /**
355     * Set the luminance color plane from the image when represented in HSL color space.
356     * This does not create a new image, but modifies this one instead. Create a
357     * copy before hand if you need to continue using the original.
358     *
359     * @param plane The MonoImage representing the new color plane.
360     * @return The resulting image.
361     */
362    public ColorImage replaceLuminancePlane(MonoImage plane) throws NIVisionException {
363        return replaceThirdColorPlane(NIVision.ColorMode.HSL, plane);
364    }
365
366    /**
367     * Set the value color plane from the image when represented in HSV color space.
368     * This does not create a new image, but modifies this one instead. Create a
369     * copy before hand if you need to continue using the original.
370     *
371     * @param plane The MonoImage representing the new color plane.
372     * @return The resulting image.
373     */
374    public ColorImage replaceValuePlane(MonoImage plane) throws NIVisionException {
375        return replaceThirdColorPlane(NIVision.ColorMode.HSV, plane);
376    }
377
378    /**
379     * Set the intensity color plane from the image when represented in HSI color space.
380     * This does not create a new image, but modifies this one instead. Create a
381     * copy before hand if you need to continue using the original.
382     *
383     * @param plane The MonoImage representing the new color plane.
384     * @return The resulting image.
385     */
386    public ColorImage replaceIntensityPlane(MonoImage plane) throws NIVisionException {
387        return replaceThirdColorPlane(NIVision.ColorMode.HSI, plane);
388    }
389
390    /**
391     * Calculates the histogram of each plane of a color image and redistributes
392     * pixel values across the desired range while maintaining pixel value
393     * groupings.
394     * This does not create a new image, but modifies this one instead. Create a
395     * copy before hand if you need to continue using the original.
396     *
397     * @return The modified image.
398     */
399    public ColorImage colorEqualize() throws NIVisionException {
400        NIVision.imaqColorEqualize(image, image, 1);
401        return this;
402    }
403
404    /**
405     * Calculates the histogram of each plane of a color image and redistributes
406     * pixel values across the desired range while maintaining pixel value
407     * groupings for the Luminance plane only.
408     * This does not create a new image, but modifies this one instead. Create a
409     * copy before hand if you need to continue using the original.
410     *
411     * @return The modified image.
412     */
413    public ColorImage luminanceEqualize() throws NIVisionException {
414        NIVision.imaqColorEqualize(image, image, 0);
415        return this;
416    }
417}