Revision 198 CalibrationUtils.cpp
| CalibrationUtils.cpp (revision 198) | ||
|---|---|---|
| 19 | 19 |
_camHeight = 240; |
| 20 | 20 |
} |
| 21 | 21 |
|
| 22 |
CalibrationUtils::~CalibrationUtils(){
|
|
| 23 |
|
|
| 22 |
CalibrationUtils::~CalibrationUtils() |
|
| 23 |
{
|
|
| 24 | 24 |
delete screenPoints; |
| 25 | 25 |
delete cameraPoints; |
| 26 | 26 |
delete triangles; |
| ... | ... | |
| 30 | 30 |
//-------------------------------------------------------------- |
| 31 | 31 |
// Load Settings from the config.xml file |
| 32 | 32 |
//-------------------------------------------------------------- |
| 33 |
void CalibrationUtils::loadXMLSettings(){
|
|
| 34 |
|
|
| 33 |
void CalibrationUtils::loadXMLSettings() |
|
| 34 |
{
|
|
| 35 | 35 |
bGoToNextStep = false; |
| 36 | 36 |
|
| 37 | 37 |
// Can this load via http? |
| 38 |
if( calibrationXML.loadFile("calibration.xml")){
|
|
| 38 |
if( calibrationXML.loadFile("calibration.xml"))
|
|
| 39 | 39 |
//WOOT! |
| 40 | 40 |
message = "Calibration Loaded!"; |
| 41 |
}else{
|
|
| 41 |
else |
|
| 42 | 42 |
//FAIL! |
| 43 | 43 |
message = "No calibration Found..."; |
| 44 | 44 |
// GENERATE DEFAULT XML DATA WHICH WILL BE SAVED INTO THE CONFIG |
| 45 |
} |
|
| 46 | 45 |
|
| 47 | 46 |
bool bboxRoot = true; |
| 48 | 47 |
bool screenRoot = true; |
| ... | ... | |
| 57 | 56 |
setGrid(GRID_X, GRID_Y); |
| 58 | 57 |
|
| 59 | 58 |
//Bounding Box Points |
| 60 |
if(bboxRoot){
|
|
| 59 |
if(bboxRoot) |
|
| 60 |
{
|
|
| 61 | 61 |
vector2df ul(calibrationXML.getValue("SCREEN:BOUNDINGBOX:ulx", 0.000000),calibrationXML.getValue("SCREEN:BOUNDINGBOX:uly", 0.000000));
|
| 62 | 62 |
vector2df lr(calibrationXML.getValue("SCREEN:BOUNDINGBOX:lrx", 1.000000),calibrationXML.getValue("SCREEN:BOUNDINGBOX:lry", 1.000000));
|
| 63 | 63 |
rect2df boundingbox(ul, lr); |
| 64 | 64 |
setScreenBBox(boundingbox); |
| 65 |
}else{
|
|
| 66 |
setScreenScale(1.0f); |
|
| 67 | 65 |
} |
| 66 |
else |
|
| 67 |
setScreenScale(1.0f); |
|
| 68 | 68 |
|
| 69 | 69 |
//Calibration Points |
| 70 | 70 |
if(screenRoot) |
| ... | ... | |
| 72 | 72 |
//lets see how many <STROKE> </STROKE> tags there are in the xml file |
| 73 | 73 |
int numDragTags = calibrationXML.getNumTags("SCREEN:POINT");
|
| 74 | 74 |
|
| 75 |
//if there is at least one <POINT> tag we can read the list of points |
|
| 76 |
if(numDragTags > 0){
|
|
| 75 |
//if there is at least one <POINT> tag we can read the list of points |
|
| 76 |
if(numDragTags > 0) |
|
| 77 |
{
|
|
| 78 |
//we push into the last POINT tag this temporarirly treats the tag as the document root. |
|
| 79 |
calibrationXML.pushTag("SCREEN:POINT", numDragTags-1);
|
|
| 77 | 80 |
|
| 78 |
//we push into the last POINT tag this temporarirly treats the tag as the document root. |
|
| 79 |
calibrationXML.pushTag("SCREEN:POINT", numDragTags-1);
|
|
| 81 |
//we see how many points we have stored in <POINT> tags |
|
| 82 |
int numPtTags = calibrationXML.getNumTags("POINT");
|
|
| 80 | 83 |
|
| 81 |
//we see how many points we have stored in <POINT> tags |
|
| 82 |
int numPtTags = calibrationXML.getNumTags("POINT");
|
|
| 83 |
|
|
| 84 |
if(numPtTags > 0){
|
|
| 85 |
|
|
| 84 |
if(numPtTags > 0) |
|
| 85 |
{
|
|
| 86 | 86 |
//We then read those x y values into our array |
| 87 |
for(int i = 0; i < numPtTags; i++){
|
|
| 88 |
|
|
| 87 |
for(int i = 0; i < numPtTags; i++) |
|
| 88 |
{
|
|
| 89 | 89 |
//the last argument of getValue can be used to specify |
| 90 | 90 |
//which tag out of multiple tags you are refering to. |
| 91 | 91 |
int x = calibrationXML.getValue("POINT:X", 0.000000, i);
|
| ... | ... | |
| 105 | 105 |
|
| 106 | 106 |
//Set the camera calibated box. |
| 107 | 107 |
calculateBox(); |
| 108 |
computeCameraToScreenMap(); |
|
| 108 |
// computeCameraToScreenMap(); |
|
| 109 | 109 |
} |
| 110 | 110 |
|
| 111 | 111 |
|
| ... | ... | |
| 134 | 134 |
float transformedX = (float)x; |
| 135 | 135 |
float transformedY = (float)y; |
| 136 | 136 |
|
| 137 |
//convert camera to screenspace for all possible camera positions |
|
| 137 |
//convert camera to screen space for all possible camera positions |
|
| 138 | 138 |
cameraToScreenSpace(transformedX, transformedY); |
| 139 |
//save these into a map of transformed camera to screenspace positions |
|
| 139 |
//save these into a map of transformed camera to screen space positions |
|
| 140 | 140 |
cameraToScreenMap[p] = vector2df(transformedX, transformedY); |
| 141 | 141 |
p++; |
| 142 | 142 |
} |
| ... | ... | |
| 157 | 157 |
|
| 158 | 158 |
initTriangles(); |
| 159 | 159 |
|
| 160 |
if(bscreenPoints && bcameraPoints){
|
|
| 161 |
initScreenPoints(); |
|
| 162 |
initCameraPoints(_camWidth, _camHeight); |
|
| 160 |
if(bscreenPoints && bcameraPoints) |
|
| 161 |
{
|
|
| 162 |
initScreenPoints(); |
|
| 163 |
initCameraPoints(_camWidth, _camHeight); |
|
| 163 | 164 |
} |
| 164 | 165 |
} |
| 165 | 166 |
|
| ... | ... | |
| 169 | 170 |
_camHeight = camHeight; |
| 170 | 171 |
} |
| 171 | 172 |
|
| 172 |
void CalibrationUtils::initTriangles(){
|
|
| 173 |
|
|
| 174 |
int i,j; |
|
| 173 |
void CalibrationUtils::initTriangles() |
|
| 174 |
{
|
|
| 175 | 175 |
int t = 0; |
| 176 |
|
|
| 177 |
for(j=0; j<GRID_Y; j++) |
|
| 176 |
for(int j = 0; j < GRID_Y; j++) |
|
| 178 | 177 |
{
|
| 179 |
for(i=0; i<GRID_X; i++) |
|
| 178 |
for(int i = 0; i < GRID_X; i++) |
|
| 180 | 179 |
{
|
| 181 | 180 |
triangles[t+0] = (i+0) + ((j+0) * (GRID_X+1)); |
| 182 | 181 |
triangles[t+1] = (i+1) + ((j+0) * (GRID_X+1)); |
| ... | ... | |
| 198 | 197 |
{
|
| 199 | 198 |
int p = 0; |
| 200 | 199 |
|
| 201 |
int i,j; |
|
| 202 |
|
|
| 203 | 200 |
vector2df xd(screenBB.lowerRightCorner.X-screenBB.upperLeftCorner.X,0.0f); |
| 204 | 201 |
vector2df yd(0.0f, screenBB.lowerRightCorner.Y-screenBB.upperLeftCorner.Y); |
| 205 | 202 |
|
| 206 | 203 |
xd /= (float) GRID_X; |
| 207 | 204 |
yd /= (float) GRID_Y; |
| 208 | 205 |
|
| 209 |
for(j=0; j<=GRID_Y; j++) |
|
| 206 |
for(int j = 0; j <= GRID_Y; j++) |
|
| 210 | 207 |
{
|
| 211 |
for(i=0; i<=GRID_X; i++) |
|
| 208 |
for(int i = 0; i <= GRID_X; i++) |
|
| 212 | 209 |
{
|
| 213 | 210 |
screenPoints[p] = screenBB.upperLeftCorner + xd*i + yd*j; |
| 214 | 211 |
//printf("(%d, %d) = (%f, %f)\n", i, j, screenPoints[p].X, screenPoints[p].Y);
|
| ... | ... | |
| 220 | 217 |
void CalibrationUtils::initCameraPoints(int camWidth, int camHeight) |
| 221 | 218 |
{
|
| 222 | 219 |
int p = 0; |
| 223 |
|
|
| 224 |
int i,j; |
|
| 225 |
for(j=0; j<=GRID_Y; j++) |
|
| 220 |
for(int j = 0; j <= GRID_Y; j++) |
|
| 226 | 221 |
{
|
| 227 |
for(i=0; i<=GRID_X; i++) |
|
| 222 |
for(int i = 0; i <= GRID_X; i++) |
|
| 228 | 223 |
{
|
| 229 | 224 |
cameraPoints[p] = vector2df((i * camWidth) / (float)GRID_X, (j * camHeight) / (float)GRID_Y); |
| 230 | 225 |
p++; |
| ... | ... | |
| 235 | 230 |
void CalibrationUtils::setScreenScale(float s) |
| 236 | 231 |
{
|
| 237 | 232 |
// legacy |
| 238 |
float offset = (1.0f - s)*0.5f; |
|
| 233 |
float offset = (1.0f - s) * 0.5f; |
|
| 239 | 234 |
screenBB = rect2df(vector2df(offset,offset),vector2df(1.0f-offset,1.0f-offset)); |
| 240 | 235 |
initScreenPoints(); |
| 241 | 236 |
} |
| ... | ... | |
| 252 | 247 |
|
| 253 | 248 |
void CalibrationUtils::cameraToScreenPosition(float &x, float &y) |
| 254 | 249 |
{
|
| 255 |
//is this right to avoid boundingbox overflow? this overflow occurs due to new angle box |
|
| 256 |
if(y > _camHeight) y = _camHeight; |
|
| 257 |
if(y < 0) y = 0; |
|
| 258 |
if(x > _camWidth) x = _camWidth; |
|
| 259 |
if(x < 0) x = 0; |
|
| 250 |
cameraToScreenSpace(x, y); |
|
| 260 | 251 |
|
| 261 |
int pos = (int)y * (int)_camWidth + (int)x; |
|
| 262 |
|
|
| 263 |
x = cameraToScreenMap[pos].X; |
|
| 264 |
y = cameraToScreenMap[pos].Y; |
|
| 265 |
|
|
| 266 |
return; |
|
| 252 |
//is this right to avoid boundingbox overflow? this overflow occurs due to new angle box |
|
| 253 |
// if(y > _camHeight) y = _camHeight; |
|
| 254 |
// if(y < 0) y = 0; |
|
| 255 |
// if(x > _camWidth) x = _camWidth; |
|
| 256 |
// if(x < 0) x = 0; |
|
| 257 |
// |
|
| 258 |
// int pos = (int)y * (int)_camWidth + (int)x; |
|
| 259 |
// |
|
| 260 |
// x = cameraToScreenMap[pos].X; |
|
| 261 |
// y = cameraToScreenMap[pos].Y; |
|
| 267 | 262 |
} |
| 268 | 263 |
|
| 269 | 264 |
void CalibrationUtils::transformDimension(float &width, float &height) |
| ... | ... | |
| 276 | 271 |
float centerX = ((maxBoxX - minBoxX)/2) + minBoxX; |
| 277 | 272 |
float centerY = ((maxBoxY - minBoxY)/2) + minBoxY; |
| 278 | 273 |
|
| 279 |
//Calculate x/y position of upperleft and lowerright x/y positions |
|
| 274 |
//Calculate x/y position of upper left and lower right x/y positions |
|
| 280 | 275 |
float ulX = centerX - halfX; |
| 281 | 276 |
float ulY = centerY - halfY; |
| 282 | 277 |
float lrX = centerX + halfX; |
| 283 | 278 |
float lrY = centerY + halfY; |
| 284 | 279 |
|
| 285 |
//Transform these x/y positions to screenspace |
|
| 280 |
//Transform these x/y positions to screen space |
|
| 286 | 281 |
cameraToScreenPosition(ulX, ulY); |
| 287 | 282 |
cameraToScreenPosition(lrX, lrY); |
| 288 | 283 |
|
| ... | ... | |
| 298 | 293 |
minBoxX = _camWidth; |
| 299 | 294 |
maxBoxY = 0; |
| 300 | 295 |
minBoxY = _camHeight; |
| 301 |
|
|
| 302 |
//Calculate the max/min points based on cameraPoints |
|
| 303 |
for(int i = 0; i < GRID_POINTS; i++){
|
|
| 304 |
|
|
| 305 |
if(cameraPoints[i].X > maxBoxX){
|
|
| 306 |
|
|
| 307 |
maxBoxX = cameraPoints[i].X; |
|
| 308 |
} |
|
| 309 |
else if(cameraPoints[i].X < minBoxX){
|
|
| 310 |
|
|
| 311 |
minBoxX = cameraPoints[i].X; |
|
| 312 |
} |
|
| 313 |
if(cameraPoints[i].Y > maxBoxY){
|
|
| 314 |
|
|
| 315 |
maxBoxY = cameraPoints[i].Y; |
|
| 316 |
} |
|
| 317 |
if(cameraPoints[i].Y < minBoxY){
|
|
| 318 |
|
|
| 319 |
minBoxY = cameraPoints[i].Y; |
|
| 320 |
} |
|
| 296 |
// Calculate the max/min points based on cameraPoints |
|
| 297 |
for(int i = 0; i < GRID_POINTS; i++) |
|
| 298 |
{
|
|
| 299 |
if(cameraPoints[i].X > maxBoxX) maxBoxX = cameraPoints[i].X; |
|
| 300 |
else if(cameraPoints[i].X < minBoxX) minBoxX = cameraPoints[i].X; |
|
| 301 |
if(cameraPoints[i].Y > maxBoxY) maxBoxY = cameraPoints[i].Y; |
|
| 302 |
else if(cameraPoints[i].Y < minBoxY) minBoxY = cameraPoints[i].Y; |
|
| 321 | 303 |
} |
| 322 | 304 |
} |
| 323 | 305 |
|
| ... | ... | |
| 325 | 307 |
void CalibrationUtils::cameraToScreenSpace(float &x, float &y) |
| 326 | 308 |
{
|
| 327 | 309 |
vector2df pt(x, y); |
| 328 |
|
|
| 329 | 310 |
int t = findTriangleWithin(pt); |
| 330 |
|
|
| 331 | 311 |
if(t != -1) |
| 332 | 312 |
{
|
| 333 | 313 |
vector2df A = cameraPoints[triangles[t+0]]; |
| ... | ... | |
| 357 | 337 |
y = transformedPos.Y; |
| 358 | 338 |
return; |
| 359 | 339 |
} |
| 360 |
|
|
| 361 | 340 |
x = 0; |
| 362 | 341 |
y = 0; |
| 363 | 342 |
// FIXME: what to do in the case that it's outside the mesh? |
| ... | ... | |
| 373 | 352 |
|
| 374 | 353 |
int CalibrationUtils::findTriangleWithin(vector2df pt) |
| 375 | 354 |
{
|
| 376 |
int t; |
|
| 377 |
|
|
| 378 |
for(t=0; t<GRID_INDICES; t+=3) |
|
| 355 |
for(int t = 0; t < GRID_INDICES; t += 3) |
|
| 379 | 356 |
{
|
| 380 |
if( isPointInTriangle(pt, cameraPoints[triangles[t]], cameraPoints[triangles[t+1]], cameraPoints[triangles[t+2]]) ) |
|
| 381 |
{
|
|
| 357 |
if(isPointInTriangle(pt, cameraPoints[triangles[t]], cameraPoints[triangles[t+1]], cameraPoints[triangles[t+2]]) ) |
|
| 382 | 358 |
return t; |
| 383 |
} |
|
| 384 | 359 |
} |
| 385 |
|
|
| 386 | 360 |
return -1; |
| 387 | 361 |
} |
| 388 | 362 |
|
| ... | ... | |
| 397 | 371 |
if(bCalibrating) |
| 398 | 372 |
{
|
| 399 | 373 |
calibrationStep++; |
| 400 |
|
|
| 401 | 374 |
if(calibrationStep >= GRID_POINTS) |
| 402 | 375 |
{
|
| 403 | 376 |
bCalibrating = false; |
| 404 | 377 |
calibrationStep = 0; |
| 405 | 378 |
saveCalibration(); |
| 406 | 379 |
calculateBox(); |
| 407 |
computeCameraToScreenMap(); |
|
| 380 |
// computeCameraToScreenMap(); |
|
| 408 | 381 |
|
| 409 | 382 |
saveCalibration(); |
| 410 | 383 |
} |
| ... | ... | |
| 432 | 405 |
int numDragTags = calibrationXML.getNumTags("SCREEN:POINT");
|
| 433 | 406 |
|
| 434 | 407 |
//if there is at least one <POINT> tag we can read the list of points |
| 435 |
if(numDragTags > 0){
|
|
| 436 |
|
|
| 408 |
if(numDragTags > 0) |
|
| 409 |
{
|
|
| 437 | 410 |
//we push into the last POINT tag this temporarirly treats the tag as the document root. |
| 438 | 411 |
calibrationXML.pushTag("SCREEN:POINT", numDragTags-1);
|
| 439 | 412 |
|
| ... | ... | |
| 450 | 423 |
calibrationXML.setValue("BOUNDINGBOX:lry", screenBB.lowerRightCorner.Y);
|
| 451 | 424 |
|
| 452 | 425 |
//Save all the Calibration Points |
| 453 |
if(GRID_POINTS > 0){
|
|
| 454 |
|
|
| 426 |
if(GRID_POINTS > 0) |
|
| 427 |
{
|
|
| 455 | 428 |
//We then read those x y values into our array |
| 456 |
for(int i = 0; i < GRID_POINTS; i++){
|
|
| 457 |
|
|
| 429 |
for(int i = 0; i < GRID_POINTS; i++) |
|
| 430 |
{
|
|
| 458 | 431 |
//the last argument of getValue can be used to specify |
| 459 | 432 |
//which tag out of multiple tags you are refering to. |
| 460 | 433 |
calibrationXML.setValue("POINT:X", cameraPoints[i].X, i);
|
Also available in: Unified diff
