Plane * findPBP(Point * a, Point *b){ Vector * n = findUnitDirVector(a, b); Point * mid = findMidPoint(a, b); Plane * pbp = malloc(sizeof(Plane)); pbp->d = mid->x*n->x + mid->y*n->y + mid->z*n->z; pbp->a = n->x; pbp->b = n->y; pbp->c = n->z; free(n); free(mid); return pbp; }
LMPacket LMHandler::handle( cv::Point2f borderPoints[ 3 ] , MazeData mazeData , bool debugMode ) { if( debugMode ) { std::cout << std::endl ; std::cout << "<!---------------------------------------------" ; std::cout << std::endl ; std::cout << "LMHandler.handle() called. handling..." ; std::cout << std::endl ; } if ( IsNull( mazeData ) ) { std::cerr << "LMHandler: mazeData of type MazeData is Null" ; std::cerr << std::endl ; return LMPacketNull ; } if ( !mazeData.image.data ) { std::cerr << "LMHandler: No mazeImage data!" ; std::cerr << std::endl ; return LMPacketNull ; } // Declare local variables cv::Mat annotatedImage ; cv::Mat processingImage ; cv::Point2f startLocation ; cv::Point2f endLocation ; cv::Point2f ballLocation ; cv::Point2f centerLocation ; cv::Point2f criticalPoints[ 6 ] ; float criticalAngles[ 6 ] ; float zeroAngle ; float ballAngle ; int sextantIndex ; float scalingArray[ 5 ] ; float normalizedBallAngle ; // our guy! std::vector< std::vector< cv::Point > > contours ; std::vector< std::vector< cv::Point > > approxContours ; std::vector< cv::Vec4i > hierarchy ; //std::vector< cv::Point > boundingTriangleVertices ; int boundingTriangleIndex ; // Initialize local variables annotatedImage = mazeData.image.clone( ) ; startLocation = mazeData.mazePoints[ 0 ] ; endLocation = mazeData.mazePoints[ 1 ] ; ballLocation = mazeData.mazePoints[ 2 ] ; centerLocation = startLocation ; criticalPoints[ 0 ] = borderPoints[ 0 ] ; // one end of upos criticalPoints[ 2 ] = borderPoints[ 1 ] ; // one end of vpos criticalPoints[ 4 ] = borderPoints[ 2 ] ; // one end of wpos criticalPoints[ 1 ] = findMidPoint( criticalPoints[ 0 ] , criticalPoints[ 2 ] ); // one end of wneg criticalPoints[ 3 ] = findMidPoint( criticalPoints[ 2 ] , criticalPoints[ 4 ] ); // one end of uneg criticalPoints[ 5 ] = findMidPoint( criticalPoints[ 0 ] , criticalPoints[ 4 ] ); // one end of vneg for ( int i = 0 ; i < 6 ; i++ ) { std::stringstream ss; ss << std::to_string( i ) << std::fixed << std::setprecision( 0 ) << "("; ss << criticalPoints[ i ].x << "," << criticalPoints[ i ].y << ")"; std::string label = ss.str(); /* std::string label ; label.assign( std::to_string( i ) ); label += "- ( "; label += std::to_string( criticalPoints[ i ].x ); label += " , "; label += std::to_string( criticalPoints[ i ].y ); label += " )"; */ setLabel( annotatedImage , label , criticalPoints[ i ] ) ; // start } /* setLabel( annotatedImage , "0" , criticalPoints[ 0 ] ) ; // start setLabel( annotatedImage , "1" , criticalPoints[ 1 ] ) ; // start setLabel( annotatedImage , "2" , criticalPoints[ 2 ] ) ; // start setLabel( annotatedImage , "3" , criticalPoints[ 3 ] ) ; // start setLabel( annotatedImage , "4" , criticalPoints[ 4 ] ) ; // start setLabel( annotatedImage , "5" , criticalPoints[ 5 ] ) ; // start */ // Draw a line in between S & B cv::line( annotatedImage , centerLocation , criticalPoints[ 0 ] , CV_RGB ( 0 , 255 , 255 ) , 1 ) ; cv::line( annotatedImage , centerLocation , criticalPoints[ 1 ] , CV_RGB ( 0 , 255 , 255 ) , 1 ) ; cv::line( annotatedImage , centerLocation , criticalPoints[ 2 ] , CV_RGB ( 0 , 255 , 255 ) , 1 ) ; cv::line( annotatedImage , centerLocation , criticalPoints[ 3 ] , CV_RGB ( 0 , 255 , 255 ) , 1 ) ; cv::line( annotatedImage , centerLocation , criticalPoints[ 4 ] , CV_RGB ( 0 , 255 , 255 ) , 1 ) ; cv::line( annotatedImage , centerLocation , criticalPoints[ 5 ] , CV_RGB ( 0 , 255 , 255 ) , 1 ) ; ballAngle = findRelativeAngle( centerLocation, ballLocation); if( debugMode ) { std::cout << "Critical points importing complete. " ; std::cout << std::endl; std::cout << "Critical points:"; std::cout << std::endl; for( int i = 0 ; i < 6 ; i++ ) { std::cout << "[ " << i << " ] : "; std::cout << criticalPoints[ i ]; std::cout << std::endl; } std::cout << "Ball angle:"; std::cout << ballAngle << std::endl; } if( debugMode ) { std::cout << "Calculating critical angles. " ; std::cout << std::endl; } criticalAngles[ 0 ] = findRelativeAngle( centerLocation, criticalPoints[ 0 ]); // upos criticalAngles[ 1 ] = findRelativeAngle( centerLocation, criticalPoints[ 1 ]); // wneg criticalAngles[ 2 ] = findRelativeAngle( centerLocation, criticalPoints[ 2 ]); // vpos criticalAngles[ 3 ] = findRelativeAngle( centerLocation, criticalPoints[ 3 ]); // uneg criticalAngles[ 4 ] = findRelativeAngle( centerLocation, criticalPoints[ 4 ]); // wpos criticalAngles[ 5 ] = findRelativeAngle( centerLocation, criticalPoints[ 5 ]); // vneg zeroAngle = criticalAngles[ 0 ]; // uneg is our zero if( debugMode ) { std::cout << "Calculating critical angles complete. " ; std::cout << std::endl; std::cout << "Critical angles:"; std::cout << std::endl; for( int i = 0 ; i < 6 ; i++ ) { std::cout << "[ " << i << " ] : "; std::cout << criticalAngles[ i ]; std::cout << std::endl; } std::cout << "Zero angle: "; std::cout << zeroAngle; std::cout << std::endl; } if( debugMode ) { std::cout << "Finding sextant index. " ; std::cout << std::endl; } sextantIndex = -1 ; for( int i = 0 ; i < 6 ; i++ ) { if( ballAngle >= criticalAngles[ i ] ) { sextantIndex = i ; } } if( sextantIndex == -1 ) { std::cerr << "LMHandler: sextantIndex estimation failed" ; std::cerr << std::endl ; return LMPacketNull ; } if( debugMode ) { std::cout << "Finding sextant index complete. " ; std::cout << std::endl; std::cout << "Sextant index: "; std::cout << sextantIndex; std::cout << std::endl; } if( debugMode ) { std::cout << "Updating critical angles. " ; std::cout << std::endl; } for( int i = 0 ; i < 6 ; i++) { criticalAngles[ i ] -= zeroAngle ; criticalAngles[ i ] = ( criticalAngles[ i ] >= 0 ? 0 : 360 ) + criticalAngles[ i ]; } ballAngle -= zeroAngle ; ballAngle = ( ballAngle >= 0 ? 0 : 360 ) + ballAngle; if( debugMode ) { std::cout << "Updating critical angles complete. " ; std::cout << std::endl; std::cout << "Updated critical angles:"; std::cout << std::endl; for( int i = 0 ; i < 6 ; i++ ) { std::cout << "[ " << i << " ] : "; std::cout << criticalAngles[ i ]; std::cout << std::endl; } } if( debugMode ) { std::cout << "Finding scaling parameters. " ; std::cout << std::endl; } for( int i = 0; i < 6; i++ ) { scalingArray[ i ] = 60 / ( criticalAngles[ (i + 1) % 6 ] - criticalAngles[ i ] ) ; } if( debugMode ) { std::cout << "Finding scaling parameters complete. " ; std::cout << std::endl; std::cout << "Scaling parameters:"; std::cout << std::endl; for( int i = 0 ; i < 5 ; i++ ) { std::cout << "[ " << i << " ] : "; std::cout << scalingArray[ i ]; std::cout << std::endl; } } if( debugMode ) { std::cout << "Finding normalized ball angle. " ; std::cout << std::endl; } normalizedBallAngle = sextantIndex * 60 + ( ballAngle - criticalAngles[ sextantIndex ] ) * scalingArray[ sextantIndex ]; if( debugMode ) { std::cout << "Finding normalized ball angle complete. " ; std::cout << std::endl; std::cout << "Ball angle: "; std::cout << ballAngle; std::cout << std::endl; std::cout << "Normalized ball angle: "; std::cout << normalizedBallAngle; std::cout << std::endl; } if( normalizedBallAngle < 0 || normalizedBallAngle > 360 ) { std::cerr << "LMHandler: normalizedBallAngle is out of bounds!" ; std::cerr << std::endl ; return LMPacketNull ; } extractContours( mazeData.image , processingImage , contours, approxContours, hierarchy ); if( debugMode ) { std::cout << "Contour extraction complete. Number of approx. contours found: " ; std::cout << approxContours.size() ; std::cout << std::endl; } /* boundingTriangleIndex = findBoundingTriangle( approxContours ) ; if( boundingTriangleIndex == -1 ) { return LMPacketNull; } if( debugMode ) { std::cout << "The bounding triangle found at index: " ; std::cout << std::to_string( boundingTriangleIndex ) ; std::cout << std::endl; std::cout << "The related hierarchy record: " ; std::cout << hierarchy[ boundingTriangleIndex ] ; std::cout << std::endl; std::cout << "The child record: " ; std::cout << hierarchy[ boundingTriangleIndex ][ 2 ] ; std::cout << std::endl; } // Annote all vertices of the approximation curve vector and extract the vertices for( std::vector< cv::Point >::size_type i = 0 ; i != 3 ; i++ ) { setLabel( annotatedImage , "V" , approxContours[ boundingTriangleIndex ] ); } */ /* // Annote all vertices of the approximation curve vector and extract the vertices // hierarchy[i][2] -> first child int mazeBoundIndex = hierarchy[ boundingTriangleIndex ][ 2 ]; for( std::vector< cv::Point >::size_type i = 0 ; i != 3 ; i++ ) { setLabel( annotatedImage , "M" , approxContours[ mazeBoundIndex ] ); } */ cv::Mat dummyImage ; // Delete everything outside the triangle cv::Mat mask = cv::Mat::zeros( processingImage.size( ) , CV_8UC1 ); //std::vector< std::vector< cv::Point > > dummyContours ; //dummyContours.push_back( contours ); //cv::drawContours( mask , contours , -1 , cv::Scalar( 255 ) , CV_FILLED ); cv::drawContours( mask , contours , -1 , cv::Scalar( 255 ) , CV_FILLED ); if( debugMode ) { std::cout << "Search for contours is complete. Displaying the results:" ; std::cout << std::endl; showImage( "LM-mask" , mask ); } processingImage.copyTo( dummyImage , mask ) ; processingImage = dummyImage.clone( ) ; //processingImage.copyTo( processingImage , mask ) ; //annotatedImage.copyTo( dummyImage , mask ) ; //annotatedImage = dummyImage.clone( ) ; //setLabel( annotatedImage , "0" , contours[ 0 ] ) ; if( debugMode ) { std::cout << "Masking complete. Displaying the results:" ; std::cout << std::endl; showImage( "LM-maskedProcessingImage" , processingImage ); } //ballLocation centerocation if( debugMode ) { //std::cout << "Search for contours is complete. Displaying the results:" ; //std::cout << std::endl; /* displayContours( "LM-Contours on processingImage" , processingImage.clone() , contours , hierarchy , // approxContours false , true ); // true ); // for enumeration , for contour only mode */ /* displayContours( "LM-Contours on mazeImage" , mazeData.image.clone() , contours , hierarchy , // approxContours false , false ); */ /* displayContours( "LM-approxContours on processingImage" , processingImage.clone() , approxContours , hierarchy , // approxContours false , true ); // true ); // for enumeration , for contour only mode displayContours( "LM-approxContours on mazeImage" , mazeData.image.clone() , approxContours , hierarchy , // approxContours false , false ); */ } //slope = startLocation.y - ballLocation //Point2f a(0.3f, 0.f), b(0.f, 0.4f); //Point pt = (a + b)*10.f; // Label the annotatedImage setLabel( annotatedImage , "S" , centerLocation ) ; // start setLabel( annotatedImage , "E" , endLocation ) ; // end setLabel( annotatedImage , "B" , ballLocation ) ; // ball // Draw a line in between S & B cv::line( annotatedImage , centerLocation , ballLocation , CV_RGB ( 0 , 255 , 255 ) , 1 ) ; //double radius = cv::norm( startLocation - ballLocation ) ;//Euclidian distance //cv::circle( annotatedImage, startLocation, radius, CV_RGB ( 0 , 255 , 0 ) , 1 ) ; if( debugMode ) { std::cout << "Annotating feature points and drawing line complete." ; std::cout << std::endl; } /* CountNonZero(bitwise_and(ShapeAImage,ShapeBImage)). */ //////////////////////////////////////////////////////// /////////////////////// EXPORTING ////////////////////// //////////////////////////////////////////////////////// // Export private variables this -> annotatedImage = annotatedImage.clone( ) ; // Exporting state variables state.ballLocationData.wayBlocked[ 0 ] = false ; state.ballLocationData.wayBlocked[ 1 ] = false ; state.ballLocationData.wayBlocked[ 2 ] = false ; state.ballLocationData.wayBlocked[ 3 ] = false ; state.ballLocationData.currentPathNo = 5 ; state.ballPositionAngle = normalizedBallAngle ; //////////////////////////////////////////////////////// ////////////////// EXPORTING COMPLETE ////////////////// //////////////////////////////////////////////////////// if( debugMode ) { std::cout << "State exporting complete." ; std::cout << std::endl; std::cout << "---------------------------------------------->"; std::cout << std::endl; std::cout << std::endl; } return state; }