void DepthProcessor::findBlobs() { if (!getDepthData()) return; Surface8u to8(mDepthSource->getDepthImage()); cv::Mat input( toOcv( to8)); cv::Mat gray; cv::Mat thresh; cv::cvtColor( input, gray, CV_RGB2GRAY ); cv::threshold(gray, gray, mDepthLowPass, 0, CV_THRESH_TOZERO_INV); if (mInitInitial < mInitFrames) { if (mInitInitial == 0) mInitial = gray.clone(); else mInitial = cv::max(gray, mInitial); mInitInitial++; return; } gray -= mInitial; cv::accumulateWeighted(gray, mLastGray, 0.9); mLastGray.convertTo(gray, CV_8U); cv::threshold( gray, thresh, mStepFrom, 255, CV_THRESH_BINARY ); auto& blobs = mBlobs[1 - mIndexFG]; blobs.clear(); float largest = mAreaThreshold; mContourSurfaces.pushFront(thresh.clone()); ContourVector vec; cv::findContours( thresh, vec, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); for( ContourVector::iterator iter = vec.begin(); iter != vec.end(); ++iter ) { float a = cv::contourArea(*iter); if (a > largest) { Blob b; b.mContourArea = a; b.mContourPoints.resize(iter->size()); copy(iter->begin(), iter->end(), b.mContourPoints.begin()); blobs.push_back(b); push_heap(blobs.begin(), blobs.end(), SortDescendingArea()); if (blobs.size() > DepthProcessor::smMAX_BLOBS) { blobs.erase(blobs.end()-1); largest = blobs.rbegin()->mContourArea; } } } for (BlobVector::iterator i = blobs.begin(); i != blobs.end(); i++) { i->mCentroid.x = i->mCentroid.y = 0.0f; float mag = 10000.0f; i->mLeftMost.x = mag; i->mRightMost.x = -mag; i->mTopMost.y = mag; i->mBottomMost.y = -mag; i->mBounds.x1 = i->mBounds.y1 = mag; i->mBounds.x2 = i->mBounds.y2 = -mag; for (vector<cv::Point>::iterator pt = i->mContourPoints.begin(); pt != i->mContourPoints.end(); ++pt) { i->mCentroid.x += pt->x; i->mCentroid.y += pt->y; i->mBounds.include(Vec2f(pt->x, pt->y)); if (i->mLeftMost.x > pt->x) { i->mLeftMost.x = pt->x; i->mLeftMost.y = pt->y; } if (i->mRightMost.x < pt->x) { i->mRightMost.x = pt->x; i->mRightMost.y = pt->y; } if (i->mTopMost.y > pt->y) { i->mTopMost.x = pt->x; i->mTopMost.y = pt->y; } if (i->mBottomMost.y < pt->y) { i->mBottomMost.x = pt->x; i->mBottomMost.y = pt->y; } } float sz = i->mContourPoints.size(); if (sz > 0.0f) { i->mCentroid.x /= sz; i->mCentroid.y /= sz; } i->mZDist = *to8.getDataRed(i->mCentroid); // Loop through and do z calc float steps = 10.0f; Vec3f step = (i->mBottomMost - i->mTopMost) / steps; Vec3f sample = i->mTopMost; for (int x = 0; x < steps; x++) { if (thresh.at<uint8_t>(cv::Point(sample.x, sample.y)) > 0) { float val = *to8.getDataRed(Vec2f(sample.x, sample.y)); if (val < mDepthLowPass) i->mZDist = max(i->mZDist, val); } sample += step; } step = (i->mRightMost - i->mLeftMost) / steps; sample = i->mLeftMost; for (int x = 0; x < steps; x++) { if (thresh.at<uint8_t>(cv::Point(sample.x, sample.y)) > 0) { float val = *to8.getDataRed(Vec2f(sample.x, sample.y)); if (val < mDepthLowPass) i->mZDist = max(i->mZDist, val); } sample += step; } } sort(blobs.begin(), blobs.end(), SortDescendingZ()); { BlobLock b(mBlobMutex); mIndexFG = 1 - mIndexFG; } }
void MotionTrackingTestApp::draw() { // gl::setViewport( getWindowBounds() ); // clear out the window with black gl::clear( Color( 1, 1, 1 ) ); // if( mSurface ){ // if( mTexture ){ // mTexture->update( mSurface ); // } else { // mTexture = gl::Texture::create( mSurface ); // } // gl::draw( mTexture, mTexture->getBounds(), getWindowBounds() ); // } if( mSurfaceDepth ){ if( mTextureDepth ){ mTextureDepth->update( Channel32f( mSurfaceDepth ) ); } else { mTextureDepth = gl::Texture::create( Channel32f( mSurfaceDepth ) ); } gl::color( Color::white() ); gl::draw( mTextureDepth, mTextureDepth->getBounds() ); } gl::pushMatrices(); gl::translate( Vec2f( 320, 0 ) ); if( mSurfaceBlur ){ if( mTextureDepth ){ mTextureDepth->update( Channel32f( mSurfaceBlur ) ); } else { mTextureDepth = gl::Texture::create( Channel32f( mSurfaceBlur ) ); } gl::draw( mTextureDepth, mTextureDepth->getBounds() ); } gl::translate( Vec2f( 0, 240 ) ); if( mSurfaceSubtract ){ if( mTextureDepth ){ mTextureDepth->update( Channel32f( mSurfaceSubtract ) ); } else { mTextureDepth = gl::Texture::create( Channel32f( mSurfaceSubtract ) ); } gl::draw( mTextureDepth, mTextureDepth->getBounds() ); } gl::translate( Vec2f( -320, 0 ) ); for( ContourVector::iterator iter = mContours.begin(); iter != mContours.end(); ++iter ){ glBegin( GL_LINE_LOOP ); for( vector< cv::Point >::iterator pt = iter->begin(); pt != iter->end(); ++pt ){ gl::color( Color( 1.0f, 0.0f, 0.0f ) ); gl::vertex( fromOcv( *pt ) ); } glEnd(); } gl::translate( Vec2f( 0, 240 ) ); for( int i=0; i<mTrackedShapes.size(); i++){ glBegin( GL_POINTS ); for( int j=0; j<mTrackedShapes[i].hull.size(); j++ ){ gl::color( Color( 1.0f, 0.0f, 0.0f ) ); gl::vertex( fromOcv( mTrackedShapes[i].hull[j] ) ); } glEnd(); } gl::popMatrices(); mParams->draw(); }