00001
00002
00003
00004
00005
00006
00007
00008
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
00020
00021
00022
00023
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;
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
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
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
00107
00108 int Hough::UpdateTree()
00109 {
00110
00111
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
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
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 nodearray[t][r]->goodsort=0;
00200 nodearray[t][r]->weight+=ww;
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
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);
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
00341
00342
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