From 0ea548ec8aff80d096d86b1264f6ad7e540203df Mon Sep 17 00:00:00 2001 From: TimZnr Date: Wed, 7 Dec 2022 22:22:15 +0100 Subject: [PATCH] Prototype reflection filter --- AutonomousMode/Processing/processing.cpp | 62 ++++++++++++++++++++++++ AutonomousMode/Processing/processing.h | 2 +- AutonomousMode/lfr.cpp | 1 + 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/AutonomousMode/Processing/processing.cpp b/AutonomousMode/Processing/processing.cpp index 0dd3462..73398dc 100644 --- a/AutonomousMode/Processing/processing.cpp +++ b/AutonomousMode/Processing/processing.cpp @@ -17,6 +17,68 @@ static double angle( Point pt1, Point pt2, Point pt0 ) return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10); } +void Processing::filterReflections(FrameData& frameData) +{ + //Try to filter reflections from the frame data. + + std::vector indicesToDelete; + for(int i = 0; i < frameData.contours.size(); i++) + { + + // First approach: correct contours nearly fill their bounding box. + // So delete all contours with an area smaller than 75% of their bounding box + double contourArea = cv::contourArea(frameData.contours[i], false); + double boundingBoxArea = double(frameData.boundingBoxes[i].width*frameData.boundingBoxes[i].height); + double minRatio = 0.75; + if(boundingBoxArea/contourArea < minRatio) + { + indicesToDelete.push_back(i); + continue; + } + + // Second approach: The contour should be nearly convex + // So delete all contours with an area smaller than 95% of their convex hull. + std::vector hull; + cv::convexHull(frameData.contours[i], hull); + double hullArea = cv::contourArea(hull, false); + double minRatioHull = 0.95; + if(contourArea/boundingBoxArea < minRatio) + { + indicesToDelete.push_back(i); + continue; + } + + // Third approach: + // Calculate the HoughLinesP of the contour. + // There should be 4 lines + // This one is not really working yet. + Rect boundingRect = cv::boundingRect(frameData.contours[i]); + Point offset(-boundingRect.x, -boundingRect.y); + Mat contourMat = Mat::zeros(frameData.boundingBoxes[i].height, frameData.boundingBoxes[i].width, CV_8UC1); + drawContours(contourMat, frameData.contours, i, Scalar(255,255,255), 1, 8, noArray(), 0, offset); + std::vector linesP; + HoughLinesP(contourMat, linesP, 1, CV_PI/180, 20, 10, 5 ); + //imshow("Some window", contourMat); + if(linesP.size() < 4) + { + //indicesToDelete.push_back(i); + //continue; + //std::cout << linesP.size(); + } + } + + //reverse the vector with the indices so the order isn't messed up when deleting: + std::reverse(indicesToDelete.begin(), indicesToDelete.end()); + for(int index : indicesToDelete) + { + frameData.boundingBoxes.erase(frameData.boundingBoxes.begin() + index); + frameData.contours.erase(frameData.contours.begin() + index); + frameData.leftEdges.erase(frameData.leftEdges.begin() + index); + frameData.middlePoints.erase(frameData.middlePoints.begin() + index); + } + return; +} + void Processing::processImage(Mat& inputPicture, int thresholdBinary, int gaussKernelSize, int thresholdCanny1, int thresholdCanny2, int apertureSizeCanny) { //Idea here is: Processing module consists of two methods: diff --git a/AutonomousMode/Processing/processing.h b/AutonomousMode/Processing/processing.h index 27732f9..82ed15b 100644 --- a/AutonomousMode/Processing/processing.h +++ b/AutonomousMode/Processing/processing.h @@ -20,6 +20,6 @@ public: ~Processing(); void processImage(Mat& inputPicture, int thresholdBinary, int gaussKernelSize, int thresholdCanny1, int thresholdCanny2, int apertureSizeCanny); - + void filterReflections(FrameData& frameData); FrameData calculateLineSegments(const Mat& inputPicture, const cv::Rect& roi); }; \ No newline at end of file diff --git a/AutonomousMode/lfr.cpp b/AutonomousMode/lfr.cpp index 50da73f..0fb05fc 100644 --- a/AutonomousMode/lfr.cpp +++ b/AutonomousMode/lfr.cpp @@ -37,6 +37,7 @@ void LFR::loop() processing.processImage(processedImage, this->thresholdBinary, this->gaussKernelSize, this->thresholdCanny1, thresholdCanny2, this->apertureSizeCanny); FrameData data = processing.calculateLineSegments(processedImage, roi); + processing.filterReflections(data); this->provideOutput(originalImage, data, roi); } if(this->videoFlag) {destroyWindow("Display window");}