blob: 163721da3c2b9d7c8e113b1be94078b6e64821c9 [file] [log] [blame]
Brian Silverman26e4e522015-12-17 01:56:40 -05001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2014. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
5/*----------------------------------------------------------------------------*/
6
7#include <stdlib.h>
8#include <stdarg.h>
9
10#include "Vision/BaeUtilities.h"
11#include "Vision/FrcError.h"
12#include "Vision/VisionAPI.h"
13
14int VisionAPI_debugFlag = 1;
15#define DPRINTF \
16 if (VisionAPI_debugFlag) dprintf
17
18/** @file
19 * Image Management functions
20 */
21
22/**
23* @brief Create an image object
24* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL, IMAQ_IMAGE_COMPLEX,
25* IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL, IMAQ_IMAGE_RGB_U64
26* The border size is defaulted to 3 so that convolutional algorithms work at the
27* edges.
28* When you are finished with the created image, dispose of it by calling
29* frcDispose().
30* To get extended error information, call GetLastError().
31*
32* @param type Type of image to create
33* @return Image* On success, this function returns the created image. On
34* failure, it returns nullptr.
35*/
36Image* frcCreateImage(ImageType type) {
37 return imaqCreateImage(type, DEFAULT_BORDER_SIZE);
38}
39
40/**
41* @brief Dispose of one object. Supports any object created on the heap.
42*
43* @param object object to dispose of
44* @return On success: 1. On failure: 0. To get extended error information, call
45* GetLastError().
46*/
47int frcDispose(void* object) { return imaqDispose(object); }
48/**
49* @brief Dispose of a list of objects. Supports any object created on the heap.
50*
51* @param functionName The name of the function
52* @param ... A list of pointers to structures that need to be disposed of.
53* The last pointer in the list should always be set to nullptr.
54*
55* @return On success: 1. On failure: 0. To get extended error information, call
56* GetLastError().
57*/
58int frcDispose(const char* functionName, ...) /* Variable argument list */
59{
60 va_list disposalPtrList; /* Input argument list */
61 void* disposalPtr; /* For iteration */
62 int success, returnValue = 1;
63
64 va_start(disposalPtrList, functionName); /* start of variable list */
65 disposalPtr = va_arg(disposalPtrList, void*);
66 while (disposalPtr != nullptr) {
67 success = imaqDispose(disposalPtr);
68 if (!success) {
69 returnValue = 0;
70 }
71 disposalPtr = va_arg(disposalPtrList, void*);
72 }
73 va_end(disposalPtrList);
74 return returnValue;
75}
76
77/**
78* @brief Copy an image object.
79* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL, IMAQ_IMAGE_RGB,
80* IMAQ_IMAGE_HSL.
81*
82* @param dest Copy of image. On failure, dest is nullptr. Must have already been
83* created using frcCreateImage().
84* When you are finished with the created image, dispose of it by calling
85* frcDispose().
86* @param source Image to copy
87*
88* @return On success: 1. On failure: 0. To get extended error information, call
89* GetLastError().
90*/
91int frcCopyImage(Image* dest, const Image* source) {
92 return imaqDuplicate(dest, source);
93}
94
95/**
96* @brief Crop image without changing the scale.
97* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL, IMAQ_IMAGE_RGB,
98* IMAQ_IMAGE_HSL.
99*
100* @param dest Modified image
101* @param source Image to crop
102* @param rect region to process, or IMAQ_NO_RECT
103*
104* @return On success: 1. On failure: 0. To get extended error information, call
105* GetLastError().
106*/
107int frcCrop(Image* dest, const Image* source, Rect rect) {
108 return imaqScale(dest, source, 1, 1, IMAQ_SCALE_LARGER, rect);
109}
110
111/**
112* @brief Scales the entire image larger or smaller.
113* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL, IMAQ_IMAGE_RGB,
114* IMAQ_IMAGE_HSL.
115*
116* @param dest Modified image
117* @param source Image to scale
118* @param xScale the horizontal reduction ratio
119* @param yScale the vertical reduction ratio
120* @param scaleMode IMAQ_SCALE_LARGER or IMAQ_SCALE_SMALLER
121*
122* @return On success: 1. On failure: 0. To get extended error information, call
123* GetLastError().
124*/
125int frcScale(Image* dest, const Image* source, int xScale, int yScale,
126 ScalingMode scaleMode) {
127 Rect rect = IMAQ_NO_RECT;
128 return imaqScale(dest, source, xScale, yScale, scaleMode, rect);
129}
130
131/**
132 * @brief Creates image object from the information in a file. The file can be
133 * in one of the following formats:
134 * PNG, JPEG, JPEG2000, TIFF, AIPD, or BMP.
135 * Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL, IMAQ_IMAGE_COMPLEX,
136 * IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL, IMAQ_IMAGE_RGB_U64.
137 *
138 * @param image Image read in
139 * @param fileName File to read. Cannot be nullptr
140 *
141 * @return On success: 1. On failure: 0. To get extended error information, call
142 * GetLastError().
143 */
144int frcReadImage(Image* image, const char* fileName) {
145 return imaqReadFile(image, fileName, nullptr, nullptr);
146}
147
148/**
149* @brief Write image to a file.
150* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL, IMAQ_IMAGE_COMPLEX,
151* IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL, IMAQ_IMAGE_RGB_U64.
152*
153* The file type is determined by the extension, as follows:
154*
155* Extension File Type
156* aipd or .apd AIPD
157* .bmp BMP
158* .jpg or .jpeg JPEG
159* .jp2 JPEG2000
160* .png PNG
161* .tif or .tiff TIFF
162*
163*
164* The following are the supported image types for each file type:
165*
166* File Types Image Types
167* AIPD all image types
168* BMP, JPEG 8-bit, RGB
169* PNG, TIFF, JPEG2000 8-bit, 16-bit, RGB, RGBU64
170*
171* @param image Image to write
172* @param fileName File to read. Cannot be nullptr. The extension determines the
173* file format that is written.
174*
175* @return On success: 1. On failure: 0. To get extended error information, call
176* GetLastError().
177*/
178int frcWriteImage(const Image* image, const char* fileName) {
179 RGBValue* colorTable = nullptr;
180 return imaqWriteFile(image, fileName, colorTable);
181}
182
183/* Measure Intensity functions */
184
185/**
186* @brief Measures the pixel intensities in a rectangle of an image.
187* Outputs intensity based statistics about an image such as Max, Min, Mean and
188* Std Dev of pixel value.
189* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL.
190*
191* Parameter Discussion :
192* Relevant parameters of the HistogramReport include:
193* min, max, mean and stdDev
194* min/max —Setting both min and max to 0 causes the function to set
195* min to 0
196* and the max to 255 for 8-bit images and to the actual
197* minimum value and
198* maximum value of the image for all other image types.
199* max—Setting both min and max to 0 causes the function to set max
200* to 255
201* for 8-bit images and to the actual maximum value of the
202* image for
203* all other image types.
204*
205* @param image Image whose histogram the function calculates.
206* @param numClasses The number of classes into which the function separates the
207* pixels.
208* Determines the number of elements in the histogram array returned
209* @param min The minimum pixel value to consider for the histogram.
210* The function does not count pixels with values less than min.
211* @param max The maximum pixel value to consider for the histogram.
212* The function does not count pixels with values greater than max.
213* @param rect Region of interest in the image. If not included, the entire image
214* is used.
215* @return On success, this function returns a report describing the pixel value
216* classification.
217* When you are finished with the report, dispose of it by calling frcDispose().
218* On failure, this function returns nullptr. To get extended error information,
219* call GetLastError().
220*
221*/
222HistogramReport* frcHistogram(const Image* image, int numClasses, float min,
223 float max) {
224 Rect rect = IMAQ_NO_RECT;
225 return frcHistogram(image, numClasses, min, max, rect);
226}
227HistogramReport* frcHistogram(const Image* image, int numClasses, float min,
228 float max, Rect rect) {
229 int success;
230 int fillValue = 1;
231
232 /* create the region of interest */
233 ROI* pRoi = imaqCreateROI();
234 success = imaqAddRectContour(pRoi, rect);
235 if (!success) {
236 GetLastVisionError();
237 return nullptr;
238 }
239
240 /* make a mask from the ROI */
241 Image* pMask = frcCreateImage(IMAQ_IMAGE_U8);
242 success = imaqROIToMask(pMask, pRoi, fillValue, nullptr, nullptr);
243 if (!success) {
244 GetLastVisionError();
245 frcDispose(__FUNCTION__, pRoi, nullptr);
246 return nullptr;
247 }
248
249 /* get a histogram report */
250 HistogramReport* pHr = nullptr;
251 pHr = imaqHistogram(image, numClasses, min, max, pMask);
252
253 /* clean up */
254 frcDispose(__FUNCTION__, pRoi, pMask, nullptr);
255
256 return pHr;
257}
258
259/**
260* @brief Calculates the histogram, or pixel distribution, of a color image.
261* Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL.
262*
263* @param image Image whose histogram the function calculates.
264* @param numClasses The number of classes into which the function separates the
265* pixels.
266* Determines the number of elements in the histogram array returned
267* @param mode The color space in which to perform the histogram. Possible values
268* include IMAQ_RGB and IMAQ_HSL.
269* @param mask An optional mask image. This image must be an IMAQ_IMAGE_U8 image.
270* The function calculates the histogram using only those pixels in the image
271* whose
272* corresponding pixels in the mask are non-zero. Set this parameter to nullptr to
273* calculate
274* the histogram of the entire image, or use the simplified call.
275*
276* @return On success, this function returns a report describing the
277* classification
278* of each plane in a HistogramReport.
279* When you are finished with the report, dispose of it by calling frcDispose().
280* On failure, this function returns nullptr.
281* To get extended error information, call imaqGetLastError().
282*/
283ColorHistogramReport* frcColorHistogram(const Image* image, int numClasses,
284 ColorMode mode) {
285 return frcColorHistogram(image, numClasses, mode, nullptr);
286}
287
288ColorHistogramReport* frcColorHistogram(const Image* image, int numClasses,
289 ColorMode mode, Image* mask) {
290 return imaqColorHistogram2((Image*)image, numClasses, mode, nullptr, mask);
291}
292
293/**
294* @brief Measures the pixel intensities in a rectangle of an image.
295* Outputs intensity based statistics about an image such as Max, Min, Mean and
296* Std Dev of pixel value.
297* Supports IMAQ_IMAGE_U8 (grayscale) IMAQ_IMAGE_RGB (color) IMAQ_IMAGE_HSL
298* (color-HSL).
299*
300* @param image The image whose pixel value the function queries
301* @param pixel The coordinates of the pixel that the function queries
302* @param value On return, the value of the specified image pixel. This parameter
303* cannot be nullptr.
304* This data structure contains either grayscale, RGB, HSL, Complex or
305* RGBU64Value depending on the type of image.
306* @return On success: 1. On failure: 0. To get extended error information, call
307* GetLastError().
308*/
309int frcGetPixelValue(const Image* image, Point pixel, PixelValue* value) {
310 return imaqGetPixel(image, pixel, value);
311}
312
313/* Particle Analysis functions */
314
315/**
316* @brief Filters particles out of an image based on their measurements.
317* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL.
318*
319* @param dest The destination image. If dest is used, it must be the same size
320* as the Source image. It will contain only the filtered particles.
321* @param source The image containing the particles to filter.
322* @param criteria An array of criteria to apply to the particles in the source
323* image. This array cannot be nullptr.
324* See the NIVisionCVI.chm help file for definitions of criteria.
325* @param criteriaCount The number of elements in the criteria array.
326* @param options Binary filter options, including rejectMatches, rejectBorder,
327* and connectivity8.
328* @param rect Area of image to filter. If omitted, the default is entire image.
329* @param numParticles On return, the number of particles left in the image
330* @return On success: 1. On failure: 0. To get extended error information, call
331* GetLastError().
332*/
333int frcParticleFilter(Image* dest, Image* source,
334 const ParticleFilterCriteria2* criteria,
335 int criteriaCount, const ParticleFilterOptions* options,
336 int* numParticles) {
337 Rect rect = IMAQ_NO_RECT;
338 return frcParticleFilter(dest, source, criteria, criteriaCount, options, rect,
339 numParticles);
340}
341
342int frcParticleFilter(Image* dest, Image* source,
343 const ParticleFilterCriteria2* criteria,
344 int criteriaCount, const ParticleFilterOptions* options,
345 Rect rect, int* numParticles) {
346 ROI* roi = imaqCreateROI();
347 imaqAddRectContour(roi, rect);
348 return imaqParticleFilter3(dest, source, criteria, criteriaCount, options,
349 roi, numParticles);
350}
351
352/**
353* @brief Performs morphological transformations on binary images.
354* Supports IMAQ_IMAGE_U8.
355*
356* @param dest The destination image. The border size of the destination image is
357* not important.
358* @param source The image on which the function performs the morphological
359* operations. The calculation
360* modifies the border of the source image. The border must be at least half as
361* large as the larger
362* dimension of the structuring element. The connected source image for a
363* morphological transformation
364* must have been created with a border capable of supporting the size of the
365* structuring element.
366* A 3 by 3 structuring element requires a minimal border of 1, a 5 by 5
367* structuring element requires a minimal border of 2, and so on.
368* @param method The morphological transform to apply.
369* @param structuringElement The structuring element used in the operation. Omit
370* this parameter if you do not want a custom structuring element.
371* @return On success: 1. On failure: 0. To get extended error information, call
372* GetLastError().
373*/
374int frcMorphology(Image* dest, Image* source, MorphologyMethod method) {
375 return imaqMorphology(dest, source, method, nullptr);
376}
377
378int frcMorphology(Image* dest, Image* source, MorphologyMethod method,
379 const StructuringElement* structuringElement) {
380 return imaqMorphology(dest, source, method, structuringElement);
381}
382
383/**
384* @brief Eliminates particles that touch the border of the image.
385* Supports IMAQ_IMAGE_U8.
386*
387* @param dest The destination image.
388* @param source The source image. If the image has a border, the function sets
389* all border pixel values to 0.
390* @param connectivity8 specifies the type of connectivity used by the algorithm
391* for particle detection.
392* The connectivity mode directly determines whether an adjacent pixel belongs to
393* the same particle or a
394* different particle. Set to TRUE to use connectivity-8 to determine whether
395* particles are touching
396* Set to FALSE to use connectivity-4 to determine whether particles are
397* touching.
398* The default setting for the simplified call is TRUE
399* @return On success: 1. On failure: 0. To get extended error information, call
400* GetLastError().
401*/
402int frcRejectBorder(Image* dest, Image* source) {
403 return imaqRejectBorder(dest, source, TRUE);
404}
405
406int frcRejectBorder(Image* dest, Image* source, int connectivity8) {
407 return imaqRejectBorder(dest, source, connectivity8);
408}
409
410/**
411* @brief Counts the number of particles in a binary image.
412* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL.
413* @param image binary (thresholded) image
414* @param numParticles On return, the number of particles.
415* @return On success: 1. On failure: 0. To get extended error information, call
416* GetLastError().
417*/
418int frcCountParticles(Image* image, int* numParticles) {
419 return imaqCountParticles(image, 1, numParticles);
420}
421
422/**
423* @brief Conduct measurements for a single particle in an images.
424* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL.
425*
426* @param image image with the particle to analyze. This function modifies the
427* source image.
428* If you need the original image, create a copy of the image using frcCopy()
429* before using this function.
430* @param particleNumber The number of the particle to get information on
431* @param par on return, a particle analysis report containing information about
432* the particle. This structure must be created by the caller.
433* @return On success: 1. On failure: 0. To get extended error information, call
434* GetLastError().
435*/
436int frcParticleAnalysis(Image* image, int particleNumber,
437 ParticleAnalysisReport* par) {
438 int success = 0;
439
440 /* image information */
441 int height, width;
442 if (!imaqGetImageSize(image, &width, &height)) {
443 return success;
444 }
445 par->imageWidth = width;
446 par->imageHeight = height;
447 par->particleIndex = particleNumber;
448
449 /* center of mass point of the largest particle */
450 double returnDouble;
451 success = imaqMeasureParticle(image, particleNumber, 0,
452 IMAQ_MT_CENTER_OF_MASS_X, &returnDouble);
453 if (!success) {
454 return success;
455 }
456 par->center_mass_x = (int)returnDouble; // pixel
457
458 success = imaqMeasureParticle(image, particleNumber, 0,
459 IMAQ_MT_CENTER_OF_MASS_Y, &returnDouble);
460 if (!success) {
461 return success;
462 }
463 par->center_mass_y = (int)returnDouble; // pixel
464
465 /* particle size statistics */
466 success = imaqMeasureParticle(image, particleNumber, 0, IMAQ_MT_AREA,
467 &returnDouble);
468 if (!success) {
469 return success;
470 }
471 par->particleArea = returnDouble;
472
473 success = imaqMeasureParticle(image, particleNumber, 0,
474 IMAQ_MT_BOUNDING_RECT_TOP, &returnDouble);
475 if (!success) {
476 return success;
477 }
478 par->boundingRect.top = (int)returnDouble;
479
480 success = imaqMeasureParticle(image, particleNumber, 0,
481 IMAQ_MT_BOUNDING_RECT_LEFT, &returnDouble);
482 if (!success) {
483 return success;
484 }
485 par->boundingRect.left = (int)returnDouble;
486
487 success = imaqMeasureParticle(image, particleNumber, 0,
488 IMAQ_MT_BOUNDING_RECT_HEIGHT, &returnDouble);
489 if (!success) {
490 return success;
491 }
492 par->boundingRect.height = (int)returnDouble;
493
494 success = imaqMeasureParticle(image, particleNumber, 0,
495 IMAQ_MT_BOUNDING_RECT_WIDTH, &returnDouble);
496 if (!success) {
497 return success;
498 }
499 par->boundingRect.width = (int)returnDouble;
500
501 /* particle quality statistics */
502 success = imaqMeasureParticle(image, particleNumber, 0,
503 IMAQ_MT_AREA_BY_IMAGE_AREA, &returnDouble);
504 if (!success) {
505 return success;
506 }
507 par->particleToImagePercent = returnDouble;
508
509 success = imaqMeasureParticle(image, particleNumber, 0,
510 IMAQ_MT_AREA_BY_PARTICLE_AND_HOLES_AREA,
511 &returnDouble);
512 if (!success) {
513 return success;
514 }
515 par->particleQuality = returnDouble;
516
517 /* normalized position (-1 to 1) */
518 par->center_mass_x_normalized = RangeToNormalized(par->center_mass_x, width);
519 par->center_mass_y_normalized = RangeToNormalized(par->center_mass_y, height);
520
521 return success;
522}
523
524/* Image Enhancement functions */
525
526/**
527* @brief Improves contrast on a grayscale image.
528* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16.
529* @param dest The destination image.
530* @param source The image to equalize
531* @param min the smallest value used for processing. After processing, all pixel
532* values that are less than or equal to the Minimum in the original image are set
533* to 0 for an 8-bit image. In 16-bit and floating-point images, these pixel
534* values are set to the smallest pixel value found in the original image.
535* @param max the largest value used for processing. After processing, all pixel
536* values that are greater than or equal to the Maximum in the original image are
537* set to 255 for an 8-bit image. In 16-bit and floating-point images, these pixel
538* values are set to the largest pixel value found in the original image.
539* @param mask an 8-bit image that specifies the region of the small image that
540* will be copied. Only those pixels in the Image Src (Small) image that
541* correspond to an equivalent non-zero pixel in the mask image are copied. All
542* other pixels keep their original values. The entire image is processed if Image
543* Mask is nullptr or this parameter is omitted.
544* @return On success: 1. On failure: 0. To get extended error information, call
545* GetLastError().
546*
547* option defaults:
548* searchRect = IMAQ_NO_RECT
549* minMatchScore = DEFAULT_MINMAX_SCORE (800)
550*/
551int frcEqualize(Image* dest, const Image* source, float min, float max) {
552 return frcEqualize(dest, source, min, max, nullptr);
553}
554
555int frcEqualize(Image* dest, const Image* source, float min, float max,
556 const Image* mask) {
557 return imaqEqualize(dest, source, min, max, mask);
558}
559
560/**
561* @brief Improves contrast on a color image.
562* Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL
563*
564* option defaults: colorEqualization = TRUE to equalize all three planes of the
565* image
566* @return On success: 1. On failure: 0. To get extended error information, call
567* GetLastError().
568* @param dest The destination image.
569* @param source The image to equalize
570* @param colorEqualization Set this parameter to TRUE to equalize all three
571* planes of the image (the default). Set this parameter to FALSE to equalize only
572* the luminance plane.
573*/
574int frcColorEqualize(Image* dest, const Image* source) {
575 return imaqColorEqualize(dest, source, TRUE);
576}
577
578int frcColorEqualize(Image* dest, const Image* source, int colorEqualization) {
579 return imaqColorEqualize(dest, source, TRUE);
580}
581
582/* Image Conversion functions */
583
584/**
585* @brief Automatically thresholds a grayscale image into a binary image for
586* Particle Analysis based on a smart threshold.
587* Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_I16
588* @param dest The destination image.
589* @param source The image to threshold
590* @param windowWidth The width of the rectangular window around the pixel on
591* which the function
592* performs the local threshold. This number must be at least 3 and cannot be
593* larger than the width of source
594* @param windowHeight The height of the rectangular window around the pixel on
595* which the function
596* performs the local threshold. This number must be at least 3 and cannot be
597* larger than the height of source
598* @param method Specifies the local thresholding method the function uses. Value
599* can be IMAQ_NIBLACK
600* (which computes thresholds for each pixel based on its local statistics using
601* the Niblack local thresholding
602* algorithm.), or IMAQ_BACKGROUND_CORRECTION (which does background correction
603* first to eliminate non-uniform
604* lighting effects, then performs thresholding using the Otsu thresholding
605* algorithm)
606* @param deviationWeight Specifies the k constant used in the Niblack local
607* thresholding algorithm, which
608* determines the weight applied to the variance calculation. Valid k constants
609* range from 0 to 1. Setting
610* this value to 0 will increase the performance of the function because the
611* function will not calculate the
612* variance for any of the pixels. The function ignores this value if method is
613* not set to IMAQ_NIBLACK
614* @param type Specifies the type of objects for which you want to look. Values
615* can be IMAQ_BRIGHT_OBJECTS
616* or IMAQ_DARK_OBJECTS.
617* @param replaceValue Specifies the replacement value the function uses for the
618* pixels of the kept objects
619* in the destination image.
620* @return On success: 1. On failure: 0. To get extended error information, call
621* GetLastError().
622*/
623int frcSmartThreshold(Image* dest, const Image* source,
624 unsigned int windowWidth, unsigned int windowHeight,
625 LocalThresholdMethod method, double deviationWeight,
626 ObjectType type) {
627 float replaceValue = 1.0;
628 return imaqLocalThreshold(dest, source, windowWidth, windowHeight, method,
629 deviationWeight, type, replaceValue);
630}
631
632int frcSmartThreshold(Image* dest, const Image* source,
633 unsigned int windowWidth, unsigned int windowHeight,
634 LocalThresholdMethod method, double deviationWeight,
635 ObjectType type, float replaceValue) {
636 return imaqLocalThreshold(dest, source, windowWidth, windowHeight, method,
637 deviationWeight, type, replaceValue);
638}
639
640/**
641* @brief Converts a grayscale image to a binary image for Particle Analysis
642* based on a fixed threshold.
643* The function sets pixels values outside of the given range to 0. The function
644* sets pixel values
645* within the range to a given value or leaves the values unchanged.
646* Use the simplified call to leave pixel values unchanged.
647* Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_I16.
648*
649* @param dest The destination image.
650* @param source The image to threshold
651* @param rangeMin The lower boundary of the range of pixel values to keep
652* @param rangeMax The upper boundary of the range of pixel values to keep.
653*
654* @return int - error code: 0 = error. To get extended error information, call
655* GetLastError().
656*/
657int frcSimpleThreshold(Image* dest, const Image* source, float rangeMin,
658 float rangeMax) {
659 int newValue = 255;
660 return frcSimpleThreshold(dest, source, rangeMin, rangeMax, newValue);
661}
662
663/**
664* @brief Converts a grayscale image to a binary image for Particle Analysis
665* based on a fixed threshold.
666* The function sets pixels values outside of the given range to 0. The function
667* sets
668* pixel values within the range to the given value.
669* Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_I16.
670*
671* @param dest The destination image.
672* @param source The image to threshold
673* @param rangeMin The lower boundary of the range of pixel values to keep
674* @param rangeMax The upper boundary of the range of pixel values to keep.
675* @param newValue The replacement value for pixels within the range. Use the
676* simplified call to leave the pixel values unchanged
677*
678* @return int - error code: 0 = error. To get extended error information, call
679* GetLastError().
680*/
681int frcSimpleThreshold(Image* dest, const Image* source, float rangeMin,
682 float rangeMax, float newValue) {
683 int useNewValue = TRUE;
684 return imaqThreshold(dest, source, rangeMin, rangeMax, useNewValue, newValue);
685}
686
687/**
688* @brief Applies a threshold to the Red, Green, and Blue values of a RGB image
689* or the Hue,
690* Saturation, Luminance values for a HSL image.
691* Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL.
692* This simpler version filters based on a hue range in the HSL mode.
693*
694* @param dest The destination image. This must be a IMAQ_IMAGE_U8 image.
695* @param source The image to threshold
696* @param mode The color space to perform the threshold in. valid values are:
697* IMAQ_RGB, IMAQ_HSL.
698* @param plane1Range The selection range for the first plane of the image. Set
699* this parameter to nullptr to use a selection range from 0 to 255.
700* @param plane2Range The selection range for the second plane of the image. Set
701* this parameter to nullptr to use a selection range from 0 to 255.
702* @param plane3Range The selection range for the third plane of the image. Set
703* this parameter to nullptr to use a selection range from 0 to 255.
704*
705* @return On success: 1. On failure: 0. To get extended error information, call
706* GetLastError().
707* */
708int frcColorThreshold(Image* dest, const Image* source, ColorMode mode,
709 const Range* plane1Range, const Range* plane2Range,
710 const Range* plane3Range) {
711 int replaceValue = 1;
712 return imaqColorThreshold(dest, source, replaceValue, mode, plane1Range,
713 plane2Range, plane3Range);
714}
715
716/**
717* @brief Applies a threshold to the Red, Green, and Blue values of a RGB image
718* or the Hue,
719* Saturation, Luminance values for a HSL image.
720* Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL.
721* The simpler version filters based on a hue range in the HSL mode.
722*
723* @param dest The destination image. This must be a IMAQ_IMAGE_U8 image.
724* @param source The image to threshold
725* @param replaceValue Value to assign to selected pixels. Defaults to 1 if
726* simplified call is used.
727* @param mode The color space to perform the threshold in. valid values are:
728* IMAQ_RGB, IMAQ_HSL.
729* @param plane1Range The selection range for the first plane of the image. Set
730* this parameter to nullptr to use a selection range from 0 to 255.
731* @param plane2Range The selection range for the second plane of the image. Set
732* this parameter to nullptr to use a selection range from 0 to 255.
733* @param plane3Range The selection range for the third plane of the image. Set
734* this parameter to nullptr to use a selection range from 0 to 255.
735*
736* @return On success: 1. On failure: 0. To get extended error information, call
737* GetLastError().
738*/
739int frcColorThreshold(Image* dest, const Image* source, int replaceValue,
740 ColorMode mode, const Range* plane1Range,
741 const Range* plane2Range, const Range* plane3Range) {
742 return imaqColorThreshold(dest, source, replaceValue, mode, plane1Range,
743 plane2Range, plane3Range);
744}
745
746/**
747* @brief A simpler version of ColorThreshold that thresholds hue range in the
748* HSL mode. Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL.
749* @param dest The destination image.
750* @param source The image to threshold
751* @param hueRange The selection range for the hue (color).
752* @param minSaturation The minimum saturation value (1-255). If not used,
753* DEFAULT_SATURATION_THRESHOLD is the default.
754*
755* @return On success: 1. On failure: 0. To get extended error information, call
756* GetLastError().
757*/
758int frcHueThreshold(Image* dest, const Image* source, const Range* hueRange) {
759 return frcHueThreshold(dest, source, hueRange, DEFAULT_SATURATION_THRESHOLD);
760}
761
762int frcHueThreshold(Image* dest, const Image* source, const Range* hueRange,
763 int minSaturation) {
764 // assume HSL mode
765 ColorMode mode = IMAQ_HSL;
766 // Set saturation 100 - 255
767 Range satRange;
768 satRange.minValue = minSaturation;
769 satRange.maxValue = 255;
770 // Set luminance 100 - 255
771 Range lumRange;
772 lumRange.minValue = 100;
773 lumRange.maxValue = 255;
774 // Replace pixels with 1 if pass threshold filter
775 int replaceValue = 1;
776 return imaqColorThreshold(dest, source, replaceValue, mode, hueRange,
777 &satRange, &lumRange);
778}
779
780/**
781* @brief Extracts the Red, Green, Blue, or Hue, Saturation or Luminance
782* information from a color image.
783* Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL, IMAQ_IMAGE_RGB_U64.
784*
785* @param image The source image that the function extracts the planes from.
786* @param mode The color space that the function extracts the planes from. Valid
787* values are IMAQ_RGB, IMAQ_HSL, IMAQ_HSV, IMAQ_HSI.
788* @param plane1 On return, the first extracted plane. Set this parameter to nullptr
789* if you do not need this information. RGB-Red, HSL/HSV/HSI-Hue.
790* @param plane2 On return, the second extracted plane. Set this parameter to
791* nullptr if you do not need this information. RGB-Green, HSL/HSV/HSI-Saturation.
792* @param plane3 On return, the third extracted plane. Set this parameter to nullptr
793* if you do not need this information. RGB-Blue, HSL-Luminance, HSV-Value,
794* HSI-Intensity.
795*
796* @return error code: 0 = error. To get extended error information, call
797* GetLastError().
798*/
799int frcExtractColorPlanes(const Image* image, ColorMode mode, Image* plane1,
800 Image* plane2, Image* plane3) {
801 return imaqExtractColorPlanes(image, mode, plane1, plane2, plane3);
802}
803
804/**
805* @brief Extracts the Hue information from a color image. Supports
806* IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL, IMAQ_IMAGE_RGB_U64
807*
808* @param image The source image that the function extracts the plane from.
809* @param huePlane On return, the extracted hue plane.
810* @param minSaturation the minimum saturation level required 0-255 (try 50)
811*
812* @return On success: 1. On failure: 0. To get extended error information, call
813* GetLastError().
814*/
815int frcExtractHuePlane(const Image* image, Image* huePlane) {
816 return frcExtractHuePlane(image, huePlane, DEFAULT_SATURATION_THRESHOLD);
817}
818
819int frcExtractHuePlane(const Image* image, Image* huePlane, int minSaturation) {
820 return frcExtractColorPlanes(image, IMAQ_HSL, huePlane, nullptr, nullptr);
821}