Advertisement
Guest User

Untitled

a guest
Jan 30th, 2015
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.03 KB | None | 0 0
  1. #include <opencv\cv.h>
  2. #include <opencv\highgui.h>
  3.  
  4. using namespace std;
  5. using namespace cv;
  6.  
  7. //our sensitivity value to be used in the threshold() function
  8. const static int SENSITIVITY_VALUE = 20;
  9. //size of blur used to smooth the image to remove possible noise and
  10. //increase the size of the object we are trying to track. (Much like dilate and erode)
  11. const static int BLUR_SIZE = 30;
  12. //we'll have just one object to search for
  13. //and keep track of its position.
  14. int theObject[2] = { 0, 0 };
  15. //bounding rectangle of the object, we will use the center of this as its position.
  16. Rect objectBoundingRectangle = Rect(0, 0, 0, 0);
  17.  
  18.  
  19. //int to string helper function
  20. string intToString(int number){
  21.  
  22.     //this function has a number input and string output
  23.     std::stringstream ss;
  24.     ss << number;
  25.     return ss.str();
  26. }
  27.  
  28. void searchForMovement(Mat thresholdImage, Mat &cameraFeed){
  29.     //notice how we use the '&' operator for the cameraFeed. This is because we wish
  30.     //to take the values passed into the function and manipulate them, rather than just working with a copy.
  31.     //eg. we draw to the cameraFeed in this function which is then displayed in the main() function.
  32.     bool objectDetected = false;
  33.     Mat temp;
  34.     thresholdImage.copyTo(temp);
  35.     //these two vectors needed for output of findContours
  36.     vector< vector<Point> > contours;
  37.     vector<Vec4i> hierarchy;
  38.     //find contours of filtered image using openCV findContours function
  39.     //findContours(temp,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE );// retrieves all contours
  40.     findContours(temp, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);// retrieves external contours
  41.  
  42.     //if contours vector is not empty, we have found some objects
  43.     if (contours.size()>0)objectDetected = true;
  44.     else objectDetected = false;
  45.  
  46.     if (objectDetected){
  47.         //the largest contour is found at the end of the contours vector
  48.         //we will simply assume that the biggest contour is the object we are looking for.
  49.         vector< vector<Point> > largestContourVec;
  50.         largestContourVec.push_back(contours.at(contours.size() - 1));
  51.         //make a bounding rectangle around the largest contour then find its centroid
  52.         //this will be the object's final estimated position.
  53.         objectBoundingRectangle = boundingRect(largestContourVec.at(0));
  54.         int xpos = objectBoundingRectangle.x + objectBoundingRectangle.width / 2;
  55.         int ypos = objectBoundingRectangle.y + objectBoundingRectangle.height / 2;
  56.  
  57.         //update the objects positions by changing the 'theObject' array values
  58.         theObject[0] = xpos, theObject[1] = ypos;
  59.     }
  60.     //make some temp x and y variables so we dont have to type out so much
  61.     int x = theObject[0];
  62.     int y = theObject[1];
  63.     //draw some crosshairs on the object
  64.     circle(cameraFeed, Point(x, y), 50, Scalar(0, 255, 0), 2);      //******************50 IS THE SIZE OF THE CIRCLE
  65.     line(cameraFeed, Point(x, y), Point(x, y - 50), Scalar(0, 255, 0), 2);  //**********50 IS THE SIZE OF THE CROSS HAIR
  66.     line(cameraFeed, Point(x, y), Point(x, y + 50), Scalar(0, 255, 0), 2);
  67.     line(cameraFeed, Point(x, y), Point(x - 50, y), Scalar(0, 255, 0), 2);
  68.     line(cameraFeed, Point(x, y), Point(x + 50, y), Scalar(0, 255, 0), 2);
  69.     putText(cameraFeed, "(" + intToString(x) + "," + intToString(y) + ")", Point(x, y), 1, 1, Scalar(255, 0, 0), 2);//*********MODIFIED
  70.  
  71.  
  72.  
  73. }
  74. int main(){
  75.  
  76.     //some boolean variables for added functionality
  77.     bool objectDetected = false;
  78.     //these two can be toggled by pressing 'd' or 't'
  79.     bool debugMode = false;
  80.     bool trackingEnabled = false;
  81.     //pause and resume code
  82.     bool pause = false;
  83.     //set up the matrices that we will need
  84.     //the two frames we will be comparing
  85.     Mat frame1, frame2;
  86.     //their grayscale images (needed for absdiff() function)
  87.     Mat grayImage1, grayImage2;
  88.     //resulting difference image
  89.     Mat differenceImage;
  90.     //thresholded difference image (for use in findContours() function)
  91.     Mat thresholdImage;
  92.     //video capture object.
  93.     VideoCapture capture;
  94.  
  95.     while (1){
  96.  
  97.         //we can loop the video by re-opening the capture every time the video reaches its last frame
  98.  
  99.         capture.open("C:\\Users\koviroli\\Desktop\\moving_ball2.mp4");  //*********OPEN VIDEO FILE
  100.  
  101.         if (!capture.isOpened()){
  102.             cout << "ERROR ACQUIRING VIDEO FEED\n";
  103.             getchar();
  104.             return -1;
  105.         }
  106.  
  107.         //check if the video has reach its last frame.
  108.         //we add '-1' because we are reading two frames from the video at a time.
  109.         //if this is not included, we get a memory error!
  110.         while (capture.get(CV_CAP_PROP_POS_FRAMES)<capture.get(CV_CAP_PROP_FRAME_COUNT) - 1){
  111.  
  112.             //read first frame
  113.             capture.read(frame1);
  114.             //convert frame1 to gray scale for frame differencing
  115.             cv::cvtColor(frame1, grayImage1, COLOR_BGR2GRAY);
  116.             //copy second frame
  117.             capture.read(frame2);
  118.             //convert frame2 to gray scale for frame differencing
  119.             cv::cvtColor(frame2, grayImage2, COLOR_BGR2GRAY);
  120.             //perform frame differencing with the sequential images. This will output an "intensity image"
  121.             //do not confuse this with a threshold image, we will need to perform thresholding afterwards.
  122.             cv::absdiff(grayImage1, grayImage2, differenceImage);
  123.             //threshold intensity image at a given sensitivity value
  124.             cv::threshold(differenceImage, thresholdImage, SENSITIVITY_VALUE, 255, THRESH_BINARY);
  125.             if (debugMode == true){
  126.                 //show the difference image and threshold image
  127.                 cv::imshow("Difference Image", differenceImage);
  128.                 cv::imshow("Threshold Image", thresholdImage);
  129.             }
  130.             else{
  131.                 //if not in debug mode, destroy the windows so we don't see them anymore
  132.                 cv::destroyWindow("Difference Image");
  133.                 cv::destroyWindow("Threshold Image");
  134.             }
  135.             //use blur() to smooth the image, remove possible noise and
  136.             //increase the size of the object we are trying to track. (Much like dilate and erode)
  137.             cv::blur(thresholdImage, thresholdImage, cv::Size(BLUR_SIZE, BLUR_SIZE));
  138.             //threshold again to obtain binary image from blur output
  139.             cv::threshold(thresholdImage, thresholdImage, SENSITIVITY_VALUE, 255, THRESH_BINARY);
  140.             if (debugMode == true){
  141.                 //show the threshold image after it's been "blurred"
  142.                 imshow("Final Threshold Image", thresholdImage);
  143.             }
  144.             else {
  145.                 //if not in debug mode, destroy the windows so we don't see them anymore
  146.                 cv::destroyWindow("Final Threshold Image");
  147.             }
  148.  
  149.             //if tracking enabled, search for contours in our thresholded image
  150.             if (trackingEnabled){
  151.                 searchForMovement(thresholdImage, frame1);
  152.             }
  153.             //show our captured frame
  154.             imshow("Frame1", frame1);
  155.             //check to see if a button has been pressed.
  156.             //this 10ms delay is necessary for proper operation of this program
  157.             //if removed, frames will not have enough time to referesh and a blank
  158.             //image will appear.
  159.             switch (waitKey(75)){   //*****************THIS WAITKEY WILL RUN VIDEO SLOWER OR FASTER
  160.  
  161.             case 27: //'esc' key has been pressed, exit program.
  162.                 return 0;
  163.             case 116: //'t' has been pressed. this will toggle tracking
  164.                 trackingEnabled = !trackingEnabled;
  165.                 if (trackingEnabled == false) cout << "Tracking disabled." << endl;
  166.                 else cout << "Tracking enabled." << endl;
  167.                 break;
  168.             case 100: //'d' has been pressed. this will debug mode
  169.                 debugMode = !debugMode;
  170.                 if (debugMode == false) cout << "Debug mode disabled." << endl;
  171.                 else cout << "Debug mode enabled." << endl;
  172.                 break;
  173.             case 112: //'p' has been pressed. this will pause/resume the code.
  174.                 pause = !pause;
  175.                 if (pause == true){
  176.                     cout << "Code paused, press 'p' again to resume" << endl;
  177.                     while (pause == true){
  178.                         //stay in this loop until
  179.                         switch (waitKey()){
  180.                             //a switch statement inside a switch statement? Mind blown.
  181.                         case 112:
  182.                             //change pause back to false
  183.                             pause = false;
  184.                             cout << "Code resumed." << endl;
  185.                             break;
  186.                         }
  187.                     }
  188.                 }
  189.  
  190.  
  191.             }
  192.  
  193.  
  194.         }
  195.         //release the capture before re-opening and looping again.
  196.         capture.release();
  197.     }
  198.  
  199.     return 0;
  200.  
  201. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement