Advertisement
Guest User

Push-ups

a guest
Apr 29th, 2014
400
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.49 KB | None | 0 0
  1. #include <opencv\highgui.h>
  2. #include <opencv\cv.h>
  3. #include "opencv2/imgproc/imgproc.hpp"
  4. #include "opencv2/highgui/highgui.hpp"
  5. #include <stdlib.h>
  6. #include <iostream>
  7. #include <stdio.h>
  8. #include <list>
  9. #include <cmath>
  10. #include <string>
  11. #include <opencv2\ml\ml.hpp>
  12. #include <Windows.h>
  13.  
  14. using namespace std;
  15. using namespace cv;
  16.  
  17. //Zooming functions
  18. Mat zoomIn(int, int);
  19. Mat zoomOut(int, int);
  20. static void onMouse(int event, int, int, int /*flags*/, void* /*param*/);
  21. void info();
  22. void zoom(Mat);
  23.  
  24. //Our functions
  25. void Morphology_Operations();
  26. void contourDetection();
  27. void draw(int&, vector<Point>&, string);
  28.  
  29. ///////////////////////////Global Variables//////////////////////////////
  30. IplImage* frame = 0;
  31. IplImage* imgGrayscale;
  32. Point2f pCen;
  33.  
  34. //Holds all the detected contours
  35. vector<vector<Point>> contours;
  36.  
  37. //Window variables
  38. HWND console;
  39. HWND look;
  40.  
  41. //Zooming variables
  42. Mat imagenOriginal, imagen, imagenMostrar;
  43.  
  44. int zoomRec = 500;
  45. int mousex, mousey;
  46. int maxRec;
  47. bool last = false;
  48.  
  49.  
  50. //Erosion dialtion variables
  51. Mat src, invsrc, dst;
  52.  
  53. int morph_elem = 0;
  54. int morph_size = 9;
  55. int morph_operator = 0;
  56. int const max_operator = 4;
  57. int const max_elem = 2;
  58. int const max_kernel_size = 21;
  59.  
  60. /////////////
  61.  
  62. int main(){
  63.     console = GetConsoleWindow();
  64.  
  65.     cout << "Loading image....";
  66.  
  67.     //Input image here
  68.     frame = cvLoadImage("train6.jpg");
  69.     src = Mat(frame);   //Convert to Mat
  70.  
  71.     //Find the largest side of the picture
  72.     if (src.rows > src.cols){
  73.         maxRec = src.cols-10;
  74.     }
  75.     else
  76.         maxRec = src.rows-10;
  77.  
  78.     //Create blank image
  79.     imgGrayscale = cvCreateImage(cvGetSize(frame), 8, 1);
  80.  
  81.     cout << "\n\nChanging from color to gray...";
  82.     //Change picture from color to gray
  83.     cvCvtColor(frame, imgGrayscale, CV_BGR2GRAY);
  84.  
  85.     cout << "\n\nThresholding image...";
  86.     //Threshold image to black and white
  87.     cvThreshold(imgGrayscale, imgGrayscale, 85, 255, 1);
  88.  
  89.     // ERODE AND DILATE HERE!!! #####################################
  90.     //*/
  91.     src = imgGrayscale;     //Convert to Mat
  92.    
  93.     bitwise_not(src, invsrc); // inverts image
  94.    
  95.     cout << "\n\nEroding and dialating....";
  96.     Morphology_Operations();        //Erode and dialate
  97.  
  98.     //###############################################################
  99.    
  100.  
  101.     ////////Start of Contour detection///////////////////////////
  102.     system("cls");
  103.  
  104.     info();
  105.     contourDetection();
  106.  
  107.     cout << "Finished!!  Here is the final result." << endl;
  108.  
  109.     //Put the console in the foreground
  110.     SetForegroundWindow(console);
  111.     last = true;
  112.    
  113.     //Change how much you zoom
  114.     zoomRec = maxRec*.50;
  115.    
  116.     //Show your results
  117.     zoom(Mat(frame));
  118.  
  119.     //Used to check the result of the erosion and dialation
  120.     //zoom(dst);
  121.        
  122.     waitKey(0);
  123.  
  124.     //Clean up used images
  125.     cvReleaseImage(&frame);
  126.     cvDestroyAllWindows(); 
  127.  
  128.     return 0;
  129. }
  130.  
  131.  
  132. //Draw function takes in a contour and draws it a given color ("green", "red", or "orange")
  133. void draw(vector<Point>& conts, string color)
  134. {  
  135.     //Total points on the contour
  136.     int totPoints = conts.size();
  137.  
  138.     //Loop through all the points on the contour
  139.     for (int j = 0; j < totPoints - 1; j++)
  140.     {
  141.         if (color == "green")
  142.             cvLine(frame, conts[j], conts[j + 1], cvScalar(0, 255, 0), 1);
  143.         else if (color == "red")
  144.             cvLine(frame, conts[j], conts[j + 1], cvScalar(0, 0, 255), 1);
  145.         else if (color == "orange")
  146.             cvLine(frame, conts[j], conts[j + 1], cvScalar(0, 115, 255), 1);
  147.  
  148.         //On the last point connect to the first point
  149.         if (j == conts.size() - 1){
  150.             if (color == "green")
  151.                 cvLine(frame, conts[j], conts[j + 1], cvScalar(0, 255, 0), 1);
  152.             else if (color == "red")
  153.                 cvLine(frame, conts[j], conts[j + 1], cvScalar(0, 0, 255), 1);
  154.             else if (color == "orange")
  155.                 cvLine(frame, conts[j], conts[j + 1], cvScalar(0, 115, 255), 1);
  156.             break;
  157.         }
  158.     }
  159. }
  160.  
  161. //Uppercase all characters in a string
  162. string strUpper(string str){
  163.     int i = 0;
  164.     while (str[i]){
  165.         str[i] = toupper(str[i]);
  166.         i++;
  167.     }
  168.     return str;
  169. }
  170.  
  171. //Start the contour detection
  172. void contourDetection(){
  173.    
  174.     //Vector that represents the hierarchy of the contours
  175.     vector< Vec4i > hierarchy;
  176.    
  177.     ///Find contours and store in a contours, then store the contour hierarchies in hierarchy
  178.     cv::findContours(dst, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
  179.  
  180.     double area;
  181.     int count = 0, all = 0;
  182.     CvSVM detector;
  183.     bool exit = false;
  184.     vector<vector<double>> allData;
  185.  
  186.     vector<float> labels;
  187.  
  188.     //Load the training data
  189.     detector.load("Muskrat_Counting_SVM.xml");
  190.  
  191.     //Size of the whole picture
  192.     int totSize = dst.total();
  193.  
  194.     //Iterate through all parent contours
  195.     for (int i = 0; i < contours.size() && exit == false; i = hierarchy[i][0])
  196.     {
  197.  
  198.         //Find the size of the outer contours (lakes)
  199.         area = contourArea(contours[i]);
  200.  
  201.         //Find the biggest contours (presumed to be the lakes)**Needs optimization
  202.         if (area > totSize*.20)// && area < totSize*.5)
  203.         {
  204.             //Draw the lake
  205.             draw(contours[i], "red");                                              
  206.  
  207.             //Using hierarchy array to determine hierarchy, this loop is for the child contours
  208.             for (int j = hierarchy[i][2]; hierarchy[j][0] > 0 && exit == false; j = hierarchy[j][0]){
  209.  
  210.                 //Find contour size
  211.                 double contArea = contourArea(contours[j]);
  212.  
  213.                 if (contArea > 20 && contArea < 300){                               //When size of the contour is inbetween those area
  214.  
  215.  
  216.                     //Get the location of the center of the contour for zooming
  217.                     Moments mu = moments(contours[j], false);
  218.                     pCen = Point2f(mu.m10 / mu.m00, mu.m01 / mu.m00);
  219.  
  220.                     all++;
  221.  
  222.                     //Draw current contour
  223.                     draw(contours[j], "orange");
  224.  
  225.                     //Evaluate next contour
  226.                     zoom(Mat(frame));
  227.  
  228.                     //Output question
  229.                     cout << "Is this a contour? (Y or N) ";
  230.                     string input;
  231.  
  232.                     while (exit == false){
  233.  
  234.                         //Retrieve user input
  235.                         getline(cin, input);
  236.                         cout << endl;
  237.                         cout << "\n\nGetting next contour...";
  238.                         //If user enters Y
  239.                         if (strUpper(input) == "Y" || strUpper(input) == "N")
  240.                         {
  241.                             if (strUpper(input) == "Y"){
  242.                                 //Draw the correct contour green
  243.                                 draw(contours[j], "green");
  244.                                 //Count the drawn contours
  245.                                 count++;
  246.  
  247.                                 labels.push_back(1);
  248.                             }
  249.                             else{
  250.                                 draw(contours[j], "red");
  251.                                 labels.push_back(-1);
  252.                             }
  253.  
  254.                             ///////////////////////###################Get training data############################////////////////////////////
  255.                             //Get aspect ratio
  256.                             Rect rect = boundingRect(contours[j]);
  257.                             double aspect_ratio = float(rect.width) / rect.height;
  258.  
  259.                             //Get extent
  260.                             double rect_area = float(rect.width)*rect.height;
  261.                             double extent = float(contArea) / rect_area;
  262.  
  263.                             //Get solidity
  264.                             vector<Point> hull;
  265.                             convexHull(contours[j], hull);
  266.                             double hull_area = contourArea(hull);
  267.                             double solidity = float(contArea) / hull_area;
  268.  
  269.                             //Get equivalent diameter
  270.                             double equi_diameter = sqrt(4 * contArea / 3.14159265);
  271.  
  272.                             //Perimeter
  273.                             double perimeter = arcLength(contours[j], true);
  274.  
  275.                             //Compile data
  276.                             vector<double> data = { aspect_ratio, extent, solidity, equi_diameter, perimeter, contArea };
  277.  
  278.                             allData.push_back(data);
  279.  
  280.                             //For prediction
  281.                             /*float response = detector.predict(trainingData);
  282.  
  283.                             if (response == 1)
  284.                             {
  285.                                 draw(contours[j], "green");
  286.                                 count++;
  287.                                 all++;
  288.                             }
  289.                             else if (response == -1)
  290.                             {
  291.                                 draw(contours[j], "red");
  292.                                 all++;
  293.                             }*/
  294.                             ////////////////////////////////////////////.........
  295.  
  296.                             break;
  297.                         }
  298.  
  299.                         //Identified as not a push-up (False detection)
  300.                         /*else if (strUpper(input) == "N")
  301.                         {
  302.                             draw(contours[j], "red");
  303.                             break;
  304.                         }*/
  305.                         //Exits training process
  306.                         else if (strUpper(input) == "QUIT")
  307.                             exit = true;
  308.                         //Incorrect entry
  309.                         else
  310.                             cout << endl << "Enter Y or N..." << endl;
  311.                        
  312.                     }
  313.                 }
  314.             }
  315.         }
  316.     }
  317.     int amount = allData.size();
  318.  
  319.     //Produce matrix containing training data
  320.     Mat trainingData(amount, 6, CV_32FC1, &allData);
  321.  
  322.     //Array to label data
  323.     Mat labelsMat(amount, 1, CV_32FC1, &labels);
  324.  
  325.     CvSVMParams params;                                                 //
  326.     params.svm_type = CvSVM::C_SVC;                                     //Required data for training
  327.     params.kernel_type = CvSVM::LINEAR;                                 //
  328.     //params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);       //
  329.  
  330.     //Append training data to SVM
  331.     detector.train(trainingData, labelsMat, Mat(), Mat(), params);
  332.     //detector.train_auto(trainingData, labelsMat, Mat(), Mat(), params);
  333.  
  334.     //Save the machine learning data
  335.     detector.save("Muskrat_Counting_SVM.xml");
  336.     system("cls");
  337.     info();
  338.     cout << "\n\nTotal Circled: " << count << endl;     //Output how many contours that were detected
  339.     cout << "Total: " << all << endl;               //Total amount of contours before refinement
  340. }
  341.  
  342. void Morphology_Operations()
  343. {
  344.     // Since MORPH_X : 2,3,4,5 and 6
  345.     //Operator:  2: Opening  3: Closing  4: Gradient   5: Top Hat   6: Black Hat
  346.     int operation = 2;
  347.  
  348.     Mat element = getStructuringElement(morph_elem, Size(2 * morph_size + 1, 2 * morph_size + 1), Point(morph_size, morph_size));
  349.  
  350.     /// Apply the specified morphology operation
  351.     morphologyEx(invsrc, dst, operation, element);
  352. }
  353.  
  354. //////////############################Zooming functions start here#################################/////////////////////////
  355.  
  356. //Re-modeled function that provides the ability to zoom
  357. //in on pictures when they are displayed
  358. Mat zoomIn(int x, int y)
  359. {
  360.     int width = zoomRec, height = zoomRec;
  361.     int ptoX = x - (zoomRec / 2), ptoY = y - (zoomRec / 2);
  362.  
  363.     if ((x + (zoomRec / 2)) > imagen.size().width){
  364.         width = width - ((x + (zoomRec / 2)) - imagen.size().width);
  365.     }
  366.     if ((y + (zoomRec / 2)) > imagen.size().height){
  367.         height = height - ((y + (zoomRec / 2)) - imagen.size().height);
  368.     }
  369.  
  370.     if ((x - (zoomRec / 2)) < 0){
  371.         ptoX = 0;
  372.     }
  373.  
  374.     if ((y - (zoomRec / 2)) < 0){
  375.         ptoY = 0;
  376.     }
  377.  
  378.     Rect roi = Rect(ptoX, ptoY, width, height);
  379.     Mat imagen_roi = imagen(roi);
  380.     resize(imagen_roi, imagen_roi, Size(imagenOriginal.size().width, imagenOriginal.size().height), 0, 0, CV_INTER_AREA);
  381.  
  382.     return imagen_roi;
  383. }
  384.  
  385. //Returns original image
  386. Mat zoomOut(int x, int y)
  387. {
  388.     return imagenOriginal;
  389. }
  390.  
  391. //Mouse click event listener
  392. static void onMouse(int event, int x, int y, int /*flags*/, void* /*param*/)
  393. {
  394.     mousex = x;
  395.     mousey = y;
  396.  
  397.     if (event == CV_EVENT_LBUTTONDOWN)
  398.         imagen = zoomIn(x, y);
  399.     else if (event == CV_EVENT_RBUTTONDOWN)
  400.         imagen = zoomOut(x, y);
  401. }
  402.  
  403.  
  404. //Zooming instructions output to the console
  405. void info(){
  406.  
  407.     cout << "Training machine learning:\n";
  408.     cout << "------------------------------\n";
  409.  
  410.     cout << "\nInstructions: \n"
  411.         "\tType \"quit\" to exit   \n"
  412.         "\tESC - Direct to console from picture \n "
  413.         "\t + - Increases the zoom \n"
  414.         "\t - - Decreases the zoom \n"
  415.         "\tCLICK L - zoom \n"
  416.         "\tCLICK R - Restores picture \n" << endl;
  417. }
  418.  
  419.  
  420. //Zooming main function
  421. void zoom(Mat argv)
  422. {  
  423.     imagenOriginal = argv;
  424.  
  425.     if (imagenOriginal.empty())
  426.         cout << "[ERROR] Could not load the image\n" << endl;
  427.  
  428.     //Create window
  429.     namedWindow("Press Esc when done analizing", CV_WINDOW_NORMAL);
  430.  
  431.     //Create event listener for mouse
  432.     setMouseCallback("Press Esc when done analizing", onMouse, 0);
  433.  
  434.     //Make copies of original image
  435.     imagenOriginal.copyTo(imagen);
  436.     imagenOriginal.copyTo(imagenMostrar);
  437.  
  438.     //Zoom in on the contour
  439.     if (last == false)
  440.         imagen = zoomIn(pCen.x, pCen.y);
  441.  
  442.     bool once = false;
  443.  
  444.     for (;;)
  445.     {  
  446.         //Done only once in the loop and not at the end
  447.         if (once == false && last == false)
  448.         {
  449.             //Put picture in the foreground
  450.             SetForegroundWindow(look);
  451.             once = true;
  452.         }
  453.  
  454.         if (imagen.empty())
  455.             break;
  456.  
  457.         imagen.copyTo(imagenMostrar);
  458.  
  459.         //Draw rectangle the represents where you will zoom
  460.         rectangle(imagenMostrar,
  461.             Point(mousex - (zoomRec / 2), mousey - (zoomRec / 2)),
  462.             Point(mousex + (zoomRec / 2), mousey + (zoomRec / 2)),
  463.             cv::Scalar(0, 255, 0), 1, 8, 0);
  464.        
  465.         //Display image
  466.         imshow("Press Esc when done analizing", imagenMostrar);
  467.  
  468.         //Get the window that shows the picture
  469.         look = GetForegroundWindow();
  470.  
  471.         char c = (char)waitKey(10);
  472.  
  473.         //When Esc is pressed
  474.         if (c == 27){
  475.             system("cls");
  476.  
  477.             //Put console in the foreground
  478.             SetForegroundWindow(console);
  479.             SetFocus(console);
  480.  
  481.             //Output instructions
  482.             info();
  483.             break;
  484.         }
  485.  
  486.         switch (c)
  487.         {
  488.             //Increase the zoom
  489.             case '+':
  490.                 if (zoomRec < maxRec)
  491.                     zoomRec = zoomRec + 10;
  492.                 break;
  493.  
  494.             //Decrease the zoom
  495.             case '-':
  496.                 if (zoomRec > 10)
  497.                     zoomRec = zoomRec - 10;
  498.                 break;
  499.             default:
  500.                 ;
  501.         }
  502.     }
  503. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement