Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Include files for required libraries
- #include <opencv2/opencv.hpp>
- #include <iostream>
- #include <fstream>
- using namespace cv;
- //compare two images by counting the non-zero pixels and working out a percentage
- float compareImages(Mat cameraImage, Mat librarySymbol)
- {
- float matchPercent = 100 - (100/((float)librarySymbol.cols*(float)librarySymbol.rows) * (2*(float)countNonZero(librarySymbol^cameraImage))); // An incorrect pixel has double weighting
- return matchPercent;
- }
- //find the centre of the contours
- Point findContourCentre(std::vector<cv::Point> contour)
- {
- Moments foundRegion; // Variables to store the region moment and the centre point
- Point centre;
- foundRegion = moments(contour, false); // Calculate the moment for the contour
- centre.x = (foundRegion.m10/foundRegion.m00); //Calculate the X and Y positions
- centre.y = (foundRegion.m01/foundRegion.m00);
- return centre;
- }
- //transform the largest contour to fit the frame
- Mat transformPerspective(std::vector<Point> boundingContour, Mat frame, int x_size, int y_size)
- {
- if(boundingContour.size() != 4)
- {
- // Error the contour has too many points. Only 4 are allowed
- Mat emptyMat;
- return emptyMat;
- }
- Mat symbol(y_size,x_size,CV_8UC1, Scalar(0));
- cv::Point2f symbolCorners[4], boundingCorners[4]; // Create (and populate) variables containing the corner locations for the transform
- symbolCorners[0] = Point2f(0,0);
- symbolCorners[1] = Point2f(symbol.cols - 1,0);
- symbolCorners[2] = Point2f(symbol.cols - 1,symbol.rows - 1);
- symbolCorners[3] = Point2f(0,symbol.rows - 1);
- Point contourCentre = findContourCentre(boundingContour); // To populate the contour corners we need to check the order of the points
- int point1, point2, point3, point4;
- if(boundingContour[0].x > contourCentre.x)
- {
- if(boundingContour[0].y > contourCentre.y)
- point3 = 0;
- else
- point2 = 0;
- }
- else
- {
- if(boundingContour[0].y > contourCentre.y)
- point4 = 0;
- else
- point1 = 0;
- }
- if(boundingContour[1].x > contourCentre.x)
- {
- if(boundingContour[1].y > contourCentre.y)
- point3 = 1;
- else
- point2 = 1;
- }
- else
- {
- if(boundingContour[1].y > contourCentre.y)
- point4 = 1;
- else
- point1 = 1;
- }
- if(boundingContour[2].x > contourCentre.x)
- {
- if(boundingContour[2].y > contourCentre.y)
- point3 = 2;
- else
- point2 = 2;
- }
- else
- {
- if(boundingContour[2].y > contourCentre.y)
- point4 = 2;
- else
- point1 = 2;
- }
- if(boundingContour[3].x > contourCentre.x)
- {
- if(boundingContour[3].y > contourCentre.y)
- point3 = 3;
- else
- point2 = 3;
- }
- else
- {
- if(boundingContour[3].y > contourCentre.y)
- point4 = 3;
- else
- point1 = 3;
- }
- if(point1 + point2 + point3 + point4 != 6)
- {
- //Unable to reconstruct rectangle
- Mat emptyMat;
- return emptyMat;
- }
- boundingCorners[0] = boundingContour[point1];
- boundingCorners[1] = boundingContour[point2];
- boundingCorners[2] = boundingContour[point3];
- boundingCorners[3] = boundingContour[point4];
- Mat transformMatrix = cv::getPerspectiveTransform(boundingCorners, symbolCorners); // Calculate the required transform operation
- Mat transformedSymbol(240,320,CV_8UC1,Scalar(0));
- cv::warpPerspective(frame, transformedSymbol, transformMatrix, cv::Size(symbol.cols,symbol.rows)); // Perform the transformation
- return transformedSymbol;
- }
- int main( )
- {
- setupCamera(320, 240); // Enable the camera for OpenCV
- //Mat image = imread("Grab.png"); // Open an image file and store in a new matrix variable
- //Mat image = imread("Fire.png");
- //Mat image = imread("GrabImage.jpg");
- //Mat image = imread("FireImage.jpg");
- Mat symbols[2];
- symbols[0] = imread("Grab.PNG");
- symbols[1] = imread("Fire.PNG");
- for (int i = 0; i <= 1; i++)
- {
- Mat symbolRed1;
- Mat symbolRed2;
- cvtColor(symbols[i], symbols[i], COLOR_BGR2HSV);
- inRange(symbols[i], Scalar(0, 50, 50), Scalar(7, 255, 255), symbolRed1); //inRange(image, min, max, mask)
- inRange(symbols[i], Scalar(173, 50, 50), Scalar(180, 255, 255), symbolRed2); //inRange(image, min, max, mask)
- symbols[i] = symbolRed1|symbolRed2;
- }
- int state = 0;
- Mat frame; //captured from the camera
- waitKey(500);
- while(frame.empty())
- frame = captureFrame(); // Capture a frame from the camera and store in a new matrix variable
- rotate(frame, frame, ROTATE_270); //rotate image 270 degrees
- imageHSV = frame;
- while(1) // Main loop to perform image processing
- {
- Mat imageHSV; // Convert the frame to HSV and apply the limits
- Mat imageDetected;
- Mat imageRGB;
- Mat transformedImage;
- cvtColor(image, imageHSV, COLOR_BGR2HSV);
- Mat red1;
- Mat red2;
- inRange(imageHSV, Scalar(0, 50, 50), Scalar(7, 255, 255), red1); //inRange(image, min, max, mask)
- inRange(imageHSV, Scalar(173, 50, 50), Scalar(180, 255, 255), red2); //inRange(image, min, max, mask)
- imageDetected = red1|red2;
- imshow("RGB", image); //Display the image in the window
- imshow("HSV", imageDetected);
- std::vector< std::vector<cv::Point> > contours;
- std::vector<Vec4i> hierarchy;
- cv::findContours(imageDetected, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
- //find the largest contour (the outline of the detected sign)
- if (contours.size() > 0){
- cvtColor(imageHSV, imageRGB, COLOR_HSV2BGR);
- std::vector< std::vector<cv::Point> > approxedcontours(contours.size());
- int a = 0;
- int maxcontour = -1;
- for (int i = 0; i < contours.size(); i++){
- approxPolyDP(contours[i], approxedcontours[i], 30, true);
- int area = cv::contourArea(contours[i]);
- if (area > a){
- a = area;
- maxcontour = i;
- }
- }
- drawContours(imageRGB, contours, maxcontour, Scalar(0, 0, 0), 2, LINE_8, noArray(), 0, Point() );
- cv::imshow("Contours", imageRGB);
- if (maxcontour != -1)
- transformedImage = transformPerspective(approxedcontours[maxcontour], imageDetected, 439, 439); //transform camera image to a normal perspective
- cv::imshow("Transform", transformedImage);
- //cvtColor(transformedImage, transformedImage, cv::COLOR_BGR2HSV);
- float b = 70;
- if (transformedImage.rows > 0 && transformedImage.cols > 0){
- for (int i = 0; i <= 1; i++){
- float match = compareImages(transformedImage, symbols[i]);
- if (match >= b){
- b = match;
- state = i + 1;
- }
- }
- }
- }
- ofstream flagFile("filename.txt");
- switch (state){
- case 0:
- printf("\nNo Symbol");
- flagFile << "0"
- break;
- case 1:
- printf("\nGrab Symbol");
- flagFile << "1"
- break;
- case 2:
- printf("\nFire Symbol");
- flagFile << "2"
- break;
- }
- flagFile.close();
- int key = cv::waitKey(1); // Wait 1ms for a keypress (required to update windows
- key = (key==255) ? -1 : key; // Check if the esc key has been pressed
- if (key == 27)
- break;
- }
- while(frame.empty())
- frame = captureFrame();
- waitKey(500);
- destroyAllWindows();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement