Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Hough.cxx

Go to the documentation of this file.
00001 
00002 // $Id: Hough.cxx,v 1.5 2008/09/11 20:12:15 ishi Exp $
00003 //
00004 // Hough transformation method.
00005 //
00006 // Author:  M. Messier    2006
00007 //          Modified by M. Ishitsuka and S. Cavanaugh in Socal framework
00008 // History  M. Ishitsuka  2007/11/01  import from Socal/MDMReco
00010 #include <cmath>
00011 #include "TH2F.h"
00012 #include "TCanvas.h"
00013 #include "TStyle.h"
00014 #include "TMath.h"
00015 #include "Hough.h"
00016 
00017 using namespace rpr;
00018 
00019 //This hough map uses a unique data structure written by Steve Cavanaugh, May 2007
00020 //Instead of using a TH2F which would result in many empty bins
00021 //  which would be search over many times when looking for a peak,
00022 //  a linked list of bins over the required threshold is instead created -
00023 //  the search for a peak then only looks at bins which are above the threshold
00024 
00025 const static int gsNtheta = 360;
00026 const static int gsNrho   = 500;
00027 
00028 const static double minrho = -500;
00029 const static double maxrho = 500;
00030 const static double mintheta = 0.0;
00031 const static double maxtheta = M_PI;
00032 
00033 float_t myThresh=0;  //will hold tree threshold when tree is first made
00034 
00035 node * nodearray[gsNtheta][gsNrho];
00036 node * thetaarray[gsNtheta];
00037 int thetacount[gsNtheta];
00038 node * treehead =NULL;
00039 
00040 hitnode * peaklist=NULL;
00041 
00042 Hough::Hough() 
00043 {
00044   for(int i=0;i<gsNtheta;i++){
00045     for(int j=0;j<gsNrho;j++)
00046     {
00047       nodearray[i][j]=NULL;
00048     }                   
00049     thetaarray[i]=NULL;
00050     thetacount[i]=0;
00051   }
00052 }
00053 
00054 //......................................................................
00055 
00056 Hough::~Hough() 
00057 {
00058   //make sure to free up all linked list nodes....
00059   
00060   for(int i=0;i<gsNtheta;i++){
00061     if(thetacount[i]>0)DeleteChain(thetaarray[i]);
00062   }
00063   
00064   delete treehead;treehead=NULL;
00065 }
00066 
00067 //......................................................................
00068 
00069 void Hough::SetThresh(float thresh){myThresh=thresh;}
00070 
00071 //......................................................................
00072 
00073 void Hough::MakeTree(float thresh){
00074   
00075   peaklist=NULL;
00076   
00077   myThresh=thresh;
00078   
00079   //need a infinite weight node for insertion sort
00080   if (treehead==NULL)
00081   {
00082     treehead=newNode(-1,-1);
00083     treehead->weight=INFINITY;
00084   }
00085   else treehead->c1=NULL;
00086   
00087   node * toadd=NULL;
00088   
00089   for(int i=0;i<gsNtheta;i++){
00090     toadd=thetaarray[i];
00091     while(toadd!=NULL){
00092       toadd->c1=NULL;
00093       if(toadd->weight>=thresh)
00094       {
00095         if(treehead->c1==NULL)treehead->c1=toadd;
00096         else InsertSort(treehead,toadd);
00097         toadd->goodsort=1;
00098       }
00099       toadd=toadd->c0;
00100     }
00101   }
00102 }
00103 
00104 //......................................................................
00105 
00106 //UpdateTree remakes the tree by resorting and only keeping bins above myThresh
00107 
00108 int Hough::UpdateTree()
00109 {
00110   
00111   //MsgDebug("Rpr","Updating Tree\n");
00112   
00113   node * toadd=NULL;
00114   node * temp = treehead->c1;
00115   node * pretemp = treehead;
00116   
00117   while(temp!=NULL){
00118     
00119     if(temp->weight<myThresh){pretemp->c1=temp->c1;temp->c1=NULL;temp=pretemp->c1;continue;}
00120     
00121     if (temp->goodsort==0){
00122       pretemp->c1=temp->c1;
00123 
00124       if(toadd==NULL)
00125       {
00126         toadd=temp;
00127         toadd->c1=NULL;
00128       }
00129       else
00130       {
00131         temp->c1=toadd;
00132         toadd=temp;
00133       }
00134       
00135       //leave pretemp in place
00136       temp=pretemp->c1;
00137       
00138     }else{
00139       pretemp=pretemp->c1;
00140       temp=pretemp->c1;
00141     }
00142   }
00143   
00144   while(toadd!=NULL){
00145     node * toaddtemp = toadd;
00146     toadd=toadd->c1;
00147     toaddtemp->c1=NULL; 
00148     
00149     toaddtemp->goodsort=1;
00150     if(toaddtemp->weight>=myThresh) InsertSort(treehead,toaddtemp);
00151   }
00152 
00153   if(treehead->c1!=NULL)return 1;
00154   return 0;  
00155 }
00156 
00157 //......................................................................
00158 
00159 void Hough::AddPoint(double theta, double rho, double ww, int ih1)
00160 {
00161   int t = (int)TMath::Floor((theta-mintheta)/(maxtheta-mintheta)*(gsNtheta));
00162   int r = (int)TMath::Floor((rho-minrho)/(maxrho-minrho)*(gsNrho));
00163   
00164   if(r<0||t<0||r>=gsNrho||t>=gsNtheta) return;
00165 
00166   if (nodearray[t][r]==NULL){
00167     nodearray[t][r]=newNode(t,r);
00168     thetacount[t]++;
00169     nodearray[t][r]->c0=thetaarray[t];
00170     thetaarray[t]=nodearray[t][r];
00171   }
00172   
00173   nodeUpdate(nodearray[t][r],ww,ih1);
00174 }
00175 
00176 //......................................................................
00177 
00178 void Hough::RemovePoint(double theta, double rho, double ww, int ih1)
00179 {
00180   int t = (int)TMath::Floor((theta-mintheta)/(maxtheta-mintheta)*(gsNtheta));
00181   int r = (int)TMath::Floor((rho-minrho)/(maxrho-minrho)*(gsNrho));
00182   
00183   if(r<0||t<0||r>=gsNrho||t>=gsNtheta) return;
00184   if(nodearray[t][r]==NULL)return;
00185 
00186   //use this code if keeping list of hits which made up bin
00187   /*
00188     int foundhit=0;
00189     
00190     hitnode * hit = nodearray[t][r]->hitlist;
00191     while(hit!=NULL&&hit->hit==ih1){nodearray[t][r]->hitlist=hit->c0;delete hit;hit=nodearray[t][r]->hitlist;foundhit=1;}
00192     while(hit!=NULL){if(hit->c0==NULL)break;if(hit->c0->hit==ih1){hitnode* t=hit->c0;hit->c0=hit->c0->c0;delete t;foundhit=1;}else hit=hit->c0;}
00193     
00194     if(foundhit==1){
00195     nodearray[t][r]->hitcount--;
00196     }
00197   */
00198   
00199   nodearray[t][r]->goodsort=0;
00200   nodearray[t][r]->weight+=ww;  //ww is <0 here... 
00201 }
00202 
00203 //......................................................................
00204 
00205 int Hough::getHit()
00206 {
00207   int hit=-1;
00208   
00209   if(peaklist!=NULL)
00210   {
00211     hit=peaklist->hit;
00212     peaklist=peaklist->c0;
00213   }
00214   return hit;
00215 }
00216 
00217 //......................................................................
00218 
00219 void Hough::nodeUpdate(node * head, double ww, int ih1)
00220 {
00221   
00222   head->weight+=ww;     
00223   
00224   //use code below to see which hits made up this bin
00225   return;
00226   hitnode *temp = head->hitlist;
00227   while(temp!=NULL){if(temp->hit==ih1){temp->weight+=ww;return;}temp=temp->c0;}
00228 
00229   hitnode *n = new hitnode;
00230   n->hit=ih1;
00231   n->weight=ww;
00232   n->c0=head->hitlist;
00233   head->hitlist=n;
00234   head->hitcount++;
00235 }
00236 
00237 //......................................................................
00238 
00239 node* Hough::newNode(int t, int r)
00240 {
00241   node *temp=new node;
00242   temp->rho=r;
00243   temp->theta=t;
00244   temp->hitcount=0;
00245   temp->weight=0.0;
00246   temp->hitlist=NULL;
00247   temp->c0=NULL;
00248   temp->c1=NULL;
00249   temp->goodsort=0;
00250   temp->treeready=0;
00251   return temp;
00252 }
00253 
00254 //......................................................................
00255 
00256 void Hough::InsertSort(node * head, node *item)
00257 {
00258         while(head->c1!=NULL&&item->weight<head->c1->weight){head=head->c1;}
00259 
00260                 item->c1=head->c1;
00261                 head->c1=item;
00262 }
00263 
00264 //......................................................................
00265 
00266 void Hough::DeleteChain(node *head)
00267 {
00268 
00269         while(head!=NULL)
00270         {
00271                 node *temp = head->c0;
00272                 DeleteChain(head->hitlist);
00273                 delete head;
00274                 head=temp;
00275         }
00276 
00277 }
00278 
00279 //......................................................................
00280 
00281 void Hough::DeleteChain(hitnode * head)
00282 {
00283 
00284         while(head!=NULL)
00285         {
00286                 hitnode *temp=head;
00287                 head=head->c0;
00288                 delete temp;
00289         }
00290 
00291 }
00292 
00294 
00295 //......................................................................
00296 
00297 void Hough::AddPoint(double x1, double sigx1, double x2, double sigx2, 
00298                      double y1, double sigy1, double y2, double sigy2, double w, int ih1) 
00299 {
00300   int itheta;
00301   int ir;
00302   double theta;
00303   double r;
00304   double yy1, yy2;
00305   double ww;
00306 
00307   double theta_segment = (y2!=y1)?
00308     -1.*atan((x2-x1)/(y2-y1)):
00309     M_PI/2.;
00310   if (theta_segment<0.) theta_segment += M_PI;
00311   double r_segment = cos(theta_segment)*x1 + sin(theta_segment)*y1;
00312 
00313   for (itheta=-3; itheta<=3; ++itheta) {
00314     theta = theta_segment + M_PI*(float)(itheta)/(float)(gsNtheta);
00315     if(theta<0.) theta = M_PI - theta;
00316     if(theta>M_PI) theta = theta - M_PI;
00317     for (ir=-3; ir<=3; ++ir) {
00318       r = r_segment + (maxrho-minrho)*(float)(ir)/(float)(gsNrho);  //mod by steve, must multiply by (maxrho-minrho)....
00319       yy1 = (sin(theta)!=0.)?
00320         (r - cos(theta)*x1)/sin(theta):
00321         y1;
00322       yy2 = (sin(theta)!=0.)?
00323         (r - cos(theta)*x2)/sin(theta):
00324         y2;
00325       ww = TMath::Gaus(yy1,y1,sigy1)*TMath::Gaus(yy2,y2,sigy2)*w;
00326 
00327         if(ww>0)AddPoint(theta,r,ww,ih1);       
00328         if(ww<0)RemovePoint(theta,r,ww,ih1);
00329     }
00330   }
00331 }
00332 
00333 //......................................................................
00334 
00335 void Hough::FindLines(double* thetamx, double* rmx, double *score)
00336 {
00337         if (treehead->c1==NULL){*score=0;peaklist=NULL;return;}
00338 
00339         if(treehead->c1->goodsort==0)UpdateTree();  
00340         //update the tree if we failed to do so
00341         //so long as treehead->c1 has not been touched
00342         //it is still the max, so don't bother resorting rest of tree
00343 
00344 
00345 
00346         if (treehead->c1==NULL){*score=0;peaklist=NULL;return;}
00347 
00348 
00349         *thetamx=(float)(treehead->c1->theta+0.5)/(float)(gsNtheta)
00350                         *(maxtheta-mintheta)+mintheta;
00351         *rmx=(float)(treehead->c1->rho+0.5)/(float)(gsNrho)
00352                         *(maxrho-minrho)+minrho;
00353         *score=treehead->c1->weight;
00354 
00355 
00356 
00357         peaklist=treehead->c1->hitlist;
00358 
00359 
00360 }
00361 
00362 //......................................................................
00363 
00364 bool Hough::TestHit(double x,     double y,
00365                     double thmx,  double rhomx,
00366                     double sigth, double sigr)
00367 {
00368   int    itheta;
00369   double theta;
00370   double r;
00371   for (itheta=0; itheta<5*gsNtheta; ++itheta) {
00372     theta = M_PI*(float)itheta/(float)(5*gsNtheta);
00373     if (fabs(theta-thmx)>sigth) continue;
00374     r     = cos(theta)*x + sin(theta)*y;
00375     if (fabs(r-rhomx)<sigr) return true;
00376   }
00377   return false;
00378 }
00379 
00380 bool Hough::TestHit(double x,     double y,
00381                     double thmx,  double rhomx,
00382                     double sigr)
00383 {
00384   double r;
00385   r     = cos(thmx)*x + sin(thmx)*y;
00386   if (fabs(r-rhomx)<sigr) return true;
00387   return false;
00388 }
00389 
00390 //......................................................................
00391 
00392 float Hough::DistHit(double x,     double y,
00393                      double thmx,  double rhomx)
00394 {
00395   double r;
00396   r     = cos(thmx)*x + sin(thmx)*y;
00397   return fabs(r-rhomx);
00398 }
00399 

Generated on Mon Dec 1 02:35:18 2008 for NOvA Offline by  doxygen 1.3.9.1