KINECT STATS GENERATOR FOR SPORTS VISUALISATION  1.0
ThreeDStatsGeneration.cpp
Go to the documentation of this file.
00001 #include "ThreeDStatsGeneration.h"
00002 
00003 //#include <Spline.hpp>
00004 
00005 /*
00006   LICENSING: You are free to use any part of this project provided I am informed about it via email
00007   at santoshwins@hotmail.com and referenced appropriately in your works
00008   */
00009 
00010 
00011 // to serve as comparison function object for vector SORT
00012 bool compare3FOnX(cv::Point3f i, cv::Point3f j){ return (i.x < j.x);}
00013 
00014 ThreeDStatsGeneration::ThreeDStatsGeneration()
00015 {
00016     m_quadFitX = new QuadCurveFitUtility();
00017     m_quadFitY = new QuadCurveFitUtility();
00018     m_quadFitZ = new QuadCurveFitUtility();
00019 }
00020 
00021 ThreeDStatsGeneration::~ThreeDStatsGeneration()
00022 {
00023     delete m_quadFitX;
00024     delete m_quadFitY;
00025     delete m_quadFitZ;
00026 }
00027 
00028 
00029 void ThreeDStatsGeneration::generatePitchDensityGraphData(cv::Point& _userDefinedTopXY, int _userDefinedWidth, int _userDefinedHeight,
00030                                                         int _gridResolution,
00031                                                         std::vector<cv::Point> &_playerImpactPtsAllRallies,
00032                                                         std::vector<cv::Point3f>& o_verticesSetOfCubeBarsGraph)
00033 {
00034     //for each point in the input array
00035 
00036     // each cell width = inputwidth/gridresolution
00037     // each cell height = inputheight/gridresolution
00038     // hashx = floor((point.x - _userDefinedTopXY.x)/each cell width)
00039     // hashy = floor((point.y - _userDefinedTopXY.y)/each cell height)
00040 
00041     // 1D hash value is hashx + hashy * gridresolution
00042 
00043     // push the point as vec[hashvalue].push_back(point)
00044 
00045     std::vector<std::vector<cv::Point> > hashMappedData;
00046 
00047     // remember to mention these scale factors
00048     float _scaleFactor = 10.0;
00049     int _heightUpScaleFactor = 1.0;
00050 
00051 
00052     float _scaledWidth = ((float)_userDefinedWidth/_scaleFactor);
00053     float _scaledHeight = ((float)_userDefinedHeight/_scaleFactor);
00054 
00055     // we scale down by 10 as pixel coords will be too large
00056 
00057 
00058     float _scaledTopX = ((float)_userDefinedTopXY.x/_scaleFactor);
00059     float _scaledTopY = ((float)_userDefinedTopXY.y/_scaleFactor);
00060 
00061     float _individualCellWidth = _scaledWidth/(float)_gridResolution; // typecast fully if problem arises
00062     float _individualCellHeight = _scaledHeight/(float)_gridResolution;
00063 
00064     int hashIncrement = 0;
00065 
00066     hashMappedData.resize(_gridResolution * _gridResolution);
00067 
00068     hashMappedData.clear();
00069 
00070 //    // allocate enough data for hashmap
00071     for(int i=0;i<_gridResolution * _gridResolution;i++)
00072     {
00073         hashMappedData.push_back(std::vector<cv::Point> ());
00074 
00075         hashMappedData[i].push_back(cv::Point(0,0));
00076     }
00077 
00078 
00079 
00080     for(int i=0;i<_playerImpactPtsAllRallies.size();i++)
00081     {
00082         int hashX = floor((((float)_playerImpactPtsAllRallies[i].x/_scaleFactor) - _scaledTopX)/_individualCellWidth);
00083         int hashY = floor((((float)_playerImpactPtsAllRallies[i].y/_scaleFactor) - _scaledTopY)/_individualCellHeight);
00084 
00085         int hashValue = (hashX + (hashY * _gridResolution));
00086 
00087         hashMappedData[hashValue].push_back(_playerImpactPtsAllRallies[i]);
00088     }
00089 
00090 
00091     // and then make the grid flow from -w to +w
00092     // and -z to +z with grid origin at center
00093     // so subtract w/2 and h/2 respectively
00094 
00095     //float _scaledTopXTranslated = _scaledTopX - (_scaledWidth/2);
00096     //float _scaledTopYTranslated = _scaledTopY - (_scaledHeight/2);
00097 
00098 
00099     float _scaledTopXTranslated =  -(_scaledWidth/2);
00100     float _scaledTopYTranslated =  -(_scaledHeight/2);
00101 
00102 //    float tempBottomX4 = 0.0, tempBottomZ4 = 0.0, tempBottomY4 = 0.0 , tempBottomX3 = 0.0, tempBottomZ3 = 0.0,tempBottomY3 = 0.0;
00103 
00104 //    float tempBottomX2 = 0.0, tempBottomZ2 = 0.0,tempBottomY2 = 0.0,tempBottomX1 = 0.0,tempBottomZ1 = 0.0,tempBottomY1 = 0.0;
00105 
00106 //    float tempTopX4 = 0.0,tempTopZ4 = 0.0,tempTopY4 = 0.0,tempTopX3 = 0.0,tempTopZ3 = 0.0,tempTopY3 = 0.0,tempTopX2 = 0.0,tempTopZ2 = 0.0;
00107 //    float tempTopY2 = 0.0,tempTopX1 = 0.0,tempTopZ1 = 0.0,tempTopY1 = 0.0;
00108 
00109 
00110     //for(float i=_scaledTopYTranslated;i<(_scaledTopYTranslated + _scaledHeight);i=i+_individualCellHeight)
00111     //{
00112       //  for(float j=_scaledTopXTranslated;j<(_scaledTopXTranslated + _scaledWidth);j=j+_individualCellWidth)
00113         //{
00114 
00115     float xPos = _scaledTopXTranslated;
00116     float zPos = _scaledTopYTranslated;
00117 
00118             for(int i = 0;i<_gridResolution;i++)
00119             {
00120                 for(int j=0;j<_gridResolution;j++)
00121                 {
00122 
00123 
00124                     if((hashMappedData[hashIncrement].size() - 1) == 0)
00125                     {
00126                         // no need to push the data as this quad should not be rendered
00127                         // with 0 height
00128                         hashIncrement++;
00129 
00130                         xPos = xPos + _individualCellWidth;
00131                         continue;
00132 
00133                     }
00134              float tempBottomX4 = xPos;
00135              float tempBottomZ4 = zPos;
00136              float tempBottomY4 = 0.0;
00137 
00138              float tempBottomX3 = xPos + _individualCellWidth;
00139              float tempBottomZ3 = zPos;
00140              float tempBottomY3 = 0.0;
00141 
00142              float tempBottomX2 = xPos + _individualCellWidth;
00143              float tempBottomZ2 = zPos + _individualCellHeight;
00144              float tempBottomY2 = 0.0;
00145 
00146              float tempBottomX1 = xPos;
00147              float tempBottomZ1 = zPos + _individualCellHeight;
00148              float tempBottomY1 = 0.0;
00149 
00150              float tempTopX4 = tempBottomX4;
00151              float tempTopZ4 = tempBottomZ4;
00152              float tempTopY4 = (hashMappedData[hashIncrement].size() - 1) * _heightUpScaleFactor;
00153 
00154              float tempTopX3 = tempBottomX3;
00155              float tempTopZ3 = tempBottomZ3;
00156              float tempTopY3 = (hashMappedData[hashIncrement].size() - 1) * _heightUpScaleFactor;
00157 
00158              float tempTopX2 = tempBottomX2;
00159              float tempTopZ2 = tempBottomZ2;
00160              float tempTopY2 = (hashMappedData[hashIncrement].size() - 1) * _heightUpScaleFactor;
00161 
00162              float tempTopX1 = tempBottomX1;
00163              float tempTopZ1 = tempBottomZ1;
00164              float tempTopY1 = (hashMappedData[hashIncrement].size() - 1) * _heightUpScaleFactor;
00165 
00166 
00167                      //std::cout<<"tempTopX1:"<<tempTop
00168 
00169             if((hashMappedData[hashIncrement].size() - 1) != 0)
00170             {
00171                 std::cout<<"hashmap Y:"<<(hashMappedData[hashIncrement].size() - 1)<<"\n";
00172             }
00173 
00174             // top first - clockwise
00175             o_verticesSetOfCubeBarsGraph.push_back(cv::Point3f(tempTopX1,tempTopY1,tempTopZ1));
00176             o_verticesSetOfCubeBarsGraph.push_back(cv::Point3f(tempTopX2,tempTopY2,tempTopZ2));
00177             o_verticesSetOfCubeBarsGraph.push_back(cv::Point3f(tempTopX3,tempTopY3,tempTopZ3));
00178             o_verticesSetOfCubeBarsGraph.push_back(cv::Point3f(tempTopX4,tempTopY4,tempTopZ4));
00179 
00180             // bottom next - clockwise
00181             o_verticesSetOfCubeBarsGraph.push_back(cv::Point3f(tempBottomX1,tempBottomY1,tempBottomZ1));
00182             o_verticesSetOfCubeBarsGraph.push_back(cv::Point3f(tempBottomX2,tempBottomY2,tempBottomZ2));
00183             o_verticesSetOfCubeBarsGraph.push_back(cv::Point3f(tempBottomX3,tempBottomY3,tempBottomZ3));
00184             o_verticesSetOfCubeBarsGraph.push_back(cv::Point3f(tempBottomX4,tempBottomY4,tempBottomZ4));
00185 
00186             // incerement the hash index as we move on to the next row
00187             hashIncrement++;
00188 
00189             xPos = xPos + _individualCellWidth;
00190 
00191         }
00192 
00193                 xPos = _scaledTopXTranslated;
00194                 zPos = zPos + _individualCellHeight;
00195 
00196 
00197     }
00198 
00199 }
00200 
00201 
00202 void ThreeDStatsGeneration::generateInterpolatedDataForAllRallies(std::vector<std::vector<cv::Point3f> > &_inputPlayerBallPts,
00203                                                                   std::vector<std::vector<int> > &_playerDeepestPtIndices,
00204                                                                   float _inputDistanceFrmKinectToPlayArea,
00205                                                                   std::vector<std::vector<cv::Point3f> > &o_interpPlayerBallPts,
00206                                                                   std::vector<float> &o_speedData)
00207 {
00208 
00209     int tempFirstIndex = 0;
00210     int tempLastIndex = 0;
00211 
00212     float paramT = 0.0;
00213 
00214     float deltaT = 0.0;
00215 
00216     // coeffs for velocity calculation
00217     float coeffX,coeffY,coeffZ;
00218 
00219     coeffX = coeffY = coeffZ = 0.0;
00220 
00221     float tempVelocity = 0.0;
00222     float tempCoeffSquared = 0.0;
00223 
00224   /*  magnet::math::Spline splineX,splineY,splineZ;
00225 
00226     splineX.clear();
00227     splineY.clear();
00228     splineZ.clear();*/
00229 
00230 
00231     // for each rally
00232     for(int i=0;i<_inputPlayerBallPts.size();i++)
00233     {
00234 
00235 
00236         // if there is no data in the depth point for this rally,
00237         // then we have come to the end dummy space which we
00238         // pushed in for rally direction change in ballprocessing
00239         if(_playerDeepestPtIndices[i].size() == 0)
00240         {
00241             continue;
00242         }
00243         // allocate data for our grand big interpolated data
00244         // for this rally
00245         o_interpPlayerBallPts.push_back(std::vector<cv::Point3f>());
00246         o_interpPlayerBallPts[i].clear();
00247 
00248         // allocate data correspondingly for our velocity
00249         // for the current rally impact points
00250         //o_speedData.push_back(std::vector<float> ());
00251         //o_speedData[i].clear();
00252 
00253         // for each depth point in the current rally,
00254         // extract from rally[j] to rally[j+1]
00255         // execute this for depthsize + 1 as we need to extract from one start depth
00256         // to another depth..so we need j and j+1 always
00257         // we will understand when we write the code////note to self: fill this comment
00258         for(int j=0;j<(_playerDeepestPtIndices[i].size() + 1);j++)
00259         {
00260             // when j == size - 1
00261             // then we need to extract the rest from _inputpoints[j] until _inputpoints[_inputpoints.size - 1]
00262             //tempFirstIndex = j;
00263 
00264             if(j == 0)
00265             {
00266                 tempFirstIndex = j;
00267                 if(_playerDeepestPtIndices[i][j] != -1)
00268                 {
00269                     tempLastIndex = _playerDeepestPtIndices[i][j];
00270                 }
00271                 // if -1, then no impact data detected for this rally, so extract from first to last of the rally
00272                 // nothing in intermediate
00273                 else
00274                 {
00275                     tempLastIndex = (_inputPlayerBallPts[i].size() - 1);
00276                 }
00277             }
00278             else if (j == _playerDeepestPtIndices[i].size())
00279             {
00280                 tempFirstIndex = _playerDeepestPtIndices[i][(j-1)];
00281                 tempLastIndex = (_inputPlayerBallPts[i].size() - 1);
00282             }
00283             else
00284             {
00285                 tempFirstIndex = _playerDeepestPtIndices[i][(j-1)];
00286                 tempLastIndex = _playerDeepestPtIndices[i][j];
00287             }
00288 
00289 
00290             std::vector<cv::Point3f>::const_iterator first = _inputPlayerBallPts[i].begin() + tempFirstIndex;
00291             std::vector<cv::Point3f>::const_iterator last = _inputPlayerBallPts[i].begin() + tempLastIndex + 1;
00292 
00293             std::vector<cv::Point3f> tempExtractedPts(first,last);
00294 
00295             // sort this temp vector of 3fs
00296             std::sort(tempExtractedPts.begin(),tempExtractedPts.end(),compare3FOnX); // need to check if this really compares
00297 
00298             std::vector<cv::Point3f> tempExtractedPtsInWorldCoords;
00299             tempExtractedPtsInWorldCoords.resize(tempExtractedPts.size());
00300             // convert to world coords before interpolating
00301             convertToWorldFromScreen(tempExtractedPts,tempExtractedPtsInWorldCoords, _inputDistanceFrmKinectToPlayArea);
00302 
00303 
00304             // 3 buffers for interpX,interpY, interpZ
00305             std::vector<float> _bufferX,_bufferY,_bufferZ;
00306 
00307             _bufferX.clear();
00308             _bufferY.clear();
00309             _bufferZ.clear();
00310 
00311             paramT = 0.0;
00312             deltaT = 0.0;
00313 
00314             // for each extracted stream different coeffs, so reset to 0
00315             coeffX = coeffY  = coeffZ = 0.0;
00316 
00317            /* splineX.clear();
00318             splineY.clear();
00319             splineZ.clear();*/
00320 
00321             if(tempExtractedPtsInWorldCoords.size() != 0)
00322             {
00323                 deltaT = (float)(1.0/tempExtractedPtsInWorldCoords.size());
00324             }
00325 
00326            for(int xIndex =0; xIndex<tempExtractedPtsInWorldCoords.size();xIndex++)
00327            {
00328 
00329 
00330                m_quadFitX->addPoints(cv::Point2f(paramT,tempExtractedPtsInWorldCoords[xIndex].x));
00331 
00332                /*splineX.addPoint(paramT,tempExtractedPtsInWorldCoords[xIndex].x);*/
00333 
00334                paramT += deltaT;
00335 
00336 
00337            }
00338 
00339            /*
00340            //A spline which turns into a parabola at the boundaries.
00341 
00342            //This BC does not need extra parameters, so just the condition is
00343            //enough.
00344            splineX.setLowBC(magnet::math::Spline::PARABOLIC_RUNOUT_BC);
00345            splineX.setHighBC(magnet::math::Spline::PARABOLIC_RUNOUT_BC);
00346 
00347            for (double x = (-0.2); x <= 1.2001; x += 0.005)
00348            {
00349               float temp = splineX(x);
00350 
00351              _bufferX.push_back(temp);
00352            }
00353             */
00354 
00355            m_quadFitX->processParametricPoints3D(_bufferX,coeffX);
00356 
00357 
00358            paramT = 0.0;
00359            for(int yIndex =0; yIndex<tempExtractedPtsInWorldCoords.size();yIndex++)
00360            {
00361 
00362 
00363                m_quadFitY->addPoints(cv::Point2f(paramT,tempExtractedPtsInWorldCoords[yIndex].y));
00364 
00365                /*splineY.addPoint(paramT,tempExtractedPtsInWorldCoords[yIndex].y);*/
00366 
00367                paramT += deltaT;
00368 
00369 
00370            }
00371 
00372            /*
00373            //A spline which turns into a parabola at the boundaries.
00374 
00375            //This BC does not need extra parameters, so just the condition is
00376            //enough.
00377            splineY.setLowBC(magnet::math::Spline::PARABOLIC_RUNOUT_BC);
00378            splineY.setHighBC(magnet::math::Spline::PARABOLIC_RUNOUT_BC);
00379 
00380            for (double x = (-0.2); x <= 1.2001; x += 0.005)
00381            {
00382               float temp = splineY(x);
00383 
00384              _bufferY.push_back(temp);
00385            }
00386            */
00387 
00388            m_quadFitY->processParametricPoints3D(_bufferY,coeffY);
00389 
00390 
00391            paramT = 0.0;
00392            for(int zIndex =0; zIndex<tempExtractedPtsInWorldCoords.size();zIndex++)
00393            {
00394 
00395 
00396                m_quadFitZ->addPoints(cv::Point2f(paramT,tempExtractedPtsInWorldCoords[zIndex].z));
00397 
00398                /*splineZ.addPoint(paramT,tempExtractedPtsInWorldCoords[zIndex].z);*/
00399 
00400                paramT += deltaT;
00401 
00402 
00403            }
00404 
00405            /*
00406            //A spline which turns into a parabola at the boundaries.
00407 
00408            //This BC does not need extra parameters, so just the condition is
00409            //enough.
00410            splineZ.setLowBC(magnet::math::Spline::PARABOLIC_RUNOUT_BC);
00411            splineZ.setHighBC(magnet::math::Spline::PARABOLIC_RUNOUT_BC);
00412 
00413            for (double x = (-0.2); x <= 1.2001; x += 0.005)
00414            {
00415               float temp = splineZ(x);
00416 
00417              _bufferZ.push_back(temp);
00418            }
00419            */
00420 
00421            m_quadFitZ->processParametricPoints3D(_bufferZ,coeffZ);
00422 
00423 
00424            if((_bufferX.size() != 0) && (_bufferY.size() != 0) && (_bufferZ.size() != 0)) // checking if we have data in the buffers..need to place additional check to see if all the sizes are equal
00425            {
00426                for(int fillIndex =0; fillIndex<_bufferX.size();fillIndex++)
00427                {
00428 
00429 
00430                    std::cout<<"BufferX:"<<_bufferX[fillIndex]<<"BufferY:"<<_bufferY[fillIndex]<<"BufferZ:"<<_bufferZ[fillIndex]<<"\n";
00431 
00432                    // our grand data (for this rally for this extracted chunk) is pushed in
00433                    o_interpPlayerBallPts[i].push_back(cv::Point3f(_bufferX[fillIndex],_bufferY[fillIndex],_bufferZ[fillIndex]));
00434 
00435 
00436                }
00437            }
00438 
00439            // push speed data for current rally's current extracted stream
00440            // made it single dimensional as we do not need rally specific impact points
00441            // so its a straight 1D vector corresponding to impactpoints3d vector
00442            // filled thru the calculateimpactptin3dfromindices function
00443 
00444            // this check will filter other coeeficients which are actually not at the depth index,
00445            // because, apart from depth index, we also pass in
00446            // parts of array from o to depthindex or from deothindex to next depthindex
00447            // where the intermediate depth index wud push 2 different speeds
00448            // for the same point
00449            // so we should avoid pushing speed at those times
00450 
00451            tempCoeffSquared = pow(coeffX,2) + pow(coeffY,2) + pow(coeffZ,2);
00452            if(tempCoeffSquared <= 0.0)
00453            {
00454                tempVelocity = 0.0;
00455            }
00456            else
00457            {
00458                tempVelocity = sqrt(tempCoeffSquared);
00459            }
00460 
00461            //std::cout<<"TempVelocity:"<<tempVelocity<<"mpersec\n";
00462 
00463            if(tempLastIndex == _playerDeepestPtIndices[i][j])
00464            {
00465                 o_speedData.push_back(tempVelocity);
00466            }
00467 
00468            if(tempLastIndex == (_inputPlayerBallPts[i].size() - 1))
00469            {
00470                // we break out of the for loop
00471                // because if lastindex has a value representing the last element of the
00472                // rally point, there is nothing more to extract
00473                // this last point could have been reached in many ways,
00474                // lik when there is no impact data, 0 to last is extracted
00475                // or if legitemately we have come until the last index like
00476                // 0 ---- impactindex1 ------ impactindex2 ----- lastindex
00477                // or 0 -----impactindex1-----impactindex2(which itself might be referring to the lastindex,
00478                // of the rally, so we should itself break out instead of extracting forward)
00479                break;
00480            }
00481 
00482         }
00483 
00484     }
00485 }
00486 
00487 
00488 void ThreeDStatsGeneration::convertToWorldFromScreen(std::vector<cv::Point3f>& _inputPointVec, std::vector<cv::Point3f>& o_PointsInWorld, float _inputDistanceFrmKinectToPlayArea)
00489 {
00490     // THIS IS TAKEN FROM THE OPENCV WIKI PAGE...
00491     // ALTERNATIVELY, THE TANGENT FORMULAE IN THE IMAGE SAVED IN DESKTOP CAN ALSO BE USED...DO THIS LATER IF ACCURACY SEEMS MISSING
00492     // or from this blog http://magicalkinect.wordpress.com/2013/02/16/metric-measuring-using-kinect/
00493 
00494 //    float minDistance = -10;
00495 //    float scaleFactor = 0.0021;
00496 //    float x = (_iScreen - 640 / 2) * (_zDepth + minDistance) * scaleFactor * (640/480);
00497 //    float y = (_jScreen - 480 / 2) * (_zDepth + minDistance) * scaleFactor;
00498 
00499     for (int i=0;i<_inputPointVec.size();i++)
00500     {
00501         float x = (_inputPointVec[i].x/640 - 0.5) * _inputPointVec[i].z * 1.111467f;
00502         float y = (0.5 - _inputPointVec[i].y/480) * _inputPointVec[i].z * 0.833599f;
00503 
00504         // we can dereference and assign instead of push back because
00505         // we have resized this vector in the parent function
00506 
00507         // my conversion in the view of the kinect
00508         //o_PointsInWorld[i] = cv::Point3f(-(y),(1 - _inputPointVec[i].z),-x);
00509 
00510         // this should actually be ditancefromkinecttotable - z as the table is at 0.762
00511         // so if the ball is at 0.762 from kinect it will be 0 frm the table
00512         // if its at 0.562 from the kinect, it would be at 0.2 from the table
00513         o_PointsInWorld[i] = cv::Point3f((x),fabs(_inputDistanceFrmKinectToPlayArea - _inputPointVec[i].z),-(y));
00514     }
00515 
00516 //    float temp = (58.12/2) * (3.14/180);
00517 //    std::cout<<".........."<< (2 * tan(temp));
00518 
00519  //   std::cout<<" X, Y and Z are:"<<x<<"::"<<y<<"::"<<_zDepth<<"\n";
00520 
00521 
00522 
00523    // m_ballPoints.push_back(cv::Point3f(x,y,(_zDepth)));
00524 
00525 
00526 
00527 }
00528 
00529 
00530 
00531 
00532 // rally specific trajectory if needed can be calculated using the rally number input, full ball points,
00533 // rally number should be valid...0 to size - 1 of the ball pts array
00534 
00535 
00536 //SPEED PITCH MAP
00537 
00538 // once we have equation of 3d data for each rally, we can calculate and display the velocity at the impact points
00539 // for each player and use color coding to display the output
00540 
00541 // this will convert the XY of impact point into XZ of world coordinates to
00542 // project in opengl
00543 // the resulting vector set would map directly to the 1D speed vector populated
00544 // in the getinterpolateddataforallrallies function
00545 void ThreeDStatsGeneration::calculatePlayerImpactPtsIn3DFromIndices(std::vector<std::vector<cv::Point3f> > &_inputPlayerBallPts,
00546                                                               std::vector<std::vector<int> > &_playerDeepestPtIndices,
00547                                                               std::vector<cv::Point3f> &o_playerImpactPtsAllRallies3D)
00548 {
00549     if(_playerDeepestPtIndices.size() != 0)
00550     {
00551         for(int i = 0;i<_playerDeepestPtIndices.size();i++)
00552         {
00553             for(int j=0;j<_playerDeepestPtIndices[i].size();j++)
00554             {
00555 
00556                 // if the impact point index is not -1, then there is an impact point for this rally
00557                 if(_playerDeepestPtIndices[i][j] != -1)
00558                 {
00559 
00560 
00561 
00562                     float x = (_inputPlayerBallPts[i][_playerDeepestPtIndices[i][j]].x/640 - 0.5) *
00563                               _inputPlayerBallPts[i][_playerDeepestPtIndices[i][j]].z * 1.111467f;
00564 
00565                     float y = (0.5 - _inputPlayerBallPts[i][_playerDeepestPtIndices[i][j]].y/480) *
00566                                _inputPlayerBallPts[i][_playerDeepestPtIndices[i][j]].z * 0.833599f;
00567 
00568                     // the plane is going to be at 0,0,0 only
00569                     // and the Y is going to be 0 as this is going to be a projection of
00570                     // XY of pixels into XZ in opengl but in world coords as opposed to
00571                     // pixel coords
00572                     // remeber this is scaled up to 10
00573                     o_playerImpactPtsAllRallies3D.push_back(cv::Point3f(10 * x,0.0,-(10 * y)));
00574                 }
00575                 else
00576                 {
00577                     std::cout<<"No impact point for Rally number:"<<i<<"..so skipping to next rally.\n";
00578                 }
00579 
00580             }
00581         }
00582     }
00583     else
00584     {
00585         std::cout<<"No data in indices array for the player.\n";
00586     }
00587 }
00588 
 All Classes Files Functions Variables Enumerations Enumerator