FireSync API
 All Classes Files Functions Variables Typedefs Friends Macros Modules Pages
kSpot.h
Go to the documentation of this file.
1 
8 #ifndef K_FIRESYNC_SPOT_H
9 #define K_FIRESYNC_SPOT_H
10 
11 #include <kFireSync/kFsDef.h>
12 #include <kFireSync/kNodeDef.h>
13 #include <kApi/Data/kArrayList.h>
14 #include <kApi/Data/kArray1.h>
15 #include <kApi/Data/kImage.h>
16 #include <kFireSync/Data/kSpot.x.h>
17 
18 #define kSPOT_CENTRE_SHIFT (8) // centre shift
19 #define kSPOT_CENTRE_SCALE (1 << kSPOT_CENTRE_SHIFT) // centre scale
20 
21 /*
22  * kSpot
23  */
24 
25 typedef struct kSpot
26 {
27  k32u centre; /* scaled centre of the spot (along slice) */
28  k16u slice; /* slice index */
29  k16u strength; /* spot strength metric (e.g. sum, peak) */
30  k16u width; /* spot width */
31 } kSpot;
32 
33 /*
34  * kSpot2
35  */
36 
37 typedef struct kSpot2
38 {
39  k32u centre[2]; /* scaled centre of the spot in each dimension */
40  k32u strength; /* spot strength metric (e.g. sum, peak) */
41 } kSpot2;
42 
43 /*
44  * kFpgaCSum
45  */
46 
47 typedef struct kFpgaCSum
48 {
49  k16u sum; /* sum of pixel intensities along slice */
50  k16u wsum; /* weighted sum of pixel intensities along slice */
51 } kFpgaCSum;
52 
53 /*
54  * kFpgaCSum3
55  */
56 
57 typedef struct kFpgaCSum3
58 {
59  k32u csum3;
60 } kFpgaCSum3;
61 
62 kInlineFx(k32u) kFpgaCSum3_Overflow(const kFpgaCSum3* cs)
63 {
64  return cs->csum3 & kFPGA_CSUM3_OVERFLOW_MASK;
65 }
66 
67 kInlineFx(k32u) kFpgaCSum3_Sum(const kFpgaCSum3* cs)
68 {
69  return (cs->csum3 & kFPGA_CSUM3_SUM_MASK) >> kFPGA_CSUM3_SUM_SHIFT;
70 }
71 
72 kInlineFx(k32u) kFpgaCSum3_WSum(const kFpgaCSum3* cs)
73 {
74  return (cs->csum3 & kFPGA_CSUM3_WSUM_MASK) >> kFPGA_CSUM3_WSUM_SHIFT;
75 }
76 
87 typedef struct kCSum4
88 {
90 } kCSum4;
91 
100 {
101  return (kCSUM4_SUM_MASK >> kCSUM4_SUM_SHIFT) - 1;
102 }
103 
110 {
111  return (kCSUM4_WSUM_MASK >> kCSUM4_WSUM_SHIFT) - 1;
112 }
113 
121 kInlineFx(void) kCSum4_Init(kCSum4* cs, k32u sum, k32u wsum)
122 {
123  cs->csum = kField_CreateNamed_(kCSUM4_SUM, sum) | kField_CreateNamed_(kCSUM4_WSUM, wsum);
124 }
125 
132 {
133  cs->csum = kCSUM4_OVERFLOW;
134 }
135 
145 {
146  return cs->csum == kCSUM4_OVERFLOW;
147 }
148 
156 {
157  kField_InsertNamed_(&cs->csum, kCSUM4_SUM, sum);
158 }
159 
167 {
168  return kField_ExtractNamed_(cs->csum, kCSUM4_SUM);
169 }
170 
178 {
179  kField_InsertNamed_(&cs->csum, kCSUM4_WSUM, wsum);
180 }
181 
189 {
190  return kField_ExtractNamed_(cs->csum, kCSUM4_WSUM);
191 }
192 
203 typedef struct kPhasePixel
204 {
205  k8u contrast;
206  k8u intensity;
207  k16s phase;
208 } kPhasePixel;
209 
218 typedef struct kPhasePixel2
219 {
220  k32u content; //packed bitfields
221 } kPhasePixel2;
222 
223 #define kPHASE_PIXEL_2_NULL_PHASE (0xFFFFFF)
224 
225 
233 kInlineFx(void) kPhasePixel2_Init(kPhasePixel2* phasePixel, k32u phase, k8u intensity)
234 {
235  kField_InsertNamed_(&phasePixel->content, kPHASE_PIXEL2_INTENSITY, intensity);
236  kField_InsertNamed_(&phasePixel->content, kPHASE_PIXEL2_PHASE, phase);
237 }
238 
247 {
248  return (k8u) kField_ExtractNamed_(phasePixel.content, kPHASE_PIXEL2_INTENSITY);
249 }
250 
259 {
260  kField_InsertNamed_(&phasePixel->content, kPHASE_PIXEL2_INTENSITY, intensity);
261 }
262 
271 {
272  return kField_ExtractNamed_(phasePixel.content, kPHASE_PIXEL2_PHASE);
273 }
274 
283 {
284  kField_InsertNamed_(&phasePixel->content, kPHASE_PIXEL2_PHASE, phase);
285 }
286 
287 /*
288  * kFpgaSpot
289  */
290 
291 typedef struct kFpgaSpot
292 {
293  k32u center_width; /* end in 16.8 fixed point format, and width */
294  k16u slice; /* slice index */
295  k16u sum_misc; /* pixel intensity sum and misc info */
296 } kFpgaSpot;
297 
298 kInlineFx(k32u) kFpgaSpot_Center(const kFpgaSpot* cg)
299 {
300  return (((cg->center_width & kxFPGA_SPOT_CENTER_MASK2) >> kxFPGA_SPOT_CENTER_SHIFT2) << kxFPGA_SPOT_CENTER_SIZE1) |
301  (cg->center_width & kxFPGA_SPOT_CENTER_MASK1);
302 }
303 
304 kInlineFx(k16u) kFpgaSpot_SpotWidth(const kFpgaSpot* cg)
305 {
306  return (cg->center_width & kxFPGA_SPOT_SPOT_WIDTH_MASK) >> kxFPGA_SPOT_SPOT_WIDTH_SHIFT;
307 }
308 
309 kInlineFx(k16u) kFpgaSpot_Slice(const kFpgaSpot* cg)
310 {
311  return (((cg->sum_misc & kxFPGA_SPOT_SLICE_MASK2) >> kxFPGA_SPOT_SLICE_SHIFT2) << kxFPGA_SPOT_SLICE_SIZE1) |
312  (cg->slice & kxFPGA_SPOT_SLICE_MASK1);
313 }
314 
315 kInlineFx(k16u) kFpgaSpot_Empty(const kFpgaSpot* cg)
316 {
317  return cg->sum_misc & kxFPGA_SPOT_MISC_EMPTY_MASK;
318 }
319 
320 kInlineFx(k16u) kFpgaSpot_Sum(const kFpgaSpot* cg)
321 {
322  return (cg->sum_misc & kxFPGA_SPOT_MISC_SUM_MASK) >> kxFPGA_SPOT_MISC_SUM_SHIFT;
323 }
324 
325 kInlineFx(k32u) kFpgaSpot_EntryValue(const kFpgaSpot* cg)
326 {
327  return ((cg->center_width & kxFPGA_SPOT_SOBEL_ENTRY_VALUE_MASK2) >> kxFPGA_SPOT_SOBEL_ENTRY_VALUE_SHIFT2) +
328  ((cg->slice & kxFPGA_SPOT_SOBEL_ENTRY_VALUE_MASK1) >> kxFPGA_SPOT_SOBEL_ENTRY_VALUE_SHIFT1);
329 }
330 
343 kInlineFx(k32u) kFpgaSpot_EntryOffset(const kFpgaSpot* cg)
344 {
345  k32u value = ((cg->center_width & kxFPGA_SPOT_SOBEL_ENTRY_VALUE_MASK2) >> kxFPGA_SPOT_SOBEL_ENTRY_VALUE_SHIFT2) +
346  ((cg->slice & kxFPGA_SPOT_SOBEL_ENTRY_VALUE_MASK1) >> kxFPGA_SPOT_SOBEL_ENTRY_VALUE_SHIFT1);
347 
348  return value << (kSPOT_CENTRE_SHIFT - kxFPGA_WIDE_SPOT_SOBEL_ENTRY_OFFSET_FRACTIONAL_BITS);
349 }
350 
363 kInlineFx(k32u) kFpgaSpot_ExitOffset(const kFpgaSpot* cg)
364 {
365  k32u value = ((cg->center_width & kxFPGA_SPOT_SOBEL_ENTRY_VALUE_MASK2) >> kxFPGA_SPOT_SOBEL_ENTRY_VALUE_SHIFT2) +
366  ((cg->slice & kxFPGA_SPOT_SOBEL_ENTRY_VALUE_MASK1) >> kxFPGA_SPOT_SOBEL_ENTRY_VALUE_SHIFT1);
367 
368  return value << (kSPOT_CENTRE_SHIFT - kxFPGA_WIDE_SPOT_SOBEL_EXIT_OFFSET_FRACTIONAL_BITS);
369 }
370 
371 kInlineFx(kBool) kFpgaSpot_IsColumn(const kFpgaSpot* cg)
372 {
373  return (cg->sum_misc & kxFPGA_SPOT_MISC_ORIENT_MASK) == 0;
374 }
375 
376 kInlineFx(kBool) kFpgaSpot_IsRow(const kFpgaSpot* cg)
377 {
378  return (cg->sum_misc & kxFPGA_SPOT_MISC_ORIENT_MASK) != 0;
379 }
380 
392 typedef struct kFpgaWideSpot
393 {
394  k32u center_width;
395  k16u slice;
396  k16u sum_misc;
397 } kFpgaWideSpot;
398 
407 {
408  return (((cg->center_width & kxFPGA_WIDE_SPOT_CENTER_MASK2) >> kxFPGA_WIDE_SPOT_CENTER_SHIFT2) << kxFPGA_WIDE_SPOT_CENTER_SIZE1) |
409  (cg->center_width & kxFPGA_WIDE_SPOT_CENTER_MASK1);
410 }
411 
420 {
421  return ((cg->center_width & kxFPGA_WIDE_SPOT_SPOT_WIDTH_MASK) >> kxFPGA_WIDE_SPOT_SPOT_WIDTH_SHIFT) << kxFPGA_WIDE_SPOT_MULTIPLIER_SHIFT;
422 }
423 
432 {
433  return (((cg->sum_misc & kxFPGA_WIDE_SPOT_SLICE_MASK2) >> kxFPGA_WIDE_SPOT_SLICE_SHIFT2) << kxFPGA_WIDE_SPOT_SLICE_SIZE1) |
434  (cg->slice & kxFPGA_WIDE_SPOT_SLICE_MASK1);
435 }
436 
445 {
446  return (cg->sum_misc & kxFPGA_WIDE_SPOT_MISC_EMPTY_MASK) != 0;
447 }
448 
457 {
458  return ((cg->sum_misc & kxFPGA_WIDE_SPOT_MISC_SUM_MASK) >> kxFPGA_WIDE_SPOT_MISC_SUM_SHIFT) << kxFPGA_WIDE_SPOT_MULTIPLIER_SHIFT;
459 }
460 
474 {
475  return ((cg->center_width & kxFPGA_WIDE_SPOT_SOBEL_SPARE_MASK2) >> kxFPGA_WIDE_SPOT_SOBEL_SPARE_SHIFT2) +
476  ((cg->slice & kxFPGA_WIDE_SPOT_SOBEL_SPARE_MASK1) >> kxFPGA_WIDE_SPOT_SOBEL_SPARE_SHIFT1);
477 }
478 
492 {
493  k32u value = ((cg->center_width & kxFPGA_WIDE_SPOT_SOBEL_SPARE_MASK2) >> kxFPGA_WIDE_SPOT_SOBEL_SPARE_SHIFT2) +
494  ((cg->slice & kxFPGA_WIDE_SPOT_SOBEL_SPARE_MASK1) >> kxFPGA_WIDE_SPOT_SOBEL_SPARE_SHIFT1);
495 
496  return value << (kSPOT_CENTRE_SHIFT - kxFPGA_WIDE_SPOT_SOBEL_ENTRY_OFFSET_FRACTIONAL_BITS);
497 }
498 
512 {
513  k32u value = ((cg->center_width & kxFPGA_WIDE_SPOT_SOBEL_SPARE_MASK2) >> kxFPGA_WIDE_SPOT_SOBEL_SPARE_SHIFT2) +
514  ((cg->slice & kxFPGA_WIDE_SPOT_SOBEL_SPARE_MASK1) >> kxFPGA_WIDE_SPOT_SOBEL_SPARE_SHIFT1);
515 
516  return value << (kSPOT_CENTRE_SHIFT - kxFPGA_WIDE_SPOT_SOBEL_EXIT_OFFSET_FRACTIONAL_BITS);
517 }
518 
519 //Deprecated: no longer supported
520 kInlineFx(kBool) kFpgaWideSpot_IsColumn(const kFpgaWideSpot* cg)
521 {
522  return (cg->sum_misc & kxFPGA_WIDE_SPOT_MISC_ORIENT_MASK) == 0;
523 }
524 kDeprecate(kFpgaWideSpot_IsColumn)
525 
526 //Deprecated: no longer supported
527 kInlineFx(kBool) kFpgaWideSpot_IsRow(const kFpgaWideSpot* cg)
528 {
529  return (cg->sum_misc & kxFPGA_WIDE_SPOT_MISC_ORIENT_MASK) != 0;
530 }
531 kDeprecate(kFpgaWideSpot_IsRow)
532 
533 /*
534 * TODO: Sort out the naming conventions for the spot algorithms below. Some of these are type-specific,
535 * others are generic (work with more than one spot type).
536 */
537 
538 
539 // input expects an array list of kTypeOf(kFpgaSpot), kTYPE_FPGA_CG or kTYPE_FPGA_CG2
540 // output expects an initialized array list of kSpot
541 kFsFx(kStatus) kSpot_Unpack(kArrayList input, kArrayList output);
542 
543 // spots expects an initialized array list of kSpot
544 kFsFx(kStatus) kSpot_ARCG(kImage img, k32u minSpotWidth, k32u maxSpotWidth, k32u threshold, kArrayList spots);
545 
546 // FPGA ACCG implementation
547 kFsFx(kStatus) kFpgaSpot_ACCG(kImage image, k32u minSpotWidth, k32u maxSpotWidth, k32u threshold, kArrayList spots);
548 
549 // spots expects an initialized array list of kSpot
550 kFsFx(kStatus) kSpot_ACCG(kImage img, k32u minSpotWidth, k32u maxSpotWidth, k32u threshold, kArrayList spots);
551 
552 kFsFx(kStatus) kSpot_CSUM(kImage image, k32u threshold, kArrayList *sums);
553 
554 // spots expects an initialized array list of kFpgaCSum3
555 kFsFx(kStatus) kSpot_CSum3(kImage image, k32u threshold, kArrayList csum3);
556 
557 // spots expects an initialized array list of k64u
558 kFsFx(kStatus) kSpot_Binarize(kImage image, k32u threshold, kArrayList binarize);
559 
560 // kSpot_SobelArcg
561 //
562 // Description:
563 // Performs Sobel-filtered ARCG spot detection. This is the old implementation. It is currently being used as this version matches the FPGA version.
564 // Inputs:
565 // image - input kImage data to be processed, expects pixel type kTypeOf(k8s)
566 // averageWindow - Sobel filter height in pixels
567 // edgeWindow - Sobel filter width in pixels, expects odd number (counts center pixel)
568 // threshold - Rising and falling edge threshold
569 // widthThreshold - Used for width calculation, only pixels with an intensity greater than baseIntensity + widthThreshold are accepted.
570 // minWidth - minimum spot width
571 // maxWidth - maximum spot width
572 // minSum - minimum spot sum
573 // Outputs:
574 // spots - returns detected spot objects, expects an initialized array of type kTYPE_SPOT, kTypeOf(kFpgaSpot), or kTypeOf(kFpgaWideSpot)
575 // with capacity equal to maximum expected number of spots
576 // bounds - returns x coordinates of rising and falling edge spot boundaries, expects an initialized array of type kTYPE_POINT_32S or kNIL
577 // edgeImage - returns the gradient image, expects an initialized image of pixel type kTypeOf(k8s) of size equal to the input image or kNIL
578 
579 kFsFx(kStatus) kSpot_SobelArcg(kImage image, k32u averageWindow, k32u edgeWindow, k32u threshold, k32u widthThreshold, k32u minWidth,
580  k32u maxWidth, k32u minSum, kArrayList spots, kArrayList bounds, kImage edgeImage);
581 
582 // kSpot_SobelArcg
583 //
584 // Description:
585 // Performs Sobel-filtered ARCG spot detection. This is the new implementation of kSpot_SobelArcg.
586 // Inputs:
587 // image - input kImage data to be processed, expects pixel type kTypeOf(k8s)
588 // averageWindow - Sobel filter height in pixels
589 // edgeWindow - Sobel filter width in pixels, expects odd number (counts center pixel)
590 // threshold - Rising and falling edge threshold
591 // widthThreshold - Used for width calculation, only pixels with an intensity greater than baseIntensity + widthThreshold are accepted.
592 // minWidth - minimum spot width
593 // maxWidth - maximum spot width
594 // minSum - minimum spot sum
595 // Outputs:
596 // spots - returns detected spot objects, expects an initialized array of type kTYPE_SPOT, kTypeOf(kFpgaSpot), or kTypeOf(kFpgaWideSpot)
597 // with capacity equal to maximum expected number of spots
598 // bounds - returns x coordinates of rising and falling edge spot boundaries, expects an initialized array of type kTYPE_POINT_32S or kNIL
599 // edgeImage - returns the gradient image, expects an initialized image of pixel type kTypeOf(k8s) of size equal to the input image or kNIL
600 
601 kFsFx(kStatus) kSpot_SobelArcgV1(kImage image, k32u averageWindow, k32u edgeWindow, k32u threshold, k32u widthThreshold, k32u minWidth,
602  k32u maxWidth, k32u minSum, kArrayList spots, kArrayList bounds, kImage edgeImage);
603 
604 // kSpot_SobelAccg
605 //
606 // Description:
607 // Performs Sobel-filtered ACCG spot detection
608 // Input:
609 // image - input kImage data to be processed, expects pixel type kTypeOf(k8s)
610 // Output:
611 // spots - returns detected spot objects, expects an initialized array of type kTYPE_SPOT, kTypeOf(kFpgaSpot), or kTypeOf(kFpgaWideSpot)
612 // with capacity equal to maximum expected number of spots
613 // bounds - returns centroid coordinates of rising and falling edge spot boundaries, expects an initialized array of type kTYPE_POINT_32S or kNIL
614 // edgeImage - returns the gradient image, expects an initialized image of pixel type kTypeOf(k8s) of size equal to the input image or kNIL
615 // Parameters:
616 // averageWindow - Sobel filter width in pixels
617 // edgeWindow - Sobel filter height in pixels, expects odd number (counts center pixel)
618 // threshold - Rising and falling edge threshold
619 // widthThreshold - Used for width calculation, only pixels with an intensity greater than baseIntensity + widthThreshold are accepted.
620 // minWidth - minimum spot width
621 // maxWidth - maximum spot width
622 // minSum - minimum spot sum
623 // spotFormat - Choice of spot format: entry value, offset from entry to centroid, or offset from centroid to exit.
624 // entryDebounceEnabled - If enabled, spot entry will be first one considered and no re-entry may occur. Otherwise, most recent spot entry will be used.
625 // exitIntensityThreshold - Used for determining spot exit. Exit intensity must be less than or equal to baseIntensity + exitIntensityThreshold. Not used if set to 0.
626 
627 kFsFx(kStatus) kSpot_SobelAccg(kImage image, k32u averageWindow, k32u edgeWindow, k32u threshold, k32u widthThreshold, k32u minWidth,
628  k32u maxWidth, k32u minSum, kArrayList spots, kArrayList bounds, kImage edgeImage);
629 
630 kFsFx(kStatus) kSpot_SobelAccgEx(kImage image, kArrayList spots, kArrayList bounds, kImage edgeImage, k32u averageWindow, k32u edgeWindow, k32u threshold, k32u widthThreshold, k32u minWidth,
631  k32u maxWidth, k32u minSum, kAcgSpotFormat spotFormat, kBool entryDebounceEnabled, k32u exitIntensityThreshold);
632 
633 kFsFx(kStatus) kSpot_YGradient(kImage input, k32u averageWindow, k32u edgeWindow, kImage output);
634 kFsFx(kStatus) kSpot_XGradient(kImage input, k32u averageWindow, k32u edgeWindow, kImage output);
635 
636 kFsFx(k32u) kSpot_NoiseBackground(kImage image);
637 
638 kFsFx(kStatus) kSpot_Sort(kArrayList spots, kArrayList sortedSpots, kSize sortedSpotCount, kCameraSpotSort sortType, kBool inverted);
639 
640 
641 // Constants used for moving average zero crossing integer math interpolation calculation
642 #define kSPOT_FPGA_2I_CENTRE_SHIFT (kSPOT_CENTRE_SHIFT) // Focalspec FPGA uses 9; we use 8 to match kSPOT
643 #define kSPOT_FPGA_2I_CENTRE_SCALE (1 << kSPOT_FPGA_2I_CENTRE_SHIFT)
644 #define kSPOT_FPGA_2I_FRACTIONAL_SHIFT (10)
645 #define kSPOT_FPGA_2I_FRACTIONAL_DISCARD_SHIFT (kSPOT_FPGA_2I_FRACTIONAL_SHIFT - kSPOT_FPGA_2I_CENTRE_SHIFT)
646 
647 #define kSPOT_FPGA_2I_SHIFT (4)
648 #define kSPOT_FPGA_2I_SCALE (1 << kSPOT_FPGA_2I_SHIFT)
649 
650 // Constants used for moving average zero crossing filter calculation
651 #define kSPOT_FPGA_2I_MAX_FILTER_SIZE (16)
652 #define kSPOT_FPGA_2I_FILTER_SHIFT (kSPOT_FPGA_2I_MAX_FILTER_SIZE / 2)
653 
654 
667 {
668  k64u data; /* Data member holding spot information */
669 };
670 
671 #define kSPOT_FPGA_2I_CENTRE_LSB ((k64u) 0)
672 #define kSPOT_FPGA_2I_CENTRE_MSB ((k64u) 21)
673 
674 #define kSPOT_FPGA_2I_DETECTION_LSB ((k64u) 24)
675 #define kSPOT_FPGA_2I_DETECTION_MSB ((k64u) 35)
676 #define kSPOT_FPGA_2I_INTENSITY_LSB ((k64u) 36)
677 #define kSPOT_FPGA_2I_INTENSITY_MSB ((k64u) 47)
678 
679 #define kSPOT_FPGA_2I_SLICE_LSB ((k64u) 48)
680 #define kSPOT_FPGA_2I_SLICE_MSB ((k64u) 61)
681 
682 #define kSPOT_FPGA_2I_PATCH_LSB ((k64u) 63)
683 #define kSPOT_FPGA_2I_PATCH_MSB ((k64u) 63)
684 
685 // Macro to get # of bits for a given field
686 #define kFpgaSpot2i_BitCount_(FIELD) (kSPOT_FPGA_2I_##FIELD##_MSB - kSPOT_FPGA_2I_##FIELD##_LSB + 1)
687 
695 {
696  kField_InsertNamedRange_(&spot->data, kSPOT_FPGA_2I_CENTRE, centre);
697 }
698 
705 kInlineFx(void) kFpgaSpot2i_SetDetection(kFpgaSpot2i *spot, k64u const detection)
706 {
707  kField_InsertNamedRange_(&spot->data, kSPOT_FPGA_2I_DETECTION, detection);
708 }
709 
716 kInlineFx(void) kFpgaSpot2i_SetIntensity(kFpgaSpot2i *spot, k64u const intensity)
717 {
718  kField_InsertNamedRange_(&spot->data, kSPOT_FPGA_2I_INTENSITY, intensity);
719 }
720 
728 {
729  kField_InsertNamedRange_(&spot->data, kSPOT_FPGA_2I_SLICE, slice);
730 }
731 
739 {
740  kField_InsertNamedRange_(&spot->data, kSPOT_FPGA_2I_PATCH, (k64u) (isPatch == kTRUE));
741 }
742 
748 {
749  spot->data = 0;
750 }
751 
759 {
760  return (k32u) kField_ExtractNamedRange_(spot->data, kSPOT_FPGA_2I_CENTRE);
761 }
762 
770 {
771  return (k16u)kField_ExtractNamedRange_(spot->data, kSPOT_FPGA_2I_DETECTION);
772 }
773 
781 {
782  return (k16u)kField_ExtractNamedRange_(spot->data, kSPOT_FPGA_2I_INTENSITY);
783 }
784 
792 {
793  return (k16u)kField_ExtractNamedRange_(spot->data, kSPOT_FPGA_2I_SLICE);
794 }
795 
803 {
804  return (kBool)kField_ExtractNamedRange_(spot->data, kSPOT_FPGA_2I_PATCH);
805 }
806 
822 kFsFx(kStatus) kFpgaSpot2i_ConvertFrom(kFpgaSpot2i *outSpots, kSpot const *inSpots, kSize count = 1);
823 
838 kFsFx(kStatus) kFpgaSpot2i_ConvertTo(kFpgaSpot2i const *inSpots, kSpot *outSpots, kSize count = 1);
839 
861 kFsFx(kStatus) kSpot_SobelvZc(kImage image, kArrayList spots,
862  kSize edgeWindow, kSize averageWindow, kSize intensityWindow, k16u threshold,
863  kImage edgeImage=kNULL, kImage averageImage=kNULL, kImage intensityImage=kNULL, kSize const *roi=kNULL);
864 
875  kSize lastPositiveIndex, k16s lastPositiveGradient, kSize firstNegativeIndex, k16s firstNegativeGradient)
876 {
877  // Convert inputs to k32u
878  const k32u lastPositiveIndex32u = (k32u) lastPositiveIndex;
879  const k32u firstNegativeIndex32u = (k32u) firstNegativeIndex;
880  const k32u absPositiveGradient32u = (k32u) lastPositiveGradient;
881  const k32u absNegativeGradient32u = (k32u) (-firstNegativeGradient);
882 
883  const k32u scaledPosition = firstNegativeIndex32u << kSPOT_FPGA_2I_CENTRE_SHIFT;
884 
885  // Note left shift by (CENTRE_SHIFT - 1) is effectively division by 2
886  const k32u saturationOffset = firstNegativeIndex32u - lastPositiveIndex32u - 1;
887  const k32u scaledSaturationOffset = saturationOffset << (kSPOT_FPGA_2I_CENTRE_SHIFT - 1);
888 
889  // Note that fractional value is computed with 10 bit precision and LSB is discarded
890  const k32u deltaGrad = absPositiveGradient32u + absNegativeGradient32u;
891  const k32u scaledNegativeGrad = absNegativeGradient32u << kSPOT_FPGA_2I_FRACTIONAL_SHIFT;
892  const k32u scaledSubpixelShift = (scaledNegativeGrad / deltaGrad) >> kSPOT_FPGA_2I_FRACTIONAL_DISCARD_SHIFT;
893 
894  const k32u interpolatedCentre = scaledPosition - scaledSaturationOffset - scaledSubpixelShift;
895 
896  return interpolatedCentre;
897 }
898 
899 #endif
kStatus kFpgaSpot2i_ConvertFrom(kFpgaSpot2i *outSpots, kSpot const *inSpots, kSize count=1)
Populate kFpgaSpot2i(s) from kSpot(s)
void kFpgaSpot2i_Zero(kFpgaSpot2i *spot)
Zero the spot.
Definition: kSpot.h:747
#define kField_CreateNamed_(FIELD_NAME, FLD_VAL)
Creates a bitfield by token-pasting mask/shift macros using a specific naming scheme.
Definition: kFsDef.h:558
void kCSum4_SetWSum(kCSum4 *cs, k32u wsum)
Sets the weighted sum component of the CSum value.
Definition: kSpot.h:177
kBool kCSum4_IsOverflow(const kCSum4 *cs)
Reports whether the csum represents an 'overflow' result.
Definition: kSpot.h:144
void kCSum4_Init(kCSum4 *cs, k32u sum, k32u wsum)
Initializes a csum to a valid value.
Definition: kSpot.h:121
Represents spot format options for PL laser-line spot-detection algorithms.
k32u kFpgaSpot2i_Centre(const kFpgaSpot2i *spot)
Extract spot centre from packed kFpgaSpot2i.
Definition: kSpot.h:758
Bit-packed spot structure for FocalSpec spot algorithm Range Count Use 63..63 1 Patch 62...
Definition: kSpot.h:666
k32u kFpgaWideSpot_ExitOffset(const kFpgaWideSpot *cg)
Reports the spot exit offset.
Definition: kSpot.h:511
k16u kFpgaSpot2i_Detection(kFpgaSpot2i const *spot)
Extract Detection filter value from packed kFpgaSpot2i.
Definition: kSpot.h:769
k16u kFpgaSpot2i_Intensity(kFpgaSpot2i const *spot)
Extract Intensity from packed kFpgaSpot2i.
Definition: kSpot.h:780
void kPhasePixel2_SetIntensity(kPhasePixel2 *phasePixel, k8u intensity)
Sets the intensity value in a kPhasePixel2 structure.
Definition: kSpot.h:258
Represents a CSum value in the format produced by the Binarize-CSum camera algorithm (version 4)...
Definition: kSpot.h:87
Represents a laser line spot detected within an image.
Definition: kSpot.h:392
Represents camera algorithm spot sort options.
#define kInlineFx(TYPE)
kStatus kSpot_SobelvZc(kImage image, kArrayList spots, kSize edgeWindow, kSize averageWindow, kSize intensityWindow, k16u threshold, kImage edgeImage=kNULL, kImage averageImage=kNULL, kImage intensityImage=kNULL, kSize const *roi=kNULL)
Focalspec Moving Average + Zero Crossing spot detector reference implementation.
k16u kFpgaWideSpot_Sum(const kFpgaWideSpot *cg)
Reports the spot intensity sum.
Definition: kSpot.h:456
k16u kFpgaWideSpot_Width(const kFpgaWideSpot *cg)
Gets the spot width.
Definition: kSpot.h:419
k16u kFpgaSpot2i_Slice(kFpgaSpot2i const *spot)
Extract Slice index from packed kFpgaSpot2i.
Definition: kSpot.h:791
Essential declarations related to FireSync nodes.
k8u kPhasePixel2_Intensity(kPhasePixel2 phasePixel)
Extracts the intensity field from a kPhasePixel2 structure.
Definition: kSpot.h:246
kStatus kFpgaSpot2i_ConvertTo(kFpgaSpot2i const *inSpots, kSpot *outSpots, kSize count=1)
Populate kSpot(s) from kFpgaSpot2i(s)
#define kTRUE
void kFpgaSpot2i_SetIntensity(kFpgaSpot2i *spot, k64u const intensity)
Set intensity in packed kFpgaSpot2i.
Definition: kSpot.h:716
k32u csum
Column sum fields.
Definition: kSpot.h:89
Represents a phase result produced by PL stripe+phase hardware acceleration algorithm.
Definition: kSpot.h:203
void kFpgaSpot2i_SetCentre(kFpgaSpot2i *spot, k64u const centre)
Set centre position in packed kFpgaSpot2i.
Definition: kSpot.h:694
#define kField_ExtractNamedRange_(REG_VAL, FIELD_NAME)
Extracts a bitfield by token-pasting left/right macros using a specific naming scheme.
Definition: kFsDef.h:633
Essential API declarations for the kFireSync library.
void kFpgaSpot2i_SetSlice(kFpgaSpot2i *spot, k64u const slice)
Set slice index in packed kFpgaSpot2i.
Definition: kSpot.h:727
k32u kSpot_InterpolateSobelvZcSpotCentre(kSize lastPositiveIndex, k16s lastPositiveGradient, kSize firstNegativeIndex, k16s firstNegativeGradient)
Integer math Focalspec spot centre interpolation.
Definition: kSpot.h:874
void kCSum4_SetSum(kCSum4 *cs, k32u sum)
Sets the sum component of the CSum value.
Definition: kSpot.h:155
k32u kPhasePixel2_Phase(kPhasePixel2 phasePixel)
Extracts the phase field from a kPhasePixel2 structure.
Definition: kSpot.h:270
#define kField_ExtractNamed_(REG_VAL, FIELD_NAME)
Extracts a bitfield by token-pasting mask/shift macros using a specific naming scheme.
Definition: kFsDef.h:606
k32u kFpgaWideSpot_Centre(const kFpgaWideSpot *cg)
Gets the spot centroid.
Definition: kSpot.h:406
k16u kFpgaWideSpot_Slice(const kFpgaWideSpot *cg)
Gets the spot slice index (column or row, depending on orientiation).
Definition: kSpot.h:431
k32u kFpgaWideSpot_EntryOffset(const kFpgaWideSpot *cg)
Reports the spot entry offset.
Definition: kSpot.h:491
k32u kCSum4_WSum(const kCSum4 *cs)
Reports the weighted-sum component of the CSum value.
Definition: kSpot.h:188
void kPhasePixel2_SetPhase(kPhasePixel2 *phasePixel, k32u phase)
Sets the phase value in a kPhasePixel2 structure.
Definition: kSpot.h:282
#define kField_InsertNamed_(REG_REF, FIELD_NAME, FLD_VAL)
Inserts a bitfield into an existing register value by token-pasting mask/shift macros using a specifi...
Definition: kFsDef.h:654
k32u kFpgaWideSpot_EntryValue(const kFpgaWideSpot *cg)
Reports the spot entry intensity value.
Definition: kSpot.h:473
void kFpgaSpot2i_SetDetection(kFpgaSpot2i *spot, k64u const detection)
Set detection filter value in packed kFpgaSpot2i.
Definition: kSpot.h:705
void kFpgaSpot2i_SetPatch(kFpgaSpot2i *spot, kBool isPatch)
Set patch in packed kFpgaSpot2i.
Definition: kSpot.h:738
Represents a phase result produced by PL stripe+phase hardware acceleration algorithm.
Definition: kSpot.h:218
void kCSum4_InitOverflow(kCSum4 *cs)
Initializes a csum to represent the 'overflow' condition.
Definition: kSpot.h:131
#define kField_InsertNamedRange_(REG_REF, FIELD_NAME, FLD_VAL)
Inserts a bitfield into an existing register value by token-pasting left/right macros using a specifi...
Definition: kFsDef.h:681
k16u kFpgaWideSpot_IsEmpty(const kFpgaWideSpot *cg)
Reports whether the spot is empty (null, filler).
Definition: kSpot.h:444
k32u kCSum4_MaxSum()
Reports the maximum sum that can be represented by this data type.
Definition: kSpot.h:99
k32u kCSum4_MaxWSum()
Reports the maximum weighted sum that can be represented by this data type.
Definition: kSpot.h:109
k32u kCSum4_Sum(const kCSum4 *cs)
Reports the sum component of the CSum value.
Definition: kSpot.h:166
void kPhasePixel2_Init(kPhasePixel2 *phasePixel, k32u phase, k8u intensity)
Initializes a kPhasePixel2 stucture.
Definition: kSpot.h:233
kBool kFpgaSpot2i_Patch(kFpgaSpot2i const *spot)
Extract patch from packed kFpgaSpot2i.
Definition: kSpot.h:802