Advertisement
Cpt_Jellyfish

EEEE4008: ‘Recon-Scout’ Platform: Symbol Recognition Code

May 13th, 2021
494
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.02 KB | None | 0 0
  1. // Include files for required libraries
  2. #include <opencv2/opencv.hpp>
  3. #include <iostream>
  4. #include <fstream>
  5.  
  6. using namespace cv;
  7.  
  8. //compare two images by counting the non-zero pixels and working out a percentage
  9. float compareImages(Mat cameraImage, Mat librarySymbol)
  10. {
  11.     float matchPercent = 100 - (100/((float)librarySymbol.cols*(float)librarySymbol.rows) * (2*(float)countNonZero(librarySymbol^cameraImage))); // An incorrect pixel has double weighting
  12.     return matchPercent;
  13. }
  14.  
  15. //find the centre of the contours
  16. Point findContourCentre(std::vector<cv::Point> contour)
  17. {
  18.     Moments foundRegion;    // Variables to store the region moment and the centre point
  19.     Point centre;
  20.     foundRegion = moments(contour, false);      // Calculate the moment for the contour
  21.     centre.x = (foundRegion.m10/foundRegion.m00);  //Calculate the X and Y positions
  22.     centre.y = (foundRegion.m01/foundRegion.m00);
  23.  
  24.     return centre;
  25. }
  26.  
  27. //transform the largest contour to fit the frame
  28. Mat transformPerspective(std::vector<Point> boundingContour, Mat frame, int x_size, int y_size)
  29. {
  30.     if(boundingContour.size() != 4)
  31.     {
  32.         // Error the contour has too many points. Only 4 are allowed
  33.         Mat emptyMat;
  34.         return emptyMat;
  35.     }
  36.  
  37.     Mat symbol(y_size,x_size,CV_8UC1, Scalar(0));
  38.  
  39.     cv::Point2f symbolCorners[4], boundingCorners[4];      // Create (and populate) variables containing the corner locations for the transform
  40.     symbolCorners[0] = Point2f(0,0);
  41.     symbolCorners[1] = Point2f(symbol.cols - 1,0);
  42.     symbolCorners[2] = Point2f(symbol.cols - 1,symbol.rows - 1);
  43.     symbolCorners[3] = Point2f(0,symbol.rows - 1);
  44.  
  45.     Point contourCentre = findContourCentre(boundingContour);   // To populate the contour corners we need to check the order of the points
  46.  
  47.     int point1, point2, point3, point4;
  48.  
  49.     if(boundingContour[0].x > contourCentre.x)
  50.     {
  51.         if(boundingContour[0].y > contourCentre.y)
  52.             point3 = 0;
  53.         else
  54.             point2 = 0;
  55.     }
  56.     else
  57.     {
  58.         if(boundingContour[0].y > contourCentre.y)
  59.             point4 = 0;
  60.         else
  61.             point1 = 0;
  62.     }
  63.  
  64.     if(boundingContour[1].x > contourCentre.x)
  65.     {
  66.         if(boundingContour[1].y > contourCentre.y)
  67.             point3 = 1;
  68.         else
  69.             point2 = 1;
  70.     }
  71.     else
  72.     {
  73.         if(boundingContour[1].y > contourCentre.y)
  74.             point4 = 1;
  75.         else
  76.             point1 = 1;
  77.     }
  78.  
  79.     if(boundingContour[2].x > contourCentre.x)
  80.     {
  81.         if(boundingContour[2].y > contourCentre.y)
  82.             point3 = 2;
  83.         else
  84.             point2 = 2;
  85.     }
  86.     else
  87.     {
  88.         if(boundingContour[2].y > contourCentre.y)
  89.             point4 = 2;
  90.         else
  91.             point1 = 2;
  92.     }
  93.  
  94.     if(boundingContour[3].x > contourCentre.x)
  95.     {
  96.         if(boundingContour[3].y > contourCentre.y)
  97.             point3 = 3;
  98.         else
  99.             point2 = 3;
  100.     }
  101.     else
  102.     {
  103.         if(boundingContour[3].y > contourCentre.y)
  104.             point4 = 3;
  105.         else
  106.             point1 = 3;
  107.     }
  108.  
  109.     if(point1 + point2 + point3 + point4 != 6)
  110.     {
  111.         //Unable to reconstruct rectangle
  112.         Mat emptyMat;
  113.         return emptyMat;
  114.     }
  115.  
  116.     boundingCorners[0] = boundingContour[point1];
  117.     boundingCorners[1] = boundingContour[point2];
  118.     boundingCorners[2] = boundingContour[point3];
  119.     boundingCorners[3] = boundingContour[point4];
  120.  
  121.     Mat transformMatrix = cv::getPerspectiveTransform(boundingCorners, symbolCorners); // Calculate the required transform operation
  122.     Mat transformedSymbol(240,320,CV_8UC1,Scalar(0));
  123.     cv::warpPerspective(frame, transformedSymbol, transformMatrix, cv::Size(symbol.cols,symbol.rows));  // Perform the transformation
  124.  
  125.     return transformedSymbol;
  126. }
  127.  
  128. int main( )
  129. {
  130.     setupCamera(320, 240);  // Enable the camera for OpenCV
  131.  
  132.     //Mat image = imread("Grab.png"); // Open an image file and store in a new matrix variable
  133.     //Mat image = imread("Fire.png");
  134.     //Mat image = imread("GrabImage.jpg");
  135.     //Mat image = imread("FireImage.jpg");
  136.  
  137.     Mat symbols[2];
  138.     symbols[0] = imread("Grab.PNG");
  139.     symbols[1] = imread("Fire.PNG");
  140.     for (int i = 0; i <= 1; i++)
  141.     {
  142.         Mat symbolRed1;
  143.         Mat symbolRed2;
  144.         cvtColor(symbols[i], symbols[i], COLOR_BGR2HSV);
  145.         inRange(symbols[i], Scalar(0, 50, 50), Scalar(7, 255, 255), symbolRed1); //inRange(image, min, max, mask)
  146.         inRange(symbols[i], Scalar(173, 50, 50), Scalar(180, 255, 255), symbolRed2); //inRange(image, min, max, mask)
  147.         symbols[i] = symbolRed1|symbolRed2;
  148.     }
  149.     int state = 0;
  150.  
  151.     Mat frame; //captured from the camera
  152.     waitKey(500);
  153.  
  154.     while(frame.empty())
  155.         frame = captureFrame(); // Capture a frame from the camera and store in a new matrix variable
  156.     rotate(frame, frame, ROTATE_270); //rotate image 270 degrees
  157.     imageHSV = frame;
  158.  
  159.     while(1)    // Main loop to perform image processing
  160.     {
  161.         Mat imageHSV;       // Convert the frame to HSV and apply the limits
  162.         Mat imageDetected;
  163.         Mat imageRGB;
  164.         Mat transformedImage;
  165.  
  166.         cvtColor(image, imageHSV, COLOR_BGR2HSV);
  167.  
  168.         Mat red1;
  169.         Mat red2;
  170.         inRange(imageHSV, Scalar(0, 50, 50), Scalar(7, 255, 255), red1); //inRange(image, min, max, mask)
  171.         inRange(imageHSV, Scalar(173, 50, 50), Scalar(180, 255, 255), red2); //inRange(image, min, max, mask)
  172.         imageDetected = red1|red2;
  173.  
  174.         imshow("RGB", image); //Display the image in the window
  175.         imshow("HSV", imageDetected);
  176.  
  177.         std::vector< std::vector<cv::Point> > contours;
  178.         std::vector<Vec4i> hierarchy;
  179.         cv::findContours(imageDetected, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
  180.  
  181.         //find the largest contour (the outline of the detected sign)
  182.         if (contours.size() > 0){
  183.             cvtColor(imageHSV, imageRGB, COLOR_HSV2BGR);
  184.             std::vector< std::vector<cv::Point> > approxedcontours(contours.size());
  185.             int a = 0;
  186.             int maxcontour = -1;
  187.             for (int i = 0; i < contours.size(); i++){
  188.                 approxPolyDP(contours[i], approxedcontours[i], 30, true);
  189.  
  190.                 int area = cv::contourArea(contours[i]);
  191.                 if (area > a){
  192.                     a = area;
  193.                     maxcontour = i;
  194.                 }
  195.             }
  196.  
  197.             drawContours(imageRGB, contours, maxcontour, Scalar(0, 0, 0), 2, LINE_8, noArray(), 0, Point() );
  198.             cv::imshow("Contours", imageRGB);
  199.  
  200.             if (maxcontour != -1)
  201.                 transformedImage = transformPerspective(approxedcontours[maxcontour], imageDetected, 439, 439); //transform camera image to a normal perspective
  202.  
  203.             cv::imshow("Transform", transformedImage);
  204.  
  205.             //cvtColor(transformedImage, transformedImage, cv::COLOR_BGR2HSV);
  206.  
  207.             float b = 70;
  208.             if (transformedImage.rows > 0 && transformedImage.cols > 0){
  209.  
  210.                 for (int i = 0; i <= 1; i++){
  211.                     float match = compareImages(transformedImage, symbols[i]);
  212.                     if (match >= b){
  213.                         b = match;
  214.                         state = i + 1;
  215.                     }
  216.                 }
  217.             }
  218.         }
  219.         ofstream flagFile("filename.txt");
  220.         switch (state){
  221.         case 0:
  222.             printf("\nNo Symbol");
  223.             flagFile << "0"
  224.             break;
  225.         case 1:
  226.             printf("\nGrab Symbol");
  227.             flagFile << "1"
  228.             break;
  229.         case 2:
  230.             printf("\nFire Symbol");
  231.             flagFile << "2"
  232.             break;
  233.         }
  234.         flagFile.close();
  235.         int key = cv::waitKey(1);   // Wait 1ms for a keypress (required to update windows
  236.  
  237.         key = (key==255) ? -1 : key;    // Check if the esc key has been pressed
  238.         if (key == 27)
  239.             break;
  240.     }
  241.  
  242.     while(frame.empty())
  243.         frame = captureFrame();
  244.  
  245.     waitKey(500);
  246.  
  247.     destroyAllWindows();
  248.  
  249.     return 0;
  250. }
  251.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement