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