Ignore:
Timestamp:
07/16/06 01:38:53 (18 years ago)
Author:
tbretz
Message:
*** empty log message ***
Location:
trunk/MagicSoft/Cosy/videodev
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/MagicSoft/Cosy/videodev/FilterLed.cc

    r7790 r7794  
    1111
    1212ClassImp(FilterLed);
     13
     14class ClusterFinder
     15{
     16private:
     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
     74public:
     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
    13146
    14147void FilterLed::DrawBox(const int x1, const int y1,
     
    33166void FilterLed::MarkPoint(const Led &led) const
    34167{
     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
    35179    const int x = (int)(led.GetX()+.5);
    36180    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);
    40183}
    41184
     
    164307            maxx=dx;
    165308            maxy=dy;
    166             max =sum;
     309            max =sumloc;
    167310        }
    168311    }
     
    170313    // 2. Calculate mean position inside a circle around
    171314    // 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);
    196325
    197326    return (int)my*fW + (int)mx;
     
    204333    unsigned int sum;
    205334    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                 continuel
    223 
    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: Interpolation
    235                 leds.Remove(led2);
    236             }
    237         }
    238     }
    239 }
    240 */
    241 void FilterLed::RemoveTwinsInterpol(Leds &leds, Int_t first, Double_t radius) const
    242 {
    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 weihgt
    283             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();
    309335}
    310336
     
    344370}
    345371
    346 class ClusterFinder
    347 {
    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 cluster
    367         if (x<fX0 || x>=fX1 || y<fY0 || y>=fY1)
    368             return -1;
    369 
    370         if (fCount>999)
    371             return -1;
    372 
    373         // get the value
    374         Float_t val = fImg[y*fW+x];
    375 
    376         // if its empty we have found the border of the cluster
    377         if (val==0)
    378             return 0;
    379 
    380         // mark the point as processed
    381         fImg[y*fW+x] = 0;
    382 
    383         fSumX += x*val; // sumx
    384         fSumY += y*val; // sumy
    385         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 touched
    396                 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 
    456372void FilterLed::Execute(Leds &leds, int xc, int yc, double &bright) const
    457373{
     
    506422}
    507423
    508 /*
    509 void FilterLed::Execute(Leds &leds, int xc, int yc, double &bright) const
    510 {
    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<max
    538     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 noise
    543     // (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 points
    555     //
    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 array
    599     //
    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 */
    617424void FilterLed::FindStar(Leds &leds, int xc, int yc, bool box) const
    618425{
     
    714521        return;
    715522
    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;
    718525
    719526    leds.Add(mx, my, 0, 0, -2.5*log10((float)mag)+13.7);
  • trunk/MagicSoft/Cosy/videodev/FilterLed.h

    r7790 r7794  
    3434                            unsigned int &sum) const;
    3535
    36     void RemoveTwinsInterpol(Leds &leds, Int_t first, Double_t radius) const;
    3736    void DrawBox(const int x1, const int y1,
    3837                 const int x2, const int y2,
Note: See TracChangeset for help on using the changeset viewer.