Changeset 7794 for trunk/MagicSoft/Cosy/videodev
- Timestamp:
- 07/16/06 01:38:53 (18 years ago)
- Location:
- trunk/MagicSoft/Cosy/videodev
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/Cosy/videodev/FilterLed.cc
r7790 r7794 11 11 12 12 ClassImp(FilterLed); 13 14 class ClusterFinder 15 { 16 private: 17 byte *fImg; 18 19 UInt_t fW; 20 UInt_t fH; 21 22 Int_t fX0; 23 Int_t fX1; 24 25 Int_t fY0; 26 Int_t fY1; 27 28 UInt_t fLimitingSize; 29 30 UInt_t fCount; 31 Float_t fSumX; 32 Float_t fSumY; 33 34 Float_t FindCluster(Int_t x, Int_t y) 35 { 36 // if edge is touched stop finding cluster 37 if (x<fX0 || x>=fX1 || y<fY0 || y>=fY1) 38 return -1; 39 40 if (fCount>fLimitingSize) 41 return -2; 42 43 // get the value 44 Float_t val = fImg[y*fW+x]; 45 46 // if its empty we have found the border of the cluster 47 if (val==0) 48 return 0; 49 50 // mark the point as processed 51 fImg[y*fW+x] = 0; 52 53 fSumX += x*val; // sumx 54 fSumY += y*val; // sumy 55 fCount++; 56 57 Float_t rc[4]; 58 rc[0] = FindCluster(x+1, y ); 59 rc[1] = FindCluster(x, y+1); 60 rc[2] = FindCluster(x-1, y ); 61 rc[3] = FindCluster(x, y-1); 62 63 for (int i=0; i<4; i++) 64 { 65 if (rc[i]<0) // check if edge is touched 66 return rc[i]; 67 68 val += rc[i]; 69 } 70 71 return val; 72 } 73 74 public: 75 ClusterFinder(byte *img, UInt_t w, UInt_t h) : fLimitingSize(999) 76 { 77 fW = w; 78 fH = h; 79 80 fX0 = 0; 81 fY0 = 0; 82 fX1 = fW; 83 fY1 = fH; 84 85 fImg = new byte[fW*fH]; 86 87 memcpy(fImg, img, fW*fH); 88 } 89 90 ~ClusterFinder() 91 { 92 delete fImg; 93 } 94 Double_t GetSumX() const { return fSumX; } 95 Double_t GetSumY() const { return fSumY; } 96 97 UInt_t GetCount() const { return fCount; } 98 99 void SetLimitingSize(UInt_t lim) { fLimitingSize=lim; } 100 101 Float_t FindClusterAt(Int_t x, Int_t y) 102 { 103 fCount = 0; 104 fSumX = 0; 105 fSumY = 0; 106 107 return FindCluster(x, y); 108 } 109 110 void SetRange(Int_t x0=0, Int_t y0=0, Int_t x1=0, Int_t y1=0) 111 { 112 fX0 = x0; 113 fY0 = y0; 114 fX1 = x1==0?fW:x1; 115 fY1 = y1==0?fH:y1; 116 } 117 118 void FindCluster(Leds &leds, Int_t x0=0, Int_t y0=0, Int_t x1=0, Int_t y1=0) 119 { 120 fX0 = x0; 121 fY0 = y0; 122 fX1 = x1==0?fW:x1; 123 fY1 = y1==0?fH:y1; 124 125 for (Int_t x=fX0; x<fX1; x++) 126 for (Int_t y=fY0; y<fY1; y++) 127 { 128 const byte &b = fImg[y*fW+x]; 129 if (b==0) 130 continue; 131 132 const Float_t mag = FindClusterAt(x, y); 133 if (fCount>999) 134 { 135 cout << "ERROR - Spot with Size>999 detected..." << endl; 136 return; 137 } 138 139 if (mag>0 && fCount>6) 140 leds.Add(fSumX/mag, fSumY/mag, 0, 0, mag); 141 } 142 leds.Compress(); 143 } 144 }; 145 13 146 14 147 void FilterLed::DrawBox(const int x1, const int y1, … … 33 166 void FilterLed::MarkPoint(const Led &led) const 34 167 { 168 /* 169 Int_t M = (int)(log(led.GetMag())*20); 170 171 cout << led.GetMag() << endl; 172 173 if (M>0xff) 174 M=0xff; 175 if (M<0xc0) 176 M=0xc0; 177 */ 178 35 179 const int x = (int)(led.GetX()+.5); 36 180 const int y = (int)(led.GetY()+.5); 37 const int m = (int)(led.GetMag()); 38 39 MarkPoint(x, y, m); 181 182 MarkPoint(x, y, 0xff); 40 183 } 41 184 … … 164 307 maxx=dx; 165 308 maxy=dy; 166 max =sum ;309 max =sumloc; 167 310 } 168 311 } … … 170 313 // 2. Calculate mean position inside a circle around 171 314 // the highst cross-signal with radius of 6 pixels. 172 unsigned int sumx=0; 173 unsigned int sumy=0; 174 175 const int rad = 17; 176 177 x0 = TMath::Max(x-box, maxx-rad); 178 y0 = TMath::Max(y-box, maxy-rad); 179 180 x1 = TMath::Min(x+box+1, maxx+rad+1); 181 y1 = TMath::Min(y+box+1, maxy+rad+1); 182 183 sum=0; 184 for (int dx=x0; dx<x1; dx++) 185 for (int dy=y0; dy<y1; dy++) 186 { 187 const byte &m = fImg[dy*fW+dx]; 188 189 sumx += m*dx; 190 sumy += m*dy; 191 sum += m; 192 } 193 194 mx = (float)sumx/sum; 195 my = (float)sumy/sum; 315 ClusterFinder find(fImg, fW, fH); 316 find.SetLimitingSize(9999); 317 find.SetRange(x0, y0, x1, y1); 318 319 const Float_t mag = find.FindClusterAt(maxx, maxy); 320 321 mx = find.GetSumX()/mag; 322 my = find.GetSumY()/mag; 323 324 sum = (int)(mag+0.5); 196 325 197 326 return (int)my*fW + (int)mx; … … 204 333 unsigned int sum; 205 334 return GetMeanPositionBox(x, y, box, mx, my, sum); 206 }207 208 209 /*210 void FilterLed::RemoveTwins(Leds &leds, Double_t radius)211 {212 for (int i=first; i<leds.GetEntriesFast(); i++)213 {214 const Led &led1 = leds(i);215 216 const Double_t x1 = led1.GetX();217 const Double_t y1 = led1.GetY();218 219 for (int j=first; j<leds.GetEntriesFast(); j++)220 {221 if (j==i)222 continuel223 224 const Led &led2 = leds(j);225 226 const Double_t x2 = led2.GetX();227 const Double_t y2 = led2.GetY();228 229 const Double_t dx = x2-x1;230 const Double_t dy = y2-y1;231 232 if (dx*dx+dy*dy<radius*radius)233 {234 // FIXME: Interpolation235 leds.Remove(led2);236 }237 }238 }239 }240 */241 void FilterLed::RemoveTwinsInterpol(Leds &leds, Int_t first, Double_t radius) const242 {243 const Int_t num=leds.GetEntriesFast();244 245 for (int i=first; i<num; i++)246 {247 Led *led1 = (Led*)leds.UncheckedAt(i);248 if (!led1)249 continue;250 251 const Double_t x1 = led1->GetX();252 const Double_t y1 = led1->GetY();253 254 Double_t mag = led1->GetMag();255 Double_t x = x1*mag;256 Double_t y = y1*mag;257 258 Double_t sqm = mag*mag;259 Double_t sqx = x*x;260 Double_t sqy = y*y;261 262 Int_t n=1;263 264 for (int j=first; j<num; j++)265 {266 if (i==j)267 continue;268 269 Led *led2 = (Led*)leds.UncheckedAt(j);270 if (!led2)271 continue;272 273 Double_t x2 = led2->GetX();274 Double_t y2 = led2->GetY();275 276 const Double_t dx = x2-x1;277 const Double_t dy = y2-y1;278 279 if (dx*dx+dy*dy>radius*radius)280 continue;281 282 // Multiply with weihgt283 const Double_t w = led2->GetMag();284 x2 *= w;285 y2 *= w;286 287 x += x2;288 y += y2;289 mag += w;290 291 sqx += x2*x2;292 sqy += y2*y2;293 sqm += w*w;294 295 n++;296 leds.Remove(led2);297 }298 299 x /= mag;300 y /= mag;301 302 sqx /= sqm;303 sqy /= sqm;304 305 leds.Add(x, y, 0/*sqrt(sqx-x*x)*/, 0/*sqrt(sqy-y*y)*/, mag/n);306 leds.Remove(led1);307 }308 leds.Compress();309 335 } 310 336 … … 344 370 } 345 371 346 class ClusterFinder347 {348 private:349 byte *fImg;350 351 UInt_t fW;352 UInt_t fH;353 354 Int_t fX0;355 Int_t fX1;356 357 Int_t fY0;358 Int_t fY1;359 360 UInt_t fCount;361 Float_t fSumX;362 Float_t fSumY;363 364 Float_t FindCluster(Int_t x, Int_t y)365 {366 // if edge is touched stop finding cluster367 if (x<fX0 || x>=fX1 || y<fY0 || y>=fY1)368 return -1;369 370 if (fCount>999)371 return -1;372 373 // get the value374 Float_t val = fImg[y*fW+x];375 376 // if its empty we have found the border of the cluster377 if (val==0)378 return 0;379 380 // mark the point as processed381 fImg[y*fW+x] = 0;382 383 fSumX += x*val; // sumx384 fSumY += y*val; // sumy385 fCount++;386 387 Float_t rc[4];388 rc[0] = FindCluster(x+1, y );389 rc[1] = FindCluster(x, y+1);390 rc[2] = FindCluster(x-1, y );391 rc[3] = FindCluster(x, y-1);392 393 for (int i=0; i<4; i++)394 {395 if (rc[i]<0) // check if edge is touched396 return -1;397 398 val += rc[i];399 }400 401 return val;402 }403 public:404 ClusterFinder(byte *img, UInt_t w, UInt_t h)405 {406 fW = w;407 fH = h;408 409 fImg = new byte[fW*fH];410 411 memcpy(fImg, img, fW*fH);412 }413 414 ~ClusterFinder()415 {416 delete fImg;417 }418 void FindCluster(Leds &leds, Int_t x0=0, Int_t y0=0, Int_t x1=0, Int_t y1=0)419 {420 fX0 = x0;421 fY0 = y0;422 fX1 = x1==0?fW:x1;423 fY1 = y1==0?fH:y1;424 425 for (Int_t x=fX0; x<fX1; x++)426 for (Int_t y=fY0; y<fY1; y++)427 {428 const byte &b = fImg[y*fW+x];429 if (b==0)430 continue;431 432 fCount = 0;433 fSumX = 0;434 fSumY = 0;435 436 const Float_t mag = FindCluster(x, y);437 if (fCount>999)438 {439 cout << "ERROR - Spot with Size>999 detected..." << endl;440 return;441 }442 443 if (mag>0 && fCount>6)444 {445 Float_t M = mag/0xff;446 if (M>0xf0)447 M=0xf0;448 449 leds.Add(fSumX/mag, fSumY/mag, 0, 0, 0xf0);450 }451 }452 leds.Compress();453 }454 };455 456 372 void FilterLed::Execute(Leds &leds, int xc, int yc, double &bright) const 457 373 { … … 506 422 } 507 423 508 /*509 void FilterLed::Execute(Leds &leds, int xc, int yc, double &bright) const510 {511 const int x0 = TMath::Max(xc-fBox, 0);512 const int y0 = TMath::Max(yc-fBox, 0);513 const int x1 = TMath::Min(xc+fBox, fW);514 const int y1 = TMath::Min(yc+fBox, fH);515 516 const int wx = x1-x0;517 const int hy = y1-y0;518 519 double sum = 0;520 double sq = 0;521 522 for (int x=x0; x<x1; x++)523 for (int y=y0; y<y1; y++)524 {525 byte &b = fImg[y*fW+x];526 527 sum += b;528 sq += b*b;529 }530 531 sum /= wx*hy;532 sq /= wx*hy;533 534 bright=sum;535 536 537 // 254 because b<=max and not b<max538 const double sdev = sqrt(sq-sum*sum);539 const byte max = sum+fCut*sdev>254 ? 254 : (byte)(sum+fCut*sdev);540 541 //542 // clean image from noise543 // (FIXME: A lookup table could accelerate things...544 //545 for (int x=x0; x<x1; x++)546 for (int y=y0; y<y1; y++)547 {548 byte &b = fImg[y*fW+x];549 if (b<=max)550 b = 0;551 }552 553 //554 // find mean points555 //556 const int maxpnt = wx*hy>0x4000?0x4000:wx*hy;557 558 int pos[maxpnt]; // (Use 'new' instead for big numbers!)559 byte mag[maxpnt]; // (Use 'new' instead for big numbers!)560 561 const int r = 5;562 563 int cnt = 0;564 for (int x=x0+r; x<x1-r; x++)565 for (int y=y0+r; y<y1-r; y++)566 {567 byte &b = fImg[y*fW+x];568 if (b==0)569 continue;570 571 const int ipos = GetMeanPosition(x, y, r);572 573 int j;574 for (j=0; j<cnt; j++)575 {576 if (pos[j]==ipos)577 {578 if (mag[j]<0xff)579 mag[j]++; // how often found (area)580 break;581 }582 }583 if (cnt && j<cnt)584 continue;585 586 pos[cnt] = ipos;587 mag[cnt] = 1;588 589 cnt++;590 if (cnt==0x4000)591 return;592 }593 594 if (cnt>1000)595 cout << "FIXME: Cnt>1000." << endl;596 597 //598 // Add found positions to array599 //600 const int first=leds.GetEntriesFast();601 602 for (int i=0; i<cnt; i++)603 {604 if (mag[i]<=7)605 continue;606 607 Float_t mx, my;608 unsigned int sum;609 GetMeanPosition(pos[i]%fW, pos[i]/fW, r, mx, my, sum);610 611 leds.Add(mx, my, 0, 0, 0);//mag[i]*10);612 }613 614 RemoveTwinsInterpol(leds, first, r);615 }616 */617 424 void FilterLed::FindStar(Leds &leds, int xc, int yc, bool box) const 618 425 { … … 714 521 return; 715 522 716 cout << "Mean=" << sum << " SDev=" << sdev << " : ";717 cout << "Sum/n = " << sum << "/" << n << " = " << (n==0?0:mag/n) << endl;523 // cout << "Mean=" << sum << " SDev=" << sdev << " : "; 524 // cout << "Sum/n = " << sum << "/" << n << " = " << (n==0?0:mag/n) << endl; 718 525 719 526 leds.Add(mx, my, 0, 0, -2.5*log10((float)mag)+13.7); -
trunk/MagicSoft/Cosy/videodev/FilterLed.h
r7790 r7794 34 34 unsigned int &sum) const; 35 35 36 void RemoveTwinsInterpol(Leds &leds, Int_t first, Double_t radius) const;37 36 void DrawBox(const int x1, const int y1, 38 37 const int x2, const int y2,
Note:
See TracChangeset
for help on using the changeset viewer.