diff --git a/AutonomousMode/Processing/processing.cpp b/AutonomousMode/Processing/processing.cpp index c7bc1f3..0dd3462 100644 --- a/AutonomousMode/Processing/processing.cpp +++ b/AutonomousMode/Processing/processing.cpp @@ -24,19 +24,37 @@ void Processing::processImage(Mat& inputPicture, int thresholdBinary, int gaussK // And one (the other one) to segment the lines. // No return value here as the input is passed by reference -> directly modified. cvtColor(inputPicture, inputPicture, COLOR_BGR2GRAY); - threshold(inputPicture, inputPicture, thresholdBinary, 255, THRESH_BINARY); GaussianBlur(inputPicture, inputPicture, Size(gaussKernelSize, gaussKernelSize), 0); - Canny(inputPicture, inputPicture, thresholdCanny1, thresholdCanny2, apertureSizeCanny); + threshold(inputPicture, inputPicture, thresholdBinary, 255, THRESH_BINARY); + + //Perform a opening + Mat kernel(5,5, CV_8UC1,1); + morphologyEx(inputPicture, inputPicture, 2, kernel); } -std::vector Processing::calculateLineSegments(const Mat& inputPicture) +FrameData Processing::calculateLineSegments(const Mat& inputPicture, const cv::Rect& roi) { - //See following link - //https://stackoverflow.com/questions/45322630/how-to-detect-lines-in-opencv - vector lines; - VectorOfLines linesInVectors; - HoughLinesP(inputPicture, lines, 1, CV_PI/360, 150, 0, 250); - //lines = linesInVectors.findMiddleLine(lines); - - return lines; + FrameData data; + cv::findContours(inputPicture, data.contours, RETR_LIST, CHAIN_APPROX_SIMPLE); + + //Delete the areas that are too small + auto iterator = data.contours.begin(); + while(iterator != data.contours.end()) + { + if (contourArea(*iterator) < 3500) + { + iterator = data.contours.erase(iterator); + } + else + { + Rect boundingBox = boundingRect(*iterator); + boundingBox.x += roi.x; + boundingBox.y += roi.y; + data.boundingBoxes.push_back(boundingBox); + data.middlePoints.push_back(Point(boundingBox.x+boundingBox.width/2, boundingBox.y+boundingBox.height/2)); + data.leftEdges.push_back(Point(boundingBox.x, boundingBox.y+boundingBox.height/2)); + ++iterator; + } + } + return data; } diff --git a/AutonomousMode/Processing/processing.h b/AutonomousMode/Processing/processing.h index bad9aae..27732f9 100644 --- a/AutonomousMode/Processing/processing.h +++ b/AutonomousMode/Processing/processing.h @@ -21,5 +21,5 @@ public: void processImage(Mat& inputPicture, int thresholdBinary, int gaussKernelSize, int thresholdCanny1, int thresholdCanny2, int apertureSizeCanny); - std::vector calculateLineSegments(const Mat& inputPicture); + FrameData calculateLineSegments(const Mat& inputPicture, const cv::Rect& roi); }; \ No newline at end of file diff --git a/AutonomousMode/Utils/utils.h b/AutonomousMode/Utils/utils.h index 05ea138..46de2a9 100644 --- a/AutonomousMode/Utils/utils.h +++ b/AutonomousMode/Utils/utils.h @@ -60,4 +60,15 @@ class VectorOfLines{ static double calcDistance(Point p0, Point p1); vector findMiddleLine(vector &lines); +}; + +class FrameData +{ +public: + std::vector> contours; + std::vector boundingBoxes; + std::vector leftEdges; + std::vector middlePoints; + + FrameData(): contours(), boundingBoxes(), leftEdges(), middlePoints() {} }; \ No newline at end of file diff --git a/AutonomousMode/lfr.cpp b/AutonomousMode/lfr.cpp index dc6abd1..ae95cf2 100644 --- a/AutonomousMode/lfr.cpp +++ b/AutonomousMode/lfr.cpp @@ -2,7 +2,7 @@ LFR::LFR(int videoHeight, int videoWidth, int thresholdBinary, int gaussKernelSize, int thresholdCanny1, int thresholdCanny2, int apertureSizeCanny) - : iAmLooping(false), input(videoHeight, videoWidth), processing(), controlModule(), interpreter(), intersectionHandler() + : iAmLooping(false), input(videoHeight, videoWidth), processing(), controlModule(), interpreter(), intersectionHandler(), roi() { this->iAmLooping = false; this->thresholdBinary = thresholdBinary; @@ -14,6 +14,10 @@ LFR::LFR(int videoHeight, int videoWidth, int thresholdBinary, int gaussKernelSi this->videoFlag = false; this->saveOutputFlag = false; this->outputFileName = ""; + + cv::Point roiOrigin(0, videoHeight*(7.5/12.0)); + roi = Rect(roiOrigin.x, roiOrigin.y, videoWidth, videoHeight/12); + } LFR::~LFR() @@ -29,23 +33,11 @@ void LFR::loop() if(this->videoFlag) {namedWindow("Display window");} while(iAmLooping) { - Mat image = input.readWebcam(); - processing.processImage(image, this->thresholdBinary, this->gaussKernelSize, this->thresholdCanny1, thresholdCanny2, this->apertureSizeCanny); - std::vector lines = processing.calculateLineSegments(image); - for( size_t i = 0; i < lines.size(); i++ ) - { - line( image, Point(lines[i][0], lines[i][1]), - Point( lines[i][2], lines[i][3]), (0,0,255), 1, 8 ); - } - if(this->videoFlag) - { - imshow("Display window", image); - char c = (char)waitKey(1); - } - if (this->saveOutputFlag && !(this->outputFileName.empty())) - { - imwrite(this->outputFileName, image); - } + Mat originalImage = input.readWebcam(); + Mat processedImage = originalImage; + processing.processImage(processedImage, this->thresholdBinary, this->gaussKernelSize, this->thresholdCanny1, thresholdCanny2, this->apertureSizeCanny); + FrameData data = processing.calculateLineSegments(processedImage, this->roi); + this->provideOutput(processedImage); } if(this->videoFlag) {destroyWindow("Display window");} input.freeWebcam(); @@ -63,3 +55,16 @@ void LFR::endLoop() this->loopThread.join(); return; } + +void LFR::provideOutput(const Mat& image) +{ + if(this->videoFlag) + { + imshow("Display window", image); + char c = (char)waitKey(1); + } + if (this->saveOutputFlag && !(this->outputFileName.empty())) + { + imwrite(this->outputFileName, image); + } +} diff --git a/AutonomousMode/lfr.h b/AutonomousMode/lfr.h index c8ea635..76460ec 100644 --- a/AutonomousMode/lfr.h +++ b/AutonomousMode/lfr.h @@ -30,6 +30,9 @@ class LFR int thresholdCanny1; int thresholdCanny2; int apertureSizeCanny; + cv::Rect roi; + + void provideOutput(const Mat& image); public: