KINECT STATS GENERATOR FOR SPORTS VISUALISATION  1.0
BallTrackingVisualization.cpp
Go to the documentation of this file.
00001 #include "BallTrackingVisualization.h"
00002 #include "StatsVisualization.h"
00003 
00004 #include <iostream>
00005 #include <libfreenect.hpp>
00006 #include <libfreenect_sync.h>
00007 #include <Mutex.h>
00008 #include <QDebug>
00009 #include <KinectInterface.h>
00010 #include <ngl/NGLInit.h>
00011 #include <ngl/ShaderLib.h>
00012 
00013 /*
00014   LICENSING: You are free to use any part of this project provided I am informed about it via email
00015   at santoshwins@hotmail.com and referenced appropriately in your works
00016   */
00017 
00018 //----------------------------------------------------------------------------------------------------------------------
00019 BallTrackingVisualization::BallTrackingVisualization(QWidget *_parent) : QGLWidget( new CreateCoreGLContext(QGLFormat::defaultFormat()), _parent )
00020 
00021 {
00022 
00023   // re-size the widget to that of the parent (in this case the GLFrame passed in on construction)
00024   this->resize(_parent->size());
00025   startTimer(20);
00026   m_rgb = cvCreateMat(480,640,CV_8UC3);
00027 
00028   m_gray = cvCreateMat(480,640,CV_8UC1);
00029 
00030   m_nextBuffer = cvCreateMat(480,640,CV_8UC1);
00031   m_prevBuffer = cvCreateMat(480,640,CV_8UC1);
00032   m_diffBuffer = cvCreateMat(480,640,CV_8UC1);
00033 
00034   m_bufferDepthRaw=cvCreateMat(480,640,CV_8UC1);
00035   m_bufferDepthRaw1=cvCreateMat(480,640,CV_8UC1);
00036 
00037   m_binaryLowerThresh = 100.0;
00038   m_binaryMaxVal = 255.0;
00039   m_cannyLowerThresh = 100.0;
00040   m_cannyHigherThresh = 200.0;
00041   m_contourAreaThresh = 100.0;
00042   m_diffAreaThresh = 10.0;
00043   m_ellipsesize = 2;
00044   m_blurSize = 5;
00045   m_noOfTimesToDialate = 2;
00046 
00047   m_masterRigCheck = 0;
00048 
00049   for( unsigned int i = 0 ; i < 640*480 ; ++i)
00050   {
00051       m_depthinm[i] = 0;
00052   }
00053 
00054 
00055   m_momentList.clear();
00056 
00057   area = rectArea = 0.0;
00058 }
00059 
00060 // This virtual function is called once before the first call to paintGL() or resizeGL(),
00061 //and then once whenever the widget has been assigned a new QGLContext.
00062 // This function should set up any required OpenGL context rendering flags, defining display lists, etc.
00063 
00064 //----------------------------------------------------------------------------------------------------------------------
00065 void BallTrackingVisualization::initializeGL()
00066 {
00067 
00068   glEnable(GL_DEPTH_TEST);
00069 
00070 
00071     //
00072   ngl::NGLInit *Init = ngl::NGLInit::instance();
00073   Init->initGlew();
00074 
00075   // now we have valid GL can create shaders etc
00076   ngl::ShaderLib *shader = ngl::ShaderLib::instance();
00077   shader->createShaderProgram("TextureTrack");
00078 
00079   shader->attachShader("TextureVertex",ngl::VERTEX);
00080   shader->attachShader("TextureFragment",ngl::FRAGMENT);
00081   shader->loadShaderSource("TextureVertex","shaders/TextureVert.glsl");
00082   shader->loadShaderSource("TextureFragment","shaders/TextureFrag.glsl");
00083 
00084   shader->compileShader("TextureVertex");
00085   shader->compileShader("TextureFragment");
00086   shader->attachShaderToProgram("TextureTrack","TextureVertex");
00087   shader->attachShaderToProgram("TextureTrack","TextureFragment");
00088 
00089   shader->linkProgramObject("TextureTrack");
00090   (*shader)["TextureTrack"]->use();
00091   shader->setShaderParam1i("tex",0);
00092 
00093   m_screen = new ScreenQuad(640,480,"TextureTrack");
00094 
00095 
00096 }
00097 
00098 //----------------------------------------------------------------------------------------------------------------------
00099 //This virtual function is called whenever the widget has been resized.
00100 // The new size is passed in width and height.
00101 void BallTrackingVisualization::resizeGL(
00102                         int _w,
00103                         int _h
00104                        )
00105 {
00106   glViewport(0,0,_w,_h);
00107 
00108 }
00109 
00110 //----------------------------------------------------------------------------------------------------------------------
00111 //This virtual function is called whenever the widget needs to be painted.
00112 // this is our main drawing routine
00113 void BallTrackingVisualization::paintGL()
00114 {
00115     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00116 
00117 
00118     KinectInterface *kinect=KinectInterface::instance();
00119 
00120     cv::Rect _boundsCheck = kinect->getBoxObject();
00121 
00122     if(kinect->getTrackingFlag())
00123     {
00124 
00125 
00126         static int _frameCount = 1;
00127        float depth = 0.0;
00128 
00129         kinect->getDepthRaw(m_bufferDepthRaw,m_depthinm);
00130 
00131         // commented for gpu trial
00132 
00133         cv::blur(m_bufferDepthRaw,m_bufferDepthRaw1,cv::Size(m_blurSize,m_blurSize)); // to reduce noise, smotthing has been done
00134         /*  cv::gpu::blur(m_bufferDepthRawGpu,m_bufferDepthRawGpu1,cv::Size(m_blurSize,m_blurSize));*/
00135 
00136         if(_frameCount == 1)
00137         {
00138             m_bufferDepthRaw1.copyTo(m_prevBuffer);
00139         }
00140 
00141         m_bufferDepthRaw1.copyTo(m_nextBuffer);
00142 
00143         // commented for gpu trial
00144 
00145         cv::absdiff(m_nextBuffer,m_prevBuffer,m_diffBuffer); // has gpu variant // bg subtraction by frame differencing ...GMM method seems good through forums if at all we need
00146         /*cv::gpu::absdiff(m_nextBufferGpu,m_prevBufferGpu,m_diffBufferGpu);*/
00147 
00148         m_nextBuffer.copyTo(m_prevBuffer);
00149 
00150         // commented for gpu trial
00151 
00152         m_diffBuffer.copyTo(m_gray);
00153         /*m_diffBuffer.copyTo(m_grayGpu);*/
00154 
00155         // commented for gpu tiral
00156         cv::threshold(m_gray,m_gray,m_binaryLowerThresh,m_binaryMaxVal,CV_THRESH_BINARY_INV); // nned to decide the thresh factors and the thresh method
00157         cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE,cv::Size(m_ellipsesize,m_ellipsesize)); // need to decide this size
00158         cv::dilate(m_gray,m_gray,element,cv::Point(-1,-1),m_noOfTimesToDialate); // try swapping this with below and try increasing iterations
00159         cv::erode(m_gray,m_gray,element,cv::Point(-1,-1),m_noOfTimesToDialate);
00160 
00161         /*cv::gpu::threshold(m_grayGpu,m_grayGpu,m_binaryLowerThresh,m_binaryMaxVal,CV_THRESH_BINARY_INV);
00162         cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE,cv::Size(m_ellipsesize,m_ellipsesize)); // need to decide this size
00163         cv::gpu::dilate(m_grayGpu,m_grayGpu,element,cv::Point(-1,-1),m_noOfTimesToDialate); // try swapping this with below and try increasing iterations
00164         cv::gpu::erode(m_grayGpu,m_grayGpu,element,cv::Point(-1,-1),m_noOfTimesToDialate);*/
00165 
00166         // commented for gpu trial
00167 
00168         // Detect edges using canny
00169         cv::Canny( m_gray, canny_output, m_cannyLowerThresh, m_cannyHigherThresh, 3 ); // maintiain upper::lower ratio as 2:1 or 3:1 for better results
00170                                                                                      // as suggested by CANNY
00171         /*  cv::gpu::Canny(m_grayGpu, canny_outputGpu, m_cannyLowerThresh, m_cannyHigherThresh, 3);*/
00172         // commented for gpu trial
00173 
00174         // Find contours
00175         cv::findContours( canny_output, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) ); // methods to be decided
00176         /*cv::findContours( canny_outputGpu, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) ); // methods to be decided*/
00177 
00178 
00179         cv::Mat drawing = cv::Mat::zeros( canny_output.size(), CV_8UC3 );
00180 
00181 
00182         for( int i = 0; i < contours.size(); i++ )
00183         {
00184 
00185             /* cv::drawContours( drawing, contours, i, cv::Scalar(255,0,0),-1, 8, hierarchy, 0, cv::Point() );*/ // -- DEV PURPOSE
00186 
00187             area = cv::contourArea(contours[i], false);
00188 
00189             cv::RotatedRect r = cv::minAreaRect(contours[i]);
00190 
00191 
00192 
00193             if (fabs(area) < m_contourAreaThresh) //my notes: this value is more important in reducing the false positives and filters out those false positives by preventing them
00194                                     // from getting processed further..provide in UI
00195             {
00196                 continue;
00197             }
00198             else
00199             {
00200                 // do nothing
00201             }
00202 
00203             if (fabs(fabs(area) - (r.size.width * r.size.height * 3.14 / 4)) < m_diffAreaThresh)
00204             {
00205 
00206                 m_momentList.push_back(cv::moments( contours[i], false ));
00207 
00208                 float _xMomentsTemp = static_cast<float>(cv::moments( contours[i], false ).m10/cv::moments( contours[i], false ).m00);
00209                 float _yMomentsTemp = static_cast<float>(cv::moments( contours[i], false ).m01/cv::moments( contours[i], false ).m00);
00210 
00211                 int depthIndex = (int)((640 - _xMomentsTemp) + (640 * _yMomentsTemp));
00212                 depth = m_depthinm[depthIndex] * 0.001;
00213 
00214                 if(depth != 0)
00215                 {
00216                    if((_xMomentsTemp >= _boundsCheck.x) && (_xMomentsTemp <= _boundsCheck.x + _boundsCheck.width)
00217                            && (_yMomentsTemp >= _boundsCheck.y) && (_yMomentsTemp <= _boundsCheck.y + _boundsCheck.height))
00218                    {
00219                        cv::ellipse(drawing,r,cv::Scalar(0,255,0),-1,8);
00220                        std::cout<<"Rect center x:"<<r.center.x<<"\n";
00221                    }
00222                  }
00223 
00224              }
00225 
00226           }
00227 
00228        _frameCount++;
00229 
00230        m_screen->draw(&drawing);
00231 
00232      }
00233      else
00234      {
00235         // tracking not yet started...do nothing
00236      }
00237 
00238 }
00239 
00240 //----------------------------------------------------------------------------------------------------------------------
00241 void BallTrackingVisualization::mouseMoveEvent ( QMouseEvent * _event)
00242 {
00243     Q_UNUSED(_event);
00244 }
00245 
00246 
00247 //----------------------------------------------------------------------------------------------------------------------
00248 void BallTrackingVisualization::mousePressEvent (QMouseEvent * _event )
00249 {
00250     Q_UNUSED(_event);
00251 
00252 }
00253 
00254 //----------------------------------------------------------------------------------------------------------------------
00255 void BallTrackingVisualization::mouseReleaseEvent ( QMouseEvent * _event )
00256 {
00257   // this event is called when the mouse button is released
00258   // we then set Rotate to false
00259   Q_UNUSED(_event);
00260 
00261 }
00262 
00263 void BallTrackingVisualization::timerEvent( QTimerEvent *_event )
00264 {
00265     Q_UNUSED(_event);
00266     // re-draw GL
00267     updateGL();
00268 
00269 }
00270 
00271 
00272 BallTrackingVisualization::~BallTrackingVisualization()
00273 {
00274     if(m_screen)
00275     {
00276         delete m_screen;
00277     }
00278 }
00279 
00280 
00281 
00282 void BallTrackingVisualization::setBinaryLowerThresh(double _lowerThresh)
00283 {
00284     m_binaryLowerThresh = _lowerThresh;
00285     updateGL();
00286 }
00287 
00288 void BallTrackingVisualization::setStructuringElementSize(int _size)
00289 {
00290     m_ellipsesize = _size;
00291     updateGL();
00292 }
00293 
00294 void BallTrackingVisualization::setBlurSize(int _size)
00295 {
00296     m_blurSize = _size;
00297     updateGL();
00298 }
00299 
00300 void BallTrackingVisualization::setCannyLowerThresh(double _lowerThresh)
00301 {
00302     m_cannyLowerThresh = _lowerThresh;
00303     updateGL();
00304 }
00305 
00306 
00307 void BallTrackingVisualization::setCannyHigherThresh(double _higherThresh)
00308 {
00309     m_cannyHigherThresh = _higherThresh;
00310     updateGL();
00311 }
00312 
00313 
00314 void BallTrackingVisualization::setNumerOfDialtions(int _numberOfDialtions)
00315 {
00316     m_noOfTimesToDialate = _numberOfDialtions;
00317     updateGL();
00318 }
00319 
00320 void BallTrackingVisualization::setContourAreaThresh(double _contourAreaThresh)
00321 {
00322     m_contourAreaThresh = _contourAreaThresh;
00323     updateGL();
00324 }
00325 
00326 void BallTrackingVisualization::setDifferenceInAreaThresh(double _diffAreaThresh)
00327 {
00328     m_diffAreaThresh = _diffAreaThresh;
00329     updateGL();
00330 }
00331 
00332 void BallTrackingVisualization::setMasterRigCheck(int _masterRigCheck)
00333 {
00334     m_masterRigCheck = _masterRigCheck;
00335     updateGL();
00336 }
00337 
 All Classes Files Functions Variables Enumerations Enumerator