Ignore:
Timestamp:
07/28/05 22:24:32 (19 years ago)
Author:
fgoebel
Message:
*** empty log message ***
File:
1 edited

Legend:

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

    r4865 r7230  
    120120    return GetMeanPosition(x, y, box, mx, my, sum);
    121121}
     122
     123int FilterLed::GetMeanPositionCircle(const int x, const int y,
     124                                     const int box, float &mx,
     125                                     float &my, unsigned int &sum) const
     126{
     127    unsigned int sumx=0;
     128    unsigned int sumy=0;
     129
     130    //-------------------------------
     131    // Improved algorithm:
     132    // 1. Look for the largest four-pixel signal inside box
     133
     134    int thissum=0, maxsum=0;
     135    int maxx=0, maxy=0;
     136    for (int dx=x-box; dx<x+box+1; dx++)
     137        for (int dy=y-box; dy<y+box+1; dy++)
     138        {
     139            thissum = fImg[dy*fW+dx]+fImg[(dy+1)*fW+dx]+
     140              fImg[dy*fW+(dx+1)]+fImg[(dy+1)*fW+(dx+1)];
     141            if(thissum>maxsum)
     142              {
     143                maxx=dx;
     144                maxy=dy;
     145                maxsum=thissum;
     146              }
     147        }
     148
     149    // 2. Calculate mean position inside a circle around
     150    // the highst four-pixel signal with radius of 5 pixels.
     151
     152    sum=0;
     153    for (int dx=x-box; dx<x+box+1; dx++)
     154        for (int dy=y-box; dy<y+box+1; dy++)
     155        {
     156            const byte &m = fImg[dy*fW+dx];
     157
     158            // Circle
     159            if(sqrt((dx-maxx)*(dx-maxx)+
     160                    (dy-maxy)*(dy-maxy)) <= 6)
     161              {
     162                sumx += m*dx;
     163                sumy += m*dy;
     164                sum  += m;
     165              }
     166        }
     167
     168    mx = (float)sumx/sum;
     169    my = (float)sumy/sum;
     170
     171    return (int)my*fW + (int)mx;
     172}
     173
     174
     175
     176int FilterLed::GetMeanPositionCircle(const int x, const int y,
     177                                     const int box) const
     178{
     179    float mx, my;
     180    unsigned int sum;
     181    return GetMeanPositionCircle(x, y, box, mx, my, sum);
     182}
     183
     184
    122185/*
    123186void FilterLed::RemoveTwins(Leds &leds, Double_t radius)
     
    486549}
    487550
     551void FilterLed::FindStarCircle(Leds &leds, int xc, int yc) const
     552{
     553    // fBox: radius of the inner (signal) box
     554    // Radius of the outer box is fBox*sqrt(2)
     555
     556    //
     557    // Define inner box in which to search the signal
     558    //
     559    int x0 = xc-fBox;
     560    int x1 = xc+fBox;
     561    int y0 = yc-fBox;
     562    int y1 = yc+fBox;
     563
     564    if (x0<0) x0=0;
     565    if (y0<0) y0=0;
     566    if (x1>fW) x1=fW;
     567    if (y1>fH) y1=fH;
     568
     569    //
     570    // Define outer box (excluding inner box) having almost
     571    // the same number of pixels in which the background
     572    // is calculated
     573    //
     574    const double sqrt2 = sqrt(2.);
     575
     576    int xa = xc-(int)rint(fBox*sqrt2);
     577    int xb = xc+(int)rint(fBox*sqrt2);
     578    int ya = yc-(int)rint(fBox*sqrt2);
     579    int yb = yc+(int)rint(fBox*sqrt2);
     580
     581    if (xa<0) xa=0;
     582    if (ya<0) ya=0;
     583    if (xb>fW) xb=fW;
     584    if (yb>fH) yb=fH;
     585
     586    //
     587    // Calculate average and sdev for a square
     588    // excluding the inner part were we expect
     589    // the signal to be.
     590    //
     591    double sum = 0;
     592    double sq  = 0;
     593
     594    int n=0;
     595    for (int x=xa; x<xb; x++)
     596        for (int y=ya; y<yb; y++)
     597        {
     598            if (x>=x0 && x<x1 && y>=y0 && y<y1)
     599                continue;
     600
     601            byte &b = fImg[y*fW+x];
     602
     603            sum += b;
     604            sq  += b*b;
     605            n++;
     606        }
     607
     608    sum /= n;
     609    sq  /= n;
     610
     611    // 254 because b<=max and not b<max
     612    const double sdev = sqrt(sq-sum*sum);
     613    const byte   max  = sum+fCut*sdev>254 ? 254 : (byte)(sum+fCut*sdev);
     614
     615    //
     616    // clean image from noise
     617    // (FIXME: A lookup table could accelerate things...
     618    //
     619    n=0;
     620    for (int x=x0; x<x1; x++)
     621        for (int y=y0; y<y1; y++)
     622        {
     623            byte &b = fImg[y*fW+x];
     624            if (b<=max)
     625                b = 0;
     626            else
     627                n++;
     628        }
     629
     630    //
     631    // Mark the background region
     632    //
     633    for (int x=xa; x<xb; x+=2)
     634    {
     635        fImg[ya*fW+x]=0xf0;
     636        fImg[yb*fW+x]=0xf0;
     637    }
     638    for (int y=ya; y<yb; y+=2)
     639    {
     640        fImg[y*fW+xa]=0xf0;
     641        fImg[y*fW+xb]=0xf0;
     642    }
     643
     644    //
     645    // Check if any pixel found...
     646    //
     647    if (n<5)
     648        return;
     649
     650    //
     651    // Get the mean position of the star
     652    //
     653    float mx, my;
     654    unsigned int mag;
     655
     656    //    int pos = GetMeanPosition(xc, yc, fBox-1, mx, my, mag);
     657
     658    // try new method
     659    int pos = GetMeanPositionCircle(xc, yc, fBox-1, mx, my, mag);
     660   
     661    if (pos<0 || pos>=fW*fH && fImg[pos]<sum+fCut*sdev)
     662        return;
     663
     664    cout << "Mean=" << sum << "  SDev=" << sdev << "  :  ";
     665    cout << "Sum/n = " << sum << "/" << n << " = " << (n==0?0:mag/n) << endl;
     666
     667    leds.Add(mx, my, 0, 0, -2.5*log10((float)mag)+13.7);
     668}
     669
     670
    488671void FilterLed::Stretch() const
    489672{
Note: See TracChangeset for help on using the changeset viewer.