00001
00002
00003
00004
00005
00006
00007
00008 #include "CheckerboardDetector.h"
00009 #include "Platform/SystemCall.h"
00010 #include "Tools/RobotConfiguration.h"
00011
00012 CheckerboardDetector::CheckerboardDetector(const ImageProcessorInterfaces& interfaces)
00013 : ImageProcessor(interfaces),minY(0),maxY(255),maxDelta(255)
00014 {
00015 }
00016
00017 Vector2<double> CheckerboardDetector::getExactTransitionMiddle(const Geometry::PixeledLine lin, const int start, const int amount)
00018 {
00019 Vector2<double> p;
00020 int index=start;
00021 int sum=0;
00022 int oldsum=0;
00023 while (abs(2*sum)<abs(amount))
00024 {
00025 oldsum = sum;
00026 sum = image.image[lin.getPixelY(index)][0][lin.getPixelX(index)]-
00027 image.image[lin.getPixelY(start-1)][0][lin.getPixelX(start-1)];
00028 index++;
00029 }
00030 double rightWeight=(sum-0.5*amount)/(sum-oldsum);
00031 p.x=(1-rightWeight)*lin.getPixelX(index-1)+rightWeight*lin.getPixelX(index);
00032 p.y=(1-rightWeight)*lin.getPixelY(index-1)+rightWeight*lin.getPixelY(index);
00033 return p;
00034 }
00035
00036 void CheckerboardDetector::getTransitionsOnLine(const Geometry::PixeledLine lin, v2dArray* transPos, bArray* transWhiteBlack, int& numOfTrans)
00037 {
00038 Vector2<double> p;
00039 int state=0;
00040 int sumDelta=0;
00041 int startIndex=0;
00042 numOfTrans=0;
00043 for (int i=1;i<lin.getNumberOfPixels();i++)
00044 {
00045 int actDelta=image.image[lin.getPixelY(i)][0][lin.getPixelX(i)]-image.image[lin.getPixelY(i-1)][0][lin.getPixelX(i-1)];
00046 if (actDelta>=maxDelta/15)
00047 {
00048 if ((state==2)&&(sumDelta<=-maxDelta/2))
00049 {
00050 p=getExactTransitionMiddle(lin,startIndex,sumDelta);
00051 (*transPos)[numOfTrans]=p;
00052 (*transWhiteBlack)[numOfTrans++]=true;
00053 DEBUG_IMAGE_SET_PIXEL_BLUE(imageProcessorGeneral, (int)p.x, (int)p.y);
00054 }
00055 if (state!=1)
00056 {
00057 startIndex=i;
00058 sumDelta=actDelta;
00059 state=1;
00060 }
00061 else
00062 {
00063 sumDelta+=actDelta;
00064 }
00065 }
00066 else if (actDelta<=-maxDelta/15)
00067 {
00068 if ((state==1)&&(sumDelta>=maxDelta/2))
00069 {
00070 p=getExactTransitionMiddle(lin,startIndex,sumDelta);
00071 (*transPos)[numOfTrans]=p;
00072 (*transWhiteBlack)[numOfTrans++]=false;
00073 DEBUG_IMAGE_SET_PIXEL_RED(imageProcessorGeneral, (int)p.x, (int)p.y);
00074 }
00075 if (state!=2)
00076 {
00077 startIndex=i;
00078 sumDelta=actDelta;
00079 state=2;
00080 }
00081 else
00082 {
00083 sumDelta+=actDelta;
00084 }
00085 }
00086 else if (state!=0)
00087 {
00088 if (abs(sumDelta)>=maxDelta/2)
00089 {
00090 p=getExactTransitionMiddle(lin,startIndex,sumDelta);
00091 (*transPos)[numOfTrans]=p;
00092 (*transWhiteBlack)[numOfTrans++]=(sumDelta<0);
00093 if (sumDelta<0)
00094 {
00095 DEBUG_IMAGE_SET_PIXEL_BLUE(imageProcessorGeneral, (int)p.x, (int)p.y);
00096 }
00097 else
00098 {
00099 DEBUG_IMAGE_SET_PIXEL_RED(imageProcessorGeneral, (int)p.x, (int)p.y);
00100 }
00101 }
00102 state=0;
00103 }
00104 }
00105 }
00106
00107 Vector2<double> CheckerboardDetector::getTransitionToWhite(const Geometry::PixeledLine lin)
00108 {
00109 if (lin.getNumberOfPixels()>0)
00110 {
00111
00112 if (image.image[lin.getPixelY(0)][0][lin.getPixelX(0)]<=minY+(maxY-minY)/4)
00113 {
00114 int state=0;
00115 int sumDelta=0;
00116 int startIndex=0;
00117 for (int i=1;i<lin.getNumberOfPixels();i++)
00118 {
00119 int actDelta=image.image[lin.getPixelY(i)][0][lin.getPixelX(i)]-image.image[lin.getPixelY(i-1)][0][lin.getPixelX(i-1)];
00120 if (actDelta>=maxDelta/10)
00121 {
00122 if (state!=1)
00123 {
00124 startIndex=i;
00125 sumDelta=actDelta;
00126 state=1;
00127 }
00128 else
00129 {
00130 sumDelta+=actDelta;
00131 }
00132 }
00133 else if (state!=0)
00134 {
00135 if (sumDelta>=maxDelta/2)
00136 {
00137 return getExactTransitionMiddle(lin,startIndex,sumDelta);
00138 }
00139 state=0;
00140 }
00141 }
00142 }
00143 }
00144
00145 return Vector2<double>(-1,-1);
00146 }
00147
00148 Vector2<double> CheckerboardDetector::getMiddleAndLengthOfPerpendicular(const Vector2<double> t1, const Vector2<double> t2, double& len)
00149 {
00150 double angle=atan2(t2.y-t1.y,t2.x-t1.x)+pi_2;
00151 double dx=400*cos(angle);
00152 double dy=400*sin(angle);
00153 Vector2<int> pmid((int)(t1.x+t2.x)/2,(int)(t1.y+t2.y)/2);
00154 Vector2<int> pend1((int)(t1.x+t2.x+dx)/2,(int)(t1.y+t2.y+dy)/2);
00155 Vector2<int> pend2((int)(t1.x+t2.x-dx)/2,(int)(t1.y+t2.y-dy)/2);
00156 const Vector2<int> botlef(0,0);
00157 const Vector2<int> toprig(image.cameraInfo.resolutionWidth-1,image.cameraInfo.resolutionHeight-1);
00158 Geometry::clipLineWithRectangleCohenSutherland(botlef,toprig,pmid,pend1);
00159 Geometry::clipLineWithRectangleCohenSutherland(botlef,toprig,pmid,pend2);
00160 Geometry::PixeledLine ray1(pmid.x,pend1.x,pmid.y,pend1.y);
00161 Geometry::PixeledLine ray2(pmid.x,pend2.x,pmid.y,pend2.y);
00162 Vector2<double> p1=getTransitionToWhite(ray1);
00163 Vector2<double> p2=getTransitionToWhite(ray2);
00164 Vector2<double> pm((p1.x+p2.x)/2,(p1.y+p2.y)/2);
00165 if (((p1.x==-1)&&(p1.y==-1))||((p2.x==-1)&&(p2.y==-1)))
00166 {
00167 pm.x=-1;
00168 pm.y=-1;
00169 len=0;
00170 }
00171 else
00172 {
00173 len=sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
00174 }
00175 return pm;
00176 }
00177
00178 bool CheckerboardDetector::getLineThroughPixelsCandidate(const v2dArray* points, const int numOfPoints, double& m, double& n)
00179 {
00180 double sumXi=0;
00181 double sumYi=0;
00182 double sumXiXi=0;
00183 double sumXiXj=0;
00184 double sumXiYi=0;
00185 double sumXiYj=0;
00186 for (int i=0;i<numOfPoints;i++)
00187 {
00188 sumXi += (*points)[i].x;
00189 sumYi += (*points)[i].y;
00190 sumXiXi += (*points)[i].x * (*points)[i].x;
00191 sumXiYi += (*points)[i].x * (*points)[i].y;
00192 for (int j=0;j<numOfPoints;j++)
00193 {
00194 sumXiXj += (*points)[i].x * (*points)[j].x;
00195 sumXiYj += (*points)[i].x * (*points)[j].y;
00196 }
00197 }
00198 if (((numOfPoints*sumXiXi-sumXiXj)==0)||((numOfPoints*sumXiXi-sumXi*sumXi)==0))
00199 {
00200 return false;
00201 }
00202 m=(numOfPoints*sumXiYi-sumXiYj)/(numOfPoints*sumXiXi-sumXiXj);
00203 n=(sumXiXi*sumYi-sumXi*sumXiYi)/(numOfPoints*sumXiXi-sumXi*sumXi);
00204 return true;
00205 }
00206
00207 bool CheckerboardDetector::getLineThroughPixels(const v2dArray* points, const int numOfPoints, Geometry::PixeledLine& lin)
00208 {
00209
00210 double m;
00211 double n;
00212 if ((numOfPoints<2)||(!getLineThroughPixelsCandidate(points,numOfPoints,m,n)))
00213 {
00214 return false;
00215 }
00216 double error2[100];
00217 double sumError2=0;
00218 int i;
00219 for (i=0;i<numOfPoints;i++)
00220 {
00221 error2[i] = m * (*points)[i].x + n - (*points)[i].y;
00222 error2[i] *= error2[i];
00223 sumError2 += error2[i];
00224 }
00225 v2dArray newPoints;
00226 int newNumOfPoints=0;
00227 for (i=0;i<numOfPoints;i++)
00228 {
00229
00230 if ((error2[i]<=sumError2/numOfPoints)||(error2[i]<1))
00231 {
00232 newPoints[newNumOfPoints++]= (*points)[i];
00233 }
00234 }
00235 if ((newNumOfPoints<2)||(!getLineThroughPixelsCandidate(&newPoints,newNumOfPoints,m,n)))
00236 {
00237 return false;
00238 }
00239 Vector2<int> p1(0,(int)(n+1));
00240 Vector2<int> p2(1000,(int)(1000*m+n+1));
00241 const Vector2<int> botlef(0,0);
00242 const Vector2<int> toprig(image.cameraInfo.resolutionWidth-1,image.cameraInfo.resolutionHeight-1);
00243 Geometry::clipLineWithRectangleCohenSutherland(botlef,toprig,p1,p2);
00244 Geometry::PixeledLine myLin(p1,p2);
00245 lin=myLin;
00246 return true;
00247 }
00248
00249 Vector2<double> CheckerboardDetector::getPositionFromAngles(const double alpha2,const double a2,const double alpha1,const double a1)
00250 {
00251
00252 Vector2<double> pos;
00253 double divident = fabs((2*a1+a2)*sin(alpha2) - a2*sin(2*alpha1+alpha2));
00254 double divisor = 2 * (a1*a1 + a1*a2 + a2*a2 - a2*(a1+a2)*cos(2*alpha1) -
00255 a1*(a1+a2)*cos(2*alpha2) + a1*a2*cos(2*(alpha1+alpha2)));
00256 if (divisor>0)
00257 {
00258 double beta11=acos(divident/sqrt(divisor));
00259 double beta12=pi-beta11;
00260 double b=sin(beta11)*a1/sin(alpha1);
00261 double error1=fabs(a2/sin(alpha2)-b/sin(pi-alpha1-alpha2-beta11));
00262 double error2=fabs(a2/sin(alpha2)-b/sin(pi-alpha1-alpha2-beta12));
00263 double beta1=(error1<error2)?beta11:beta12;
00264 double c1 = sin(pi-alpha1-beta1)*a1/sin(alpha1);
00265 pos.x = -c1*sin(beta1);
00266 pos.y = -a1+c1*cos(beta1);
00267 }
00268 else
00269 {
00270 pos.x = -5000;
00271 pos.y = 0;
00272
00273 }
00274 return pos;
00275 }
00276
00277 double CheckerboardDetector::getAngleBetweenScreenPoints(const Vector2<double>& p1, const Vector2<double>& p2)
00278 {
00279
00280
00281
00282 double xarc=
00283 atan((p2.x-image.cameraInfo.resolutionWidth/2)*
00284 tan(image.cameraInfo.openingAngleWidth/2)/(image.cameraInfo.resolutionWidth/2))
00285 -atan((p1.x-image.cameraInfo.resolutionWidth/2)*
00286 tan(image.cameraInfo.openingAngleWidth/2)/(image.cameraInfo.resolutionWidth/2));
00287 double yarc=
00288 atan((p2.y-image.cameraInfo.resolutionHeight/2)*
00289 tan(image.cameraInfo.openingAngleHeight/2)/(image.cameraInfo.resolutionHeight/2))
00290 -atan((p1.y-image.cameraInfo.resolutionHeight/2)*
00291 tan(image.cameraInfo.openingAngleHeight/2)/(image.cameraInfo.resolutionHeight/2));
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 return 2*atan(sqrt(2-2*cos(xarc)*cos(yarc))/2);
00328 }
00329
00330 double CheckerboardDetector::yPosFromTransitionIndex(int index)
00331 {
00332 return 49.5 + 210*(-index/2) + (index<0?111:99)*(-index%2);
00333 }
00334
00335 void CheckerboardDetector::execute()
00336 {
00337 specialPercept.reset(image.frameNumber);
00338 double distancePanCenterToCamera = getRobotConfiguration().getRobotDimensions().distancePanCenterToCameraX;
00339
00340 int i,x;
00341
00342 minY=image.image[image.cameraInfo.resolutionHeight*16/35][0][0];
00343 maxY=minY;
00344
00345 for (i=12;i<=26;i++)
00346 {
00347 int y=image.cameraInfo.resolutionHeight*i/35;
00348 for (x=0;x<image.cameraInfo.resolutionWidth;x++)
00349 {
00350 int actY=image.image[y][0][x];
00351 if (actY>maxY) maxY=actY;
00352 if (actY<minY) minY=actY;
00353 }
00354 }
00355 maxDelta=maxY-minY;
00356
00357 INIT_DEBUG_IMAGE(imageProcessorGeneral, image);
00358
00359 v2dArray blackBlockMiddle;
00360 int numOfBlackBlockMiddle=0;
00361
00362
00363 v2dArray transPos;
00364 bArray transWhiteBlack;
00365 int numOfTrans;
00366 for (i=12;i<=26;i++)
00367 {
00368 double dummyLen;
00369 numOfTrans=0;
00370 Geometry::PixeledLine lin(0,image.cameraInfo.resolutionWidth-1,image.cameraInfo.resolutionHeight*i/35,image.cameraInfo.resolutionHeight*i/35);
00371 getTransitionsOnLine(lin,&transPos,&transWhiteBlack,numOfTrans);
00372
00373
00374 if ((!transWhiteBlack[0])&&(transPos[0].x<image.cameraInfo.resolutionWidth/4))
00375 {
00376 Vector2<double> left(0,transPos[0].y);
00377 Vector2<double> m=getMiddleAndLengthOfPerpendicular(left,transPos[0],dummyLen);
00378 if ((m.x>=0)&&(m.y>=0))
00379 {
00380 DEBUG_IMAGE_SET_PIXEL_YELLOW(imageProcessorGeneral, (int)m.x, (int)m.y);
00381 blackBlockMiddle[numOfBlackBlockMiddle++]=m;
00382 }
00383 }
00384 if ((transWhiteBlack[numOfTrans-1])&&(transPos[numOfTrans-1].x>image.cameraInfo.resolutionWidth*3/4))
00385 {
00386 Vector2<double> right(image.cameraInfo.resolutionWidth-1,transPos[0].y);
00387 Vector2<double> m=getMiddleAndLengthOfPerpendicular(transPos[numOfTrans-1],right,dummyLen);
00388 if ((m.x>=0)&&(m.y>=0))
00389 {
00390 DEBUG_IMAGE_SET_PIXEL_YELLOW(imageProcessorGeneral, (int)m.x, (int)m.y);
00391 blackBlockMiddle[numOfBlackBlockMiddle++]=m;
00392 }
00393 }
00394 for (int t=0;t<numOfTrans-1;t++)
00395 {
00396 if ((transWhiteBlack[t])&&(!transWhiteBlack[t+1]))
00397 {
00398 Vector2<double> m=getMiddleAndLengthOfPerpendicular(transPos[t],transPos[t+1],dummyLen);
00399 if ((m.x>=0)&&(m.y>=0))
00400 {
00401 DEBUG_IMAGE_SET_PIXEL_YELLOW(imageProcessorGeneral, (int)m.x, (int)m.y);
00402 blackBlockMiddle[numOfBlackBlockMiddle++]=m;
00403 }
00404 }
00405 }
00406 }
00407
00408
00409
00410 Geometry::PixeledLine lin(0,0,1,1);
00411 if (getLineThroughPixels(&blackBlockMiddle,numOfBlackBlockMiddle,lin))
00412 {
00413 for (i=0;i<lin.getNumberOfPixels();i++)
00414 {
00415 int y=image.image[lin.getPixelY(i)][0][lin.getPixelX(i)];
00416 if (y<=minY+(maxY-minY)/4)
00417 {
00418 DEBUG_IMAGE_SET_PIXEL_BLACK(imageProcessorGeneral, lin.getPixelX(i), lin.getPixelY(i));
00419 }
00420 else if (y>=maxY-(maxY-minY)/2)
00421 {
00422 DEBUG_IMAGE_SET_PIXEL_WHITE(imageProcessorGeneral, lin.getPixelX(i), lin.getPixelY(i));
00423 }
00424 else
00425 {
00426 DEBUG_IMAGE_SET_PIXEL_Y(imageProcessorGeneral, lin.getPixelX(i), lin.getPixelY(i), 128);
00427 }
00428 }
00429
00430
00431
00432 minY=image.image[lin.getPixelY(0)][0][lin.getPixelX(0)];
00433 maxY=minY;
00434 for (i=0;i<lin.getNumberOfPixels();i++)
00435 {
00436 int actY=image.image[lin.getPixelY(i)][0][lin.getPixelX(i)];
00437 if (actY>maxY) maxY=actY;
00438 if (actY<minY) minY=actY;
00439 }
00440 maxDelta=maxY-minY;
00441
00442 v2dArray transPos;
00443 bArray transWhiteBlack;
00444 int numOfTrans;
00445 getTransitionsOnLine(lin,&transPos,&transWhiteBlack,numOfTrans);
00446 int numOfBlocks=0;
00447 double blockHeight[30];
00448 if (numOfTrans>2)
00449 {
00450 for (i=0;i<numOfTrans;i++)
00451 {
00452 DEBUG_IMAGE_SET_PIXEL_GREEN(imageProcessorGeneral, (int)(transPos[i].x), (int)(transPos[i].y-2));
00453 DEBUG_IMAGE_SET_PIXEL_GREEN(imageProcessorGeneral, (int)(transPos[i].x), (int)(transPos[i].y-1));
00454 DEBUG_IMAGE_SET_PIXEL_GREEN(imageProcessorGeneral, (int)(transPos[i].x), (int)(transPos[i].y));
00455 DEBUG_IMAGE_SET_PIXEL_GREEN(imageProcessorGeneral, (int)(transPos[i].x), (int)(transPos[i].y+1));
00456 DEBUG_IMAGE_SET_PIXEL_GREEN(imageProcessorGeneral, (int)(transPos[i].x), (int)(transPos[i].y+2));
00457 }
00458
00459
00460 Vector2<double> middleBlock(-1,-1);
00461 double longest=0;
00462 int middleOffset=-1;
00463 int middleBlockNum=-1;
00464 double l;
00465 Vector2<double> m;
00466 if (!transWhiteBlack[0])
00467 {
00468 Vector2<double> lBorder=Vector2<double>(lin.getPixelX(0),lin.getPixelY(0));
00469 m=getMiddleAndLengthOfPerpendicular(lBorder,transPos[0],l);
00470 if (l>0)
00471 {
00472 blockHeight[numOfBlocks++]=l;
00473 }
00474 for (int len=0;len<l;len++)
00475 {
00476 if(m.y+len <image.cameraInfo.resolutionHeight)
00477 {
00478 DEBUG_IMAGE_SET_PIXEL_RED(imageProcessorGeneral, (int)(m.x), (int)(m.y+len));
00479 }
00480 }
00481 }
00482 for (i=0;i<numOfTrans-1;i++)
00483 {
00484 if ((transWhiteBlack[i])&&(!transWhiteBlack[i+1]))
00485 {
00486 m=getMiddleAndLengthOfPerpendicular(transPos[i],transPos[i+1],l);
00487 blockHeight[numOfBlocks++]=l;
00488 if (l>longest)
00489 {
00490 longest=l;
00491 middleBlock=m;
00492 middleOffset=i;
00493 middleBlockNum=numOfBlocks-1;
00494 }
00495 for (int len=0;len<l;len++)
00496 {
00497 if(m.y+len <image.cameraInfo.resolutionHeight)
00498 {
00499 DEBUG_IMAGE_SET_PIXEL_RED(imageProcessorGeneral, (int)(m.x), (int)(m.y+len));
00500 }
00501 }
00502 }
00503 }
00504 if (transWhiteBlack[numOfTrans-1])
00505 {
00506 Vector2<double> rBorder=Vector2<double>(lin.getPixelX(lin.getNumberOfPixels()-1),lin.getPixelY(lin.getNumberOfPixels()-1));
00507 m=getMiddleAndLengthOfPerpendicular(transPos[numOfTrans-1],rBorder,l);
00508 if (l>0)
00509 {
00510 blockHeight[numOfBlocks++]=l;
00511 }
00512 for (int len=0;len<l;len++)
00513 {
00514 if(m.y+len <image.cameraInfo.resolutionHeight)
00515 {
00516 DEBUG_IMAGE_SET_PIXEL_RED(imageProcessorGeneral, (int)(m.x), (int)(m.y+len));
00517 }
00518 }
00519 }
00520
00521
00522 double lastDist=(transPos[1]-transPos[0]).abs();
00523 for (i=1;i<numOfTrans-1;i++)
00524 {
00525 double dist=(transPos[i]-transPos[i-1]).abs();
00526
00527 if ((transWhiteBlack[i]==transWhiteBlack[i-1])||
00528 (dist>2.25*lastDist)||(dist*2.25<lastDist))
00529 {
00530
00531 middleOffset=-1;
00532 middleBlockNum=-1;
00533 break;
00534 }
00535 lastDist=dist;
00536 }
00537
00538 if (middleBlockNum>=0)
00539 {
00540
00541
00542 if (((middleBlockNum>0)&&(middleBlockNum<numOfBlocks-1)&&(blockHeight[middleBlockNum-1]*1.35<blockHeight[middleBlockNum])&&(blockHeight[middleBlockNum+1]*1.35<blockHeight[middleBlockNum]))||
00543 ((middleBlockNum==0)&&(numOfBlocks>2)&&(blockHeight[middleBlockNum+1]>0)&&(blockHeight[middleBlockNum+2])&&(blockHeight[middleBlockNum+1]/blockHeight[middleBlockNum+2]*1.35<blockHeight[middleBlockNum]/blockHeight[middleBlockNum+1]))||
00544 ((middleBlockNum==numOfBlocks-1)&&(numOfBlocks>2)&&(blockHeight[middleBlockNum-1]>0)&&(blockHeight[middleBlockNum-2])&&(blockHeight[middleBlockNum-1]/blockHeight[middleBlockNum-2]*1.35<blockHeight[middleBlockNum]/blockHeight[middleBlockNum-1])))
00545 {
00546 for (int len=0;len<longest;len++)
00547 {
00548 if(middleBlock.y+len <image.cameraInfo.resolutionHeight)
00549 {
00550 DEBUG_IMAGE_SET_PIXEL_BLUE(imageProcessorGeneral, (int)(middleBlock.x), (int)(middleBlock.y+len));
00551 }
00552 }
00553
00554 int halfIndex=(numOfTrans-1)/2;
00555 double halfYPos=yPosFromTransitionIndex(halfIndex-middleOffset);
00556 double leftAngle=getAngleBetweenScreenPoints(transPos[0],transPos[halfIndex]);
00557 double leftLength=yPosFromTransitionIndex(0-middleOffset)-halfYPos;
00558 double rightAngle=getAngleBetweenScreenPoints(transPos[numOfTrans-1],transPos[halfIndex]);
00559 double rightLength=halfYPos-yPosFromTransitionIndex(numOfTrans-1-middleOffset);
00560 Vector2<double> pos = getPositionFromAngles(leftAngle,leftLength,rightAngle,rightLength);
00561
00562
00563 Vector3<double> front = cameraMatrix.rotation * Vector3<double>(1,0,0);
00564 Vector3<double> vectorToPoint(
00565 (double)image.cameraInfo.resolutionWidth/2/tan(image.cameraInfo.openingAngleWidth/2),
00566
00567 (double)image.cameraInfo.resolutionWidth/2 - transPos[halfIndex].x,
00568 (double)image.cameraInfo.resolutionHeight/2 - transPos[halfIndex].y);
00569 Vector3<double> vectorToPointWorld = cameraMatrix.rotation * vectorToPoint;
00570 double dir = atan2(-pos.y,-pos.x)-
00571 (atan2(vectorToPointWorld.y,vectorToPointWorld.x)-
00572 atan2(front.y,front.x));
00573
00574 specialPercept.checkerPose.translation = pos + Vector2<double>(-cos(dir)*distancePanCenterToCamera, -sin(dir)*distancePanCenterToCamera + halfYPos);
00575
00576 specialPercept.type=SpecialPercept::checkerboard;
00577 specialPercept.checkerPose.rotation = dir - atan2(front.y,front.x);
00578 }
00579 }
00580 }
00581 }
00582 SEND_DEBUG_IMAGE(imageProcessorGeneral);
00583 }
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682