5 #include <opencv2/opencv.hpp>
7 #include <vision_module/Tools/Parameters.hpp>
8 #include <vision_module/Tools/General.hpp>
9 #include <vision_module/Projections/CameraProjections.hpp>
10 #include <vision_module/SoccerObjects/IDetector.hpp>
11 #include <vision_module/Tools/SortFuntions.hpp>
12 #include <vision_module/Tools/LinearBoundaryChecker.hpp>
24 bool GetPosts(Mat& cannyImg, Mat& rawHSV, Mat &gray,
const Mat &binaryFrame,
26 vector<LineSegment> &resLines, vector<LineSegment> &alllLines,
27 vector<Point2f> &goalPosition,
bool SHOWGUI, Mat &guiImg)
30 if (binaryFrame.empty())
37 rec.width = params.camera->width();
38 rec.height = params.camera->height();
39 const int MinLineLength = params.goal->MinLineLength();
40 const int DistanceToMerge = params.goal->DistanceToMerge();
41 const int MaxOutField = params.goal->MaxOutField();
42 const int MinNearFieldUpPoint = -20;
44 vector<cv::Vec4i> linesP;
46 HoughLinesP(cannyImg, linesP, 1, M_PI / 45, 10, MinLineLength, 20);
47 vector<LineSegment> allVerLines;
48 for (
size_t i = 0; i < linesP.size(); i++)
50 cv::Vec4i lP = linesP[i];
52 cv::Point2d(lP[2], lP[3]));
55 if (tmpLine.GetAbsMinAngleDegree(
56 LineSegment(cv::Point(0, 0), cv::Point(0, 100))) < 15)
58 vector<cv::Point2d> midds = tmpLine.GetMidPoints(5);
59 int maxMidPoint = midds.size();
60 int vote_for_doubleLeft = 0;
61 int vote_for_doubleRight = 0;
64 (tmpLine.P1.y < tmpLine.P2.y) ? tmpLine.P2 : tmpLine.P1;
65 double jumpDouble = params.goal->jumpMax();
67 if (!projection.GetOnRealCordinate_single(down, downReal))
69 ROS_ERROR(
"Erorr in programming!");
72 double downDistance2Field = pointPolygonTest(fieldHull, down,
74 if (downDistance2Field < MaxOutField)
76 double distance = GetDistance(downReal);
81 else if (distance >= 2 && distance < 3)
90 for (
size_t j = 0; j < midds.size(); j++)
93 LineSegment tocheck = tmpLine.PerpendicularLineSegment(
94 jumpDouble, midds[j]);
97 (tocheck.P1.x < tocheck.P2.x) ?
98 tocheck.P1 : tocheck.P2;
100 (tocheck.P1.x < tocheck.P2.x) ?
101 tocheck.P2 : tocheck.P1;
102 cv::LineIterator itLeft(cannyImg, midds[j], left, 8);
103 cv::LineIterator itRight(cannyImg, midds[j], right, 8);
104 cv::LineIterator itHSVLeft(rawHSV, midds[j], left, 8);
105 cv::LineIterator itHSVRight(rawHSV, midds[j], right, 8);
108 if (tocheck.P1.x >= 0 && tocheck.P1.y >= 0
109 && tocheck.P1.x < params.camera->width()
110 && tocheck.P1.y < params.camera->height())
114 if (tocheck.P2.x >= 0 && tocheck.P2.y >= 0
115 && tocheck.P2.x < params.camera->width()
116 && tocheck.P2.y < params.camera->height())
122 for (
int k = 0; k < itLeft.count;
123 k++, ++itLeft, ++itHSVLeft)
127 uchar val = *(*itLeft);
128 cv::Vec3b hsvC = (cv::Vec3b) *itHSVLeft;
130 if (val > 0 && k > params.goal->minDoubleLength())
132 if (safeToShow >= 2 && SHOWGUI
133 && params.goal->showVote())
135 cv::line(guiImg, midds[j], itHSVLeft.pos(),
139 vote_for_doubleLeft++;
143 if (hsvC[0] >= params.goal->h0()
144 && hsvC[0] <= params.goal->h1()
145 && hsvC[1] >= params.goal->s0()
146 && hsvC[1] <= params.goal->s1()
147 && hsvC[2] >= params.goal->v0()
148 && hsvC[2] <= params.goal->v1())
158 for (
int k = 0; k < itRight.count;
159 k++, ++itRight, ++itHSVRight)
163 uchar val = *(*itRight);
164 cv::Vec3b hsvC = (cv::Vec3b) *itHSVRight;
166 if (val > 0 && k > params.goal->minDoubleLength())
168 if (safeToShow >= 2 && SHOWGUI
169 && params.goal->showVote())
171 cv::line(guiImg, midds[j], itHSVRight.pos(),
175 vote_for_doubleRight++;
179 if (hsvC[0] >= params.goal->h0()
180 && hsvC[0] <= params.goal->h1()
181 && hsvC[1] >= params.goal->s0()
182 && hsvC[1] <= params.goal->s1()
183 && hsvC[2] >= params.goal->v0()
184 && hsvC[2] <= params.goal->v1())
196 bool leftOK = (vote_for_doubleLeft / (float) maxMidPoint) * 100.
197 > params.goal->doubleVote();
199 bool rightOk = (vote_for_doubleRight / (float) maxMidPoint)
200 * 100. > params.goal->doubleVote();
202 if (leftOK || rightOk)
209 int amount = abs(leftAvg / vote_for_doubleLeft)
211 tmpLineChanged.P1.x -= amount;
212 tmpLineChanged.P2.x -= amount;
216 int amount = abs(rightAvg / vote_for_doubleRight)
218 tmpLineChanged.P1.x += amount;
219 tmpLineChanged.P2.x += amount;
221 tmpLineChanged.Clip(rec);
222 allVerLines.push_back(tmpLineChanged);
228 vector<LineSegment> allVerLines2;
229 MergeLinesMax(allVerLines, 30, DistanceToMerge, allVerLines2, rec);
231 for (
size_t i = 0; i < allVerLines2.size(); i++)
235 (tmpLine.P1.y > tmpLine.P2.y) ? tmpLine.P2 : tmpLine.P1;
237 (tmpLine.P1.y < tmpLine.P2.y) ? tmpLine.P2 : tmpLine.P1;
239 double verLen = tmpLine.GetLength();
240 if (pointPolygonTest(fieldHull, up,
true) > MinNearFieldUpPoint)
244 cv::Point2f downReal;
245 if (!projection.GetOnRealCordinate_single(down, downReal))
247 ROS_ERROR(
"Erorr in programming!");
251 if (!checkDistance_Box(downReal, verLen))
253 double downDistance2Field = pointPolygonTest(fieldHull, down,
true);
254 if (downDistance2Field < MaxOutField)
256 if (GetDistance(downReal) > 5)
258 goalPosition.push_back(downReal);
262 if (SHOWGUI && params.goal->showVote())
264 for (
size_t i = 0; i < allVerLines2.size(); i++)
266 cv::line(guiImg, allVerLines2[i].P1, allVerLines2[i].P2,
270 if (SHOWGUI && params.goal->showResult())
272 for (
size_t i = 0; i < resLines.size(); i++)
274 cv::line(guiImg, resLines[i].P1, resLines[i].P2, blueColor(),
278 return resLines.size() > 0;
281 bool checkDistance_Box(Point2f downPointInReal,
double length)
285 Point2f(params.goal->NearestDistance(), params.goal->NearMinLen()),
286 Point2f(params.goal->FarestDistance(), params.goal->FarMinLen()));
288 Point2f(params.goal->NearestDistance(), params.goal->NearMaxLen()),
289 Point2f(params.goal->FarestDistance(), params.goal->FarMaxLen()));
292 double distanceToRobot = GetDistance(downPointInReal);
294 return checker.CheckInside(distanceToRobot, length);
300 if(!readFromFile<Point3d>(params.goal->distSizeVecPath, params.goal->distSizeVec))
302 ROS_ERROR(
"Create or modify %s!",params.goal->distSizeVecPath.c_str());
305 std::sort(params.goal->distSizeVec.begin(),
306 params.goal->distSizeVec.end(), [](
const Point3d& a,
const Point3d& b)
For pixel projections.
Definition: CameraProjections.hpp:50
A class representing line segments.
Definition: LineSegment.hpp:17
A class for check if a point is between two given line segments.
Definition: LinearBoundaryChecker.hpp:15
For detecting potential goal posts.
Definition: GoalDetector.hpp:20