00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "GUI/ViewPort3D.H"
00037 #include "Util/log.H"
00038 #include "Util/WorkThreadServer.H"
00039 #include "Util/JobWithSemaphore.H"
00040 #include "Component/ModelManager.H"
00041 #include "Raster/GenericFrame.H"
00042 #include "Image/Layout.H"
00043 #include "Image/MatrixOps.H"
00044 #include "Image/DrawOps.H"
00045 #include "GUI/DebugWin.H"
00046 #include "Media/FrameSeries.H"
00047 #include "Transport/FrameInfo.H"
00048 #include <stdlib.h>
00049 #include <math.h>
00050 #include <stdlib.h>
00051 #include <stdio.h>
00052
00053 #include "GUI/XWinManaged.H"
00054 #include "GUI/ImageDisplayStream.H"
00055
00056
00057
00058
00059
00060
00061 struct GPSPos
00062 {
00063 float latDeg;
00064 float latMin;
00065 float latSec;
00066
00067 float lonDeg;
00068 float lonMin;
00069 float lonSec;
00070
00071 GPSPos(float ld, float lm, float ls, float nd, float nm, float ns) :
00072 latDeg(ld), latMin(lm), latSec(ls), lonDeg(nd), lonMin(nm), lonSec(ns)
00073 {}
00074
00075 double getLat()
00076 {
00077 return (latDeg + (latMin * 60.0) / 3600.0)*M_PI/180;
00078 }
00079
00080 double getLon()
00081 {
00082 return (lonDeg + (lonMin * 60.0) / 3600.0)*M_PI/180;
00083 }
00084
00085
00086 };
00087
00088 Point3D<float> getGpsPos(GPSPos pos)
00089 {
00090 GPSPos center(34,1.270,0,118,17.334,0);
00091
00092 Point3D<float> relPos(0,0,0);
00093
00094
00095 double R = 6378.7 ;
00096 double theta = center.getLon() - pos.getLon();
00097 double d1 = sin(center.getLat()) * sin(center.getLat());
00098 double d2 = cos(center.getLat()) * cos(center.getLat()) * cos(theta);
00099 double y = acos(d1 + d2) * R * 1000.0;
00100
00101 LINFO("%f %f %f %f %f", R, theta, d1, d2, y);
00102
00103 d1 = sin(center.getLat()) * sin(pos.getLat());
00104 d2 = cos(center.getLat()) * cos(pos.getLat());
00105 double x = acos(d1 + d2) * R * 1000.0;
00106
00107 if(x != 0.0 && y != 0.0)
00108 {
00109 relPos.x = (center.getLat() > pos.getLat()) ? x : -x;
00110 relPos.y = (center.getLon() > pos.getLon()) ? y : -y;
00111 }
00112
00113 return relPos;
00114 }
00115
00116
00117 Point2D<float> getGpsPos(double lon1, double lat1, double lon2, double lat2)
00118 {
00119 Point2D<float> relPos(0,0);
00120
00121
00122 double R = 6378.7 ;
00123 double theta = lon1- lon2;
00124 double d1 = sin(lat1) * sin(lat1);
00125 double d2 = cos(lat1) * cos(lat1) * cos(theta);
00126
00127 double y = 0;
00128 if (-1 <= d1 + d2 &&
00129 1 >= d1 + d2)
00130 y = acos(d1 + d2) * R * 1000.0;
00131
00132
00133 d1 = sin(lat1) * sin(lat2);
00134 d2 = cos(lat1) * cos(lat2);
00135
00136 double x = 0;
00137 if (-1 <= d1 + d2 &&
00138 1 >= d1 + d2)
00139 x = acos(d1 + d2) * R * 1000.0;
00140
00141
00142 {
00143 relPos.i = (lat1 > lat2) ? x : -x;
00144 relPos.j = (lon1 > lon2) ? y : -y;
00145 }
00146
00147 return relPos;
00148 }
00149
00150 Image<float> computeAffine()
00151 {
00152
00153 std::vector<Point2D<double> > gpsLocations;
00154
00155
00156
00157
00158
00159
00160 gpsLocations.push_back(Point2D<double>(34.021790332,-118.290910238));
00161 gpsLocations.push_back(Point2D<double>(34.021877944,-118.290840708));
00162 gpsLocations.push_back(Point2D<double>(34.021991116,-118.291105977));
00163 gpsLocations.push_back(Point2D<double>(34.021938097,-118.291058661));
00164 gpsLocations.push_back(Point2D<double>(34.021864139,-118.290929807));
00165
00166
00167
00168 std::vector<Point2D<double> > gtLocations;
00169 gtLocations.push_back(Point2D<double>(0,0));
00170 gtLocations.push_back(Point2D<double>(14.5796,0));
00171 gtLocations.push_back(Point2D<double>(14.5796,27.9654));
00172 gtLocations.push_back(Point2D<double>(8.4582,1.8542+11.91));
00173 gtLocations.push_back(Point2D<double>(8.4582,1.8542));
00174
00175 printf("D=[ \n");
00176 for(uint i=0; i<gpsLocations.size(); i++)
00177 {
00178 Point2D<float> pos = getGpsPos(
00179 double(-118*M_PI/180), double(34*M_PI/180),
00180 gpsLocations[i].j*M_PI/180, gpsLocations[i].i*M_PI/180);
00181
00182 printf("%f %f %f %f; \n",
00183 pos.i, pos.j, gtLocations[i].i, gtLocations[i].j);
00184
00185 }
00186 printf("];\n");
00187
00188 printf("gps=[D(:,1)'; D(:,2)'; ones(1,size(D,1))]; \n");
00189 printf("gt=[D(:,3)'; D(:,4)'; ones(1,size(D,1))]; \n");
00190 printf("M = gt / gps\n");
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 Image<float> aff;
00233 return aff;
00234 }
00235
00236
00237 void showPos(ViewPort3D& vp, GPSPos pos)
00238 {
00239 Point3D<float> relPos = getGpsPos(pos);
00240
00241 vp.drawBox( relPos,
00242 Point3D<float>(0,0,0),
00243 Point3D<float>(0.52324,0.5/4, 1.7),
00244 PixRGB<byte>(256,256,256)
00245 );
00246 }
00247
00248 Image<PixRGB<byte> > getScene(ViewPort3D& vp, double gtx, double gty)
00249 {
00250 vp.initFrame();
00251
00252
00253 vp.drawBox( Point3D<float>(0,0,0),
00254 Point3D<float>(0,0,0),
00255 Point3D<float>(9.14400, 9.14400, 0.001),
00256 PixRGB<byte>(256,256,256)
00257 );
00258
00259 vp.drawBox( Point3D<float>(-(10.9728/2)+(9.144/2),-(23.7744/2)+(9.144/2),0),
00260 Point3D<float>(0,0,0),
00261 Point3D<float>(10.9728, 23.7744, 0.001),
00262 PixRGB<byte>(256,256,256)
00263 );
00264
00265 if (gtx != -1)
00266 {
00267 vp.drawBox( Point3D<float>(gtx-(9.144/2),
00268 gty-(9.144/2),1.7/2),
00269 Point3D<float>(0,0,0),
00270 Point3D<float>(0.52324,0.5/4, 1.7),
00271 PixRGB<byte>(256,256,256)
00272 );
00273 }
00274
00275 Image<PixRGB<byte> > img(vp.getDims(), ZEROS);
00276 std::vector<ViewPort3D::Line> lines = vp.getFrameLines();
00277 for(uint i=0; i<lines.size(); i++)
00278 drawLine(img, Point2D<int>(lines[i].p1), Point2D<int>(lines[i].p2), PixRGB<byte>(0,255,0));
00279
00280
00281 return img;
00282
00283
00284 }
00285
00286
00287 Image<PixRGB<byte> > getPersonCenter(ViewPort3D& vp, Image<float>& aff,
00288 double px, double py, Point2D<float>& center)
00289 {
00290 vp.initFrame();
00291
00292
00293 Point2D<float> pos = getGpsPos(
00294 double(-118*M_PI/180), double(34*M_PI/180),
00295 py*M_PI/180, px*M_PI/180);
00296
00297 Image<float> x(3, 1, NO_INIT);
00298 x.setVal(0, 0, pos.i);
00299 x.setVal(1, 0, pos.j);
00300 x.setVal(2, 0, 1.0f);
00301
00302
00303 Image<float> mappedLoc = matrixMult(x,aff);
00304
00305 vp.drawBox( Point3D<float>(mappedLoc.getVal(0,0), mappedLoc.getVal(1,0),1.7/2),
00306 Point3D<float>(0,0,0),
00307 Point3D<float>(0.52324,0.5/4, 1.7),
00308 PixRGB<byte>(256,256,256)
00309 );
00310
00311 center = Point2D<float>(0,0);
00312 Image<PixRGB<byte> > img(vp.getDims(), ZEROS);
00313 std::vector<ViewPort3D::Line> lines = vp.getFrameLines();
00314 for(uint i=0; i<lines.size(); i++)
00315 {
00316 drawLine(img, Point2D<int>(lines[i].p1), Point2D<int>(lines[i].p2), PixRGB<byte>(0,0,255));
00317
00318 center += lines[i].p1;
00319 center += lines[i].p2;
00320 }
00321 center /= lines.size()*2;
00322
00323 return img;
00324
00325 }
00326
00327 int getKey(nub::ref<OutputFrameSeries> &ofs)
00328 {
00329 const nub::soft_ref<ImageDisplayStream> ids =
00330 ofs->findFrameDestType<ImageDisplayStream>();
00331
00332 const rutz::shared_ptr<XWinManaged> uiwin =
00333 ids.is_valid()
00334 ? ids->getWindow("gpsOutput")
00335 : rutz::shared_ptr<XWinManaged>();
00336 if (uiwin.is_valid())
00337 return uiwin->getLastKeyPress();
00338 else
00339 return -1;
00340 }
00341
00342 Point2D<int> getMouseClick(nub::ref<OutputFrameSeries> &ofs)
00343 {
00344 const nub::soft_ref<ImageDisplayStream> ids =
00345 ofs->findFrameDestType<ImageDisplayStream>();
00346
00347 const rutz::shared_ptr<XWinManaged> uiwin =
00348 ids.is_valid()
00349 ? ids->getWindow("ViewPort3D")
00350 : rutz::shared_ptr<XWinManaged>();
00351
00352 if (uiwin.is_valid())
00353 return uiwin->getLastMouseClick();
00354 else
00355 return Point2D<int>(-1,-1);
00356 }
00357
00358
00359 std::vector<Point2D<double> > getGpsTracks(const char* filename)
00360 {
00361
00362 std::vector<Point2D<double> > gpsTracks;
00363
00364
00365
00366 gpsTracks.push_back(Point2D<double>(34.021790332,-118.290910238));
00367 gpsTracks.push_back(Point2D<double>(34.021877944,-118.290840708));
00368 gpsTracks.push_back(Point2D<double>(34.021991116,-118.291105977));
00369 gpsTracks.push_back(Point2D<double>(34.021938097,-118.291058661));
00370 gpsTracks.push_back(Point2D<double>(34.021864139,-118.290929807));
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 return gpsTracks;
00389 }
00390
00391 int main(int argc, char *argv[]){
00392
00393 ModelManager manager("Test Viewport");
00394
00395 nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00396 manager.addSubComponent(ofs);
00397
00398 nub::ref<InputFrameSeries> ifs(new InputFrameSeries(manager));
00399 manager.addSubComponent(ifs);
00400
00401
00402
00403 if (manager.parseCommandLine(argc, argv, "<fps> <start>", 2, 2) == false) return(1);
00404
00405 manager.start();
00406
00407 float fps = atof(manager.getExtraArg(0).c_str());
00408 int startFrame = atoi(manager.getExtraArg(1).c_str());
00409
00410
00411
00412
00413 std::vector<Point2D<double> > gpsTracks = getGpsTracks("gpsTracks.txt");
00414
00415
00416
00417 Image<float> aff(3,3,ZEROS);
00418
00419
00420
00421
00422
00423
00424
00425
00426 aff.setVal(0,0,-1.12208358608957); aff.setVal(0,1, -0.622078400100041 ); aff.setVal(0,2, 13980.5274210865 );
00427 aff.setVal(1,0, -0.617532176829138); aff.setVal(1,1, 0.709870729691164); aff.setVal(1,2, -20560.1790593578 );
00428 aff.setVal(2,0, 0 ); aff.setVal(2,1, 0 ); aff.setVal(2,2, 1 );
00429
00430 ViewPort3D vp(1920,1088, true, false, true);
00431 vp.setProjectionMatrix(27, 1.680, 0.005, 500);
00432
00433
00434
00435
00436
00437
00438
00439 Point3D<float> camPos(-7.7, -35.8, 20.0);
00440 Point3D<float> camOri(117.000000, 0.000000, -26.000000);
00441
00442
00443
00444
00445
00446
00447 Point2D<int> lastLoc(512/2,512/2);
00448 Point2D<int> clickPos(-1,-1);
00449
00450
00451 Image< PixRGB<byte> > inputImg;
00452
00453
00454
00455
00456
00457 int frameOne = ifs->frame();
00458 for(float frame=startFrame; frame<240000*fps; frame++)
00459 {
00460 ifs->updateNext();
00461
00462
00463
00464
00465
00466 GenericFrame input = ifs->readFrame();
00467
00468
00469 inputImg = input.asRgb();
00470
00471
00472
00473 int key = getKey(ofs);
00474 switch(key)
00475 {
00476 case 113: camPos.x -= 0.1; break;
00477 case 114: camPos.x += 0.1; break;
00478 case 111: camPos.y -= 0.1; break;
00479 case 116: camPos.y += 0.1; break;
00480 case 38: camPos.z += 0.1; break;
00481 case 52: camPos.z -= 0.1; break;
00482
00483 case 10: camOri.x += 1; break;
00484 case 24: camOri.x -= 1; break;
00485 case 11: camOri.y += 1; break;
00486 case 25: camOri.y -= 1; break;
00487 case 12: camOri.z += 1; break;
00488 case 26: camOri.z -= 1; break;
00489
00490 default:
00491 if (key != -1)
00492 LINFO("Key %i", key);
00493 break;
00494 }
00495 vp.setCamera(camPos, camOri);
00496
00497 Point2D<int> mouseLoc = getMouseClick(ofs);
00498 if (mouseLoc.isValid())
00499 {
00500 clickPos = mouseLoc;
00501
00502 Point3D<float> pos3D = vp.getPosition(Point3D<float>(clickPos.i, clickPos.j, -29));
00503 LINFO("Click Pos %ix%i %fx%fx%f", clickPos.i, clickPos.j, pos3D.x, pos3D.y, pos3D.z);
00504 }
00505
00506
00507
00508
00509
00510 int idx = (int(float(ifs->frame()-frameOne)/fps) + startFrame)%gpsTracks.size();
00511
00512 LINFO("Frame %i idx: %i (%f,%f)", ifs->frame() - frameOne, idx, gpsTracks[idx].i, gpsTracks[idx].j );
00513 Point2D<float> personCenter;
00514 Image<PixRGB<byte> > projectedScene = getPersonCenter(vp, aff,
00515 gpsTracks[idx].i, gpsTracks[idx].j, personCenter);
00516
00517
00518 vp.initFrame();
00519
00520
00521
00522
00523
00524
00525 vp.drawCircle(Point3D<float>(0,0,0), Point3D<float>(0,0,0), 0.25, PixRGB<byte>(255,0,0));
00526 vp.drawCircle(Point3D<float>(14.5796,0,0), Point3D<float>(0,0,0), 0.25, PixRGB<byte>(255,0,0));
00527 vp.drawCircle(Point3D<float>(14.5796,27.9654,0), Point3D<float>(0,0,0), 0.25, PixRGB<byte>(255,0,0));
00528 vp.drawCircle(Point3D<float>(8.4582,1.8542+11.91,0), Point3D<float>(0,0,0), 0.25, PixRGB<byte>(255,0,0));
00529 vp.drawCircle(Point3D<float>(8.4582,1.8542,0), Point3D<float>(0,0,0), 0.25, PixRGB<byte>(255,0,0));
00530 vp.drawGrid(Dims(100,100), Dims(5,5));
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 Image<PixRGB<byte> > img(vp.getDims(), ZEROS);
00541 std::vector<ViewPort3D::Line> lines = vp.getFrameLines();
00542 for(uint i=0; i<lines.size(); i++)
00543 drawLine(img, Point2D<int>(lines[i].p1), Point2D<int>(lines[i].p2), PixRGB<byte>(0,128,0),1);
00544
00545 Image<PixRGB<byte> > tmp = inputImg + img;
00546
00547 int cropWidth = 130;
00548 drawCircle(tmp, Point2D<int>(personCenter), cropWidth, PixRGB<byte>(255,0,0));
00549
00550 if (inputImg.coordsOk(Point2D<int>((int)personCenter.i + cropWidth, (int)personCenter.j + cropWidth)) )
00551 {
00552 Point2D<int> tl((int)personCenter.i - cropWidth, (int)personCenter.j - cropWidth);
00553
00554 if (inputImg.coordsOk(Point2D<int>((int)personCenter.i - cropWidth, (int)personCenter.j - cropWidth)))
00555 {
00556 Image<PixRGB<byte> > patch = crop(inputImg, tl, Dims(cropWidth*2, cropWidth*2));
00557
00558 inplacePaste(tmp, patch, Point2D<int>(100,900-cropWidth*2));
00559 drawRect(tmp, Rectangle(Point2D<int>(100,900-cropWidth*2), Dims(cropWidth*2, cropWidth*2)),
00560 PixRGB<byte>(0,255,0),3);
00561 } else {
00562 if (tl.i <= 0) tl.i = 0;
00563 if (tl.j <= 0) tl.j = 0;
00564
00565 Image<PixRGB<byte> > patch = crop(inputImg, tl, Dims(cropWidth*2, cropWidth*2));
00566
00567 inplacePaste(tmp, patch, Point2D<int>(100,900-cropWidth*2));
00568 drawRect(tmp, Rectangle(Point2D<int>(100,900-cropWidth*2), Dims(cropWidth*2, cropWidth*2)),
00569 PixRGB<byte>(0,255,0),3);
00570 }
00571
00572 }
00573
00574
00575 ofs->writeRGB(tmp, "gpsOutput", FrameInfo("gpsOutput", SRC_POS));
00576 usleep(10000);
00577
00578 }
00579
00580 exit(0);
00581
00582 }