QTrk
Classes | Public Types | Public Member Functions | Public Attributes | List of all members
CPUTracker Class Reference

Class with all CPU algorithm implementations. More...

#include <cpu_tracker.h>

Classes

class  FFT2D
 Class to facilitate 2D Fourier transforms. More...
 
struct  Gauss2DResult
 Structure to group results from the 2D Gaussian fit. More...
 

Public Types

enum  LUTProfileMaxComputeMode { LUTProfMaxQuadraticFit, LUTProfMaxSplineFit, LUTProfMaxSimpleInterp }
 Settings to compute the Z coordinate from the error curve. More...
 

Public Member Functions

float * GetRadialZLUT (int index)
 Get the start of the ZLUT of a specific bead. More...
 
float & GetPixel (int x, int y)
 Get the image pixel greyscale value at point (x,y). More...
 
int GetWidth ()
 Get the width of the image. More...
 
int GetHeight ()
 Get the height of the image. More...
 
 CPUTracker (int w, int h, int xcorwindow=128, bool testRun=false)
 Create an instance of CPUTracker. More...
 
 ~CPUTracker ()
 Destroy a CPUTracker instance. More...
 
bool CheckBoundaries (vector2f center, float radius)
 Test to see if a circle extends outside of image boundaries. More...
 
vector2f ComputeXCorInterpolated (vector2f initial, int iterations, int profileWidth, bool &boundaryHit)
 Compute the cross correlation offsets and resulting position. More...
 
vector2f ComputeQI (vector2f initial, int iterations, int radialSteps, int angularStepsPerQuadrant, float angStepIterationFactor, float minRadius, float maxRadius, bool &boundaryHit, float *radialweights=0)
 Execute the quadrant interpolation algorithm. More...
 
Gauss2DResult Compute2DGaussianMLE (vector2f initial, int iterations, float sigma)
 Calculate a 2D Gaussian fit on the image. More...
 
scalar_t QI_ComputeOffset (complex_t *qi_profile, int nr, int axisForDebug)
 QI helper function to calculate the offset from concatenated profiles. More...
 
scalar_t QuadrantAlign_ComputeOffset (complex_t *profile, complex_t *zlut_prof_fft, int nr, int axisForDebug)
 QA helper function to calculate the offset from concatenated profiles. More...
 
float ComputeAsymmetry (vector2f center, int radialSteps, int angularSteps, float minRadius, float maxRadius, float *dstAngProf=0)
 Find a measure for the asymmetry of the ROI. More...
 
template<typename TPixel >
void SetImage (TPixel *srcImage, uint srcpitch)
 Set the image on which to perform the tracking. More...
 
void SetImage16Bit (ushort *srcImage, uint srcpitch)
 Set an image with 16 bit type. More...
 
void SetImage8Bit (uchar *srcImage, uint srcpitch)
 Set an image with 8 bit type. More...
 
void SetImageFloat (float *srcImage)
 Set an image with float type. More...
 
void SaveImage (const char *filename)
 Save the tracker's image to a jpg file. More...
 
vector2f ComputeMeanAndCOM (float bgcorrection=0.0f)
 Calculate the center of mass of the image. More...
 
void ComputeRadialProfile (float *dst, int radialSteps, int angularSteps, float minradius, float maxradius, vector2f center, bool crp, bool *boundaryHit=0, bool normalize=true)
 Wrapper to compute a radial profile. More...
 
void ComputeQuadrantProfile (scalar_t *dst, int radialSteps, int angularSteps, int quadrant, float minRadius, float maxRadius, vector2f center, float *radialWeights=0)
 Wrapper to compute a radial profile. More...
 
float ComputeZ (vector2f center, int angularSteps, int zlutIndex, bool *boundaryHit=0, float *profile=0, float *cmpprof=0, bool normalizeProfile=true)
 Helper function to calculate the Z position. More...
 
void FourierTransform2D ()
 Calculate a 2D fourier transform of the tracker's image. More...
 
void FourierRadialProfile (float *dst, int radialSteps, int angularSteps, float minradius, float maxradius)
 Calculate the radial profile based on the fourier transform. More...
 
void Normalize (float *image=0)
 Normalize an image. More...
 
void SetRadialZLUT (float *data, int planes, int res, int num_zluts, float minradius, float maxradius, bool copyMemory, bool useCorrelation)
 Tell the tracker where in memory the LUT is located. More...
 
void SetRadialWeights (float *radweights)
 Set the radial weights to be used for profile comparisons. More...
 
void CalculateErrorCurve (double *errorcurve_dest, float *profile, float *zlut_sel)
 Calculate the error curve from a specific profile and LUT. More...
 
void CalculateInterpolatedZLUTProfile (float *profile_dest, float z, int zlutIndex)
 Calculates an intermediate ZLUT profile between two planes. More...
 
float CalculateErrorFlag (double *prof1, double *prof2)
 WIP. Calculate the error flag between two profiles. More...
 
float LUTProfileCompare (float *profile, int zlutIndex, float *cmpProf, LUTProfileMaxComputeMode maxPosMethod, float *fitcurve=0, int *maxPos=0, int frameNum=0)
 Compare a profile to a LUT and calculate the optimum Z value for it. More...
 
float LUTProfileCompareAdjustedWeights (float *rprof, int zlutIndex, float z_estim)
 Compare a profile to a LUT and calculate the optimum Z value for it using an initial estimate. More...
 
float * GetDebugImage ()
 Get the debug image. More...
 
void ApplyOffsetGain (float *offset, float *gain, float offsetFactor, float gainFactor)
 Scale the input image with the background calibration values. More...
 
void AllocateQIFFTs (int nsteps)
 Initializes the fft handles. More...
 
vector3f QuadrantAlign (vector3f initial, int beadIndex, int angularStepsPerQuadrant, bool &boundaryHit)
 Perform the quadrant align algorithm. More...
 

Public Attributes

int width
 ROI width. More...
 
int height
 ROI height. More...
 
int xcorw
 Cross correlation profile length. More...
 
int trackerID
 ID of this tracker (= ID of thread it runs in). More...
 
float * srcImage
 Memory region that holds the image on which tracking is to be performed. More...
 
float * debugImage
 Memory in which an intermediate image can optionally be place and retrieved. More...
 
float mean
 Mean intensity of the ROI. Calculated in ComputeMeanAndCOM. More...
 
float stdev
 Standard deviation of values in the ROI. Calculated in ComputeMeanAndCOM. More...
 
float * zluts
 Pointer to the first data in the ZLUTs. More...
 
bool zlut_memoryOwner
 Flag indicating if this instance is the owner of the zluts memory, or is it external. False in all normal operation. More...
 
int zlut_planes
 Number of planes per ZLUT. More...
 
int zlut_res
 ZLUT resolution = number of radial steps in a plane. More...
 
int zlut_count
 Number of ZLUTs (= # beads) available. More...
 
float zlut_minradius
 Minimum radius in pixels to start sampling for a ZLUT profile. More...
 
float zlut_maxradius
 Maximum radius in pixels of the ZLUT profile sampling circle. More...
 
std::vector< float > zlut_radialweights
 Vector with the radialweights used by the error curve calculation. More...
 
kissfft< scalar_t > * qa_fft_forward
 Handle to forward FFT kissfft instance for quadrant align. More...
 
kissfft< scalar_t > * qa_fft_backward
 Handle to backward FFT kissfft instance for quadrant align. More...
 
bool testRun
 Flag to enable running a test run. More...
 
XCor1DBufferxcorBuffer
 The handle from which to perform cross correlation calculations. More...
 
std::vector< vector2fquadrantDirs
 Vector with the sampling points for a single quadrant (cos & sin pairs). More...
 
int qi_radialsteps
 Number of radialsteps in the QI calculations. More...
 
kissfft< scalar_t > * qi_fft_forward
 Handle to forward FFT kissfft instance for QI. More...
 
kissfft< scalar_t > * qi_fft_backward
 Handle to backward FFT kissfft instance for QI. More...
 
FFT2Dfft2d
 Instance of FFT2D to perform 2D FFTs. More...
 

Detailed Description

Class with all CPU algorithm implementations.

Has one ROI in its memory (srcImage) and the correct member functions are called from its parent's QueuedCPUTracker::ProcessJob. All functions work on the image in memory. Many of the settings that appear here come from QTrkComputedConfig and are further explained there.

Definition at line 38 of file cpu_tracker.h.

Member Enumeration Documentation

§ LUTProfileMaxComputeMode

Settings to compute the Z coordinate from the error curve.

Enumerator
LUTProfMaxQuadraticFit 

Default. Use a 7-point quadratic fit around the error curve's maximum.

LUTProfMaxSplineFit 

Compute a spline fit.

LUTProfMaxSimpleInterp 

Unimplemented.

Definition at line 378 of file cpu_tracker.h.

378  {
382  };
Default. Use a 7-point quadratic fit around the error curve&#39;s maximum.
Definition: cpu_tracker.h:379
Compute a spline fit.
Definition: cpu_tracker.h:380

Constructor & Destructor Documentation

§ CPUTracker()

CPUTracker::CPUTracker ( int  w,
int  h,
int  xcorwindow = 128,
bool  testRun = false 
)

Create an instance of CPUTracker.

Parameters
[in]wImage width.
[in]hImage height.
[in]xcorwindowCross correlation window size.
[in]testRunFlag for test run. See QTrkSettings::testRun.

Definition at line 39 of file cpu_tracker.cpp.

40  : width(w), height(h), xcorw(xcorwindow), testRun(testMode)
41 {
42  trackerID = 0;
43 
44  xcorBuffer = 0;
45 
46  mean=0.0f;
47  srcImage = new float [w*h];
48  debugImage = new float [w*h];
49  std::fill(srcImage, srcImage+w*h, 0.0f);
50  std::fill(debugImage, debugImage+w*h, 0.0f);
51 
52  zluts = 0;
55 
57 
58  qi_radialsteps = 0;
60 
61  fft2d=0;
62 }
kissfft< scalar_t > * qa_fft_backward
Handle to backward FFT kissfft instance for quadrant align.
Definition: cpu_tracker.h:70
kissfft< scalar_t > * qi_fft_forward
Handle to forward FFT kissfft instance for QI.
Definition: cpu_tracker.h:95
float zlut_maxradius
Maximum radius in pixels of the ZLUT profile sampling circle.
Definition: cpu_tracker.h:67
float zlut_minradius
Minimum radius in pixels to start sampling for a ZLUT profile.
Definition: cpu_tracker.h:66
int zlut_planes
Number of planes per ZLUT.
Definition: cpu_tracker.h:63
int zlut_res
ZLUT resolution = number of radial steps in a plane.
Definition: cpu_tracker.h:64
bool testRun
Flag to enable running a test run.
Definition: cpu_tracker.h:82
int zlut_count
Number of ZLUTs (= # beads) available.
Definition: cpu_tracker.h:65
FFT2D * fft2d
Instance of FFT2D to perform 2D FFTs.
Definition: cpu_tracker.h:120
int height
ROI height.
Definition: cpu_tracker.h:42
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46
int xcorw
Cross correlation profile length.
Definition: cpu_tracker.h:43
float mean
Mean intensity of the ROI. Calculated in ComputeMeanAndCOM.
Definition: cpu_tracker.h:48
kissfft< scalar_t > * qa_fft_forward
Handle to forward FFT kissfft instance for quadrant align.
Definition: cpu_tracker.h:69
XCor1DBuffer * xcorBuffer
The handle from which to perform cross correlation calculations.
Definition: cpu_tracker.h:92
float * debugImage
Memory in which an intermediate image can optionally be place and retrieved.
Definition: cpu_tracker.h:47
int qi_radialsteps
Number of radialsteps in the QI calculations.
Definition: cpu_tracker.h:94
int trackerID
ID of this tracker (= ID of thread it runs in).
Definition: cpu_tracker.h:44
kissfft< scalar_t > * qi_fft_backward
Handle to backward FFT kissfft instance for QI.
Definition: cpu_tracker.h:96
float * zluts
Pointer to the first data in the ZLUTs.
Definition: cpu_tracker.h:61
int width
ROI width.
Definition: cpu_tracker.h:41

§ ~CPUTracker()

CPUTracker::~CPUTracker ( )

Destroy a CPUTracker instance.

Definition at line 64 of file cpu_tracker.cpp.

65 {
66  delete[] srcImage;
67  delete[] debugImage;
68  if (zluts && zlut_memoryOwner)
69  delete[] zluts;
70 
71  if (xcorBuffer)
72  delete xcorBuffer;
73 
74  if (qi_fft_forward) {
75  delete qi_fft_forward;
76  delete qi_fft_backward;
77  }
78 
79  if (qa_fft_backward) {
80  delete qa_fft_backward;
81  delete qa_fft_forward;
82  }
83 
84  if (fft2d)
85  delete fft2d;
86 }
kissfft< scalar_t > * qa_fft_backward
Handle to backward FFT kissfft instance for quadrant align.
Definition: cpu_tracker.h:70
kissfft< scalar_t > * qi_fft_forward
Handle to forward FFT kissfft instance for QI.
Definition: cpu_tracker.h:95
FFT2D * fft2d
Instance of FFT2D to perform 2D FFTs.
Definition: cpu_tracker.h:120
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46
kissfft< scalar_t > * qa_fft_forward
Handle to forward FFT kissfft instance for quadrant align.
Definition: cpu_tracker.h:69
XCor1DBuffer * xcorBuffer
The handle from which to perform cross correlation calculations.
Definition: cpu_tracker.h:92
float * debugImage
Memory in which an intermediate image can optionally be place and retrieved.
Definition: cpu_tracker.h:47
kissfft< scalar_t > * qi_fft_backward
Handle to backward FFT kissfft instance for QI.
Definition: cpu_tracker.h:96
float * zluts
Pointer to the first data in the ZLUTs.
Definition: cpu_tracker.h:61
bool zlut_memoryOwner
Flag indicating if this instance is the owner of the zluts memory, or is it external. False in all normal operation.
Definition: cpu_tracker.h:62

Member Function Documentation

§ AllocateQIFFTs()

void CPUTracker::AllocateQIFFTs ( int  nsteps)

Initializes the fft handles.

Readies qi_fft_forward and qi_fft_backward for use.

Parameters
[in]nstepsThe number of radial steps per profile. FFT length is 2 * nsteps.

Definition at line 247 of file cpu_tracker.cpp.

248 {
249  if(!qi_fft_forward || qi_radialsteps != nr) {
250  if(qi_fft_forward) {
251  delete qi_fft_forward;
252  delete qi_fft_backward;
253  }
254  qi_radialsteps = nr;
255  qi_fft_forward = new kissfft<scalar_t>(nr*2,false);
256  qi_fft_backward = new kissfft<scalar_t>(nr*2,true);
257  }
258 }
kissfft< scalar_t > * qi_fft_forward
Handle to forward FFT kissfft instance for QI.
Definition: cpu_tracker.h:95
int qi_radialsteps
Number of radialsteps in the QI calculations.
Definition: cpu_tracker.h:94
kissfft< scalar_t > * qi_fft_backward
Handle to backward FFT kissfft instance for QI.
Definition: cpu_tracker.h:96

§ ApplyOffsetGain()

void CPUTracker::ApplyOffsetGain ( float *  offset,
float *  gain,
float  offsetFactor,
float  gainFactor 
)

Scale the input image with the background calibration values.

See QueuedTracker::SetPixelCalibrationImages() for more information.

Parameters
[in]offsetArray with per-pixel offsets.
[in]gainArray with per-pixel gains.
[in]offsetFactorFactor by which to scale the offsets.
[in]gainFactorFactor by which to scale the gains.

Definition at line 95 of file cpu_tracker.cpp.

96 {
97  if (offset && !gain) {
98  for (int i=0;i<width*height;i++)
99  srcImage[i] = srcImage[i]+offset[i]*offsetFactor;
100  }
101  if (gain && !offset) {
102  for (int i=0;i<width*height;i++)
103  srcImage[i] = srcImage[i]*gain[i]*gainFactor;
104  }
105  if (gain && offset) {
106  for (int i=0;i<width*height;i++)
107  srcImage[i] = (srcImage[i]+offset[i]*offsetFactor)*gain[i]*gainFactor;
108  }
109 }
int height
ROI height.
Definition: cpu_tracker.h:42
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46
int width
ROI width.
Definition: cpu_tracker.h:41

§ CalculateErrorCurve()

void CPUTracker::CalculateErrorCurve ( double *  errorcurve_dest,
float *  profile,
float *  zlut_sel 
)

Calculate the error curve from a specific profile and LUT.

Parameters
[out]errorcurve_destPre-allocated output array of size zlut_planes which will be filled with the error curve.
[in]profileArray with the profile to compare against the LUT.
[in]zlut_selPointer to the first element of the selected LUT.

Definition at line 776 of file cpu_tracker.cpp.

777 {
778 #if 0
779  float* zlut_norm = ALLOCA_ARRAY(float, zlut_res);
780  float* prof_norm = ALLOCA_ARRAY(float, zlut_res);
781  for (int r=0;r<zlut_res;r++)
782  prof_norm[r] = rprof[r] * zlut_radialweights[r];
783  NormalizeRadialProfile(prof_norm, zlut_res);
784 
785  for (int k=0;k<zlut_planes;k++) {
786  double diffsum = 0.0f;
787 
788  if (zlut_radialweights.empty()) {
789  for (int r=0;r<zlut_res;r++) zlut_norm[r]=zlut_sel[k*zlut_res+r];
790  } else {
791  for (int r=0;r<zlut_res;r++) {
792  zlut_norm[r] = zlut_sel[k*zlut_res+r] * zlut_radialweights[r];
793  }
794  }
795  NormalizeRadialProfile(zlut_norm, zlut_res);
796 
797  for (int r = 0; r<zlut_res;r++) {
798  double d = prof_norm[r]-zlut_norm[r];
799  d = -d*d;
800  diffsum += d;
801  }
802  rprof_diff[k] = diffsum;
803  }
804 #else
805  for (int k=0;k<zlut_planes;k++) {
806  double diffsum = 0.0f;
807  for (int r = 0; r<zlut_res;r++) {
808  double d = profile[r]-zlut_sel[k*zlut_res+r];
809  if (!zlut_radialweights.empty())
810  d*=zlut_radialweights[r];
811  d = -d*d;
812  diffsum += d;
813  }
814  errorcurve_dest[k] = diffsum;
815  }
816 #endif
817 }
int zlut_planes
Number of planes per ZLUT.
Definition: cpu_tracker.h:63
int zlut_res
ZLUT resolution = number of radial steps in a plane.
Definition: cpu_tracker.h:64
std::vector< float > zlut_radialweights
Vector with the radialweights used by the error curve calculation.
Definition: cpu_tracker.h:68
void NormalizeRadialProfile(scalar_t *prof, int rsteps)
Definition: utils.cpp:257
#define ALLOCA_ARRAY(T, N)
Definition: std_incl.h:153

§ CalculateErrorFlag()

float CPUTracker::CalculateErrorFlag ( double *  prof1,
double *  prof2 
)

WIP. Calculate the error flag between two profiles.

Parameters
[in]prof1The first profile. Typically the measured profile.
[in]prof2The second profile. Typically a profile from the LUT.
Returns
The error value between the two profiles. If 'high', tracking was unreliable.

Definition at line 833 of file cpu_tracker.cpp.

834 {
835  // sum(abs(expectedCurve-errorCurve))/size(errorCurve,2)
836  float flag = 0.0f;
837  for(int ii = 0; ii < zlut_res; ii++){
838  flag += std::abs(prof1[ii]-prof2[ii]);
839  }
840  return flag/zlut_res;
841 }
int zlut_res
ZLUT resolution = number of radial steps in a plane.
Definition: cpu_tracker.h:64
float abs(std::complex< float > x)
Definition: BeadFinder.cpp:19

§ CalculateInterpolatedZLUTProfile()

void CPUTracker::CalculateInterpolatedZLUTProfile ( float *  profile_dest,
float  z,
int  zlutIndex 
)

Calculates an intermediate ZLUT profile between two planes.

At each radial step, the value is linearly interpolated based on the two nearest saved profiles. Use to obtain estimated profiles at non-integer z values.

Parameters
[out]profile_destPre-allocated output array of size zlut_res which will be filled with the error curve.
[in]zThe height at which to determine the expected profile.
[in]zlutIndexThe index of the zlut/bead.

Definition at line 819 of file cpu_tracker.cpp.

820 {
821  float* zlut_sel = GetRadialZLUT(zlutIndex);
822  for (int r = 0; r<zlut_res;r++) {
823  if ( z < 0 )
824  profile_dest[r] = 0;
825  else if( ((int)z+1) < zlut_planes ) // Index out of bounds if z > LUT resolution
826  profile_dest[r] = Lerp(zlut_sel[(int)z*zlut_res+r],zlut_sel[((int)z+1)*zlut_res+r],z-(int)z);
827  else
828  profile_dest[r] = zlut_sel[(zlut_planes-1)*zlut_res+r];
829  }
830  NormalizeRadialProfile(profile_dest,zlut_res);
831 }
int zlut_planes
Number of planes per ZLUT.
Definition: cpu_tracker.h:63
int zlut_res
ZLUT resolution = number of radial steps in a plane.
Definition: cpu_tracker.h:64
void NormalizeRadialProfile(scalar_t *prof, int rsteps)
Definition: utils.cpp:257
T Lerp(T a, T b, float x)
Definition: utils.h:40
float * GetRadialZLUT(int index)
Get the start of the ZLUT of a specific bead.
Definition: cpu_tracker.h:90

§ CheckBoundaries()

bool CPUTracker::CheckBoundaries ( vector2f  center,
float  radius 
)

Test to see if a circle extends outside of image boundaries.

Parameters
[in]centerThe center of the circle to test.
[in]radiusThe radius of the circle.
Returns
False if circle remains inside image boundaries.

Definition at line 157 of file cpu_tracker.cpp.

158 {
159  return center.x + radius >= width ||
160  center.x - radius < 0 ||
161  center.y + radius >= height ||
162  center.y - radius < 0;
163 }
int height
ROI height.
Definition: cpu_tracker.h:42
int width
ROI width.
Definition: cpu_tracker.h:41

§ Compute2DGaussianMLE()

CPUTracker::Gauss2DResult CPUTracker::Compute2DGaussianMLE ( vector2f  initial,
int  iterations,
float  sigma 
)

Calculate a 2D Gaussian fit on the image.

Parameters
[in]initialThe initial position from which to start the algorithm.
[in]iterationsThe number of iterations to perform.
[in]sigmaExpected standard deviation of the gaussian fit.
Returns
The fitting results.

Definition at line 497 of file cpu_tracker.cpp.

498 {
499  vector2f pos = initial;
500  float I0 = mean*0.5f*width*height;
501  float bg = mean*0.5f;
502 
503  const float _1oSq2Sigma = 1.0f / (sqrtf(2) * sigma);
504  const float _1oSq2PiSigma = 1.0f / (sqrtf(2*3.14159265359f) * sigma);
505  const float _1oSq2PiSigma3 = 1.0f / (sqrtf(2*3.14159265359f) * sigma*sigma*sigma);
506 
507  for (int i=0;i<iterations;i++)
508  {
509  double dL_dx = 0.0;
510  double dL_dy = 0.0;
511  double dL_dI0 = 0.0;
512  double dL_dIbg = 0.0;
513  double dL2_dx = 0.0;
514  double dL2_dy = 0.0;
515  double dL2_dI0 = 0.0;
516  double dL2_dIbg = 0.0;
517 
518  double mu_sum = 0.0;
519 
520  for (int y=0;y<height;y++)
521  {
522  for (int x=0;x<width;x++)
523  {
524  float Xexp0 = (x-pos.x + .5f) * _1oSq2Sigma;
525  float Yexp0 = (y-pos.y + .5f) * _1oSq2Sigma;
526 
527  float Xexp1 = (x-pos.x - .5f) * _1oSq2Sigma;
528  float Yexp1 = (y-pos.y - .5f) * _1oSq2Sigma;
529 
530  float DeltaX = 0.5f * erf(Xexp0) - 0.5f * erf(Xexp1);
531  float DeltaY = 0.5f * erf(Yexp0) - 0.5f * erf(Yexp1);
532  float mu = bg + I0 * DeltaX * DeltaY;
533 
534  float dmu_dx = I0*_1oSq2PiSigma * ( expf(-Xexp1*Xexp1) - expf(-Xexp0*Xexp0)) * DeltaY;
535 
536  float dmu_dy = I0*_1oSq2PiSigma * ( expf(-Yexp1*Yexp1) - expf(-Yexp0*Yexp0)) * DeltaX;
537  float dmu_dI0 = DeltaX*DeltaY;
538  float dmu_dIbg = 1;
539 
540  float smp = GetPixel(x,y);
541  float f = smp / mu - 1;
542  dL_dx += dmu_dx * f;
543  dL_dy += dmu_dy * f;
544  dL_dI0 += dmu_dI0 * f;
545  dL_dIbg += dmu_dIbg * f;
546 
547  float d2mu_dx = I0*_1oSq2PiSigma3 * ( (x - pos.x - .5f) * expf (-Xexp1*Xexp1) - (x - pos.x + .5f) * expf(-Xexp0*Xexp0) ) * DeltaY;
548  float d2mu_dy = I0*_1oSq2PiSigma3 * ( (y - pos.y - .5f) * expf (-Yexp1*Yexp1) - (y - pos.y + .5f) * expf(-Yexp0*Yexp0) ) * DeltaX;
549  dL2_dx += d2mu_dx * f - dmu_dx*dmu_dx * smp / (mu*mu);
550  dL2_dy += d2mu_dy * f - dmu_dy*dmu_dy * smp / (mu*mu);
551  dL2_dI0 += -dmu_dI0*dmu_dI0 * smp / (mu*mu);
552  dL2_dIbg += -smp / (mu*mu);
553 
554  mu_sum += mu;
555  }
556  }
557 
558  double mean_mu = mu_sum / (width*height);
559 
560  pos.x -= dL_dx / dL2_dx;
561  pos.y -= dL_dy / dL2_dy;
562  I0 -= dL_dI0 / dL2_dI0;
563  bg -= dL_dIbg / dL2_dIbg;
564  }
565 
566  Gauss2DResult r;
567  r.pos = pos;
568  r.I0 = I0;
569  r.bg = bg;
570 
571  return r;
572 }
T erf(T x)
Definition: utils.h:373
int height
ROI height.
Definition: cpu_tracker.h:42
float & GetPixel(int x, int y)
Get the image pixel greyscale value at point (x,y).
Definition: cpu_tracker.h:122
float mean
Mean intensity of the ROI. Calculated in ComputeMeanAndCOM.
Definition: cpu_tracker.h:48
int width
ROI width.
Definition: cpu_tracker.h:41

§ ComputeAsymmetry()

float CPUTracker::ComputeAsymmetry ( vector2f  center,
int  radialSteps,
int  angularSteps,
float  minRadius,
float  maxRadius,
float *  dstAngProf = 0 
)

Find a measure for the asymmetry of the ROI.

The center of mass of each radial line (see further explanation of the QI algorithm) is calculated. The standard deviation of these COMs is returned as a measure of the asymmetry.

See QTrkComputedConfig for more information on the settings.

Parameters
[in]centerThe center of the sampling area.
[in]radialStepsThe number of radial steps per spoke.
[in]angularStepsThe number of angular steps to take.
[in]minRadiusMinimum sampling radius in pixels.
[in]maxRadiusMaximum sampling radius in pixels.
[in]dstAngProfOptional. Pre-allocated array to hold the calculated COMs.
Returns
Standard deviation of the radial spokes' centers of mass.

Definition at line 575 of file cpu_tracker.cpp.

577 {
578  vector2f* radialDirs = (vector2f*)ALLOCA(sizeof(vector2f)*angularSteps);
579  for (int j=0;j<angularSteps;j++) {
580  float ang = 2*3.141593f*j/(float)angularSteps;
581  radialDirs[j] = vector2f (cosf(ang), sinf(ang));
582  }
583 
584  // profile along single radial direction
585  float* rline = (float*)ALLOCA(sizeof(float)*radialSteps);
586 
587  if (!dstAngProf)
588  dstAngProf = (float*)ALLOCA(sizeof(float)*radialSteps);
589 
590  float rstep = (maxRadius-minRadius) / radialSteps;
591 
592  for (int a=0;a<angularSteps;a++) {
593  // fill rline
594  // angularProfile[a] = rline COM
595 
596  float r = minRadius;
597  for (int i=0;i<radialSteps;i++) {
598  float x = center.x + radialDirs[a].x * r;
599  float y = center.y + radialDirs[a].y * r;
600  rline[i] = Interpolate(srcImage,width,height, x,y);
601  r += rstep;
602  }
603 
604  // Compute rline COM
605  dstAngProf[a] = ComputeBgCorrectedCOM1D(rline, radialSteps, 1.0f);
606  }
607 
608  float stdev = ComputeStdDev(dstAngProf, angularSteps);
609  return stdev;
610 }
float ComputeBgCorrectedCOM1D(float *data, int len, float cf)
Definition: utils.cpp:231
int height
ROI height.
Definition: cpu_tracker.h:42
vector2< float > vector2f
Definition: std_incl.h:39
float stdev
Standard deviation of values in the ROI. Calculated in ComputeMeanAndCOM.
Definition: cpu_tracker.h:49
T ComputeStdDev(T *data, int len)
Definition: utils.h:221
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46
T Interpolate(T *image, int width, int height, float x, float y, bool *outside=0)
Definition: utils.h:43
#define ALLOCA(size)
Definition: std_incl.h:151
int width
ROI width.
Definition: cpu_tracker.h:41

§ ComputeMeanAndCOM()

vector2f CPUTracker::ComputeMeanAndCOM ( float  bgcorrection = 0.0f)

Calculate the center of mass of the image.

Also calculates and saves the mean and standard deviation of the image. Always performed as first step in localization for a first guess.

The moments are calculated as absolute values around the mean. An optional background correction is possible by only taking into account outliers.

Parameters
[in]bgcorrectionFactor of standard deviation not to take into account for the center of mass calculation. Default is 0.

Definition at line 661 of file cpu_tracker.cpp.

662 {
663  double sum=0, sum2=0;
664  double momentX=0;
665  double momentY=0;
666  // Order is important
667  //COM: x:53.959133, y:53.958984
668  //COM: x:53.958984, y:53.959133
669 
670  for (int y=0;y<height;y++) {
671  for (int x=0;x<width;x++) {
672  float v = GetPixel(x,y);
673  sum += v;
674  sum2 += v*v;
675  }
676  }
677 
678  float invN = 1.0f/(width*height);
679  mean = sum * invN;
680  stdev = sqrtf(sum2 * invN - mean * mean);
681  sum = 0.0f;
682 
683  /*float *ymom = ALLOCA_ARRAY(float, width);
684  float *xmom = ALLOCA_ARRAY(float, height);
685 
686  for(int x=0;x<width;x++)
687  ymom[x]=0;
688  for(int y=0;y<height;y++)
689  xmom[y]=0;*/
690 
691  // Comments: Gaussian mask not currently used
692  //vector2f centre = vector2f((float)width/2,(float)height/2);
693  //float sigma = (float)width/4; // Suppress to 5% at edges
694  //float devi = 1/(2*sigma*sigma);
695 
696  for(int x=0;x<width;x++) {
697  for (int y=0;y<height;y++) {
698  float v = GetPixel(x,y);
699 
700  //float xabs = (x-centre.x); float yabs = (y-centre.y);
701  //float gaussfact = 1.0f;//expf(- xabs*xabs*devi - yabs*yabs*devi);
702 
703  v = std::max(0.0f, fabs(v-mean)-bgcorrection*stdev);
704  sum += v;
705  // xmom[y] += x*v;
706  // ymom[x] += y*v;
707  momentX += x*(double)v;
708  momentY += y*(double)v;
709  }
710  }
711 
712  vector2f com;
713  com.x = (float)( momentX / sum );
714  com.y = (float)( momentY / sum );
715  return com;
716 }
int height
ROI height.
Definition: cpu_tracker.h:42
float stdev
Standard deviation of values in the ROI. Calculated in ComputeMeanAndCOM.
Definition: cpu_tracker.h:49
float & GetPixel(int x, int y)
Get the image pixel greyscale value at point (x,y).
Definition: cpu_tracker.h:122
float mean
Mean intensity of the ROI. Calculated in ComputeMeanAndCOM.
Definition: cpu_tracker.h:48
int width
ROI width.
Definition: cpu_tracker.h:41

§ ComputeQI()

vector2f CPUTracker::ComputeQI ( vector2f  initial,
int  iterations,
int  radialSteps,
int  angularStepsPerQuadrant,
float  angStepIterationFactor,
float  minRadius,
float  maxRadius,
bool &  boundaryHit,
float *  radialweights = 0 
)

Execute the quadrant interpolation algorithm.

See [3] for algorithm details. See QTrkComputedConfig for more information on the settings.

Parameters
[in]initialThe initial position from which to start the algorithm.
[in]iterationsThe number of iterations to perform.
[in]radialStepsAmount of radial steps per quadrant profile.
[in]angularStepsPerQuadrantAmount of angular sampling steps per profile.
[in]angStepIterationFactorAngular step iteration factor, see QTrkSettings::qi_angstep_factor.
[in]minRadiusMinimum radius of the sampling area in pixels.
[in]maxRadiusMaximum radius of the sampling area in pixels.
[in,out]boundaryHitPre-allocated bool that will be set to true if the image boundaries have been exceeded during sampling.
[in]radialweightsArray of the radial weights to use.
Returns
The resulting position with applied offsets.

Definition at line 260 of file cpu_tracker.cpp.

262 {
263  int nr=radialSteps;
264 #ifdef _DEBUG
265  std::copy(srcImage, srcImage+width*height, debugImage);
266  maxImageValue = *std::max_element(srcImage,srcImage+width*height);
267 #endif
268 
269  if (angularStepsPerQ != quadrantDirs.size()) {
270  quadrantDirs.resize(angularStepsPerQ);
271  for (int j=0;j<angularStepsPerQ;j++) {
272  float ang = 0.5*3.141593f*(j+0.5f)/(float)angularStepsPerQ;
273  quadrantDirs[j] = vector2f( cosf(ang), sinf(ang) );
274  }
275  }
276 
277  AllocateQIFFTs(radialSteps);
278 
279  scalar_t* buf = (scalar_t*)ALLOCA(sizeof(scalar_t)*nr*4);
280  scalar_t* q0=buf, *q1=buf+nr, *q2=buf+nr*2, *q3=buf+nr*3;
281  complex_t* concat0 = (complex_t*)ALLOCA(sizeof(complex_t)*nr*2);
282  complex_t* concat1 = concat0 + nr;
283 
284  vector2f center = initial;
285 
286  float pixelsPerProfLen = (maxRadius-minRadius)/radialSteps;
287  boundaryHit = false;
288 
289  float angsteps = angularStepsPerQ / powf(angStepIterationFactor, iterations);
290 
291  for (int k=0;k<iterations;k++){
292  // check bounds
293  boundaryHit = CheckBoundaries(center, maxRadius);
294 
295  for (int q=0;q<4;q++) {
296  ComputeQuadrantProfile(buf+q*nr, nr, angsteps, q, minRadius, maxRadius, center, radialWeights);
297  //NormalizeRadialProfile(buf+q*nr, nr);
298  }
299 #ifdef QI_DEBUG
300  cmp_cpu_qi_prof.assign (buf,buf+4*nr);
301 #endif
302 
303  // Build Ix = [ qL(-r) qR(r) ]
304  // qL = q1 + q2 (concat0)
305  // qR = q0 + q3 (concat1)
306  for(int r=0;r<nr;r++) {
307  concat0[nr-r-1] = q1[r]+q2[r];
308  concat1[r] = q0[r]+q3[r];
309  }
310 
311  scalar_t offsetX = QI_ComputeOffset(concat0, nr, 0);
312 
313  // Build Iy = [ qB(-r) qT(r) ]
314  // qT = q0 + q1
315  // qB = q2 + q3
316  for(int r=0;r<nr;r++) {
317  concat1[r] = q0[r]+q1[r];
318  concat0[nr-r-1] = q2[r]+q3[r];
319  }
320 
321  scalar_t offsetY = QI_ComputeOffset(concat0, nr, 1);
322 
323 #ifdef QI_DBG_EXPORT
324  std::copy(concat0, concat0+nr*2,tmp.begin()+nr*2);
325  WriteComplexImageAsCSV("cpuprofxy.txt", &tmp[0], nr, 4);
326  dbgprintf("[%d] OffsetX: %f, OffsetY: %f\n", k, offsetX, offsetY);
327 #endif
328 
329  center.x += offsetX * pixelsPerProfLen;
330  center.y += offsetY * pixelsPerProfLen;
331 
332  angsteps *= angStepIterationFactor;
333  }
334 
335  return center;
336 }
std::vector< float > cmp_cpu_qi_prof
Definition: test.cu:668
scalar_t QI_ComputeOffset(complex_t *qi_profile, int nr, int axisForDebug)
QI helper function to calculate the offset from concatenated profiles.
int height
ROI height.
Definition: cpu_tracker.h:42
vector2< float > vector2f
Definition: std_incl.h:39
void AllocateQIFFTs(int nsteps)
Initializes the fft handles.
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46
bool CheckBoundaries(vector2f center, float radius)
Test to see if a circle extends outside of image boundaries.
float scalar_t
Definition: scalar_types.h:9
void WriteComplexImageAsCSV(const char *file, std::complex< float > *d, int w, int h, const char *labels[])
Definition: utils.cpp:579
float * debugImage
Memory in which an intermediate image can optionally be place and retrieved.
Definition: cpu_tracker.h:47
void dbgprintf(const char *fmt,...)
Definition: utils.cpp:149
std::vector< vector2f > quadrantDirs
Vector with the sampling points for a single quadrant (cos & sin pairs).
Definition: cpu_tracker.h:93
#define ALLOCA(size)
Definition: std_incl.h:151
std::complex< scalar_t > complex_t
Definition: scalar_types.h:12
void ComputeQuadrantProfile(scalar_t *dst, int radialSteps, int angularSteps, int quadrant, float minRadius, float maxRadius, vector2f center, float *radialWeights=0)
Wrapper to compute a radial profile.
int width
ROI width.
Definition: cpu_tracker.h:41

§ ComputeQuadrantProfile()

void CPUTracker::ComputeQuadrantProfile ( scalar_t dst,
int  radialSteps,
int  angularSteps,
int  quadrant,
float  minRadius,
float  maxRadius,
vector2f  center,
float *  radialWeights = 0 
)

Wrapper to compute a radial profile.

Parameters
[in,out]dstPre-allocated float array of size radialSteps to return the profile.
[in]radialStepsNumber of radial steps in the profile.
[in]angularStepsNumber of angular steps in the profile.
[in]quadrantQuadrant number. 0-3, 1 is upper right, progresses in counterclockwise order.
[in]minRadiusMinimum sampling circle radius in pixels.
[in]maxRadiusMaximum sampling circle radius in pixels.
[in]centerThe center around which to sample.
[in]radialWeightsOptional. Array of radial weights by which to weigh the profile.

Definition at line 613 of file cpu_tracker.cpp.

615 {
616  const int qmat[] = {
617  1, 1,
618  -1, 1,
619  -1, -1,
620  1, -1 };
621  int mx = qmat[2*quadrant+0];
622  int my = qmat[2*quadrant+1];
623 
624  if (angularSteps < MIN_RADPROFILE_SMP_COUNT)
625  angularSteps = MIN_RADPROFILE_SMP_COUNT;
626 
627  for (int i=0;i<radialSteps;i++)
628  dst[i]=0.0f;
629 
630  scalar_t total = 0.0f;
631  scalar_t rstep = (maxRadius - minRadius) / radialSteps;
632  for (int i=0;i<radialSteps; i++) {
633  scalar_t sum = 0.0f;
634  scalar_t r = minRadius + rstep * i;
635 
636  int nPixels = 0;
637  scalar_t angstepf = (scalar_t) quadrantDirs.size() / angularSteps;
638  for (int a=0;a<angularSteps;a++) {
639  int i = (int)angstepf * a;
640  scalar_t x = center.x + mx*quadrantDirs[i].x * r;
641  scalar_t y = center.y + my*quadrantDirs[i].y * r;
642 
643  bool outside;
644  scalar_t v = Interpolate(srcImage,width,height, x,y, &outside);
645  if (!outside) {
646  sum += v;
647  nPixels++;
648  MARKPIXELI(x,y);
649  }
650  }
651 
652  dst[i] = nPixels>=MIN_RADPROFILE_SMP_COUNT ? sum/nPixels : mean;
653  if (radialWeights) dst[i] *= radialWeights[i];
654  total += dst[i];
655  }
656 
657  //WriteImageAsCSV(SPrintf("D:\\TestImages\\qprof%d.txt", quadrant).c_str(), dst, 1, radialSteps);
658  //WriteArrayAsCSVRow("D:\\TestImages\\radialWeights.csv",radialWeights,radialSteps,false);
659 }
#define MARKPIXELI(x, y)
int height
ROI height.
Definition: cpu_tracker.h:42
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46
float scalar_t
Definition: scalar_types.h:9
#define MIN_RADPROFILE_SMP_COUNT
Minimum number of samples for a profile radial bin. Below this the image mean will be used...
Definition: QueuedTracker.h:74
float mean
Mean intensity of the ROI. Calculated in ComputeMeanAndCOM.
Definition: cpu_tracker.h:48
T Interpolate(T *image, int width, int height, float x, float y, bool *outside=0)
Definition: utils.h:43
std::vector< vector2f > quadrantDirs
Vector with the sampling points for a single quadrant (cos & sin pairs).
Definition: cpu_tracker.h:93
int width
ROI width.
Definition: cpu_tracker.h:41

§ ComputeRadialProfile()

void CPUTracker::ComputeRadialProfile ( float *  dst,
int  radialSteps,
int  angularSteps,
float  minradius,
float  maxradius,
vector2f  center,
bool  crp,
bool *  boundaryHit = 0,
bool  normalize = true 
)

Wrapper to compute a radial profile.

Parameters
[in,out]dstPre-allocated float array of size radialSteps to return the profile.
[in]radialStepsNumber of radial steps in the profile.
[in]angularStepsNumber of angular steps in the profile.
[in]minradiusMinimum sampling circle radius in pixels.
[in]maxradiusMaximum sampling circle radius in pixels.
[in]centerThe center around which to sample.
[in]crpNo clue, good luck Josko!
[in,out]boundaryHitOptional. Bool set to indicate whether the image boundary has been hit during sampling.
[in]normalizeOptional. Normalize the radial profile?

Definition at line 727 of file cpu_tracker.cpp.

728 {
729  bool boundaryHit = CheckBoundaries(center, maxradius);
730  if (pBoundaryHit) *pBoundaryHit = boundaryHit;
731 
732  ImageData imgData (srcImage, width,height);
733  if (crp) {
734  ComputeCRP(dst, radialSteps, angularSteps, minradius, maxradius, center, &imgData, mean);
735  }
736  else {
737  ::ComputeRadialProfile(dst, radialSteps, angularSteps, minradius, maxradius, center, &imgData, mean, normalize);
738  }
739 }
void ComputeRadialProfile(float *dst, int radialSteps, int angularSteps, float minradius, float maxradius, vector2f center, bool crp, bool *boundaryHit=0, bool normalize=true)
Wrapper to compute a radial profile.
void normalize(TPixel *d, uint w, uint h)
Definition: utils.h:27
int height
ROI height.
Definition: cpu_tracker.h:42
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46
bool CheckBoundaries(vector2f center, float radius)
Test to see if a circle extends outside of image boundaries.
float mean
Mean intensity of the ROI. Calculated in ComputeMeanAndCOM.
Definition: cpu_tracker.h:48
void ComputeCRP(float *dst, int radialSteps, int angularSteps, float minradius, float maxradius, vector2f center, ImageData *img, float paddingValue, float *crpmap)
Definition: utils.cpp:181
int width
ROI width.
Definition: cpu_tracker.h:41

§ ComputeXCorInterpolated()

vector2f CPUTracker::ComputeXCorInterpolated ( vector2f  initial,
int  iterations,
int  profileWidth,
bool &  boundaryHit 
)

Compute the cross correlation offsets and resulting position.

See https://en.wikipedia.org/wiki/Cross-correlation for algorithm details.

Parameters
[in]initialThe initial position from which to start the algorithm.
[in]iterationsThe number of iterations to perform.
[in]profileWidthWidth of the profiles to correlate.
[in,out]boundaryHitPre-allocated bool that will be set to true if the image boundaries have been exceeded during sampling.
Returns
The resulting position with applied offsets.

Definition at line 165 of file cpu_tracker.cpp.

166 {
167  // extract the image
168  vector2f pos = initial;
169 
170  if (!xcorBuffer)
172 
173  if (xcorw < profileWidth)
174  profileWidth = xcorw;
175 
176 #ifdef _DEBUG
177  std::copy(srcImage, srcImage+width*height, debugImage);
178  maxImageValue = *std::max_element(srcImage,srcImage+width*height);
179 #endif
180 
181  if (xcorw > width || xcorw > height) {
182  boundaryHit = true;
183  return initial;
184  }
185 
186  complex_t* prof = (complex_t*)ALLOCA(sizeof(complex_t)*xcorw);
187  complex_t* prof_rev = (complex_t*)ALLOCA(sizeof(complex_t)*xcorw);
188  scalar_t* prof_autocor = (scalar_t*)ALLOCA(sizeof(scalar_t)*xcorw);
189 
190  boundaryHit = false;
191  for (int k=0;k<iterations;k++) {
192  boundaryHit = CheckBoundaries(pos, XCorScale*xcorw/2);
193 
194  float xmin = pos.x - XCorScale * xcorw/2;
195  float ymin = pos.y - XCorScale * xcorw/2;
196 
197  // generate X position xcor array (summing over y range)
198  for (int x=0;x<xcorw;x++) {
199  scalar_t s = 0.0f;
200  int n=0;
201  for (int y=0;y<profileWidth;y++) {
202  scalar_t xp = x * XCorScale + xmin;
203  scalar_t yp = pos.y + XCorScale * (y - profileWidth/2);
204  bool outside;
205  s += Interpolate(srcImage, width, height, xp, yp, &outside);
206  n += outside?0:1;
207  MARKPIXELI(xp, yp);
208  }
209  if (n >0) s/=n;
210  else s=0;
211  prof [x] = s;
212  prof_rev [xcorw-x-1] = s;
213  }
214 
215  xcorBuffer->XCorFFTHelper(prof, prof_rev, prof_autocor);
216  scalar_t offsetX = ComputeMaxInterp<scalar_t,QI_LSQFIT_NWEIGHTS>::Compute(prof_autocor, xcorw, QIWeights) - (scalar_t)xcorw/2;
217 
218  // generate Y position xcor array (summing over x range)
219  for (int y=0;y<xcorw;y++) {
220  scalar_t s = 0.0f;
221  int n=0;
222  for (int x=0;x<profileWidth;x++) {
223  scalar_t xp = pos.x + XCorScale * (x - profileWidth/2);
224  scalar_t yp = y * XCorScale + ymin;
225  bool outside;
226  s += Interpolate(srcImage,width,height, xp, yp, &outside);
227  n += outside?0:1;
228  MARKPIXELI(xp,yp);
229  }
230  if (n >0) s/=n;
231  else s=0;
232  prof[y] = s;
233  prof_rev [xcorw-y-1] =s;
234  }
235 
236  xcorBuffer->XCorFFTHelper(prof,prof_rev, prof_autocor);
237  //WriteImageAsCSV("xcorautoconv.txt",&xcorBuffer->Y_result[0],xcorBuffer->Y_result.size(),1);
238  scalar_t offsetY = ComputeMaxInterp<scalar_t, QI_LSQFIT_NWEIGHTS>::Compute(prof_autocor, xcorw, QIWeights) - (scalar_t)xcorw/2;
239 
240  pos.x += (offsetX - 1) * XCorScale * 0.5f;
241  pos.y += (offsetY - 1) * XCorScale * 0.5f;
242  }
243 
244  return pos;
245 }
const scalar_t QIWeights[QI_LSQFIT_NWEIGHTS]
Definition: cpu_tracker.cpp:32
#define MARKPIXELI(x, y)
int height
ROI height.
Definition: cpu_tracker.h:42
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46
int xcorw
Cross correlation profile length.
Definition: cpu_tracker.h:43
bool CheckBoundaries(vector2f center, float radius)
Test to see if a circle extends outside of image boundaries.
float scalar_t
Definition: scalar_types.h:9
const float XCorScale
Definition: cpu_tracker.cpp:24
XCor1DBuffer * xcorBuffer
The handle from which to perform cross correlation calculations.
Definition: cpu_tracker.h:92
float * debugImage
Memory in which an intermediate image can optionally be place and retrieved.
Definition: cpu_tracker.h:47
static CUDA_SUPPORTED_FUNC T Compute(T *data, int len, const T *weights, LsqSqQuadFit< T > *fit=0)
void XCorFFTHelper(complex_t *prof, complex_t *prof_rev, scalar_t *result)
Calculates a cross correlation much like https://en.wikipedia.org/wiki/Autocorrelation#Efficient_comp...
T Interpolate(T *image, int width, int height, float x, float y, bool *outside=0)
Definition: utils.h:43
Class to facilitate 1D cross correlation calculations.
Definition: cpu_tracker.h:9
#define ALLOCA(size)
Definition: std_incl.h:151
std::complex< scalar_t > complex_t
Definition: scalar_types.h:12
int width
ROI width.
Definition: cpu_tracker.h:41

§ ComputeZ()

float CPUTracker::ComputeZ ( vector2f  center,
int  angularSteps,
int  zlutIndex,
bool *  boundaryHit = 0,
float *  profile = 0,
float *  cmpprof = 0,
bool  normalizeProfile = true 
)
inline

Helper function to calculate the Z position.

Calculates the radial profile with CPUTracker::ComputeRadialProfile and calls CPUTracker::LUTProfileCompare to compare it to the LUT.

Parameters
[in]centerThe center around which to sample.
[in]angularStepsNumber of angular steps in the profile.
[in]zlutIndexIndex of the ZLUT/bead number.
[in,out]boundaryHitOptional. Bool set to indicate whether the image boundary has been hit during sampling.
[in,out]profileOptional. Pre-allocated array to retrieve the profile if so desired.
[in,out]cmpprofOptional. Pre-allocated array to retrieve the error curve if so desired..
[in]normalizeProfileOptional. Normalize the profile? Default is true.

Definition at line 319 of file cpu_tracker.h.

320  {
321  float* prof = profile ? profile : ALLOCA_ARRAY(float, zlut_res);
322  ComputeRadialProfile(prof,zlut_res,angularSteps, zlut_minradius, zlut_maxradius, center, false, boundaryHit, normalizeProfile);
323  return LUTProfileCompare(prof, zlutIndex, cmpprof, LUTProfMaxQuadraticFit);
324  }
void ComputeRadialProfile(float *dst, int radialSteps, int angularSteps, float minradius, float maxradius, vector2f center, bool crp, bool *boundaryHit=0, bool normalize=true)
Wrapper to compute a radial profile.
float zlut_maxradius
Maximum radius in pixels of the ZLUT profile sampling circle.
Definition: cpu_tracker.h:67
float zlut_minradius
Minimum radius in pixels to start sampling for a ZLUT profile.
Definition: cpu_tracker.h:66
int zlut_res
ZLUT resolution = number of radial steps in a plane.
Definition: cpu_tracker.h:64
float LUTProfileCompare(float *profile, int zlutIndex, float *cmpProf, LUTProfileMaxComputeMode maxPosMethod, float *fitcurve=0, int *maxPos=0, int frameNum=0)
Compare a profile to a LUT and calculate the optimum Z value for it.
#define ALLOCA_ARRAY(T, N)
Definition: std_incl.h:153
Default. Use a 7-point quadratic fit around the error curve&#39;s maximum.
Definition: cpu_tracker.h:379

§ FourierRadialProfile()

void CPUTracker::FourierRadialProfile ( float *  dst,
int  radialSteps,
int  angularSteps,
float  minradius,
float  maxradius 
)

Calculate the radial profile based on the fourier transform.

Setting is available, not ever really used.

Parameters
[in,out]dstPre-allocated float array of size radialSteps to return the profile.
[in]radialStepsNumber of radial steps in the profile.
[in]angularStepsNumber of angular steps in the profile.
[in]minradiusMinimum sampling circle radius in pixels.
[in]maxradiusMaximum sampling circle radius in pixels.

Definition at line 1060 of file cpu_tracker.cpp.

1061 {
1064  ::ComputeRadialProfile(dst, radialSteps, angularSteps, 1, width*0.3f, vector2f(width/2,height/2), &img, 0, false);
1065  for (int i=0;i<radialSteps;i++) {
1066  dst[i]=logf(dst[i]);
1067  }
1068  //NormalizeRadialProfile(dst, radialSteps);
1069 }
void ComputeRadialProfile(float *dst, int radialSteps, int angularSteps, float minradius, float maxradius, vector2f center, bool crp, bool *boundaryHit=0, bool normalize=true)
Wrapper to compute a radial profile.
int height
ROI height.
Definition: cpu_tracker.h:42
vector2< float > vector2f
Definition: std_incl.h:39
void FourierTransform2D()
Calculate a 2D fourier transform of the tracker&#39;s image.
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46
int width
ROI width.
Definition: cpu_tracker.h:41

§ FourierTransform2D()

void CPUTracker::FourierTransform2D ( )

Calculate a 2D fourier transform of the tracker's image.

See FFT2D for more information.

Definition at line 1016 of file cpu_tracker.cpp.

1017 {
1018  //kissfft<float> yfft(h, inverse);
1019  if (!fft2d){
1020  fft2d = new FFT2D(width, height);
1021  }
1022 
1023  fft2d->Apply(srcImage);
1024 }
FFT2D * fft2d
Instance of FFT2D to perform 2D FFTs.
Definition: cpu_tracker.h:120
int height
ROI height.
Definition: cpu_tracker.h:42
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46
void Apply(float *d)
Apply the 2D FFT.
void FFT2D(std::complex< float > *d, int w, int h, bool inverse)
Definition: BeadFinder.cpp:44
int width
ROI width.
Definition: cpu_tracker.h:41

§ GetDebugImage()

float* CPUTracker::GetDebugImage ( )
inline

Get the debug image.

The debug image can be used to store intermediate results of image processing and retrieved using this function.

Returns
A pointer to the array with the debug image in it.

Definition at line 440 of file cpu_tracker.h.

440 { return debugImage; }
float * debugImage
Memory in which an intermediate image can optionally be place and retrieved.
Definition: cpu_tracker.h:47

§ GetHeight()

int CPUTracker::GetHeight ( )
inline

Get the height of the image.

Definition at line 124 of file cpu_tracker.h.

§ GetPixel()

float& CPUTracker::GetPixel ( int  x,
int  y 
)
inline

Get the image pixel greyscale value at point (x,y).

Definition at line 122 of file cpu_tracker.h.

§ GetRadialZLUT()

float* CPUTracker::GetRadialZLUT ( int  index)
inline

Get the start of the ZLUT of a specific bead.

Parameters
[in]indexThe bead number for which to get the LUT.
Returns
A pointer to the start of the LUT of this bead.

Definition at line 90 of file cpu_tracker.h.

90 { return &zluts[zlut_res*zlut_planes*index]; }
int zlut_planes
Number of planes per ZLUT.
Definition: cpu_tracker.h:63
int zlut_res
ZLUT resolution = number of radial steps in a plane.
Definition: cpu_tracker.h:64
float * zluts
Pointer to the first data in the ZLUTs.
Definition: cpu_tracker.h:61

§ GetWidth()

int CPUTracker::GetWidth ( )
inline

Get the width of the image.

Definition at line 123 of file cpu_tracker.h.

§ LUTProfileCompare()

float CPUTracker::LUTProfileCompare ( float *  profile,
int  zlutIndex,
float *  cmpProf,
LUTProfileMaxComputeMode  maxPosMethod,
float *  fitcurve = 0,
int *  maxPos = 0,
int  frameNum = 0 
)

Compare a profile to a LUT and calculate the optimum Z value for it.

Parameters
[in]profileThe profile to compare.
[in]zlutIndexThe number of the ZLUT to compare with.
[in]cmpProfPre-allocated array in which to return the error curve. Not used if null pointer is passed.
[in]maxPosMethodWhich method to use to determine the Z position from the error curve. See LUTProfileMaxComputeMode.
[in]fitcurveOptional. Pre-allocated array in which to return the error curve fit. Not used if null pointer is passed.
[in]maxPosOptional. Pre-allocated integer in which the position of the error curve's maximum will be put.
[in]frameNumOptional. The number of the frame this track job belongs to. Only used in testRun.

Definition at line 843 of file cpu_tracker.cpp.

844 {
845  /* From this function save:
846  - Frame number?
847 
848  - Original image
849  - Profile
850  - LUT
851  - Error curve
852  - Final value
853  */
854 
855  bool freeMem = false;
856  std::string outputName;
857  float zOffset;
858 
859  if(testRun){
860  outputName = SPrintf("%s%05d-%05d",GetCurrentOutputPath().c_str(),zlutIndex,frameNum);
861 
862  if (FILE *file = fopen(SPrintf("%s.jpg",outputName.c_str()).c_str(), "r")) {
863  fclose(file);
864  printf("File exists\n");
865  }
866  SaveImage(SPrintf("%s.jpg",outputName.c_str()).c_str());
867  //FloatToJPEGFile(SPrintf("%s-prof.jpg",outputName.c_str()).c_str(), rprof, zlut_res, 1);
868  WriteArrayAsCSVRow(SPrintf("%s-prof.txt",outputName.c_str()).c_str(), rprof, zlut_res, 0);
869 
870  if(!fitcurve){
871  fitcurve = new float[zlut_planes];
872  freeMem = true;
873  }
874 
875  /*
876  For testing, we want to introduce a fixed height offset of xx nm, regardless of amount of zlut planes
877  Z is in zlut planes here, so calculate back
878 
879  int numImgInStack = 1218;
880  int numPositions = 1001; // ~10nm/frame
881  float range = 10.0f; // total range 25.0 um -> 35.0 um
882  float umPerImg = range/numImgInStack; //
883 
884  int zplanes = 50;
885  int startFrame = 400;
886  */
887  float range = 10.0f; // total range 25.0 um -> 35.0 um
888  int numImgInStack = 1218;
889  float umPerImg = range/numImgInStack;
890  int startFrame = 400;
891  int usedFrames = numImgInStack-startFrame;
892  float rangeInLUT = usedFrames*umPerImg; // Total um of LUT range
893  float umPerPlane = rangeInLUT/zlut_planes;
894 
895  float error = 0.000f; // Forced error in um
896  zOffset = error/umPerPlane; // um * planes / um
897  }
898 
899  if (!zluts)
900  return 0.0f;
901 
902  double* rprof_diff = ALLOCA_ARRAY(double, zlut_planes);
903  //WriteImageAsCSV("zlutradprof-cpu.txt", rprof, zlut_res, 1);
904 
905  // Now compare the radial profile to the profiles stored in Z
906  float* zlut_sel = GetRadialZLUT(zlutIndex);
907 
908  if(testRun){
909  FloatToJPEGFile(SPrintf("%s-zlut.jpg",outputName.c_str()).c_str(),zlut_sel,zlut_res,zlut_planes);
910  }
911 
912  CalculateErrorCurve(rprof_diff, rprof, zlut_sel);
913 
914  if (cmpProf) {
915  //cmpProf->resize(zlut_planes);
916  std::copy(rprof_diff, rprof_diff+zlut_planes, cmpProf);
917  }
918 
919  if (maxPosComputeMode == LUTProfMaxQuadraticFit) {
920  if (maxPos) {
921  *maxPos = std::max_element(rprof_diff, rprof_diff+zlut_planes) - rprof_diff;
922  }
923 
924  if (fitcurve) {
927 
928  int iMax = std::max_element(rprof_diff, rprof_diff+zlut_planes) - rprof_diff;
929  for (int i=0;i<zlut_planes;i++)
930  fitcurve[i] = fit.compute(i-iMax);
931 
932  if(testRun) {
933  z += zOffset; // For testing purposes
934 
935  // Calculate errorcurve of found ZLUT plane
936  float* int_prof = ALLOCA_ARRAY(float, zlut_res);
937  CalculateInterpolatedZLUTProfile(int_prof, z, zlutIndex);
938 
939  double* plane_auto_diff = ALLOCA_ARRAY(double, zlut_planes);
940  CalculateErrorCurve(plane_auto_diff, int_prof, zlut_sel);
941  /*for (int k=0;k<zlut_planes;k++) {
942  double diffsum = 0.0f;
943  for (int r = 0; r<zlut_res;r++) {
944  double d = int_prof[r] - zlut_sel[k*zlut_res+r];
945  if (!zlut_radialweights.empty())
946  d*=zlut_radialweights[r];
947  d = -d*d;
948  diffsum += d;
949  }
950  plane_auto_diff[k] = diffsum;
951  }*/
952 
953  //float errorFlag = CalculateErrorFlag(rprof_diff, plane_auto_diff);
954 
955  WriteArrayAsCSVRow(SPrintf("%s-int-prof.txt",outputName.c_str()).c_str(), int_prof, zlut_res, 0);
956 
957  FILE* f = fopen(SPrintf("%s-out.txt",outputName.c_str()).c_str(),"w+");
958  fprintf_s(f,"z: %f\n",z);
959  for (int i=0;i<zlut_planes;i++)
960  fprintf_s(f,"%f\t%f\t%f\t%f\t%f\n",rprof_diff[i],fitcurve[i],plane_auto_diff[i],fit.a,fit.vertexForm());
961  fclose(f);
962 
963  if(freeMem)
964  delete[] fitcurve;
965  }
966 
967  return z;
968  } else {
970  }
971  }
972  else if (maxPosComputeMode == LUTProfMaxSimpleInterp) {
973  assert(0);
974  return 0;
975  } else
976  return ComputeSplineFitMaxPos(rprof_diff, zlut_planes);
977 }
void WriteArrayAsCSVRow(const char *file, float *d, int len, bool append)
Definition: utils.cpp:537
CUDA_SUPPORTED_FUNC T compute(T pos)
void SaveImage(const char *filename)
Save the tracker&#39;s image to a jpg file.
int zlut_planes
Number of planes per ZLUT.
Definition: cpu_tracker.h:63
int zlut_res
ZLUT resolution = number of radial steps in a plane.
Definition: cpu_tracker.h:64
bool testRun
Flag to enable running a test run.
Definition: cpu_tracker.h:82
CUDA_SUPPORTED_FUNC T vertexForm()
float * GetRadialZLUT(int index)
Get the start of the ZLUT of a specific bead.
Definition: cpu_tracker.h:90
void CalculateErrorCurve(double *errorcurve_dest, float *profile, float *zlut_sel)
Calculate the error curve from a specific profile and LUT.
const double ZLUTWeights_d[ZLUT_LSQFIT_NWEIGHTS]
Definition: cpu_tracker.cpp:34
std::string GetCurrentOutputPath(bool ext)
Definition: utils.cpp:19
void CalculateInterpolatedZLUTProfile(float *profile_dest, float z, int zlutIndex)
Calculates an intermediate ZLUT profile between two planes.
#define ALLOCA_ARRAY(T, N)
Definition: std_incl.h:153
static CUDA_SUPPORTED_FUNC T Compute(T *data, int len, const T *weights, LsqSqQuadFit< T > *fit=0)
Default. Use a 7-point quadratic fit around the error curve&#39;s maximum.
Definition: cpu_tracker.h:379
float CUDA_SUPPORTED_FUNC ComputeSplineFitMaxPos(T *data, int len)
Definition: CubicBSpline.h:55
void FloatToJPEGFile(const char *name, const float *d, int w, int h)
Definition: fastjpg.cpp:189
float * zluts
Pointer to the first data in the ZLUTs.
Definition: cpu_tracker.h:61
std::string SPrintf(const char *fmt,...)
Definition: utils.cpp:132

§ LUTProfileCompareAdjustedWeights()

float CPUTracker::LUTProfileCompareAdjustedWeights ( float *  rprof,
int  zlutIndex,
float  z_estim 
)

Compare a profile to a LUT and calculate the optimum Z value for it using an initial estimate.

Warning
Specific use unknown, only called when LT_LocalizeZWeighted is enabled. Probably was used to test the effect of different weights and fit methods.
Parameters
[in]rprofThe profile to compare.
[in]zlutIndexThe number of the ZLUT to compare against.
[in]z_estimAn initial guess for the z position.

Definition at line 979 of file cpu_tracker.cpp.

980 {
981  if (!zluts)
982  return 0.0f;
983 
984  double* rprof_diff = ALLOCA_ARRAY(double, zlut_planes);
985 
986  // Now compare the radial profile to the profiles stored in Z
987  float* zlut_sel = GetRadialZLUT(zlutIndex);
988 
989  int zi = (int)z_estim;
990  if (zi > zlut_planes-2) zi = zlut_planes-2;
991  float* z0 = &zlut_sel[zi*zlut_res];
992  float* z1 = &zlut_sel[(zi+1)*zlut_res];
993  double* zlut_weights = ALLOCA_ARRAY(double, zlut_res);
994  for (int i=0;i<zlut_res;i++)
995  zlut_weights[i] = fabs((double)z1[i]-(double)z0[i]) * ( zlut_minradius + (zlut_maxradius - zlut_minradius) * i/(float)zlut_res );
996 
997  for (int k=0;k<zlut_planes;k++) {
998  double diffsum = 0.0f;
999  for (int r = 0; r<zlut_res;r++) {
1000  double d = (double)rprof[r]-(double)zlut_sel[k*zlut_res+r];
1001  d = -d*d;
1002  d *= zlut_weights[r];
1003  diffsum += d;
1004  }
1005  rprof_diff[k] = diffsum;
1006  }
1007  //return ComputeSplineFitMaxPos(rprof_diff,zlut_planes);
1009 }
float zlut_maxradius
Maximum radius in pixels of the ZLUT profile sampling circle.
Definition: cpu_tracker.h:67
float zlut_minradius
Minimum radius in pixels to start sampling for a ZLUT profile.
Definition: cpu_tracker.h:66
int zlut_planes
Number of planes per ZLUT.
Definition: cpu_tracker.h:63
int zlut_res
ZLUT resolution = number of radial steps in a plane.
Definition: cpu_tracker.h:64
float * GetRadialZLUT(int index)
Get the start of the ZLUT of a specific bead.
Definition: cpu_tracker.h:90
const double ZLUTWeights_d[ZLUT_LSQFIT_NWEIGHTS]
Definition: cpu_tracker.cpp:34
#define ALLOCA_ARRAY(T, N)
Definition: std_incl.h:153
static CUDA_SUPPORTED_FUNC T Compute(T *data, int len, const T *weights, LsqSqQuadFit< T > *fit=0)
float * zluts
Pointer to the first data in the ZLUTs.
Definition: cpu_tracker.h:61

§ Normalize()

void CPUTracker::Normalize ( float *  image = 0)

Normalize an image.

See normalize.

Parameters
[in]imageOptional. The image to normalize. If a null pointer (default) is given, uses the source image.

Definition at line 719 of file cpu_tracker.cpp.

720 {
721  if (!d) d=srcImage;
722  normalize(d, width, height);
723 }
void normalize(TPixel *d, uint w, uint h)
Definition: utils.h:27
int height
ROI height.
Definition: cpu_tracker.h:42
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46
int width
ROI width.
Definition: cpu_tracker.h:41

§ QI_ComputeOffset()

scalar_t CPUTracker::QI_ComputeOffset ( complex_t qi_profile,
int  nr,
int  axisForDebug 
)

QI helper function to calculate the offset from concatenated profiles.

Parameters
[in]qi_profileThe concatenated profiles' FFT from which to obtain the offset.
[in]nrThe number of radial steps per quadrant profile.
[in]axisForDebugAxis number used to save intermediate data.
Returns
The calculated offset.

Definition at line 351 of file cpu_tracker.cpp.

352 {
353  complex_t* reverse = ALLOCA_ARRAY(complex_t, nr*2);
354  complex_t* fft_out = ALLOCA_ARRAY(complex_t, nr*2);
355  complex_t* fft_out2 = ALLOCA_ARRAY(complex_t, nr*2);
356 
357  for(int x=0;x<nr*2;x++)
358  reverse[x] = profile[nr*2-1-x];
359 
360  qi_fft_forward->transform(profile, fft_out);
361  qi_fft_forward->transform(reverse, fft_out2); // fft_out2 contains fourier-domain version of reverse profile
362 
363  // multiply with conjugate
364  for(int x=0;x<nr*2;x++)
365  fft_out[x] *= conjugate(fft_out2[x]);
366 
367  qi_fft_backward->transform(fft_out, fft_out2);
368 
369 #ifdef QI_DEBUG
370  cmp_cpu_qi_fft_out.assign(fft_out2, fft_out2+nr*2);
371 #endif
372 
373  // fft_out2 now contains the autoconvolution
374  // convert it to float
375  scalar_t* autoconv = ALLOCA_ARRAY(scalar_t, nr*2);
376  for(int x=0;x<nr*2;x++) {
377  autoconv[x] = fft_out2[(x+nr)%(nr*2)].real();
378  }
379 
380  float* profileReal = ALLOCA_ARRAY(float, nr*2);
381  for(int x=0;x<nr*2;x++) {
382  profileReal[x] = profile[x].real();
383  }
384  //WriteArrayAsCSVRow(SPrintf("D:\\TestImages\\AutoconvProf-%d.txt",axisForDebug).c_str() ,profileReal,nr*2,false);
385  //WriteArrayAsCSVRow(SPrintf("D:\\TestImages\\Autoconv-%d.txt",axisForDebug).c_str() ,autoconv,nr*2,false); // */
386 
388  return (maxPos - nr) * (3.14159265359f / 4);
389 }
kissfft< scalar_t > * qi_fft_forward
Handle to forward FFT kissfft instance for QI.
Definition: cpu_tracker.h:95
const scalar_t QIWeights[QI_LSQFIT_NWEIGHTS]
Definition: cpu_tracker.cpp:32
std::vector< std::complex< float > > cmp_cpu_qi_fft_out
Definition: test.cu:671
float scalar_t
Definition: scalar_types.h:9
#define ALLOCA_ARRAY(T, N)
Definition: std_incl.h:153
static CUDA_SUPPORTED_FUNC T Compute(T *data, int len, const T *weights, LsqSqQuadFit< T > *fit=0)
T conjugate(const T &v)
Definition: cpu_tracker.cpp:30
kissfft< scalar_t > * qi_fft_backward
Handle to backward FFT kissfft instance for QI.
Definition: cpu_tracker.h:96
std::complex< scalar_t > complex_t
Definition: scalar_types.h:12

§ QuadrantAlign()

vector3f CPUTracker::QuadrantAlign ( vector3f  initial,
int  beadIndex,
int  angularStepsPerQuadrant,
bool &  boundaryHit 
)

Perform the quadrant align algorithm.

See LT_ZLUTAlign.

Parameters
[in]initialThe initial, 3 dimensional position.
[in]beadIndexThe index of the bead/zlut.
[in]angularStepsPerQuadrantNumber of angular steps per quadrant.
[in]boundaryHitPre-allocated bool to return whether the image boundary has been hit.
Returns
The updated 3D position.

Definition at line 435 of file cpu_tracker.cpp.

436 {
437  float* zlut = GetRadialZLUT(beadIndex);
438  int res=zlut_res;
439  complex_t* profile = ALLOCA_ARRAY(complex_t, res*2);
440  complex_t* concat0 = ALLOCA_ARRAY(complex_t, res*2);
441  complex_t* concat1 = concat0 + res;
442 
443  memset(concat0, 0, sizeof(complex_t)*res*2);
444 
445  int zp0 = clamp( (int)pos.z, 0, zlut_planes - 1);
446  int zp1 = clamp( (int)pos.z + 1, 0, zlut_planes - 1);
447 
448  float* zlut0 = &zlut[ res * zp0 ];
449  float* zlut1 = &zlut[ res * zp1 ];
450  float frac = pos.z - (int)pos.z;
451  for (int r=0;r<zlut_res;r++) {
452  // Interpolate plane
453  double zlutValue = Lerp(zlut0[r], zlut1[r], frac);
454  concat0[res-r-1] = concat1[r] = zlutValue;
455  }
456 // WriteComplexImageAsCSV("qa_zlutprof.txt", concat0, res,2);
457  qa_fft_forward->transform(concat0, profile);
458 
459  scalar_t* buf = ALLOCA_ARRAY(scalar_t, res*4);
460  scalar_t* q0=buf, *q1=buf+res, *q2=buf+res*2, *q3=buf+res*3;
461 
462  boundaryHit = CheckBoundaries(vector2f(pos.x,pos.y), zlut_maxradius);
463  for (int q=0;q<4;q++) {
464  scalar_t *quadrantProfile = buf+q*res;
465  ComputeQuadrantProfile(quadrantProfile, res, angularStepsPerQuadrant, q, zlut_minradius, zlut_maxradius, vector2f(pos.x,pos.y));
466  NormalizeRadialProfile(quadrantProfile, res);
467  }
468 
469  //WriteImageAsCSV("qa_qdr.txt" , buf, res,4);
470 
471  float pixelsPerProfLen = (zlut_maxradius-zlut_minradius)/zlut_res;
472  boundaryHit = false;
473 
474  // Build Ix = [ qL(-r) qR(r) ]
475  // qL = q1 + q2 (concat0)
476  // qR = q0 + q3 (concat1)
477  for(int r=0;r<res;r++) {
478  concat0[res-r-1] = q1[r]+q2[r];
479  concat1[r] = q0[r]+q3[r];
480  }
481 
482  scalar_t offsetX = QuadrantAlign_ComputeOffset(concat0, profile, res, 0);
483 
484  // Build Iy = [ qB(-r) qT(r) ]
485  // qT = q0 + q1
486  // qB = q2 + q3
487  for(int r=0;r<res;r++) {
488  concat1[r] = q0[r]+q1[r];
489  concat0[res-r-1] = q2[r]+q3[r];
490  }
491 
492  scalar_t offsetY = QuadrantAlign_ComputeOffset(concat0, profile, res, 1);
493 
494  return vector3f(pos.x + offsetX * pixelsPerProfLen, pos.y + offsetY * pixelsPerProfLen, pos.z);
495 }
float zlut_maxradius
Maximum radius in pixels of the ZLUT profile sampling circle.
Definition: cpu_tracker.h:67
float zlut_minradius
Minimum radius in pixels to start sampling for a ZLUT profile.
Definition: cpu_tracker.h:66
int zlut_planes
Number of planes per ZLUT.
Definition: cpu_tracker.h:63
int zlut_res
ZLUT resolution = number of radial steps in a plane.
Definition: cpu_tracker.h:64
void NormalizeRadialProfile(scalar_t *prof, int rsteps)
Definition: utils.cpp:257
vector2< float > vector2f
Definition: std_incl.h:39
T Lerp(T a, T b, float x)
Definition: utils.h:40
float * GetRadialZLUT(int index)
Get the start of the ZLUT of a specific bead.
Definition: cpu_tracker.h:90
bool CheckBoundaries(vector2f center, float radius)
Test to see if a circle extends outside of image boundaries.
float scalar_t
Definition: scalar_types.h:9
kissfft< scalar_t > * qa_fft_forward
Handle to forward FFT kissfft instance for quadrant align.
Definition: cpu_tracker.h:69
#define ALLOCA_ARRAY(T, N)
Definition: std_incl.h:153
vector3< float > vector3f
Definition: std_incl.h:114
scalar_t QuadrantAlign_ComputeOffset(complex_t *profile, complex_t *zlut_prof_fft, int nr, int axisForDebug)
QA helper function to calculate the offset from concatenated profiles.
static int clamp(int v, int a, int b)
Definition: cpu_tracker.cpp:36
std::complex< scalar_t > complex_t
Definition: scalar_types.h:12
void ComputeQuadrantProfile(scalar_t *dst, int radialSteps, int angularSteps, int quadrant, float minRadius, float maxRadius, vector2f center, float *radialWeights=0)
Wrapper to compute a radial profile.

§ QuadrantAlign_ComputeOffset()

scalar_t CPUTracker::QuadrantAlign_ComputeOffset ( complex_t profile,
complex_t zlut_prof_fft,
int  nr,
int  axisForDebug 
)

QA helper function to calculate the offset from concatenated profiles.

Parameters
[in]profileThe concatenated profiles' FFT from which to obtain the offset.
[in]zlut_prof_fftThe ZLUT profiles' FFT from which to obtain the offset.
[in]nrThe number of radial steps per quadrant profile.
[in]axisForDebugAxis number used to save intermediate data.
Returns
The calculated offset.

Definition at line 393 of file cpu_tracker.cpp.

394 {
395  complex_t* fft_out = ALLOCA_ARRAY(complex_t, nr*2);
396 
397 // WriteComplexImageAsCSV("qa_profile.txt", profile, nr*2, 1);
398 
399  qa_fft_forward->transform(profile, fft_out);
400 
401  // multiply with conjugate
402  for(int x=0;x<nr*2;x++)
403  fft_out[x] *= conjugate(zlut_prof_fft[x]);
404 
405  qa_fft_backward->transform(fft_out, profile);
406 
407 #ifdef QI_DEBUG
408  cmp_cpu_qi_fft_out.assign(fft_out2, fft_out2+nr*2);
409 #endif
410 
411  // profile now contains the autoconvolution
412  // convert it to float
413  scalar_t* autoconv = ALLOCA_ARRAY(scalar_t, nr*2);
414  for(int x=0;x<nr*2;x++) {
415  autoconv[x] = profile[(x+nr)%(nr*2)].real();
416  }
417 
418 // WriteImageAsCSV("qa_autoconv.txt", autoconv, nr*2, 1);
419 
421  return (maxPos - nr) * (3.14159265359f / 4);
422 
423 }
kissfft< scalar_t > * qa_fft_backward
Handle to backward FFT kissfft instance for quadrant align.
Definition: cpu_tracker.h:70
const scalar_t QIWeights[QI_LSQFIT_NWEIGHTS]
Definition: cpu_tracker.cpp:32
std::vector< std::complex< float > > cmp_cpu_qi_fft_out
Definition: test.cu:671
float scalar_t
Definition: scalar_types.h:9
kissfft< scalar_t > * qa_fft_forward
Handle to forward FFT kissfft instance for quadrant align.
Definition: cpu_tracker.h:69
#define ALLOCA_ARRAY(T, N)
Definition: std_incl.h:153
static CUDA_SUPPORTED_FUNC T Compute(T *data, int len, const T *weights, LsqSqQuadFit< T > *fit=0)
T conjugate(const T &v)
Definition: cpu_tracker.cpp:30
std::complex< scalar_t > complex_t
Definition: scalar_types.h:12

§ SaveImage()

void CPUTracker::SaveImage ( const char *  filename)

Save the tracker's image to a jpg file.

Parameters
[in]filenameName of the file. Can also be full path.

Definition at line 1011 of file cpu_tracker.cpp.

1012 {
1013  FloatToJPEGFile(filename, srcImage, width, height);
1014 }
int height
ROI height.
Definition: cpu_tracker.h:42
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46
void FloatToJPEGFile(const char *name, const float *d, int w, int h)
Definition: fastjpg.cpp:189
int width
ROI width.
Definition: cpu_tracker.h:41

§ SetImage()

template<typename TPixel >
void CPUTracker::SetImage ( TPixel *  srcImage,
uint  srcpitch 
)

Set the image on which to perform the tracking.

Parameters
[in]srcImageArray with the image data.
[in]srcpitchWidth of one row of data in bytes (typically size(dataType)*imageWidth).

Definition at line 476 of file cpu_tracker.h.

477 {
478  uchar* bp = (uchar*)data;
479 
480  for (int y=0;y<height;y++) {
481  for (int x=0;x<width;x++) {
482  srcImage[y*width+x] = ((TPixel*)bp)[x];
483  }
484  bp += pitchInBytes;
485  }
486 
487  mean=0.0f;
488 }
int height
ROI height.
Definition: cpu_tracker.h:42
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46
float mean
Mean intensity of the ROI. Calculated in ComputeMeanAndCOM.
Definition: cpu_tracker.h:48
unsigned char uchar
Definition: std_incl.h:130
int width
ROI width.
Definition: cpu_tracker.h:41

§ SetImage16Bit()

void CPUTracker::SetImage16Bit ( ushort srcImage,
uint  srcpitch 
)
inline

Set an image with 16 bit type.

Parameters
[in]srcImageArray with the image data.
[in]srcpitchWidth of one row of data in bytes (typically size(dataType)*imageWidth).

Definition at line 247 of file cpu_tracker.h.

247 { SetImage(srcImage, srcpitch); }
void SetImage(TPixel *srcImage, uint srcpitch)
Set the image on which to perform the tracking.
Definition: cpu_tracker.h:476
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46

§ SetImage8Bit()

void CPUTracker::SetImage8Bit ( uchar srcImage,
uint  srcpitch 
)
inline

Set an image with 8 bit type.

Parameters
[in]srcImageArray with the image data.
[in]srcpitchWidth of one row of data in bytes (typically size(dataType)*imageWidth).

Definition at line 254 of file cpu_tracker.h.

254 { SetImage(srcImage, srcpitch); }
void SetImage(TPixel *srcImage, uint srcpitch)
Set the image on which to perform the tracking.
Definition: cpu_tracker.h:476
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46

§ SetImageFloat()

void CPUTracker::SetImageFloat ( float *  srcImage)

Set an image with float type.

Parameters
[in]srcImageArray with the image data.

Definition at line 88 of file cpu_tracker.cpp.

89 {
90  for (int k=0;k<width*height;k++)
91  srcImage[k]=src[k];
92  mean=0.0f;
93 }
int height
ROI height.
Definition: cpu_tracker.h:42
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46
float mean
Mean intensity of the ROI. Calculated in ComputeMeanAndCOM.
Definition: cpu_tracker.h:48
int width
ROI width.
Definition: cpu_tracker.h:41

§ SetRadialWeights()

void CPUTracker::SetRadialWeights ( float *  radweights)

Set the radial weights to be used for profile comparisons.

Parameters
[in]radweightsArray with the radial weights.

Definition at line 767 of file cpu_tracker.cpp.

768 {
769  if (radweights) {
771  std::copy(radweights, radweights+zlut_res, zlut_radialweights.begin());
772  } else
773  zlut_radialweights.clear();
774 }
int zlut_res
ZLUT resolution = number of radial steps in a plane.
Definition: cpu_tracker.h:64
std::vector< float > zlut_radialweights
Vector with the radialweights used by the error curve calculation.
Definition: cpu_tracker.h:68

§ SetRadialZLUT()

void CPUTracker::SetRadialZLUT ( float *  data,
int  planes,
int  res,
int  num_zluts,
float  minradius,
float  maxradius,
bool  copyMemory,
bool  useCorrelation 
)

Tell the tracker where in memory the LUT is located.

The LUT is a large contiguous memory area in which all LUTs are saved. See QueuedCPUTracker::zluts.

It is possible to make one CPUTracker instance the owner of the ZLUT memory if no other manager (like QueuedCPUTracker) is used. For this, use the copyMemory parameter.

Parameters
[in]dataPointer to the first element of the ZLUT memory.
[in]planesThe number of planes per lookup table.
[in]resNumber of radial steps per plane.
[in]num_zlutsThe number of LUTs in memory.
[in]minradiusStarting sampling distance of the profiles in pixels.
[in]maxradiusEnding sampling distance of the profiles in pixels.
[in]copyMemoryBool to indicate whether the data should be copied to locally managed memory.
[in]useCorrelationDeprecated. No effect, only there not to break calls.

Definition at line 741 of file cpu_tracker.cpp.

742 {
743  if (zluts && zlut_memoryOwner)
744  delete[] zluts;
745 
746  if (copyMemory) {
747  zluts = new float[planes*res*numLUTs];
748  std::copy(data, data+(planes*res*numLUTs), zluts);
749  } else
750  zluts = data;
751  zlut_memoryOwner = copyMemory;
752  zlut_planes = planes;
753  zlut_res = res;
754  zlut_count = numLUTs;
755  zlut_minradius = minradius;
756  zlut_maxradius = maxradius;
757 
758  if (qa_fft_backward) {
759  delete qa_fft_backward;
760  delete qa_fft_forward;
761  }
762 
763  qa_fft_forward = new kissfft<scalar_t>(res*2,false);
764  qa_fft_backward = new kissfft<scalar_t>(res*2,true);
765 }
kissfft< scalar_t > * qa_fft_backward
Handle to backward FFT kissfft instance for quadrant align.
Definition: cpu_tracker.h:70
float zlut_maxradius
Maximum radius in pixels of the ZLUT profile sampling circle.
Definition: cpu_tracker.h:67
float zlut_minradius
Minimum radius in pixels to start sampling for a ZLUT profile.
Definition: cpu_tracker.h:66
int zlut_planes
Number of planes per ZLUT.
Definition: cpu_tracker.h:63
int zlut_res
ZLUT resolution = number of radial steps in a plane.
Definition: cpu_tracker.h:64
int zlut_count
Number of ZLUTs (= # beads) available.
Definition: cpu_tracker.h:65
kissfft< scalar_t > * qa_fft_forward
Handle to forward FFT kissfft instance for quadrant align.
Definition: cpu_tracker.h:69
float * zluts
Pointer to the first data in the ZLUTs.
Definition: cpu_tracker.h:61
bool zlut_memoryOwner
Flag indicating if this instance is the owner of the zluts memory, or is it external. False in all normal operation.
Definition: cpu_tracker.h:62

Member Data Documentation

§ debugImage

float* CPUTracker::debugImage

Memory in which an intermediate image can optionally be place and retrieved.

Definition at line 47 of file cpu_tracker.h.

§ fft2d

FFT2D* CPUTracker::fft2d

Instance of FFT2D to perform 2D FFTs.

Definition at line 120 of file cpu_tracker.h.

§ height

int CPUTracker::height

ROI height.

Definition at line 42 of file cpu_tracker.h.

§ mean

float CPUTracker::mean

Mean intensity of the ROI. Calculated in ComputeMeanAndCOM.

Definition at line 48 of file cpu_tracker.h.

§ qa_fft_backward

kissfft<scalar_t>* CPUTracker::qa_fft_backward

Handle to backward FFT kissfft instance for quadrant align.

Definition at line 70 of file cpu_tracker.h.

§ qa_fft_forward

kissfft<scalar_t>* CPUTracker::qa_fft_forward

Handle to forward FFT kissfft instance for quadrant align.

Definition at line 69 of file cpu_tracker.h.

§ qi_fft_backward

kissfft<scalar_t>* CPUTracker::qi_fft_backward

Handle to backward FFT kissfft instance for QI.

Definition at line 96 of file cpu_tracker.h.

§ qi_fft_forward

kissfft<scalar_t>* CPUTracker::qi_fft_forward

Handle to forward FFT kissfft instance for QI.

Definition at line 95 of file cpu_tracker.h.

§ qi_radialsteps

int CPUTracker::qi_radialsteps

Number of radialsteps in the QI calculations.

Definition at line 94 of file cpu_tracker.h.

§ quadrantDirs

std::vector<vector2f> CPUTracker::quadrantDirs

Vector with the sampling points for a single quadrant (cos & sin pairs).

Definition at line 93 of file cpu_tracker.h.

§ srcImage

float* CPUTracker::srcImage

Memory region that holds the image on which tracking is to be performed.

Definition at line 46 of file cpu_tracker.h.

§ stdev

float CPUTracker::stdev

Standard deviation of values in the ROI. Calculated in ComputeMeanAndCOM.

Definition at line 49 of file cpu_tracker.h.

§ testRun

bool CPUTracker::testRun

Flag to enable running a test run.

A test run outputs a lot of intermediate data into an output path using GetCurrentOutputPath. This can currently be used to analyse the particulars of the ZLUT algorithms.

Output currently happens in LUTProfileCompare. A Matlab GUI has been created to read and analyse the created files.

Warning
No link to LabVIEW, test executables only.

Definition at line 82 of file cpu_tracker.h.

§ trackerID

int CPUTracker::trackerID

ID of this tracker (= ID of thread it runs in).

Definition at line 44 of file cpu_tracker.h.

§ width

int CPUTracker::width

ROI width.

Definition at line 41 of file cpu_tracker.h.

§ xcorBuffer

XCor1DBuffer* CPUTracker::xcorBuffer

The handle from which to perform cross correlation calculations.

Definition at line 92 of file cpu_tracker.h.

§ xcorw

int CPUTracker::xcorw

Cross correlation profile length.

Definition at line 43 of file cpu_tracker.h.

§ zlut_count

int CPUTracker::zlut_count

Number of ZLUTs (= # beads) available.

Definition at line 65 of file cpu_tracker.h.

§ zlut_maxradius

float CPUTracker::zlut_maxradius

Maximum radius in pixels of the ZLUT profile sampling circle.

Definition at line 67 of file cpu_tracker.h.

§ zlut_memoryOwner

bool CPUTracker::zlut_memoryOwner

Flag indicating if this instance is the owner of the zluts memory, or is it external. False in all normal operation.

Definition at line 62 of file cpu_tracker.h.

§ zlut_minradius

float CPUTracker::zlut_minradius

Minimum radius in pixels to start sampling for a ZLUT profile.

Definition at line 66 of file cpu_tracker.h.

§ zlut_planes

int CPUTracker::zlut_planes

Number of planes per ZLUT.

Definition at line 63 of file cpu_tracker.h.

§ zlut_radialweights

std::vector<float> CPUTracker::zlut_radialweights

Vector with the radialweights used by the error curve calculation.

Definition at line 68 of file cpu_tracker.h.

§ zlut_res

int CPUTracker::zlut_res

ZLUT resolution = number of radial steps in a plane.

Definition at line 64 of file cpu_tracker.h.

§ zluts

float* CPUTracker::zluts

Pointer to the first data in the ZLUTs.

All LUTs are saved in one big contiguous section of memory of size zlut_planes*zlut_count*zlut_res. Calculate specific LUTs or planes based on their indexes:

zluts[index * (zlut_planes * zlut_res) + plane * zlut_res + r].

The ZLUT system stores 'zlut_count' number of 2D zlut's, so every bead can be tracked with its own unique ZLUT.

Definition at line 61 of file cpu_tracker.h.


The documentation for this class was generated from the following files: