Advertisement
Cai_B

Symbol Recognition with a Raspberry Pi

Apr 21st, 2024 (edited)
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.84 KB | None | 0 0
  1. #include <stdio.h>
  2.  
  3. #include "opencv_aee.hpp"
  4. #include "main.hpp" // You can use this file for declaring defined values and functions
  5. #include "pi2c.h"
  6.  
  7. using namespace cv;
  8. using namespace std;
  9.  
  10. Pi2c car(0x22); // Configure the I2C interface to the Car as a global variable
  11.  
  12. void setup(void) {
  13.   setupCamera(320, 240); // Enable the camera for OpenCV
  14. }
  15. //Resizes the Symbol files stored in memory intially
  16. // Inputs
  17. //      - The symbol and whether the shape is to be enlarged or shrunk
  18. // Returns a matrix which is the resized shape in 320 by 240 format
  19. Mat resizeimage(Mat shape,int resize_method)
  20. {
  21.     Mat resized_image;
  22.     resize(shape, resized_image, Size(320, 240), 0.0, 0.0, resize_method);
  23.  
  24.     return resized_image;
  25. }
  26.  
  27. // Converts the Resized Symbol file to now a black and white image
  28. // Inputs
  29. //          - The resized Symbol file
  30. // Returns a matrix representing the image in grayscale
  31. Mat blackandwhite(Mat resized_image)
  32. {
  33.     Mat image_HSV;
  34.     Mat image_GREY;
  35.  
  36.     cvtColor(resized_image, image_HSV, COLOR_BGR2HSV); // Convert the image to HSV
  37.     inRange(image_HSV, Scalar(128, 50, 50), Scalar(179, 255 , 255), image_GREY); // Isolates the purple pixels of the Symbol
  38.  
  39.     return image_GREY;
  40.  
  41. }
  42.  
  43. int main(int argc, char** argv) {
  44.   setup(); // Call a setup function to prepare IO and devices
  45.  
  46.   cv::namedWindow("Approximated Contours");
  47.   cv::namedWindow("Original Image");
  48.  
  49.  
  50.   while (1) { // Main loop to perform image processing
  51.     Mat frame;
  52.     Mat frame_HSV;
  53.     Mat frame_GREY;
  54.  
  55.     Mat triangle;
  56.     Mat circle;
  57.     Mat star;
  58.     Mat umbrella;
  59.  
  60.     Mat storetransform;
  61.     while (frame.empty())
  62.       frame = captureFrame(); // Capture a frame from the camera and store in a new matrix variable
  63.  
  64.     // Reads in the Symbol Files  
  65.     triangle = imread("/home/B01-20/Desktop/OpenCV-Template/Triangle (Blue Line).png");
  66.     circle= imread("/home/B01-20/Desktop/OpenCV-Template/Circle (Red Line).png");
  67.     star=imread("/home/B01-20/Desktop/OpenCV-Template/Star (Green Line).png");
  68.     umbrella=imread("/home/B01-20/Desktop/OpenCV-Template/Umbrella (Yellow Line).png");
  69.  
  70.     // Determines whether the  Symbol files need to be enlarged or shrunk according to the current and target aspect ratio  
  71.     double orig_aspect = triangle.cols / static_cast<double>(triangle.rows);
  72.     double target_aspect = 320.0 / 240.0;
  73.     int resize_method = orig_aspect > target_aspect ? INTER_AREA : INTER_CUBIC;
  74.  
  75.     // Calls function to resize the Symbol files  
  76.     triangle=resizeimage(triangle,resize_method);
  77.     circle=resizeimage(circle,resize_method);
  78.     star=resizeimage(star,resize_method);
  79.     umbrella=resizeimage(umbrella,resize_method);
  80.  
  81.     // Calls function to convert Symbol files to grayscale
  82.     triangle= blackandwhite(triangle);
  83.     circle= blackandwhite(circle);
  84.     star= blackandwhite(star);
  85.     umbrella= blackandwhite(umbrella);
  86.  
  87.     cvtColor(frame, frame_HSV, COLOR_BGR2HSV);
  88.     inRange(frame_HSV, Scalar(128, 25, 15), Scalar(179, 255, 255), frame_GREY); // Isolates the purple pixels in the frame
  89.  
  90.     // Vectors created to store the contours  
  91.     vector<vector<Point>> contours;
  92.     vector<Vec4i> hierarchy;
  93.  
  94.     findContours(frame_GREY, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0)); // Calculate the contours and store them
  95.  
  96.     vector<vector<Point>> approxedcontours(contours.size());
  97.  
  98.     for (int i = 0; i < contours.size(); i++)
  99.     {
  100.       approxPolyDP(contours[i], approxedcontours[i], 10, true); //Finds the approximated contours from the countours
  101.       drawContours(frame, approxedcontours, (int)i, Scalar(255, 0, 0), 2, LINE_8, noArray(), 0, Point()); // Draws contours onto frame
  102.  
  103.       if (approxedcontours[i].size()==4)    // Transforms the image if all 4 corners of the Symbol can be seen
  104.       {
  105.         Mat transformed = transformPerspective(approxedcontours[0], frame_GREY, 320, 240); // Symbol is transformed to a 320 by 240 frame
  106.  
  107.           if(!transformed.empty())
  108.           {
  109.             imshow("Transformed",transformed);
  110.             rotate(transformed,transformed,ROTATE_180);  // Camera is upside down so Symbol needs to be rotated
  111.              
  112.             // Dilates the transformed Symbol to accentuate its features so a Star can be told apart from a circle  
  113.             Mat maskMorph = cv::getStructuringElement(MORPH_RECT, Size(10, 10));
  114.             cv::dilate(transformed, transformed, maskMorph);
  115.             storetransform=transformed;
  116.           }
  117.       }
  118.  
  119.     }
  120.  
  121.  
  122.     imshow("Approximated Contours", frame);
  123.     imshow("Original Image", frame_GREY);
  124.      
  125.      
  126.     // Compares the similarity of the Symbol in the frame that has been transformed to all Symbol files in memory
  127.     float match = compareImages(storetransform,triangle);
  128.     float match1= compareImages(storetransform,circle);
  129.     float match2=compareImages(storetransform,star);
  130.     float match3=compareImages(storetransform,umbrella);
  131.  
  132.     //Checks which Symbol file the frame matches  
  133.        if((match1<match)&&(match>5)&&(match2<match)&&(match3<match))
  134.     {
  135.         cout<<"Triangle"<<endl;
  136.     }
  137.     else if((match1>match)&&(match1>5)&&(match2<match1)&&(match3<match1))
  138.     {
  139.         cout<<"Circle"<<endl;
  140.     }
  141.     else if((match2>5)&&(match2>match1)&&(match2>match)&&(match3<match2))
  142.     {
  143.         cout<<"Star"<<endl;
  144.     }
  145.         else if((match3>5)&&(match3>match1)&&(match3>match)&&(match2<match3))
  146.     {
  147.         cout<<"umbrella"<<endl;
  148.     }
  149.     else if((match1<5)&&(match<5)&&(match2<5)&&(match3<5))
  150.     {
  151.         cout<<"No shape detected"<<endl;
  152.     }
  153.  
  154.  
  155. cout<<"End of if "<<endl;
  156.  
  157.     int key = waitKey(1); // Wait 1ms for a keypress (required to update windows)
  158.  
  159.     key = (key == 255) ? -1 : key; // Check if the ESC key has been pressed
  160.     if (key == 27)
  161.       break;
  162.   }
  163.  
  164.   closeCV(); // Disable the camera and close any windows
  165.  
  166.   return 0;
  167. }
  168.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement