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