|
| 1 | +/*----------------------------------------------------------------------------*/ |
| 2 | +/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */ |
| 3 | +/* Open Source Software - may be modified and shared by FRC teams. The code */ |
| 4 | +/* must be accompanied by the FIRST BSD license file in the root directory of */ |
| 5 | +/* the project. */ |
| 6 | +/*----------------------------------------------------------------------------*/ |
| 7 | + |
| 8 | +#include <thread> |
| 9 | + |
| 10 | +#include "ImageProcess.h" |
| 11 | +#include <cameraserver/CameraServer.h> |
| 12 | +#include <frc/TimedRobot.h> |
| 13 | +#include <opencv2/core/core.hpp> |
| 14 | +#include <opencv2/core/types.hpp> |
| 15 | +#include <opencv2/imgproc/imgproc.hpp> |
| 16 | +#include <wpi/raw_ostream.h> |
| 17 | + |
| 18 | +/** |
| 19 | + * This is a demo program showing the use of OpenCV to do vision processing. The |
| 20 | + * image is acquired from the USB camera, then a rectangle is put on the image |
| 21 | + * and sent to the dashboard. OpenCV has many methods for different types of |
| 22 | + * processing. |
| 23 | + */ |
| 24 | +class Robot : public frc::TimedRobot { |
| 25 | +#if defined(__linux__) |
| 26 | + |
| 27 | + private: |
| 28 | + static void VisionThread() { |
| 29 | + // Get the USB camera from CameraServer |
| 30 | + cs::UsbCamera camera = |
| 31 | + frc::CameraServer::GetInstance()->StartAutomaticCapture(); |
| 32 | + // Set the resolution |
| 33 | + camera.SetResolution(640, 480); |
| 34 | + |
| 35 | + // Get a CvSink. This will capture Mats from the Camera |
| 36 | + cs::CvSink cvSink = frc::CameraServer::GetInstance()->GetVideo(); |
| 37 | + // Setup a CvSource. This will send images back to the Dashboard |
| 38 | + cs::CvSource outputStream = |
| 39 | + frc::CameraServer::GetInstance()->PutVideo("Rectangle", 640, 480); |
| 40 | + |
| 41 | + // Mats are very memory expensive. Lets reuse this Mat. |
| 42 | + cv::Mat mat; |
| 43 | + |
| 44 | + while (true) { |
| 45 | + // Tell the CvSink to grab a frame from the camera and |
| 46 | + // put it |
| 47 | + // in the source mat. If there is an error notify the |
| 48 | + // output. |
| 49 | + if (cvSink.GrabFrame(mat) == 0) { |
| 50 | + // Send the output the error. |
| 51 | + outputStream.NotifyError(cvSink.GetError()); |
| 52 | + // skip the rest of the current iteration |
| 53 | + continue; |
| 54 | + } |
| 55 | + // Put a rectangle on the image |
| 56 | + rectangle(mat, cv::Point(100, 100), cv::Point(400, 400), |
| 57 | + cv::Scalar(255, 255, 255), 5); |
| 58 | + // Give the output stream a new image to display |
| 59 | + outputStream.PutFrame(mat); |
| 60 | + } |
| 61 | + } |
| 62 | +#endif |
| 63 | + |
| 64 | + void RobotInit() override { |
| 65 | + // We need to run our vision program in a separate thread. If not, our robot |
| 66 | + // program will not run. |
| 67 | +#if defined(__linux__) |
| 68 | + std::thread visionThread(VisionThread); |
| 69 | + visionThread.detach(); |
| 70 | +#else |
| 71 | + wpi::errs() << "Vision only available on Linux.\n"; |
| 72 | + wpi::errs().flush(); |
| 73 | +#endif |
| 74 | + } |
| 75 | +}; |
| 76 | + |
| 77 | +/*std::string ImageProcess::getPutTextData(int count){ |
| 78 | + if (count == 1){ |
| 79 | + return "---"; |
| 80 | + }else if (count == 2){ |
| 81 | + return std::to_string(0); |
| 82 | + }else if(count == 3){ |
| 83 | + return std::to_string(0.3); |
| 84 | + }else if(count == 4){ |
| 85 | + return std::to_string(0.5); |
| 86 | + }else if(count == 5){ |
| 87 | + return std::to_string(0.7); |
| 88 | + }else if(count == 6){ |
| 89 | + return std::to_string(0.9); |
| 90 | + }else if(count == 7){ |
| 91 | + return std::to_string(1.2); |
| 92 | + }else if(count == 8){ |
| 93 | + return std::to_string(1.5); |
| 94 | + }else if(count == 9){ |
| 95 | + return std::to_string(1.7); |
| 96 | + }else if(count == 10){ |
| 97 | + return std::to_string(2); |
| 98 | + }else if(count == 11){ |
| 99 | + return std::to_string(2.2) ; |
| 100 | + }else if(count == 12){ |
| 101 | + return std::to_string(2.4); |
| 102 | + }else if(count == 13){ |
| 103 | + return std::to_string(2.8); |
| 104 | + }else if(count == 14){ |
| 105 | + return std::to_string(3.1); |
| 106 | + }else if(count == 15){ |
| 107 | + return std::to_string(3.4); |
| 108 | + }else if(count == 16){ |
| 109 | + return std::to_string(3.6); |
| 110 | + }else { |
| 111 | + return "-"; |
| 112 | + } |
| 113 | + }*/ |
| 114 | + |
| 115 | + void ImageProcess::makeGrid(Mat img, int cellSize) { |
| 116 | + |
| 117 | + int dist= cellSize; |
| 118 | + int width= img.size().width; |
| 119 | + int height= img.size().height; |
| 120 | + |
| 121 | + //b g r |
| 122 | + cv::Scalar lineColor(0, 0, 0, 0); |
| 123 | + cv::Scalar centerColor(0, 0, 255, 0); |
| 124 | + cv::Scalar textColor(0, 255, 0, 0); |
| 125 | + |
| 126 | + int midWidth = width /2; |
| 127 | + int midHeight = height /2; |
| 128 | + |
| 129 | + int lineNum = (height - midHeight) / dist; |
| 130 | + int count = lineNum; |
| 131 | + for (int bHeigth = midHeight; bHeigth<height; bHeigth += dist) { |
| 132 | + cv::line(img, Point(0, bHeigth), Point(width, bHeigth), lineColor); |
| 133 | + putText(img, std::to_string(count), cvPoint(midWidth-cellSize*5, bHeigth+dist), CV_FONT_HERSHEY_SIMPLEX, 0.5, textColor, 1, cv::LINE_8); |
| 134 | + putText(img, std::to_string(count--), cvPoint(midWidth+cellSize*4, bHeigth+dist), CV_FONT_HERSHEY_SIMPLEX, 0.5, textColor, 1, cv::LINE_8); |
| 135 | + std::string putTextData = getPutTextData(count);//std::to_string(count); |
| 136 | + /*if (count % 2 == 0 ){ |
| 137 | + putTextData = ""; |
| 138 | + }*/ |
| 139 | + /*putText(img, putTextData, cvPoint(midWidth-cellSize*7, bHeigth+dist), CV_FONT_HERSHEY_SIMPLEX, 0.5, textColor, 1, cv::LINE_8); |
| 140 | + putText(img, putTextData, cvPoint(midWidth+cellSize*6, bHeigth+dist), CV_FONT_HERSHEY_SIMPLEX, 0.5, textColor, 1, cv::LINE_8); |
| 141 | + count = count - 1;*/ |
| 142 | + } |
| 143 | + }; |
| 144 | + /*count = ++lineNum; |
| 145 | + for (int uHeight = midHeight; uHeight>0; uHeight -= dist) { |
| 146 | + cv::line(img, Point(0, uHeight), Point(width, uHeight),lineColor); |
| 147 | + putText(img, std::to_string(count), cvPoint(midWidth-cellSize*5, uHeight), CV_FONT_HERSHEY_SIMPLEX, 0.5, textColor, 1, cv::LINE_8); |
| 148 | + putText(img, std::to_string(count++), cvPoint(midWidth+cellSize*4, uHeight), CV_FONT_HERSHEY_SIMPLEX, 0.5, textColor, 1, cv::LINE_8); |
| 149 | + std::string putTextData = std::to_string(count); |
| 150 | + /*if (count % 2 == 0){ |
| 151 | + putTextData = ""; |
| 152 | + }*/ |
| 153 | + /*putText(img, putTextData, cvPoint(midWidth-cellSize*7, uHeight), CV_FONT_HERSHEY_SIMPLEX, 0.5, textColor, 1, cv::LINE_8); |
| 154 | + putText(img, putTextData, cvPoint(midWidth+cellSize*6, uHeight), CV_FONT_HERSHEY_SIMPLEX, 0.5, textColor, 1, cv::LINE_8); |
| 155 | + count = count + 1; |
| 156 | + } |
| 157 | +
|
| 158 | + cv::line(img, Point(0, midHeight), Point(width, midHeight), centerColor,2); |
| 159 | + for (int lWidth = midWidth; lWidth>0; lWidth -= dist) |
| 160 | + cv::line(img, Point(lWidth, 0), Point(lWidth, height), lineColor); |
| 161 | + for (int rWidth = midWidth; rWidth<width; rWidth += dist) |
| 162 | + cv::line(img, Point(rWidth, 0), Point(rWidth, height), lineColor); |
| 163 | + cv::line(img, Point(midWidth, 0), Point(midWidth, height), centerColor,2); |
| 164 | + //for (int i = 0; i<width; i += dist) |
| 165 | + // cv::line(img, Point(i, 0), Point(i, height), cv::Scalar(255, 0, 0)); |
| 166 | + }*/ |
| 167 | + /*Mat ImageProcess::makeGrid(char *fileName, char *result) { |
| 168 | + cv::Mat img = cv::imread(fileName, 0); |
| 169 | + makeGrid(img, 10 |
| 170 | + ); |
| 171 | + imwrite(result, img); |
| 172 | + }*/ |
| 173 | +#ifndef RUNNING_FRC_TESTS |
| 174 | +int main() { return frc::StartRobot<Robot>(); } |
| 175 | +#endif |
0 commit comments