//************************************************************************ // CLCDGfx::StartTransition //************************************************************************ void CLCDGfx::Cache() { DWORD dwStart = GetTickCount(); // Initialize pixels if(m_eTransition == TRANSITION_MORPH) { SLCDPixel *pPixel = NULL; SLCDPixel *pSource = NULL; int iIndex = 0; bool bBreak = false; bool bSearch = true; int iTransitionPixels = 0; POINT pt; for(int j=0;j<2;j++) { iIndex = 0; for(int i=0;i<m_nHeight * m_nWidth;i++) { pt.y = i/m_nWidth; pt.x = i - (i/m_nWidth)*m_nWidth; if((j==0 && !PtInRect(&m_rTransitionRegion,pt)) || (m_pSavedBitmapBits[i] != 0x00 && (j==1 || m_pBitmapBits[i] != 0x00))) { iIndex = i; pPixel = new SLCDPixel(); pPixel->dSpeed = GetRandomDouble()*0.5 + 1; if(!PtInRect(&m_rTransitionRegion,pt)) { pPixel->cValue = m_pBitmapBits[i]; } else { pPixel->cValue = m_pSavedBitmapBits[i]; } pPixel->Start.y = pt.y; pPixel->Start.x = pt.x; pPixel->Position = pPixel->Start; bBreak = false; if(j==1 && bSearch) { // search for a pixel in circles with increasing radius around the location iIndex = findNearestMatch(m_pBitmapBits,i); if(iIndex < 0) { iIndex = i; } else { bBreak = true; } } if(j==0 || bBreak) { pPixel->Destination.y = iIndex/m_nWidth; pPixel->Destination.x = iIndex - (iIndex/m_nWidth)*m_nWidth; m_pBitmapBits[iIndex] = 0; m_pSavedBitmapBits[i] = 0; if(bBreak) iTransitionPixels++; } else { if(m_LMovingPixels.size() > 0 && iTransitionPixels > 0) { pSource = m_LMovingPixels[GetRandomInt(0, (int)m_LMovingPixels.size()-1)]; pPixel->Destination = pSource->Destination; } else { pPixel->Destination.x = GetRandomInt(0,m_nWidth-1); pPixel->Destination.y = GetRandomInt(0,1)==1?-1:m_nHeight+1; } bSearch = false; } if(j == 0) m_LStaticPixels.push_back(pPixel); else { m_LMovingPixels.push_back(pPixel); } } } } bool bRandom = false; if(m_LMovingPixels.size() <= 0) bRandom = true; for(iIndex=0;iIndex<m_nHeight * m_nWidth;iIndex++) { if(m_pBitmapBits[iIndex] == 0) continue; pPixel = new SLCDPixel(); pPixel->dSpeed = GetRandomDouble()*0.5 + 1; pPixel->cValue = m_pBitmapBits[iIndex]; if(!bRandom) { pSource = m_LMovingPixels[GetRandomInt(0, (int)m_LMovingPixels.size()-1)]; pPixel->Start = pSource->Start; } else { pPixel->Start.x = GetRandomInt(0,m_nWidth-1); pPixel->Start.y = GetRandomInt(0,1)==1?-1:m_nHeight+1; } pPixel->Position = pPixel->Start; pPixel->Destination.y = iIndex/m_nWidth; pPixel->Destination.x = iIndex - (iIndex/m_nWidth)*m_nWidth; m_LMovingPixels.push_back(pPixel); } } m_dwTransitionStart = GetTickCount(); TRACE(_T("Textmorphing: time consumed: %0.2f\n"),(double)(m_dwTransitionStart-dwStart)/(double)1000); }
void ShapeDetection::onDepth( openni::VideoFrameRef frame, const OpenNI::DeviceOptions& deviceOptions ) { // convert frame from the camera to an OpenCV matrix mInput = toOcv( OpenNI::toChannel16u(frame) ); cv::Mat thresh; cv::Mat eightBit; cv::Mat withoutBlack; // remove black pixels from frame which get detected as noise withoutBlack = removeBlack( mInput, mNearLimit, mFarLimit ); // convert matrix from 16 bit to 8 bit with some color compensation withoutBlack.convertTo( eightBit, CV_8UC3, 0.1/1.0 ); // invert the image cv::bitwise_not( eightBit, eightBit ); mContours.clear(); mApproxContours.clear(); // using a threshold to reduce noise cv::threshold( eightBit, thresh, mThresh, mMaxVal, CV_8U ); // draw lines around shapes cv::findContours( thresh, mContours, mHierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); vector<cv::Point> approx; // approx number of points per contour for ( int i = 0; i < mContours.size(); i++ ) { cv::approxPolyDP(mContours[i], approx, 1, true ); mApproxContours.push_back( approx ); } mShapes.clear(); // get data that we can later compare mShapes = getEvaluationSet( mApproxContours, 75, 100000 ); // find the nearest match for each shape for ( int i = 0; i < mTrackedShapes.size(); i++ ) { Shape* nearestShape = findNearestMatch( mTrackedShapes[i], mShapes, 5000 ); // a tracked shape was found, update that tracked shape with the new shape if ( nearestShape != NULL ) { nearestShape->matchFound = true; mTrackedShapes[i].centroid = nearestShape->centroid; // get depth value from center point float centerDepth = (float)mInput.at<short>( mTrackedShapes[i].centroid.y, mTrackedShapes[i].centroid.x ); // map 10 10000 to 0 1 mTrackedShapes[i].depth = lmap( centerDepth, (float)mNearLimit, (float)mFarLimit, 0.0f, 1.0f ); mTrackedShapes[i].lastFrameSeen = ci::app::getElapsedFrames(); mTrackedShapes[i].hull.clear(); mTrackedShapes[i].hull = nearestShape->hull; mTrackedShapes[i].motion = nearestShape->motion; Vec3f centerVec = Vec3f( mTrackedShapes[i].centroid.x, mTrackedShapes[i].centroid.y, 0.0f ); mTrackedShapes[i].mTrailPoint.arrive(centerVec); mTrackedShapes[i].mTrailPoint.updateTrail(); } } // if shape->matchFound is false, add it as a new shape for ( int i = 0; i < mShapes.size(); i++ ) { if( mShapes[i].matchFound == false ){ // assign an unique ID mShapes[i].ID = shapeUID; mShapes[i].lastFrameSeen = ci::app::getElapsedFrames(); // starting point of the trail mShapes[i].mTrailPoint.mLocation = Vec3f( mShapes[i].centroid.x, mShapes[i].centroid.y, 0.0f ); // add this new shape to tracked shapes mTrackedShapes.push_back( mShapes[i] ); shapeUID++; } } // if we didn't find a match for x frames, delete the tracked shape for ( vector<Shape>::iterator it = mTrackedShapes.begin(); it != mTrackedShapes.end(); ) { if ( ci::app::getElapsedFrames() - it->lastFrameSeen > 20 ) { // remove the tracked shape it = mTrackedShapes.erase(it); } else { ++it; } } mSurfaceDepth = Surface8u( fromOcv( mInput ) ); mSurfaceSubtract = Surface8u( fromOcv(eightBit) ); }