QTrk
main.cpp
Go to the documentation of this file.
1 #include "../cputrack/std_incl.h"
2 #include "../cputrack/cpu_tracker.h"
3 #include "../cputrack/random_distr.h"
4 #include "../cputrack/QueuedCPUTracker.h"
5 #include "../cputrack/FisherMatrix.h"
6 #include "../cputrack/BeadFinder.h"
7 #include "../cputrack/LsqQuadraticFit.h"
8 #include "../utils/ExtractBeadImages.h"
9 #include "../cputrack/BenchmarkLUT.h"
10 #include "../cputrack/CubicBSpline.h"
11 #include <string>
12 #include <stdio.h>
13 #include <iostream>
14 #include <fstream>
15 #include <sstream>
16 #include <time.h>
17 #include "testutils.h"
18 #include "SharedTests.h"
19 #include "ResultManager.h"
20 
21 const float ANGSTEPF = 1.5f;
22 
23 const bool InDebugMode =
24 #ifdef _DEBUG
25  true
26 #else
27  false
28 #endif
29  ;
30 
32 {
33 
34 }
35 
36 void SpeedTest()
37 {
38 #ifdef _DEBUG
39  int N = 20;
40 #else
41  int N = 1000;
42 #endif
43  int qi_iterations = 7;
44  int xcor_iterations = 7;
45  CPUTracker* tracker = new CPUTracker(150,150, 128);
46 
47  int radialSteps = 64, zplanes = 120;
48  float zmin = 2, zmax = 8;
49  float zradius = tracker->xcorw/2;
50 
51  float* zlut = new float[radialSteps*zplanes];
52  for (int x=0;x<zplanes;x++) {
53  vector2f center (tracker->GetWidth()/2, tracker->GetHeight()/2);
54  float s = zmin + (zmax-zmin) * x/(float)(zplanes-1);
55  GenerateTestImage(ImageData(tracker->srcImage, tracker->GetWidth(), tracker->GetHeight()), center.x, center.y, s, 0.0f);
56  tracker->mean = 0.0f;
57  tracker->ComputeRadialProfile(&zlut[x*radialSteps], radialSteps, 64, 1, zradius, center, false);
58  }
59  tracker->SetRadialZLUT(zlut, zplanes, radialSteps, 1,1, zradius, true, true);
60  delete[] zlut;
61 
62  // Speed test
63  vector2f comdist, xcordist, qidist;
64  float zdist=0.0f;
65  double zerrsum=0.0f;
66  double tcom = 0.0, tgen=0.0, tz = 0.0, tqi=0.0, txcor=0.0;
67  for (int k=0;k<N;k++)
68  {
69  double t0 = GetPreciseTime();
70  float xp = tracker->GetWidth()/2+(rand_uniform<float>() - 0.5) * 5;
71  float yp = tracker->GetHeight()/2+(rand_uniform<float>() - 0.5) * 5;
72  float z = zmin + 0.1f + (zmax-zmin-0.2f) * rand_uniform<float>();
73 
74  GenerateTestImage(ImageData(tracker->srcImage, tracker->GetWidth(), tracker->GetHeight()), xp, yp, z, 0);
75 
76  double t1 = GetPreciseTime();
77  vector2f com = tracker->ComputeMeanAndCOM();
78  vector2f initial(com.x, com.y);
79  double t2 = GetPreciseTime();
80  bool boundaryHit = false;
81  vector2f xcor = tracker->ComputeXCorInterpolated(initial, xcor_iterations, 16, boundaryHit);
82  if (boundaryHit)
83  dbgprintf("xcor boundaryhit!!\n");
84 
85  comdist.x += fabsf(com.x - xp);
86  comdist.y += fabsf(com.y - yp);
87 
88  xcordist.x +=fabsf(xcor.x - xp);
89  xcordist.y +=fabsf(xcor.y - yp);
90  double t3 = GetPreciseTime();
91  boundaryHit = false;
92  vector2f qi = tracker->ComputeQI(initial, qi_iterations, 64, 16,ANGSTEPF, 5,50, boundaryHit);
93  qidist.x += fabsf(qi.x - xp);
94  qidist.y += fabsf(qi.y - yp);
95  double t4 = GetPreciseTime();
96  if (boundaryHit)
97  dbgprintf("qi boundaryhit!!\n");
98 
99  boundaryHit = false;
100  float est_z = zmin + (zmax-zmin)*tracker->ComputeZ(qi, 64, 0, &boundaryHit, 0) / (zplanes-1);
101  zdist += fabsf(est_z-z);
102  zerrsum += est_z-z;
103 
104  if (boundaryHit)
105  dbgprintf("computeZ boundaryhit!!\n");
106  double t5 = GetPreciseTime();
107  // dbgout(SPrintf("xpos:%f, COM err: %f, XCor err: %f\n", xp, com.x-xp, xcor.x-xp));
108  if (k>0) { // skip first initialization round
109  tgen+=t1-t0;
110  tcom+=t2-t1;
111  txcor+=t3-t2;
112  tqi+=t4-t3;
113  tz+=t5-t4;
114  }
115  }
116 
117  int Nns = N-1;
118  dbgprintf("Image gen. (img/s): %f\nCenter-of-Mass speed (img/s): %f\n", Nns/tgen, Nns/tcom);
119  dbgprintf("XCor estimation (img*it/s): %f\n", (Nns*xcor_iterations)/txcor);
120  dbgprintf("COM+XCor(%d) (img/s): %f\n", xcor_iterations, Nns/(tcom+txcor));
121  dbgprintf("Z estimation (img/s): %f\n", Nns/tz);
122  dbgprintf("QI speed: %f (img*it/s)\n", (Nns*qi_iterations)/tqi);
123  dbgprintf("Average dist: COM x: %f, y: %f\n", comdist.x/N, comdist.y/N);
124  dbgprintf("Average dist: Cross-correlation x: %f, y: %f\n", xcordist.x/N, xcordist.y/N);
125  dbgprintf("Average dist: QI x: %f, y: %f\n", qidist.x/N, qidist.y/N);
126  dbgprintf("Average dist: Z: %f. Mean error:%f\n", zdist/N, zerrsum/N);
127 
128  delete tracker;
129 }
130 
132 {
133  CPUTracker* tracker = new CPUTracker(32,32, 16);
134 
135  tracker->GetPixel(15,15) = 1;
136  dbgout(SPrintf("Pixel at 15,15\n"));
137  vector2f com = tracker->ComputeMeanAndCOM();
138  dbgout(SPrintf("COM: %f,%f\n", com.x, com.y));
139 
140  vector2f initial(15,15);
141  bool boundaryHit = false;
142  vector2f xcor = tracker->ComputeXCorInterpolated(initial,2, 16, boundaryHit);
143  dbgout(SPrintf("XCor: %f,%f\n", xcor.x, xcor.y));
144 
145  assert(xcor.x == 15.0f && xcor.y == 15.0f);
146  delete tracker;
147 }
148 
150 {
151  CPUTracker *tracker = new CPUTracker(50,50, 16);
152 
153  GenerateTestImage(ImageData(tracker->srcImage, tracker->GetWidth(), tracker->GetHeight()), tracker->width/2,tracker->height/2, 9, 0.0f);
154  FloatToJPEGFile("smallimg.jpg", tracker->srcImage, tracker->width, tracker->height);
155 
156  vector2f com = tracker->ComputeMeanAndCOM(0);
157  dbgout(SPrintf("COM: %f,%f\n", com.x, com.y));
158 
159  vector2f initial(25,25);
160  bool boundaryHit = false;
161  vector2f xcor = tracker->ComputeXCorInterpolated(initial, 2, 16, boundaryHit);
162  dbgout(SPrintf("XCor: %f,%f\n", xcor.x, xcor.y));
163  //assert(fabsf(xcor.x-15.0f) < 1e-6 && fabsf(xcor.y-15.0f) < 1e-6);
164 
165  int I=4;
166  vector2f pos = initial;
167  for (int i=0;i<I;i++) {
168  bool bhit;
169  vector2f np = tracker->ComputeQI(pos, 1, 32, 4, 1, 1, 16, bhit);
170  dbgprintf("qi[%d]. New=%.4f, %.4f;\tOld=%.4f, %.4f\n", i, np.x, np.y, pos.x, pos.y);
171  }
172 
173 
174  FloatToJPEGFile("debugimg.jpg", tracker->GetDebugImage(), tracker->width, tracker->height);
175  delete tracker;
176 }
177 
179 {
180  CPUTracker *tracker = new CPUTracker(128,128, 16);
181  bool boundaryHit;
182 
183  for (int i=0;i<10;i++) {
184  float xp = tracker->GetWidth()/2+(rand_uniform<float>() - 0.5) * 20;
185  float yp = tracker->GetHeight()/2+(rand_uniform<float>() - 0.5) * 20;
186 
187  GenerateTestImage(ImageData(tracker->srcImage, tracker->GetWidth(), tracker->GetHeight()), xp, yp, 1, 0.0f);
188 
189  vector2f com = tracker->ComputeMeanAndCOM();
190  dbgout(SPrintf("COM: %f,%f\n", com.x-xp, com.y-yp));
191 
192  vector2f initial = com;
193  boundaryHit=false;
194  vector2f xcor = tracker->ComputeXCorInterpolated(initial, 3, 16, boundaryHit);
195  dbgprintf("XCor: %f,%f. Err: %d\n", xcor.x-xp, xcor.y-yp, boundaryHit);
196 
197  boundaryHit=false;
198  vector2f qi = tracker->ComputeQI(initial, 3, 64, 32, ANGSTEPF, 1, 10, boundaryHit);
199  dbgprintf("QI: %f,%f. Err: %d\n", qi.x-xp, qi.y-yp, boundaryHit);
200  }
201 
202  delete tracker;
203 }
204 
206 {
207  CPUTracker *tracker = new CPUTracker(32,32, 16);
208  bool boundaryHit;
209 
210  for (int i=0;i<10;i++) {
211  float xp = tracker->GetWidth()/2+(rand_uniform<float>() - 0.5) * 20;
212  float yp = tracker->GetHeight()/2+(rand_uniform<float>() - 0.5) * 20;
213 
214  GenerateTestImage(ImageData(tracker->srcImage, tracker->GetWidth(), tracker->GetHeight()), xp, yp, 1, 0.0f);
215 
216  vector2f com = tracker->ComputeMeanAndCOM();
217  dbgout(SPrintf("COM: %f,%f\n", com.x-xp, com.y-yp));
218 
219  vector2f initial = com;
220  boundaryHit=false;
221  vector2f xcor = tracker->ComputeXCorInterpolated(initial, 3, 16, boundaryHit);
222  dbgprintf("XCor: %f,%f. Err: %d\n", xcor.x-xp, xcor.y-yp, boundaryHit);
223 
224  boundaryHit=false;
225  vector2f qi = tracker->ComputeQI(initial, 3, 64, 32, ANGSTEPF, 1, 10, boundaryHit);
226  dbgprintf("QI: %f,%f. Err: %d\n", qi.x-xp, qi.y-yp, boundaryHit);
227  }
228 
229  delete tracker;
230 }
231 
233 {
234  CPUTracker *tracker = new CPUTracker(128,128, 64);
235 
236  float X = tracker->GetWidth()/2;
237  float Y = tracker->GetHeight()/2;
238  int N = 20;
239  for (int x=0;x<N;x++) {
240  float xpos = X + 2.0f * x / (float)N;
241  GenerateTestImage(ImageData(tracker->srcImage, tracker->GetWidth(), tracker->GetHeight()), xpos, X, 1, 0.0f);
242 
243  vector2f com = tracker->ComputeMeanAndCOM();
244  //dbgout(SPrintf("COM: %f,%f\n", com.x, com.y));
245 
246  vector2f initial(X,Y);
247  bool boundaryHit = false;
248  vector2f xcorInterp = tracker->ComputeXCorInterpolated(initial, 3, 32, boundaryHit);
249  vector2f qipos = tracker->ComputeQI(initial, 3, tracker->GetWidth(), 128, 1, 2.0f, tracker->GetWidth()/2-10, boundaryHit);
250  dbgprintf("xpos:%f, COM err: %f, XCorInterp err: %f. QI err: %f\n", xpos, com.x-xpos, xcorInterp.x-xpos, qipos.x-xpos);
251 
252  }
253  delete tracker;
254 }
255 
256 void BuildConvergenceMap(int iterations)
257 {
258  int W=80, H=80;
259  char* data=new char[W*H];
260  FILE* f=fopen("singlebead.bin", "rb");
261  fread(data,1,80*80,f);
262  fclose(f);
263 
264  float testrange=20;
265  int steps=100;
266  float step=testrange/steps;
267  vector2f errXCor, errQI;
268  CPUTracker trk(W,H,40);
269 
270  // Get a good starting estimate
271  trk.SetImage8Bit((uchar*)data,W);
272  vector2f com = trk.ComputeMeanAndCOM();
273  bool boundaryHit;
274  vector2f cmp = trk.ComputeQI(com,8,80,64,ANGSTEPF,2,25,boundaryHit);
275 
276  float *xcorErrMap = new float[steps*steps];
277  float *qiErrMap = new float[steps*steps];
278 
279  for (int y=0;y<steps;y++){
280  for (int x=0;x<steps;x++)
281  {
282  vector2f initial (cmp.x+step*(x-steps/2), cmp.y+step*(y-steps/2) );
283  vector2f xcor = trk.ComputeXCorInterpolated(initial, iterations, 64, boundaryHit);
284  vector2f qi = trk.ComputeQI(initial, iterations, 80, 64,ANGSTEPF,2,30,boundaryHit);
285 
286  errXCor.x += fabs(xcor.x-cmp.x);
287  errXCor.y += fabs(xcor.y-cmp.y);
288  xcorErrMap[y*steps+x] = distance(xcor,cmp);
289 
290  errQI.x += fabs(qi.x-cmp.x);
291  errQI.y += fabs(qi.y-cmp.y);
292  qiErrMap[y*steps+x] = distance(qi,cmp);
293  }
294  dbgprintf("y=%d\n", y);
295  }
296 
297 
298  WriteImageAsCSV(SPrintf("xcor-err-i%d.csv", iterations).c_str(), xcorErrMap, steps,steps);
299  WriteImageAsCSV(SPrintf("qi-err-i%d.csv", iterations).c_str(), qiErrMap, steps,steps);
300 
301  delete[] qiErrMap;
302  delete[] xcorErrMap;
303  delete[] data;
304 }
305 
307 {
308  int w=64,h=64;
309  float* img = new float[w*h];
310  const char* lutname = "LUTexample25X.jpg";
311  std::vector<uchar> lutdata = ReadToByteBuffer(lutname);
312 
313  int lutw,luth;
314  uchar* lut;
315  ReadJPEGFile(&lutdata[0], lutdata.size(), &lut, &lutw, &luth);
316  delete[] img;
317 }
318 
320 {
321  // read image
322  const char* imgname = "SingleBead.jpg";
323  ImageData img = ReadJPEGFile(imgname);
324 
325  // localize
326  CPUTracker trk(img.w,img.h);
327  trk.SetImageFloat(img.data);
328  vector2f com = trk.ComputeMeanAndCOM();
329  bool boundaryHit;
330  vector2f qi = trk.ComputeQI(com, 4, 64, 64,ANGSTEPF, 1, 30, boundaryHit);
331  dbgprintf("%s: COM: %f, %f. QI: %f, %f\n", imgname, com.x, com.y, qi.x, qi.y);
332 
333  std::vector<float> angularProfile(128);
334  float asym = trk.ComputeAsymmetry(qi, 64, angularProfile.size(), 1, 30, &angularProfile[0]);
335 // ComputeAngularProfile(&angularProfile[0], 64, angularProfile.size(), 1, 30, qi, &img, trk.mean);
336  WriteImageAsCSV("angprof.csv", &angularProfile[0], angularProfile.size(), 1);
337  dbgprintf("Asymmetry value: %f\n", asym);
338  std::vector<float> crp(128);
339  float* crpmap = new float[angularProfile.size()*crp.size()];
340  ComputeCRP(&crp[0], crp.size(), angularProfile.size(), 1, 30, qi, &img, 0.0f);
341  WriteImageAsCSV("crpmap.csv", crpmap, crp.size(), angularProfile.size());
342  delete[] crpmap;
343  delete[] img.data;
344 
345  //CRP_TestGeneratedData();
346 
347 // GenerateImageFromLUT(ImageData(img,w,h), ImageData
348 }
349 
350 void WriteRadialProf(const char *file, ImageData& d)
351 {
352  CPUTracker trk(d.w,d.h);
353  trk.SetImageFloat(d.data);
354  vector2f com = trk.ComputeMeanAndCOM();
355  bool bhit;
356  vector2f qipos = trk.ComputeQI(com, 4, 64, 64,ANGSTEPF, 5, 50, bhit);
357 
358  const int radialsteps=64;
359  float radprof[radialsteps];
360  trk.ComputeRadialProfile(radprof, radialsteps, 128, 5, 40, qipos, false);
361 
362  WriteImageAsCSV(file, radprof, radialsteps, 1);
363 }
364 
365 std::vector<float> ComputeRadialWeights(int rsteps, float minRadius, float maxRadius)
366 {
367  std::vector<float> wnd(rsteps);
368  for(int x=0;x<rsteps;x++)
369  wnd[x]=Lerp(minRadius, maxRadius, x/(float)rsteps) / (0.5f * (minRadius+maxRadius));
370  return wnd;
371 }
372 
373 void TestBias()
374 {
375  ImageData lut = ReadLUTFile("lut000.jpg");
376 
377  ImageData img = ImageData::alloc(80,80);
378  CPUTracker trk(img.w,img.h);
379 
380  float o = 2.03f;
381  vector3f pos (img.w/2+o, img.h/2+o, lut.h/2);
382  NormalizeZLUT(lut.data, 1, lut.h, lut.w);
383  lut.normalize();
384 
385  srand(time(0));
386  for (int i=0;i<10;i++) {
387  GenerateImageFromLUT(&img, &lut, 0, img.w/2, pos, true);
388  ApplyPoissonNoise(img, 11050);
389  float stdev = StdDeviation(img.data, img.data + img.w);
390  dbgprintf("Noise level std: %f\n",stdev);
391  }
392 
393  WriteJPEGFile("TestBias-smp.jpg", img);
394  trk.SetImageFloat(img.data);
395 
396  vector2f com = trk.ComputeMeanAndCOM();
397  dbgprintf("COM: x:%f, y:%f\n", com.x,com.y);
398  bool bhit;
399  auto rw = ComputeRadialBinWindow(img.w);
400  vector2f qi = trk.ComputeQI(com, 3, img.w, 3*img.w/4, 1, 0, img.w/2, bhit, &rw[0]);
401  dbgprintf("QI: x: %f, y:%f\n", qi.x,qi.y);
402 
403  trk.SetRadialZLUT(lut.data, lut.h, lut.w, 1, 0, img.w/2, true, false);
404  float z = trk.ComputeZ(qi,3*img.w, 0, 0, 0, 0, false);
405  float znorm = trk.ComputeZ(qi,3*img.w, 0, 0, 0, 0, true);
406 
407  dbgprintf("Z: %f, ZNorm: %f, true:%f\n", z, znorm, pos.z);
408 
409  img.free();
410  lut.free();
411 }
412 
413 void TestZRangeBias(const char *name, const char *lutfile, bool normProf)
414 {
415  ImageData lut = ReadLUTFile(lutfile);
416 
417  QTrkComputedConfig settings;
418  settings.width=settings.height=100;
419  settings.Update();
420  ImageData img=ImageData::alloc(settings.width,settings.height);
421 
422  CPUTracker trk(settings.width,settings.height);
423  NormalizeZLUT(lut.data, 1, lut.h, lut.w);
424  trk.SetRadialZLUT(lut.data, lut.h, lut.w, 1, 1, settings.qi_maxradius, true, false);
425  float* prof= ALLOCA_ARRAY(float,lut.w);
426 
427  int N=1000;
428  std::vector< vector2f> results (N);
429  for (int i=0;i<N;i++) {
430  vector3f pos (settings.width/2, settings.height/2, i/(float)N*lut.h);
431  GenerateImageFromLUT(&img, &lut, 1, settings.qi_maxradius, pos);
432  if(InDebugMode&&i==0){
433  WriteJPEGFile(SPrintf("%s-smp.jpg",name).c_str(),img);
434  }
435 
436  trk.SetImageFloat(img.data);
437  //trk.ComputeRadialProfile(prof,lut.w,settings.zlut_angularsteps, settings.zlut_minradius, settings.zlut_maxradius, pos.xy(), false);
438  //float z=trk.LUTProfileCompare(prof, 0, 0, normProf ? CPUTracker::LUTProfMaxSplineFit : CPUTracker::LUTProfMaxQuadraticFit); result: splines no go!
439  float z = trk.ComputeZ(pos.xy(), settings.zlut_angularsteps, 0, 0, 0, 0,true);
440  results[i].x = pos.z;
441  results[i].y = z-pos.z;
442  }
443 
444  WriteImageAsCSV(SPrintf("%s-results.txt", name).c_str(),(float*) &results[0], 2, N);
445 
446  lut.free();
447  img.free();
448 }
449 
451 
452 void TestZRange(const char *name, const char *lutfile, int extraFlags, int clean_lut, RWeightMode weightMode=RWNone, bool biasMap=false, bool biasCorrect=false)
453 {
454  ImageData lut = ReadLUTFile(lutfile);
455  vector3f delta(0.001f,0.001f, 0.001f);
456 
457  if(PathSeperator(lutfile).extension != "jpg"){
458  WriteJPEGFile(SPrintf("%s-lut.jpg",name).c_str(), lut);
459  }
460 
461  if (clean_lut) {
463  WriteJPEGFile( std::string(lutfile).substr(0, strlen(lutfile)-4).append("_bmlut.jpg").c_str(), lut );
464  }
465 
466  QTrkComputedConfig settings;
467  settings.qi_iterations = 2;
468  settings.zlut_minradius = 1;
469  settings.qi_minradius = 1;
470  settings.width = settings.height = 100;
471  settings.Update();
472 
473  float maxVal=10000;
474  std::vector<float> stdv;
475  dbgprintf("High-res LUT range...\n");
476  SampleFisherMatrix fm( maxVal);
477 
478  QueuedCPUTracker trk(settings);
479  ImageData rescaledLUT;
480  ResampleLUT(&trk, &lut, lut.h, &rescaledLUT);
481 
482  if (biasCorrect) {
483  CImageData result;
484  trk.ComputeZBiasCorrection(lut.h*10, &result, 4, true);
485 
486  WriteImageAsCSV(SPrintf("%s-biasc.txt", name).c_str(), result.data, result.w, result.h);
487  }
488 
489  int f = 0;
490  if (weightMode == RWDerivative)
492  else if(weightMode == RWRadial) {
493  std::vector<float> w(settings.zlut_radialsteps);
494  for (int i=0;i<settings.zlut_radialsteps;i++)
495  w[i]= settings.zlut_minradius + i/(float)settings.zlut_radialsteps*settings.zlut_maxradius;
496  trk.SetRadialWeights(&w[0]);
497  }
498  else if (weightMode == RWStetson)
500 
502 
503  uint nstep= InDebugMode ? 20 : 1000;
504  uint smpPerStep = InDebugMode ? 2 : 200;
505  if (biasMap) {
506  smpPerStep=1;
507  nstep=InDebugMode? 200 : 2000;
508  }
509 
510  std::vector<vector3f> truepos, positions,crlb;
511  std::vector<float> stdevz;
512  for (uint i=0;i<nstep;i++)
513  {
514  float z = 1 + i / (float)nstep * (rescaledLUT.h-2);
515  vector3f pos = vector3f(settings.width/2, settings.height/2, z);
516  truepos.push_back(pos);
517  Matrix3X3 invFisherLUT = fm.Compute(pos, delta, rescaledLUT, settings.width, settings.height, settings.zlut_minradius, settings.zlut_maxradius).Inverse();
518  crlb.push_back(sqrt(invFisherLUT.diag()));
519 
520  ImageData img=ImageData::alloc(settings.width,settings.height);
521 
522  for (uint j=0;j<smpPerStep; j++) {
523  vector3f rndvec(rand_uniform<float>(), rand_uniform<float>(), rand_uniform<float>());
524  if (biasMap) rndvec=vector3f();
525  vector3f rndpos = pos + vector3f(1,1,0.1) * (rndvec-0.5f); // 0.1 plane is still a lot larger than the 0.02 typical accuracy
526  GenerateImageFromLUT(&img, &rescaledLUT, settings.zlut_minradius, settings.zlut_maxradius, rndpos, true);
527  img.normalize();
528  if (!biasMap) ApplyPoissonNoise(img, maxVal);
529  LocalizationJob job(positions.size(), 0, 0, 0);
530  trk.ScheduleImageData(&img, &job);
531  positions.push_back(rndpos);
532  if(j==0 && InDebugMode) {
533  WriteJPEGFile(SPrintf("%s-sampleimg.jpg",name).c_str(), img);
534  }
535  }
536  dbgprintf("[%d] z=%f Min std deviation: X=%f, Y=%f, Z=%f.\n", i, z, crlb[i].x,crlb[i].y,crlb[i].z);
537  img.free();
538  }
539  WaitForFinish(&trk, positions.size());
540  std::vector<vector3f> trkmean(nstep), trkstd(nstep);
541  std::vector<vector3f> resultpos(nstep*smpPerStep);
542  for (uint i=0;i<positions.size();i++) {
544  trk.FetchResults(&lr, 1);
545  resultpos[lr.job.frame]=lr.pos;
546  }
547  for (uint i=0;i<nstep;i++) {
548  for (uint j=0;j<smpPerStep;j ++) {
549  vector3f err=resultpos[i*smpPerStep+j]-positions[i*smpPerStep+j];
550  trkmean[i]+=err;
551  }
552  trkmean[i]/=smpPerStep;
553  vector3f variance;
554  for (uint j=0;j<smpPerStep;j ++) {
555  vector3f r = resultpos[i*smpPerStep+j];
556  vector3f t = positions[i*smpPerStep+j];;
557  vector3f err=r-t;
558  err -= trkmean[i];
559  variance += err*err;
560 
561  if (InDebugMode) {
562  dbgprintf("Result: x=%f,y=%f,z=%f. True: x=%f,y=%f,z=%f\n", r.x,r.y,r.z,t.x,t.y,t.z);
563  }
564  }
565  if (biasMap) trkstd[i]=vector3f();
566  else trkstd[i] = sqrt(variance / (smpPerStep-1));
567  }
568 
569  vector3f mean_std;
570  std::vector<float> output;
571  for(uint i=0;i<nstep;i++) {
572  dbgprintf("trkstd[%d]:%f crlb=%f bias=%f true=%f\n", i, trkstd[i].z, crlb[i].z, trkmean[i].z, truepos[i].z);
573  output.push_back(truepos[i].z);
574  output.push_back(trkmean[i].x);
575  output.push_back(trkstd[i].x);
576  output.push_back(trkmean[i].z);
577  output.push_back(trkstd[i].z);
578  output.push_back(crlb[i].x);
579  output.push_back(crlb[i].z);
580 
581  mean_std += trkstd[i];
582  }
583  dbgprintf("mean z err: %f\n", (mean_std/nstep).z);
584  WriteImageAsCSV( SPrintf("%s_%d_flags%d_cl%d.txt",name, weightMode, extraFlags,clean_lut).c_str(), &output[0], 7, output.size()/7);
585  lut.free();
586  rescaledLUT.free();
587 }
588 
590 {
591  auto img = ReadJPEGFile("00008153.jpg");
592  auto smp = ReadJPEGFile("00008153-s.jpg");
593  BeadFinder::Config cfg;
594  cfg.img_distance = 0.5f;
595  cfg.roi = 80;
596  cfg.similarity = 0.5;
597 
598  auto results=BeadFinder::Find(&img, smp.data, &cfg);
599 
600  for (uint i=0;i<results.size();i++) {
601  dbgprintf("beadpos: x=%d, y=%d\n", results[i].x, results[i].y);
602  img.at(results[i].x+cfg.roi/2, results[i].y+cfg.roi/2) = 1.0f;
603  }
604  dbgprintf("%d beads total\n", results.size());
605 
606  FloatToJPEGFile("autobeadfind.jpg", img.data, img.w, img.h);
607 
608  img.free();
609  smp.free();
610 }
611 
613 {
614  QTrkSettings cfg;
615  cfg.width = cfg.height = 60;
616  cfg.zlut_minradius=3;
617  cfg.zlut_roi_coverage=1;
618 
619 // auto locMode = (LocMode_t)(LT_ZLUTAlign | LT_NormalizeProfile | LT_LocalizeZ);
620 // auto resultsCOM = RunTracker<QueuedCPUTracker> ("lut000.jpg", &cfg, false, "com-zlutalign", locMode, 100 );
621 
622  const float NF=28;
623  float zpos=10;
624 
626  auto resultsZA = RunTracker<QueuedCPUTracker> ("lut000.jpg", &cfg, false, "qi-fourierlut", locMode, 200, NF,zpos);
627 
628  auto locModeQI = (LocMode_t)(LT_QI | LT_NormalizeProfile | LT_LocalizeZ);
629  auto resultsQI = RunTracker<QueuedCPUTracker> ("lut000.jpg", &cfg, false, "qi", locModeQI, 200, NF, zpos);
630 
631  resultsZA.computeStats();
632  resultsQI.computeStats();
633 
634  dbgprintf("FourierLUT: X= %f. stdev: %f\tZ=%f, stdev: %f\n", resultsZA.meanErr.x, resultsZA.stdev.x, resultsZA.meanErr.z, resultsZA.stdev.z);
635  dbgprintf("Only QI: X= %f. stdev: %f\tZ=%f, stdev: %f\n", resultsQI.meanErr.x, resultsQI.stdev.x, resultsQI.meanErr.z, resultsQI.stdev.z);
636 }
637 
639 {
640  const char*basepath= "D:/jcnossen1/datasets/RefBeads 2013-09-02/2013-09-02/";
641 
642  process_bead_dir(SPrintf("%s/%s", basepath, "tmp_001").c_str(), 80, [&] (ImageData *img, int bead, int frame) {
643 
644 
645 
646  }, 1000);
647 }
648 
650 {
651  QTrkSettings cfg;
652  cfg.width = cfg.height = 60;
653 
654 // auto locMode = (LocMode_t)(LT_ZLUTAlign | LT_NormalizeProfile | LT_LocalizeZ);
655 // auto resultsCOM = RunTracker<QueuedCPUTracker> ("lut000.jpg", &cfg, false, "com-zlutalign", locMode, 100 );
656 
657  const float NF=28;
658 
659  auto locModeQI = (LocMode_t)(LT_QI | LT_NormalizeProfile | LT_LocalizeZ);
660  auto resultsQI = RunTracker<QueuedCPUTracker> ("lut000.jpg", &cfg, false, "qi", locModeQI, 200, NF);
661 
663  auto resultsZA = RunTracker<QueuedCPUTracker> ("lut000.jpg", &cfg, false, "qi-zlutalign", locMode, 200, NF );
664 
665  resultsZA.computeStats();
666  resultsQI.computeStats();
667 
668  dbgprintf("ZLUTAlign: X= %f. stdev: %f\tZ=%f, stdev: %f\n", resultsZA.meanErr.x, resultsZA.stdev.x, resultsZA.meanErr.z, resultsZA.stdev.z);
669  dbgprintf("Only QI: X= %f. stdev: %f\tZ=%f, stdev: %f\n", resultsQI.meanErr.x, resultsQI.stdev.x, resultsQI.meanErr.z, resultsQI.stdev.z);
670 }
671 
673 {
674  QTrkSettings cfg;
675  cfg.width = cfg.height = 60;
676  cfg.numThreads=1;
677 
678 // auto locMode = (LocMode_t)(LT_ZLUTAlign | LT_NormalizeProfile | LT_LocalizeZ);
679 // auto resultsCOM = RunTracker<QueuedCPUTracker> ("lut000.jpg", &cfg, false, "com-zlutalign", locMode, 100 );
680 
681  const float NF=10;
682 
683 #ifdef _DEBUG
684  int N=1;
685  cfg.numThreads=1;
686 #else
687  int N=2000;
688 #endif
689 
690  auto locModeQI = (LocMode_t)(LT_QI | LT_NormalizeProfile | LT_LocalizeZ);
691  auto resultsQI = RunTracker<QueuedCPUTracker> ("lut000.jpg", &cfg, false, "qa", locModeQI, N, NF);
692 
694  auto resultsZA = RunTracker<QueuedCPUTracker> ("lut000.jpg", &cfg, false, "qa-qalign", locMode, N, NF );
695 
696  resultsZA.computeStats();
697  resultsQI.computeStats();
698 
699  dbgprintf("QuadrantAlign: X= %f. stdev: %f\tZ=%f, stdev: %f\n", resultsZA.meanErr.x, resultsZA.stdev.x, resultsZA.meanErr.z, resultsZA.stdev.z);
700  dbgprintf("Only QI: X= %f. stdev: %f\tZ=%f, stdev: %f\n", resultsQI.meanErr.x, resultsQI.stdev.x, resultsQI.meanErr.z, resultsQI.stdev.z);
701 }
702 
704 {
705  QTrkSettings cfg;
706  cfg.qi_minradius=0;
707  cfg.zlut_minradius = 0;
708  cfg.width = cfg.height = 30;
709  auto locModeQI = (LocMode_t)(LT_QI | LT_NormalizeProfile | LT_LocalizeZ);
710  auto results = RunTracker<QueuedCPUTracker> ("lut000.jpg", &cfg, false, "qi", locModeQI, 1000, 10000/255 );
711 
712  results.computeStats();
713  dbgprintf("X= %f. stdev: %f\tZ=%f, stdev: %f\n",
714  results.meanErr.x, results.stdev.x, results.meanErr.z, results.stdev.z);
715 }
716 
717 static void TestBSplineMax(float maxpos)
718 {
719  const int N=100;
720  float v[N];
721 
722  for (int i=0;i<N;i++)
723  v[i] = -sqrt(1+(i-maxpos)*(i-maxpos));
724  float max = ComputeSplineFitMaxPos(v, N);
725  dbgprintf("Max: %f, true: %f\n", max, maxpos);
726 }
727 
728 void GenerateZLUTFittingCurve(const char *lutfile)
729 {
730  QTrkSettings settings;
731  settings.width = settings.height = 80;
732 
733  QueuedCPUTracker qt(settings);
734  ImageData lut = ReadJPEGFile(lutfile);
735  ImageData nlut;
736  ResampleLUT(&qt, &lut, lut.h, &nlut);
737 
738  CPUTracker trk(settings.width,settings.height);
739 
740  ImageData smp = ImageData::alloc(settings.width,settings.height);
741 
742  trk.SetRadialZLUT(nlut.data, nlut.h, nlut.w, 1, qt.cfg.zlut_minradius, qt.cfg.zlut_maxradius, false, false);
743 
744  int N=8;
745  for (int z=0;z<6;z++) {
746  vector3f pos(settings.width/2,settings.height/2, nlut.h * (1+z) / (float)N + 0.123f);
747  GenerateImageFromLUT(&smp, &nlut, qt.cfg.zlut_minradius, qt.cfg.zlut_maxradius, pos);
748  ApplyPoissonNoise(smp, 10000);
749  WriteJPEGFile( SPrintf("zlutfitcurve-smpimg-z%d.jpg", z).c_str(), smp);
750  trk.SetImageFloat(smp.data);
751  std::vector<float> profile(qt.cfg.zlut_radialsteps), cmpProf(nlut.h), fitted(nlut.h);
752  trk.ComputeRadialProfile(&profile[0], qt.cfg.zlut_radialsteps, qt.cfg.zlut_angularsteps, qt.cfg.zlut_minradius, qt.cfg.zlut_maxradius, pos.xy(), false);
753  trk.LUTProfileCompare(&profile[0], 0, &cmpProf[0], CPUTracker::LUTProfMaxQuadraticFit, &fitted[0]);
754 
755  WriteArrayAsCSVRow("zlutfitcurve-profile.txt", &profile[0], profile.size(), z>0);
756  WriteArrayAsCSVRow("zlutfitcurve-cmpprof.txt", &cmpProf[0], cmpProf.size(), z>0);
757  WriteArrayAsCSVRow("zlutfitcurve-fitted.txt", &fitted[0], fitted.size(), z>0);
758  }
759 
760  smp.free();
761  nlut.free();
762  lut.free();
763 }
764 
765 void BenchmarkParams();
766 
767 static SpeedAccResult AccBiasTest(ImageData& lut, QueuedTracker *trk, int N, vector3f centerpos, vector3f range, const char *name, int MaxPixelValue, int extraFlags=0)
768 {
769  typedef QueuedTracker TrkType;
770  std::vector<vector3f> results, truepos;
771 
772  int NImg=N;//std::max(1,N/20);
773  std::vector<ImageData> imgs(NImg);
774  const float R=5;
775 
776  int flags= LT_LocalizeZ|LT_NormalizeProfile|extraFlags;
777  if (trk->cfg.qi_iterations>0) flags|=LT_QI;
778 
779  trk->SetLocalizationMode((LocMode_t)flags);
780  Matrix3X3 fisher;
781  for (int i=0;i<NImg;i++) {
782  imgs[i]=ImageData::alloc(trk->cfg.width,trk->cfg.height);
783  vector3f pos = centerpos + range*vector3f(rand_uniform<float>()-0.5f, rand_uniform<float>()-0.5f, rand_uniform<float>()-0.5f)*1;
784  GenerateImageFromLUT(&imgs[i], &lut, trk->cfg.zlut_minradius, trk->cfg.zlut_maxradius, vector3f( pos.x,pos.y, pos.z));
785 
786  SampleFisherMatrix fm(MaxPixelValue);
787  fisher += fm.Compute(pos, vector3f(1,1,1)*0.001f, lut, trk->cfg.width,trk->cfg.height, trk->cfg.zlut_minradius,trk->cfg.zlut_maxradius);
788 
789  imgs[i].normalize();
790  if (MaxPixelValue> 0) ApplyPoissonNoise(imgs[i], MaxPixelValue);
791  //if(i==0) WriteJPEGFile(name, imgs[i]);
792 
793  LocalizationJob job(i, 0, 0, 0);
794  trk->ScheduleLocalization((uchar*)imgs[i%NImg].data, sizeof(float)*trk->cfg.width, QTrkFloat, &job);
795  truepos.push_back(pos);
796  }
797  WaitForFinish(trk, N);
798 
799  results.resize(trk->GetResultCount());
800  for (uint i=0;i<results.size();i++) {
802  trk->FetchResults(&r,1);
803  results[r.job.frame]=r.pos;
804  }
805 
806  for (int i=0;i<NImg;i++)
807  imgs[i].free();
808 
809  SpeedAccResult r;
810  r.Compute(results, [&](int index) { return truepos[index]; });
811 
812  fisher *= 1.0f/NImg;
813  r.crlb = sqrt(fisher.Inverse().diag());
814  return r;
815 }
816 
817 void ScatterBiasArea(int roi, float scan_width, int steps, int samples, int qi_it, float angstep)
818 {
819  std::vector<float> u=linspace(roi/2-scan_width/2,roi/2+scan_width/2, steps);
820 
821  QTrkComputedConfig cfg;
822  cfg.width=cfg.height=roi;
823  cfg.qi_angstep_factor = angstep;
824  cfg.qi_iterations = qi_it;
825  cfg.qi_angular_coverage = 0.7f;
826  cfg.qi_roi_coverage = 1;
827  cfg.qi_radial_coverage = 1.5f;
828  cfg.qi_minradius=0;
829  cfg.zlut_minradius=0;
830  cfg.zlut_angular_coverage = 0.7f;
831  cfg.zlut_roi_coverage = 1;
832  cfg.zlut_radial_coverage = 1.5f;
833  cfg.zlut_minradius = 0;
834  cfg.qi_minradius = 0;
835  cfg.com_bgcorrection = 0;
836  cfg.xc1_profileLength = roi*0.8f;
837  cfg.xc1_profileWidth = roi*0.2f;
838  cfg.xc1_iterations = 1;
839  cfg.Update();
840 
841  ImageData lut,orglut = ReadLUTFile("10x.radialzlut#4");
842  vector3f ct(roi/2,roi/2,lut.h/2 + 0.123f);
843  float dx = scan_width/steps;
844 
845  QueuedCPUTracker trk(cfg);
846  ResampleLUT(&trk, &orglut, orglut.h, &lut);
847  int maxval = 10000;
848 
849  ImageData tmp=ImageData::alloc(roi,roi);
850  GenerateImageFromLUT(&tmp, &lut, 0, cfg.zlut_maxradius, vector3f(roi/2,roi/2,lut.h/2));
851  ApplyPoissonNoise(tmp, maxval);
852 
853  std::string fn = SPrintf( "sb_area_roi%d_scan%d_steps%d_qit%d_N%d", roi, (int)scan_width, steps, qi_it, samples);
854  WriteJPEGFile( (fn + ".jpg").c_str(), tmp);
855  tmp.free();
856 
857  fn += ".txt";
858  for (int y=0;y<steps;y++) {
859  for (int x=0;x<steps;x++)
860  {
861  vector3f cpos( (x+0.5f-steps/2) * dx, (y+0.5f-steps/2) * dx, 0 );
862 
863  cfg.qi_iterations = qi_it;
864  auto r= AccBiasTest(orglut, &trk, samples, cpos+ct, vector3f(), 0, maxval, qi_it < 0 ? LT_XCor1D : 0);
865 
866  float row[] = { r.acc.x, r.acc.y, r.acc.z, r.bias.x, r.bias.y, r.bias.z, r.crlb.x, r.crlb.z, samples };
867  WriteArrayAsCSVRow(fn.c_str(), row, 9, x+y>0);
868 
869  dbgprintf("X=%d,Y=%d\n", x,y);
870  }
871  }
872  orglut.free();
873  lut.free();
874 }
875 
876 void RunCOMAndQI(ImageData img, outputter* output){
877  char buf[256];
878  CPUTracker trk(img.w,img.h);
879  trk.SetImageFloat(img.data);
880  double t = GetPreciseTime();
881  vector2f com = trk.ComputeMeanAndCOM();
882  t = GetPreciseTime() - t;
883  //float asym = trk.ComputeAsymmetry(com,64,64,5,50,dstAngProf);
884  sprintf(buf,"%f %f %f",com.x,com.y,t);
885  output->outputString(buf);
886 
887  vector2f initial(com.x, com.y);
888 
889  bool boundaryHit = false;
890  for(int qi_iterations = 1; qi_iterations < 10; qi_iterations++){
891  t = GetPreciseTime();
892  vector2f qi = trk.ComputeQI(initial, qi_iterations, 64, 16,ANGSTEPF, 5,50, boundaryHit);
893  t = GetPreciseTime() - t;
894  //float asym = trk.ComputeAsymmetry(qi,64,64,5,50,dstAngProf);
895  sprintf(buf,"%f %f %f",qi.x,qi.y,t);
896  output->outputString(buf);
897  boundaryHit = false;
898  }
899 }
900 
901 float SkewParam(ImageData img){
902  int size = img.w * 2 + img.h * 2 - 4;
903  float* outeredge = new float[size];
904  GetOuterEdges(outeredge,size,img);
905  float* max = std::max_element(img.data,img.data+(img.w*img.h));
906  float* min = std::min_element(img.data,img.data+(img.w*img.h));
907  float* outer_max = std::max_element(outeredge,outeredge+size);
908  float* outer_min = std::min_element(outeredge,outeredge+size);
909 
910  float out = (*outer_max-*outer_min)/(*max-*min);
911  delete[] outeredge;
912  return out;
913 }
914 
915 void TestROIDisplacement(std::vector<BeadPos> beads, ImageData oriImg, outputter* output, int ROISize, int maxdisplacement = 0)
916 {
917  for(uint ii = 0; ii < beads.size(); ii++){
918 
919  output->newFile(SPrintf("%d,%d-ROI-%d",beads.at(ii).x,beads.at(ii).y,ROISize));
920 
921  for(int x_i = -maxdisplacement; x_i <= maxdisplacement; x_i++){
922  for(int y_i = -maxdisplacement; y_i <= maxdisplacement; y_i++){
923  int x = beads.at(ii).x + x_i - ROISize/2;
924  int y = beads.at(ii).y + y_i - ROISize/2;
925  ImageData img = CropImage(oriImg,x,y,ROISize,ROISize);
926  output->outputImage(img,SPrintf("%d,%d-Crop",beads.at(ii).x + x_i, beads.at(ii).y + y_i));
927  output->outputString(SPrintf("%d,%d - ROI (%d,%d) -> (%d,%d)",x_i,y_i,x,y,x+ROISize,y+ROISize));
928  RunCOMAndQI(img,output);
929  img.free();
930  }
931  }
932  }
933 }
934 
935 void TestInterference(std::vector<BeadPos> beads, ImageData oriImg, outputter* output, int ROISize, vector2f displacement = vector2f(60,0))
936 {
937  ImageData added = AddImages(oriImg,oriImg,displacement);
938  //output->outputImage(added,"Added");
939 
940  for(uint ii = 0; ii < beads.size(); ii++){
941  output->newFile(SPrintf("%d,%d-Inter",beads.at(ii).x,beads.at(ii).y));
942 
943  int x = beads.at(ii).x - ROISize/2;
944  int y = beads.at(ii).y - ROISize/2;
945 
946  ImageData img = CropImage(added,x,y,ROISize,ROISize);
947  output->outputImage(img,SPrintf("%d,%d-Inter",beads.at(ii).x,beads.at(ii).y));
948 
949  RunCOMAndQI(img,output);
950  img.free();
951  }
952 
953  added.free();
954 }
955 
956 void TestSkew(std::vector<BeadPos> beads, ImageData oriImg, outputter* output, int ROISize)
957 {
958  for(uint ii = 0; ii < beads.size(); ii++){
959  output->newFile(SPrintf("%d,%d-Skew",beads.at(ii).x,beads.at(ii).y));
960 
961  int x = beads.at(ii).x - ROISize/2;
962  int y = beads.at(ii).y - ROISize/2;
963 
964  ImageData img = CropImage(oriImg,x,y,ROISize,ROISize);
965  ImageData skewImg = SkewImage(img,20);
966  output->outputImage(skewImg,SPrintf("%d,%d-Skew",beads.at(ii).x,beads.at(ii).y));
967  float imgSkew = SkewParam(img);
968  float skewImgSkew = SkewParam(skewImg);
969  output->outputString(SPrintf("%f %f",imgSkew,skewImgSkew));
970  RunCOMAndQI(skewImg,output);
971  img.free();
972  skewImg.free();
973  }
974 }
975 
976 void TestBackground(std::vector<BeadPos> beads, ImageData oriImg, outputter* output, int ROISize)
977 {
978  std::string out;
979 
980  out = "Beads-Background";
981  output->newFile(out);
982 
983  for(uint ii = 0; ii < beads.size(); ii++){
984  int x = beads.at(ii).x - ROISize/2;
985  int y = beads.at(ii).y - ROISize/2;
986  ImageData img = CropImage(oriImg,x,y,ROISize,ROISize);
987  output->outputImage(img,SPrintf("%d,%d-Crop",beads.at(ii).x, beads.at(ii).y));
988  output->outputString(SPrintf("%d,%d-Crop",beads.at(ii).x, beads.at(ii).y));
989  output->outputString(SPrintf("median: %f",BackgroundMedian(img)));
990  output->outputString(SPrintf("sigma: %f",BackgroundStdDev(img)));
991  output->outputString(SPrintf("rms: %f",BackgroundRMS(img)));
992  output->outputString("");
993  img.free();
994  }
995 }
996 
997 void BuildZLUT(std::string folder, outputter* output)
998 {
999  int ROISize = 100;
1000  std::vector<BeadPos> beads = read_beadlist(SPrintf("%sbeadlist.txt",folder.c_str()));
1001 
1002 
1003  int numImgInStack = 1218;
1004  int numPositions = 1001; // 10nm/frame
1005  float range = 10.0f; // total range 25.0 um -> 35.0 um
1006  float umPerImg = range/numImgInStack;
1007 
1008  QTrkComputedConfig cfg;
1009  cfg.width=cfg.height = ROISize;
1010  cfg.qi_angstep_factor = 1;
1011  cfg.qi_iterations = 6;
1012  cfg.qi_angular_coverage = 0.7f;
1013  cfg.qi_roi_coverage = 1;
1014  cfg.qi_radial_coverage = 1.5f;
1015  cfg.qi_minradius=0;
1016  cfg.zlut_minradius=0;
1017  cfg.zlut_angular_coverage = 0.7f;
1018  cfg.zlut_roi_coverage = 1;
1019  cfg.zlut_radial_coverage = 1.5f;
1020  cfg.zlut_minradius = 0;
1021  cfg.qi_minradius = 0;
1022  cfg.com_bgcorrection = 0;
1023  cfg.xc1_profileLength = ROISize*0.8f;
1024  cfg.xc1_profileWidth = ROISize*0.2f;
1025  cfg.xc1_iterations = 1;
1026  cfg.Update();
1027  cfg.WriteToFile();
1028 
1029  int zplanes = 50;
1030 
1031  QueuedCPUTracker* qtrk = new QueuedCPUTracker(cfg);
1033  qtrk->SetRadialZLUT(0, beads.size(), zplanes);
1034  qtrk->BeginLUT(0);
1035 
1036  int pxPerBead = ROISize*ROISize;
1037  int memSizePerBead = pxPerBead*sizeof(float);
1038  int startFrame = 400;
1039  for(int plane = 0; plane < zplanes; plane++){
1040  output->outputString(SPrintf("Frame %d/%d",plane+1,zplanes),true);
1041  int frameNum = startFrame+(int)(numImgInStack-startFrame)*((float)plane/zplanes);
1042  std::string file = SPrintf("%s\img%05d.jpg",folder.c_str(),frameNum);
1043 
1044  ImageData frame = ReadJPEGFile(file.c_str());
1045 
1046  float* data = new float[beads.size()*pxPerBead];
1047 
1048  for(uint ii = 0; ii < beads.size(); ii++){
1049  vector2f pos;
1050  pos.x = beads.at(ii).x - ROISize/2;
1051  pos.y = beads.at(ii).y - ROISize/2;
1052  ImageData crop = CropImage(frame,pos.x,pos.y,ROISize,ROISize);
1053  //output->outputImage(crop,SPrintf("%d-%05d",ii,plane));
1054  memcpy(data+ii*pxPerBead,crop.data,memSizePerBead);
1055  crop.free();
1056  }
1057 
1058  /*
1059  // To verify seperate frame bead stack generation
1060  output->newFile(SPrintf("data-plane-%d",plane));
1061  output->outputArray(data,beads.size()*pxPerBead);
1062 
1063  ImageData allBeads = ImageData(data,ROISize,ROISize*beads.size());
1064  output->outputImage(allBeads,SPrintf("allBeads-%05d",frameNum));//*/
1065 
1066  qtrk->BuildLUT(data, sizeof(float)*ROISize, QTrkFloat, plane);
1067 
1068  frame.free();
1069  delete[] data;
1070  }
1071 
1072  qtrk->FinalizeLUT();
1073 
1074  for(int ii = 0; ii < beads.size(); ii++){
1075  ImageData lut = ImageData::alloc(cfg.zlut_radialsteps,zplanes);
1076  memcpy(lut.data,qtrk->GetZLUTByIndex(ii),cfg.zlut_radialsteps*zplanes*sizeof(float));
1077  //output->outputImage(lut,SPrintf("lut%03d,%d",beads.at(ii).x,beads.at(ii).y));
1078  output->outputImage(lut,SPrintf("lut%03d",ii));
1079  lut.free();
1080  }
1081 
1082  qtrk->Flush();
1083  delete qtrk;
1084 }
1085 
1086 void RunZTrace(std::string imagePath, std::string zlutPath, outputter* output)
1087 {
1088  int ROISize = 100;
1089  std::vector<BeadPos> beads = read_beadlist(SPrintf("%sbeadlist.txt",imagePath.c_str()));
1090  //std::vector<BeadPos> beads = read_labview_beadlist(SPrintf("%sbeadlist.txt",imagePath.c_str()));
1091  if(beads.size() == 0){
1092  output->outputString("Empty beadlist!",true);
1093  return;
1094  }
1095 
1096  QTrkComputedConfig cfg;
1097  /*
1098  output->outputString("Enter used ZLUT settings.",true);
1099  output->outputString(SPrintf("ROI size (currently %d)",ROISize),true);
1100  std::cin >> ROISize;
1101  output->outputString("ZLUT radial sample density (default 1)",true);
1102  std::cin >> cfg.zlut_radial_coverage;
1103  output->outputString("ZLUT minradius (default 2)",true);
1104  std::cin >> cfg.zlut_minradius;
1105  output->outputString("ZLUT ROI coverage (default 1)",true);
1106  std::cin >> cfg.zlut_roi_coverage;
1107  output->outputString("ZLUT angular coverage (default 0.7)",true);
1108  std::cin >> cfg.zlut_angular_coverage;
1109  */
1110  /*
1111  cfg.width = cfg.height = ROISize;
1112  cfg.qi_angstep_factor = 1;
1113  cfg.qi_iterations = 6;
1114  cfg.qi_angular_coverage = 0.7f;
1115  cfg.qi_roi_coverage = 1;
1116  cfg.qi_radial_coverage = 1.5f;
1117  cfg.qi_minradius = 0;
1118  cfg.zlut_minradius = 2;
1119  cfg.zlut_radial_coverage = 2;
1120  cfg.zlut_angular_coverage = 0.7f;
1121  cfg.zlut_roi_coverage = 1;
1122  cfg.com_bgcorrection = 0;
1123  cfg.xc1_profileLength = ROISize*0.8f;
1124  cfg.xc1_profileWidth = ROISize*0.2f;
1125  cfg.xc1_iterations = 1;
1126  cfg.testRun = true;
1127  */
1128  cfg.width=cfg.height = ROISize;
1129  cfg.qi_angstep_factor = 1;
1130  cfg.qi_iterations = 6;
1131  cfg.qi_angular_coverage = 0.7f;
1132  cfg.qi_roi_coverage = 1;
1133  cfg.qi_radial_coverage = 1.5f;
1134  cfg.qi_minradius=0;
1135  cfg.zlut_minradius=0;
1136  cfg.zlut_angular_coverage = 0.7f;
1137  cfg.zlut_roi_coverage = 1;
1138  cfg.zlut_radial_coverage = 1.5f;
1139  cfg.zlut_minradius = 0;
1140  cfg.qi_minradius = 0;
1141  cfg.com_bgcorrection = 0;
1142  cfg.xc1_profileLength = ROISize*0.8f;
1143  cfg.xc1_profileWidth = ROISize*0.2f;
1144  cfg.xc1_iterations = 1;
1145  cfg.testRun = true;
1146  cfg.Update();
1147  cfg.WriteToFile();
1148 
1149  std::string file = SPrintf("%s\lut%03d.jpg",zlutPath.c_str(),0);
1150  ImageData lut = ReadJPEGFile(file.c_str());
1151 
1152  if(cfg.zlut_radialsteps != lut.w){
1153  output->outputString("ZLUT settings do not match LUT image sizes!",true);
1154  lut.free();
1155  return;
1156  }
1157 
1158  int zplanes = lut.h;
1159  lut.free();
1160  int res = cfg.zlut_radialsteps;
1161 
1162  float* zluts = new float[zplanes*res*beads.size()];
1163  ROIPosition* positions = new ROIPosition[beads.size()];
1164  for(int ii = 0; ii < beads.size(); ii++){
1165  std::string file = SPrintf("%s\lut%03d.jpg",zlutPath.c_str(),ii);
1166  ImageData lut = ReadJPEGFile(file.c_str());
1167  memcpy(zluts+ii*res*zplanes,lut.data,res*zplanes*sizeof(float));
1168 
1169  lut.free();
1170 
1171  positions[ii].x = beads.at(ii).x - ROISize/2;
1172  positions[ii].y = beads.at(ii).y - ROISize/2;
1173  }
1174 
1175  QueuedCPUTracker* qtrk = new QueuedCPUTracker(cfg);
1176  qtrk->SetRadialZLUT(zluts,beads.size(),zplanes);
1177  qtrk->FinalizeLUT();
1178 
1179  /*for(int ii = 0; ii < beads.size(); ii++){
1180  ImageData lut = ImageData::alloc(cfg.zlut_radialsteps,zplanes);
1181  memcpy(lut.data,qtrk->GetZLUTByIndex(ii),cfg.zlut_radialsteps*zplanes*sizeof(float));
1182  output->outputImage(lut,SPrintf("lut-%d,%d",beads.at(ii).x,beads.at(ii).y));
1183  lut.free();
1184  }*/
1185  //qtrk->ZLUTSelfTest();
1186 
1188 
1189  ResultManagerConfig RMcfg;
1190  RMcfg.numBeads = beads.size();
1191  RMcfg.numFrameInfoColumns = 0;
1192  RMcfg.scaling = vector3f(1.0f,1.0f,1.0f);
1193  RMcfg.offset = vector3f(0.0f,0.0f,0.0f);
1194  RMcfg.writeInterval = 25;
1195  RMcfg.maxFramesInMemory = 100;
1196  RMcfg.binaryOutput = false;
1197 
1198  std::vector<std::string> colnames;
1199  for(int ii = 0;ii<RMcfg.numFrameInfoColumns;ii++){
1200  colnames.push_back(SPrintf("%d",ii));
1201  }
1202 
1203  ResultManager* RM = new ResultManager(
1204  SPrintf("%s\\RMOutput.txt",output->folder.c_str()).c_str(),
1205  SPrintf("%s\\RMFrameInfo.txt",output->folder.c_str()).c_str(),
1206  &RMcfg, colnames);
1207 
1208  RM->SetTracker(qtrk);
1209 
1210  int numFramesToTrack = NumJpgInDir(imagePath + "*");
1211  for(int ii = 0; ii < numFramesToTrack; ii++){
1212  std::string file = SPrintf("%s\img%05d.jpg",imagePath.c_str(),ii);
1213  ImageData img = ReadJPEGFile(file.c_str());
1214 
1215  LocalizationJob job(ii, 0, 0, 0);
1216  int queued = qtrk->ScheduleFrame(img.data,sizeof(float)*img.w,img.w,img.h,positions,beads.size(),QTrkFloat,&job);
1217  //output->outputString(SPrintf("Queueing frame %d. Current Queue size: %d. Added: %d.",ii,qtrk->GetQueueLength(),queued),true);
1219  output->outputString(SPrintf("Queueing frame %d. Current Queue size: %d.\n\tcaptured: %d\n\tprocessed: %d\n\tlocalizations: %d\n\tLOST: %d\n",ii,qtrk->GetQueueLength(),cnt.capturedFrames,cnt.processedFrames,cnt.localizationsDone,cnt.lostFrames),true);
1220 
1221  img.free();
1222  }
1223 
1224  while(qtrk->GetQueueLength() != 0);
1225  RM->Flush();
1226  delete RM;
1227 
1228  /* NO RESULT MANAGER
1229 
1230  int numFramesToTrack = NumJpgInDir(imagePath + "*");
1231  for(int ii = 0; ii < numFramesToTrack; ii++){
1232  std::string file = SPrintf("%s\img%05d.jpg",imagePath.c_str(),ii);
1233  ImageData img = ReadJPEGFile(file.c_str());
1234 
1235  LocalizationJob job(ii, 0, 0, 0);
1236  int queued = qtrk->ScheduleFrame(img.data,sizeof(float)*img.w,img.w,img.h,positions,beads.size(),QTrkFloat,&job);
1237  output->outputString(SPrintf("Queueing frame %d. Current Queue size: %d. Added: %d.",ii,qtrk->GetQueueLength(),queued),true);
1238  img.free();
1239 
1240  while(qtrk->GetResultCount() != 0) {
1241  LocalizationResult lr;
1242  qtrk->FetchResults(&lr,1);
1243  output->outputString(SPrintf("frame %d, bead %d: %f %f %f",lr.job.frame,lr.job.zlutIndex,lr.pos.x,lr.pos.y,lr.pos.z));
1244  //delete &(lr.job);
1245  }
1246  }
1247 
1248  while(qtrk->GetQueueLength() != 0) {
1249  if(qtrk->GetResultCount() != 0) {
1250  LocalizationResult lr;
1251  qtrk->FetchResults(&lr,1);
1252  output->outputString(SPrintf("frame %d, bead %d: %f %f %f",lr.job.frame,lr.job.zlutIndex,lr.pos.x,lr.pos.y,lr.pos.z));
1253  }
1254  }
1255  */
1256  /*ImageData allLuts = ImageData::alloc(res,zplanes*beads.size());
1257  memcpy(allLuts.data,zluts,res*zplanes*beads.size()*sizeof(float));
1258  output->outputImage(allLuts,"allLuts");
1259  allLuts.free();//*/
1260 
1261  qtrk->ClearResults();
1262  delete qtrk;
1263  delete positions;
1264  delete[] zluts;
1265 }
1266 
1267 enum Tests{
1272 };
1273 
1274 void RunTest(Tests test, const char* image, outputter* output, int ROISize)
1275 {
1276  ImageData source = ReadJPEGFile(image);
1277  std::vector<BeadPos> beads = read_beadlist("D:\\TestImages\\beadlist.txt");
1278  output->newFile("TestInfo","a");
1279 
1280  if(test == ROIDis)
1281  output->outputString("ROI Displacement test");
1282  else if(test == Inter)
1283  output->outputString("Interference test");
1284  else if(test == Skew)
1285  output->outputString("Skew test");
1286  else if(test == Backg)
1287  output->outputString("Background test");
1288  output->outputString(SPrintf("Image %s\nBeadlist D:\\TestImages\\beadlist.txt\nNumBeads %d\nROISize %d",image,beads.size(),ROISize));
1289 
1290  double t0 = GetPreciseTime();
1291 
1292  switch(test){
1293  case ROIDis:
1294  TestROIDisplacement(beads,source,output,ROISize);
1295  break;
1296  case Inter:
1297  TestInterference(beads,source,output,ROISize);
1298  break;
1299  case Skew:
1300  TestSkew(beads,source,output,ROISize);
1301  break;
1302  case Backg:
1303  TestBackground(beads,source,output,ROISize);
1304  break;
1305  };
1306 
1307  double t1 = GetPreciseTime();
1308  output->newFile("TestInfo","a");
1309  output->outputString(SPrintf("Duration %f\n",t1-t0));
1310  source.free();
1311 }
1312 
1313 void ManTest()
1314 {
1315  int ROISize = 101;
1316  float displacement = 0;
1317  float skewFact = 0.0f;
1318  float bgCorr = 2;
1319  int imgSel = 0;
1320 
1321  char inChar;
1322  do
1323  {
1324  char selChar;
1325  do{
1326  printf_s("Current settings: image %s\nROI %d, skewFact %f, displacement %f, bgCorr %f\n\n", (imgSel == 0)? "generated":"CroppedBead.jpg", ROISize, skewFact, displacement, bgCorr);
1327  std::cout << "What setting to change? (? for list, 0 to run)\n";
1328  std::cin >> selChar;
1329  switch(selChar){
1330  case '?':
1331  printf("i: imgSel (0: Generated, 1: CroppedBead.jpg)\nr: ROISize\nb: COM Background correction\n");
1332  printf("\nOnly for generated image:\n\ts: skewFact\n\td: displacement\n");
1333  break;
1334  case 'i':
1335  std::cin >> imgSel;
1336  break;
1337  case 'r':
1338  std::cin >> ROISize;
1339  break;
1340  case 's':
1341  std::cin >> skewFact;
1342  break;
1343  case 'd':
1344  std::cin >> displacement;
1345  break;
1346  case 'b':
1347  std::cin >> bgCorr;
1348  break;
1349  default:
1350  break;
1351  }
1352  std::cout << std::endl;
1353  } while(selChar != '0');
1354  ImageData img;
1355  if(imgSel == 1){
1356  ImageData imgRaw = ReadJPEGFile("D:\\TestImages\\CroppedBead.jpg");
1357  ROISize = imgRaw.w;
1358  img = SkewImage(imgRaw,skewFact);
1359  img.normalize();
1360  imgRaw.free();
1361  } else {
1362  ImageData imgRaw = ImageData::alloc(ROISize,ROISize);
1363  GenerateTestImage(imgRaw,(float)ROISize/2+displacement,(float)ROISize/2+displacement,5,0);
1364  img = SkewImage(imgRaw,skewFact);
1365  img.normalize();
1366  imgRaw.free();
1367  }
1368  FloatToJPEGFile("D:\\TestImages\\test.jpg",img.data,ROISize,ROISize);
1369 
1370  QTrkComputedConfig cfg;
1371  cfg.width = cfg.height = ROISize;
1372  cfg.qi_angstep_factor = 1;
1373  cfg.qi_iterations = 10;
1374  cfg.qi_angular_coverage = 0.7f;
1375  cfg.qi_roi_coverage = 1.0f;
1376  cfg.qi_radial_coverage = 1.5f;
1377  cfg.qi_minradius = 0;
1378  cfg.zlut_minradius = 2;
1379  cfg.zlut_radial_coverage = 2;
1380  cfg.zlut_angular_coverage = 0.7f;
1381  cfg.zlut_roi_coverage = 1;
1382  cfg.com_bgcorrection = bgCorr;
1383  cfg.xc1_profileLength = ROISize*0.8f;
1384  cfg.xc1_profileWidth = ROISize*0.2f;
1385  cfg.xc1_iterations = 4;
1386  cfg.testRun = true;
1387 
1388  cfg.Update();
1389 
1390  QueuedCPUTracker* qtrk = new QueuedCPUTracker(cfg);
1392  LocalizationJob job(0, 0, 0, 0);
1393  ROIPosition pos;
1394  pos.x = 0;
1395  pos.y = 0;
1396  int queued = qtrk->ScheduleFrame(img.data,sizeof(float)*img.w,img.w,img.h,&pos,1,QTrkFloat,&job);
1397  printf("q: %d\n",queued);
1398  while(qtrk->GetQueueLength() != 0);
1399  while(qtrk->GetResultCount() != 0) {
1400  LocalizationResult lr;
1401  qtrk->FetchResults(&lr,1);
1402 
1403  printf("%f %f %f %f\n",lr.firstGuess.x,lr.firstGuess.y,lr.pos.x,lr.pos.y);
1404 
1405  float* prof = ALLOCA_ARRAY(float,cfg.zlut_radialsteps);
1406  bool boundaryHit;
1407  ImageData imgData (img.data,ROISize,ROISize);
1408  ComputeRadialProfile(prof,cfg.zlut_radialsteps, cfg.zlut_angularsteps, cfg.zlut_minradius, cfg.zlut_maxradius, lr.pos.xy(), &imgData, lr.imageMean, false);
1409  WriteArrayAsCSVRow("D:\\TestImages\\RadialProfile.txt",prof,cfg.zlut_radialsteps,false);
1410  ComputeRadialProfile(prof,cfg.zlut_radialsteps, cfg.zlut_angularsteps, cfg.zlut_minradius, cfg.zlut_maxradius, lr.pos.xy(), &imgData, lr.imageMean, true);
1411  WriteArrayAsCSVRow("D:\\TestImages\\RadialProfile.txt",prof,cfg.zlut_radialsteps,true);
1412  }
1413 
1414  img.free();
1415  qtrk->Flush();
1416  delete qtrk;
1417  std::cout << "\nContinue?\n";
1418  std::cin >> inChar;
1419  } while(inChar != '0');
1420 }
1421 
1422 void PrintMenu(outputter* output)
1423 {
1424  output->outputString("0. Quit",true);
1425  output->outputString("1. ROI Displacement",true);
1426  output->outputString("2. Interference",true);
1427  output->outputString("3. Skew",true);
1428  output->outputString("4. Background",true);
1429  output->outputString("5. Build ZLUTs",true);
1430  output->outputString("6. Run Trace",true);
1431  output->outputString("m. Manual",true);
1432  output->outputString("r. Change ROI size",true);
1433  output->outputString("?. Menu",true);
1434 }
1435 
1436 void SelectTests(const char* image, int OutputMode)
1437 {
1438  outputter* output = new outputter(OutputMode);
1439  int testNum = 1;
1440  int ROISize = 120;
1441 
1442  PrintMenu(output);
1443  char inChar;
1444  do
1445  {
1446  output->outputString("Select test or ? for menu:",true);
1447  std::string imagesPath, LUTPath;
1448  std::cin >> inChar;
1449  switch(inChar)
1450  {
1451  case '0':
1452  break;
1453  case '1':
1454  RunTest(ROIDis,image,output,ROISize);
1455  output->outputString("Test done!",true);
1456  break;
1457  case '2':
1458  RunTest(Inter,image,output,ROISize);
1459  output->outputString("Test done!",true);
1460  break;
1461  case '3':
1462  RunTest(Skew,image,output,ROISize);
1463  output->outputString("Test done!",true);
1464  break;
1465  case '4':
1466  RunTest(Backg,image,output,ROISize);
1467  output->outputString("Test done!",true);
1468  break;
1469  case '5':
1470  //BuildZLUT("L:\\BN\\ND\\Shared\\Jordi\\TestMovie150507_2\\images\\jpg\\Zstack\\",output);
1471  BuildZLUT("D:\\TestImages\\TestMovie150507_2\\images\\jpg\\Zstack\\",output);
1472  output->outputString("ZLUTs Built",true);
1473  break;
1474  case '6':
1475  /*while(!(DirExists(imagesPath) && NumJpgInDir(imagesPath) > 0)){
1476  output->outputString("Enter image folder (with beadlist):",true);
1477  std::cin >> imagesPath;
1478  output->outputString(SPrintf("%d jpgs in folder",NumJpgInDir(imagesPath)),true);
1479  }
1480  while(!(DirExists(LUTPath) && NumJpgInDir(LUTPath) > 0)){
1481  output->outputString("Enter LUT folder:",true);
1482  std::cin >> LUTPath;
1483  output->outputString(SPrintf("%d jpgs in folder",NumJpgInDir(LUTPath)),true);
1484  }
1485  RunZTrace(imagesPath,LUTPath,output);*/
1486  //RunZTrace("L:\\BN\\ND\\Shared\\Jordi\\20150804_TestMovie\\images\\jordi_test\\jpg\\","L:\\BN\\ND\\Shared\\Jordi\\20150804_TestMovie\\images\\lut\\",output);
1487  //RunZTrace("D:\\TestImages\\20150804_TestMovie\\images\\jordi_test\\jpg\\","D:\\TestImages\\20150804_TestMovie\\images\\lut\\",output);
1488  RunZTrace("C:\\TestImages\\TestMovie150507_2\\images\\jpg\\Zstack\\","C:\\TestImages\\TestMovie150507_2\\ZLUTS_50planes\\",output);
1489  break;
1490  case 'm':
1491  ManTest();
1492  break;
1493  case 'R':
1494  case 'r':
1495  output->outputString(SPrintf("Enter new ROI size (currently %d)",ROISize),true);
1496  std::cin >> ROISize;
1497  break;
1498  default:
1499  output->outputString("Wrong input",true);
1500  case '?':
1501  PrintMenu(output);
1502  break;
1503  }
1504  } while(inChar != '0');
1505 
1506  delete output;
1507 }
1508 
1509 int main()
1510 {
1511 #ifdef _DEBUG
1512 // Matrix3X3::test();
1513 #endif
1514  SelectTests("D:\\TestImages\\img00095.jpg", Files+Images);
1515 // ManTest();
1516 
1517 // SimpleTest();
1518 
1519 // GenerateZLUTFittingCurve("lut000.jpg");
1520 
1521  /*TestBias();
1522  TestZRangeBias("ref169-norm", "zrange\\exp_qi.radialzlut#169", true);
1523  TestZRangeBias("ref169-raw", "zrange\\exp_qi.radialzlut#169", false);
1524 
1525 // SmallROITest("lut000.jpg");
1526 
1527  //TestZRange("lut227-ref","lut227.jpg", 0, 0, RWStetson);
1528  TestZRange("zrange\\lut169ref-biasmap-c","zrange\\exp_qi.radialzlut#169", 0, 0, RWStetson, true, true);
1529  TestZRange("zrange\\lut169ref-biasmap","zrange\\exp_qi.radialzlut#169", 0, 0, RWStetson, true, false);
1530  TestZRange("zrange\\lut169ref","zrange\\exp_qi.radialzlut#169", 0, 0, RWStetson, false, false);
1531  TestZRange("zrange\\lut169ref-c","zrange\\exp_qi.radialzlut#169", 0, 0, RWStetson, false, true);
1532  TestZRange("zrange\\lut013tether","zrange\\exp_qi.radialzlut#13", 0, 0, RWStetson, false, false);
1533  TestZRange("zrange\\lut013tether-c","zrange\\exp_qi.radialzlut#13", 0, 0, RWStetson, false, true);*/
1534 /*
1535  TestZRange("zrange\\longlut1-c","zrange\\long.radialzlut#1", 0,0, RWStetson, false, true);
1536  TestZRange("zrange\\longlut1","zrange\\long.radialzlut#1", 0,0, RWStetson, false, false);
1537  TestZRange("zrange\\longlut3-c","zrange\\long.radialzlut#3", 0,0, RWStetson, false, true);
1538  TestZRange("zrange\\longlut3","zrange\\long.radialzlut#3", 0,0, RWStetson, false, false);
1539 */
1540  //TestZRange("cleanlut1", "lut000.jpg", LT_LocalizeZWeighted, 0);
1541  //TestZRange("cleanlut1", "lut000.jpg", LT_LocalizeZWeighted, 1);
1542  //TestZRange("cleanlut10", "lut10.jpg", LT_LocalizeZWeighted, 1);
1543  //TestZRange("cleanlut10", "lut10.jpg", LT_LocalizeZWeighted, 1);
1544 
1545 // BenchmarkParams();
1546 // int N=50;
1547  /*ScatterBiasArea(80, 4, 100, N, 3, 1);
1548  ScatterBiasArea(80, 4, 100, N, 4, 1);
1549  ScatterBiasArea(80, 4, 100, N, 1, 1);
1550  ScatterBiasArea(80, 4, 100, N, 2, 1);
1551  ScatterBiasArea(80, 4, 100, N, 0, 1);
1552  ScatterBiasArea(80, 4, 100, N, -1, 1);
1553  */
1554 /*
1555  ImageData img=ReadLUTFile("lut000.jpg");
1556  img.mean();
1557 
1558  TestZRange("rbin1x", "1x.radialzlut#4", 0, 0, RWUniform);
1559  TestZRange("rbin1x", "1x.radialzlut#4", 0, 0, RWRadial);
1560  TestZRange("rbin1x", "1x.radialzlut#4", 0, 0, RWDerivative);
1561 
1562  TestZRange("rbin10x", "10x.radialzlut#4", 0, 0, RWUniform);
1563  TestZRange("rbin10x", "10x.radialzlut#4", 0, 0, RWRadial);
1564  TestZRange("rbin10x", "10x.radialzlut#4", 0, 0, RWDerivative);
1565  */
1566 // QTrkTest();
1567 // TestCMOSNoiseInfluence<QueuedCPUTracker>("lut000.jpg");
1568 
1569  //AutoBeadFindTest();
1570 // Gauss2DTest<QueuedCPUTracker>();
1571 
1572  //SpeedTest();
1573  //PixelationErrorTest();
1574  //ZTrackingTest();
1575  //Test2DTracking();
1576  //TestBoundCheck();
1577  //QTrkTest();
1578  //for (int i=1;i<8;i++)
1579  // BuildConvergenceMap(i);
1580 
1581  //TestFourierLUT();
1582 // TestQuadrantAlign();
1583  //TestZLUTAlign();
1584  //TestImageLUT();
1585 // TestBuildRadialZLUT<QueuedCPUTracker>( "lut000.jpg" );
1586  //TestImageLUT();
1587 
1588  //CorrectedRadialProfileTest();
1589 
1590  //system("pause");
1591  return 0;
1592 }
void WriteArrayAsCSVRow(const char *file, float *d, int len, bool append)
Definition: utils.cpp:537
virtual int GetResultCount()=0
Get the number of finished localization jobs (=results) available in memory.
float zlut_minradius
Distance in pixels from the bead center from which to start sampling profiles. Default 1...
Definition: qtrk_c_api.h:135
static void TestBSplineMax(float maxpos)
Definition: main.cpp:717
void BuildConvergenceMap(int iterations)
Definition: main.cpp:256
virtual int ScheduleFrame(void *imgptr, int pitch, int width, int height, ROIPosition *positions, int numROI, QTRK_PixelDataType pdt, const LocalizationJob *jobInfo)
Schedule an entire frame at once, allowing for further optimizations.
float BackgroundRMS(ImageData img)
Definition: testutils.cpp:258
std::vector< float > ComputeRadialWeights(int rsteps, float minRadius, float maxRadius)
Definition: main.cpp:365
void GetOuterEdges(float *out, int size, ImageData img)
Definition: testutils.cpp:212
int localizationsDone
Amount of localizations finished by the linked QueuedTracker instance.
void GenerateTestImage(ImageData &img, float xp, float yp, float size, float SNratio)
Definition: utils.cpp:162
int numBeads
Number of beads for which to grab results. Should always equal the amount of beads in a single frame...
Definition: ResultManager.h:64
static double WaitForFinish(QueuedTracker *qtrk, int N)
Definition: SharedTests.h:300
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.
64 bit float
Definition: qtrk_c_api.h:37
void SmallImageTest()
Definition: main.cpp:149
TImageData< float > ImageData
Definition: QueuedTracker.h:69
void FinalizeLUT() override
Finalize the lookup tables in memory.
std::string folder
Definition: testutils.h:39
void Compute(const std::vector< vector3f > &results, std::function< vector3f(int x) > truepos)
Definition: SharedTests.h:473
int NumJpgInDir(const std::string &dirName_in)
Definition: testutils.cpp:42
void dbgout(const std::string &s)
Definition: utils.cpp:143
void outputImage(ImageData img, std::string filename="UsedImage")
Definition: testutils.cpp:82
void TestBoundCheck()
Definition: main.cpp:205
float qi_minradius
Distance in pixels from the bead center from which to start sampling profiles. Default 1...
Definition: qtrk_c_api.h:141
int width
Width of regions of interest to be handled. Typically equals height (square ROI). ...
Definition: qtrk_c_api.h:106
vector3f scaling
Scaling factor for each of the three dimensions.
Definition: ResultManager.h:71
uint maxFramesInMemory
Number of frames for which to keep the data in memory. 0 for infinite.
Definition: ResultManager.h:80
int processedFrames
Number of frames processed by the ResultManager.
Tests
Definition: main.cpp:1267
void RunTest(Tests test, const char *image, outputter *output, int ROISize)
Definition: main.cpp:1274
static void CleanupLUT(ImageData &lut)
void outputString(std::string out, bool ConsoleOnly=false)
Definition: testutils.cpp:70
void ResampleLUT(T *qtrk, ImageData *lut, int zplanes, ImageData *newlut, const char *jpgfile=0, uint buildLUTFlags=0)
Definition: SharedTests.h:35
void PixelationErrorTest()
Definition: main.cpp:232
Struct used to define the top-left corner position of an ROI within a frame. ROI is [ x ...
Definition: qtrk_c_api.h:178
Class with all CPU algorithm implementations.
Definition: cpu_tracker.h:38
ImageData ReadLUTFile(const char *lutfile)
Definition: utils.cpp:720
void GenerateZLUTFittingCurve(const char *lutfile)
Definition: main.cpp:728
void Flush() override
Stop waiting for more jobs to do, and just process the current batch.
unsigned int uint
Definition: std_incl.h:127
vector3f offset
Offset value for each of the three dimensions.
Definition: ResultManager.h:78
void TestZLUTAlign()
Definition: main.cpp:649
void ManTest()
Definition: main.cpp:1313
void GenerateImageFromLUT(ImageData *image, ImageData *zlut, float minradius, float maxradius, vector3f pos, bool splineInterp, int oversampleSubdiv)
Definition: utils.cpp:354
void WriteJPEGFile(uchar *data, int w, int h, const char *filename, int quality)
Definition: fastjpg.cpp:89
bool testRun
Flag to run a test run.
Definition: qtrk_c_api.h:174
ImageData AddImages(ImageData img1, ImageData img2, vector2f displacement)
Definition: testutils.cpp:164
int FetchResults(LocalizationResult *dstResult, int maxResults) override
Fetch available results.
float distance(vector2f a, vector2f b)
Definition: testutils.cpp:10
void BeginLUT(uint flags)
Setup to begin building a lookup table.
Structure for job results.
Definition: qtrk_c_api.h:67
void BuildZLUT(std::string folder, outputter *output)
Definition: main.cpp:997
int height
Height of regions of interest to be handled. Typically equals width (square ROI). ...
Definition: qtrk_c_api.h:107
int GetResultCount() override
Get the number of finished localization jobs (=results) available in memory.
Definition: main.cpp:1270
int height
ROI height.
Definition: cpu_tracker.h:42
vector2< float > vector2f
Definition: std_incl.h:39
void ClearResults() override
Clear results.
vector2< T > xy()
Definition: std_incl.h:104
Structure for the settings used by the algorithms implemented in QueuedTracker.
Definition: qtrk_c_api.h:82
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.
int zlut_radialsteps
Number of radial steps to sample on.
Definition: qtrk_c_api.h:198
vector3< T > sqrt(const vector3< T > &a)
Definition: std_incl.h:112
void RescaleLUT(CPUTracker *trk, ImageData *lut)
Definition: main.cpp:31
std::vector< Position > Find(ImageData *img, float *sample, Config *cfg)
Definition: BeadFinder.cpp:168
void SetImage8Bit(uchar *srcImage, uint srcpitch)
Set an image with 8 bit type.
Definition: cpu_tracker.h:254
float imageMean
Average pixel value of the ROI.
Definition: qtrk_c_api.h:73
Class that handles data gathering and saving from QueuedTracker instances.
Definition: ResultManager.h:91
Structure to keep track of frame counts.
virtual void SetLocalizationMode(LocMode_t locType)=0
Select which algorithm is to be used.
uint frame
Frame number this ROI belongs to.
Definition: qtrk_c_api.h:56
int numFrameInfoColumns
Number of columns in the frame info metadata file. Additional columns can be added to save more data ...
Definition: ResultManager.h:65
static TImageData alloc(int w, int h)
Definition: utils.h:110
double GetPreciseTime()
Definition: utils.cpp:669
void normalize()
Definition: utils.h:101
float SkewParam(ImageData img)
Definition: main.cpp:901
int LocMode_t
Definition: qtrk_c_api.h:30
float & GetPixel(int x, int y)
Get the image pixel greyscale value at point (x,y).
Definition: cpu_tracker.h:122
T Lerp(T a, T b, float x)
Definition: utils.h:40
Definition: main.cpp:1271
void TestROIDisplacement(std::vector< BeadPos > beads, ImageData oriImg, outputter *output, int ROISize, int maxdisplacement=0)
Definition: main.cpp:915
COM+XCor1D.
Definition: qtrk_c_api.h:8
vector2f ComputeMeanAndCOM(float bgcorrection=0.0f)
Calculate the center of mass of the image.
std::vector< uchar > ReadToByteBuffer(const char *filename)
Definition: utils.cpp:608
int main()
Definition: main.cpp:1509
std::vector< float > ComputeRadialBinWindow(int rsteps)
Calculate the radial weights for ZLUT profile comparisons.
Definition: utils.cpp:706
Matrix3X3 Inverse() const
Definition: utils.h:298
int lostFrames
Number of frames deleted from memory before results were finished and/or saved.
void Update()
Compute the derived settings.
void TestZRange(const char *name, const char *lutfile, int extraFlags, int clean_lut, RWeightMode weightMode=RWNone, bool biasMap=false, bool biasCorrect=false)
Definition: main.cpp:452
float * srcImage
Memory region that holds the image on which tracking is to be performed.
Definition: cpu_tracker.h:46
const bool InDebugMode
Definition: main.cpp:23
Make a fourier based lookup table.
Definition: qtrk_c_api.h:24
vector3f pos
Final 3D position found. If no z localization was performed, the value of z will be 0...
Definition: qtrk_c_api.h:69
int xcorw
Cross correlation profile length.
Definition: cpu_tracker.h:43
void TestZRangeBias(const char *name, const char *lutfile, bool normProf)
Definition: main.cpp:413
RWeightMode
Definition: main.cpp:450
Enable z localization.
Definition: qtrk_c_api.h:21
void SpeedTest()
Definition: main.cpp:36
float com_bgcorrection
Background correction factor for COM. Defines the number of standard deviations data needs to be away...
Definition: qtrk_c_api.h:133
vector3f crlb
Definition: SharedTests.h:471
void TestInterference(std::vector< BeadPos > beads, ImageData oriImg, outputter *output, int ROISize, vector2f displacement=vector2f(60, 0))
Definition: main.cpp:935
void CorrectedRadialProfileTest()
Definition: main.cpp:319
float mean
Mean intensity of the ROI. Calculated in ComputeMeanAndCOM.
Definition: cpu_tracker.h:48
ImageData CropImage(ImageData img, int x, int y, int w, int h)
Definition: testutils.cpp:132
float qi_maxradius
Max radius in pixels of the sampling circle.
Definition: qtrk_c_api.h:204
Normalize found radial profiles.
Definition: qtrk_c_api.h:22
vector3f diag() const
Definition: utils.h:277
void SetRadialZLUT(float *data, int num_zluts, int planes) override
Set the radial lookup tables to be used for z tracking.
float * GetZLUTByIndex(int index)
Get a pointer to the starting pixel of the specified LUT.
float BackgroundMedian(ImageData img)
Definition: testutils.cpp:235
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.
Definition: cpu_tracker.h:319
virtual void ScheduleLocalization(void *data, int pitch, QTRK_PixelDataType pdt, const LocalizationJob *jobInfo)=0
Add a job to the queue to be processed. A job entails running the required algorithms on a single reg...
LocalizationJob job
Job metadata. See LocalizationJob.
Definition: qtrk_c_api.h:68
CPU implementation of the QueuedTracker interface.
Structure for settings used by ResultManager.
Definition: ResultManager.h:62
QTrkComputedConfig cfg
The settings used by this instance of QueuedTracker.
std::vector< T > linspace(T a, T b, int N)
Definition: SharedTests.h:461
void free()
Definition: utils.h:111
void SetTracker(QueuedTracker *qtrk)
Set the tracker from which to fetch results.
void SetLocalizationMode(LocMode_t lt) override
Select which algorithm is to be used.
int ReadJPEGFile(uchar *srcbuf, int srclen, uchar **data, int *width, int *height)
Definition: fastjpg.cpp:12
float zlut_roi_coverage
Factor of the ROI to include in sampling. Between 0 and 1, default 1. Maxradius = ROI/2*roi_coverage...
Definition: qtrk_c_api.h:138
vector2f ComputeXCorInterpolated(vector2f initial, int iterations, int profileWidth, bool &boundaryHit)
Compute the cross correlation offsets and resulting position.
void SelectTests(const char *image, int OutputMode)
Definition: main.cpp:1436
int GetWidth()
Get the width of the image.
Definition: cpu_tracker.h:123
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.
void TestFourierLUT()
Definition: main.cpp:612
Definition: main.cpp:450
int capturedFrames
Number of frames captured. Counted through calls to StoreFrameInfo.
#define ALLOCA_ARRAY(T, N)
Definition: std_incl.h:153
void Flush()
Write all available data regardless of ResultManagerConfig::writeInterval.
float qi_radial_coverage
Sampling points per radial pixel. Default 3.0.
Definition: qtrk_c_api.h:142
Structure for derived settings computed from base settings in QTrkSettings.
Definition: qtrk_c_api.h:189
const float ANGSTEPF
Definition: main.cpp:21
float zlut_angular_coverage
Factor of the sampling perimeter to cover with angular sampling steps. Between 0 and 1...
Definition: qtrk_c_api.h:137
FrameCounters GetFrameCounters()
Returns a FrameCounters structure with the current counts.
void SetRadialWeights(float *rweights) override
Set radial weights used for comparing LUT profiles.
Default. Use a 7-point quadratic fit around the error curve&#39;s maximum.
Definition: cpu_tracker.h:379
int h
Definition: utils.h:81
void BuildLUT(void *data, int pitch, QTRK_PixelDataType pdt, int plane, vector2f *known_pos=0) override
Add a new lookup table plane.
static SpeedAccResult AccBiasTest(ImageData &lut, QueuedTracker *trk, int N, vector3f centerpos, vector3f range, const char *name, int MaxPixelValue, int extraFlags=0)
Definition: main.cpp:767
int GetHeight()
Get the height of the image.
Definition: cpu_tracker.h:124
vector2f firstGuess
(x,y) position found by the COM localization. Used as initial position for the subsequent algorithms...
Definition: qtrk_c_api.h:71
void PrintMenu(outputter *output)
Definition: main.cpp:1422
COM+QI.
Definition: qtrk_c_api.h:9
float qi_roi_coverage
Factor of the ROI to include in sampling. Between 0 and 1, default 1. Maxradius = ROI/2*roi_coverage...
Definition: qtrk_c_api.h:144
void TestBias()
Definition: main.cpp:373
vector3< float > vector3f
Definition: std_incl.h:114
void dbgprintf(const char *fmt,...)
Definition: utils.cpp:149
float CUDA_SUPPORTED_FUNC ComputeSplineFitMaxPos(T *data, int len)
Definition: CubicBSpline.h:55
int qi_iterations
Number of times to run the QI algorithm, sampling around the last found position. ...
Definition: qtrk_c_api.h:140
void TestBackground(std::vector< BeadPos > beads, ImageData oriImg, outputter *output, int ROISize)
Definition: main.cpp:976
void TestQuadrantAlign()
Definition: main.cpp:672
void ComputeCRP(float *dst, int radialSteps, int angularSteps, float minradius, float maxradius, vector2f center, ImageData *img, float paddingValue, float *crpmap)
Definition: utils.cpp:181
void ScatterBiasArea(int roi, float scan_width, int steps, int samples, int qi_it, float angstep)
Definition: main.cpp:817
int xc1_iterations
Number of times to run the cross correlation algorithm.
Definition: qtrk_c_api.h:161
int writeInterval
Interval of number of gathered frames at which to write the data.
Definition: ResultManager.h:79
Enable ZLUT align.
Definition: qtrk_c_api.h:19
void AutoBeadFindTest()
Definition: main.cpp:589
float qi_angstep_factor
Factor to reduce angular steps on lower iterations. Default 1.0 (no effect).
Definition: qtrk_c_api.h:157
void FloatToJPEGFile(const char *name, const float *d, int w, int h)
Definition: fastjpg.cpp:189
void CRP_TestGeneratedData()
Definition: main.cpp:306
void BenchmarkParams()
Definition: Benchmark.cpp:120
void ComputeRadialProfile(float *dst, int radialSteps, int angularSteps, float minradius, float maxradius, vector2f center, ImageData *img, float mean, bool normalize)
Definition: utils.cpp:298
void ComputeZBiasCorrection(int bias_planes, CImageData *result, int smpPerPixel, bool useSplineInterp)
int GetQueueLength(int *maxQueueLength=0) override
Get the lengths of the queue of jobs to be handled.
uint8_t binaryOutput
Flag (boolean) to output a binary file instead of a text file.
Definition: ResultManager.h:81
void OutputProfileImg()
Definition: main.cpp:178
T StdDeviation(T *start, T *end)
Definition: utils.h:139
void RunZTrace(std::string imagePath, std::string zlutPath, outputter *output)
Definition: main.cpp:1086
int xc1_profileWidth
Profile width for the cross correlation.
Definition: qtrk_c_api.h:160
void newFile(std::string filename, const char *mode="a")
Definition: testutils.cpp:89
ImageData SkewImage(ImageData img, float fact)
Definition: testutils.cpp:194
virtual int FetchResults(LocalizationResult *results, int maxResults)=0
Fetch available results.
void WriteToFile()
Write all settings to specified output file (Jordi, to combine with QTrkSettings.testRun) ...
float BackgroundStdDev(ImageData img)
Definition: testutils.cpp:249
float * GetDebugImage()
Get the debug image.
Definition: cpu_tracker.h:440
void SimpleTest()
Definition: main.cpp:703
void RunCOMAndQI(ImageData img, outputter *output)
Definition: main.cpp:876
void WriteImageAsCSV(const char *file, float *d, int w, int h, const char *labels[])
Definition: utils.cpp:551
Abstract tracker interface, implemented by QueuedCUDATracker and QueuedCPUTracker.
Definition: QueuedTracker.h:86
Definition: main.cpp:1269
void ScheduleImageData(ImageData *data, const LocalizationJob *jobInfo)
Quick function to schedule a single ROI from an ImageData object.
void TestSkew(std::vector< BeadPos > beads, ImageData oriImg, outputter *output, int ROISize)
Definition: main.cpp:956
Matrix3X3 Compute(vector3f pos, vector3f delta, ImageData &lut, int w, int h, float zlutMinRadius, float zlutMaxRadius)
Definition: FisherMatrix.h:38
int numThreads
Number of threads/streams to use. Defaults differ between CPU and GPU implementations.
Definition: qtrk_c_api.h:114
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.
float zlut_radial_coverage
Sampling points per radial pixel. Default 3.0.
Definition: qtrk_c_api.h:136
float qi_angular_coverage
Factor of the sampling perimeter to cover with angular sampling steps. Between 0 and 1...
Definition: qtrk_c_api.h:143
float ComputeAsymmetry(vector2f center, int radialSteps, int angularSteps, float minRadius, float maxRadius, float *dstAngProf=0)
Find a measure for the asymmetry of the ROI.
Structure for region of interest metadata.
Definition: qtrk_c_api.h:49
int xc1_profileLength
Profile length for the cross correlation.
Definition: qtrk_c_api.h:159
int zlut_angularsteps
Number of angular steps to sample on.
Definition: qtrk_c_api.h:199
float zlut_maxradius
Max radius in pixels of the sampling circle.
Definition: qtrk_c_api.h:200
unsigned char uchar
Definition: std_incl.h:130
void WriteRadialProf(const char *file, ImageData &d)
Definition: main.cpp:350
void TestFourierLUTOnDataset()
Definition: main.cpp:638
void SetImageFloat(float *srcImage)
Set an image with float type.
Definition: cpu_tracker.cpp:88
std::string SPrintf(const char *fmt,...)
Definition: utils.cpp:132
Do a ZLUT lookup with adjusted weights, for testing purposes.
Definition: qtrk_c_api.h:25
T * data
Definition: utils.h:80
int w
Definition: utils.h:81
void NormalizeZLUT(float *zlut, int numBeads, int planes, int radialsteps)
Definition: utils.cpp:291
void OnePixelTest()
Definition: main.cpp:131
int width
ROI width.
Definition: cpu_tracker.h:41
void ApplyPoissonNoise(ImageData &img, float poissonMax, float maxval)
Definition: utils.cpp:432