-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGripPipeline.cpp
More file actions
201 lines (189 loc) · 7.9 KB
/
GripPipeline.cpp
File metadata and controls
201 lines (189 loc) · 7.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#include "GripPipeline.h"
namespace grip {
GripPipeline::GripPipeline() {
}
/**
* Runs an iteration of the pipeline and updates outputs.
*/
void GripPipeline::Process(cv::Mat& source0){
//Step HSV_Threshold0:
//input
cv::Mat hsvThresholdInput = source0;
double hsvThresholdHue[] = {58.273381294964025, 106.65534804753818};
double hsvThresholdSaturation[] = {176.57374100719423, 255.0};
double hsvThresholdValue[] = {110.07194244604317, 255.0};
hsvThreshold(hsvThresholdInput, hsvThresholdHue, hsvThresholdSaturation, hsvThresholdValue, this->hsvThresholdOutput);
//Step Find_Contours0:
//input
cv::Mat findContoursInput = hsvThresholdOutput;
bool findContoursExternalOnly = false; // default Boolean
findContours(findContoursInput, findContoursExternalOnly, this->findContoursOutput);
//Step Filter_Contours0:
//input
std::vector<std::vector<cv::Point> > filterContoursContours = findContoursOutput;
double filterContoursMinArea = 70.0; // default Double
double filterContoursMinPerimeter = 0.0; // default Double
double filterContoursMinWidth = 0.0; // default Double
double filterContoursMaxWidth = 80.0; // default Double
double filterContoursMinHeight = 0.0; // default Double
double filterContoursMaxHeight = 200.0; // default Double
double filterContoursSolidity[] = {0, 100};
double filterContoursMaxVertices = 70.0; // default Double
double filterContoursMinVertices = 0.0; // default Double
double filterContoursMinRatio = 0.0; // default Double
double filterContoursMaxRatio = 1000.0; // default Double
filterContours(filterContoursContours, filterContoursMinArea, filterContoursMinPerimeter, filterContoursMinWidth, filterContoursMaxWidth, filterContoursMinHeight, filterContoursMaxHeight, filterContoursSolidity, filterContoursMaxVertices, filterContoursMinVertices, filterContoursMinRatio, filterContoursMaxRatio, this->filterContoursOutput);
//Step Find_Lines0:
//input
cv::Mat findLinesInput = hsvThresholdOutput;
findLines(findLinesInput, this->findLinesOutput);
//Step Filter_Lines0:
//input
std::vector<Line> filterLinesLines = findLinesOutput;
double filterLinesMinLength = 10.0; // default Double
double filterLinesAngle[] = {61.01694915254237, 117.4468085106383};
filterLines(filterLinesLines, filterLinesMinLength, filterLinesAngle, this->filterLinesOutput);
}
/**
* This method is a generated getter for the output of a HSV_Threshold.
* @return Mat output from HSV_Threshold.
*/
cv::Mat* GripPipeline::GetHsvThresholdOutput(){
return &(this->hsvThresholdOutput);
}
/**
* This method is a generated getter for the output of a Find_Contours.
* @return ContoursReport output from Find_Contours.
*/
std::vector<std::vector<cv::Point> >* GripPipeline::GetFindContoursOutput(){
return &(this->findContoursOutput);
}
/**
* This method is a generated getter for the output of a Filter_Contours.
* @return ContoursReport output from Filter_Contours.
*/
std::vector<std::vector<cv::Point> >* GripPipeline::GetFilterContoursOutput(){
return &(this->filterContoursOutput);
}
/**
* This method is a generated getter for the output of a Find_Lines.
* @return LinesReport output from Find_Lines.
*/
std::vector<Line>* GripPipeline::GetFindLinesOutput(){
return &(this->findLinesOutput);
}
/**
* This method is a generated getter for the output of a Filter_Lines.
* @return LinesReport output from Filter_Lines.
*/
std::vector<Line>* GripPipeline::GetFilterLinesOutput(){
return &(this->filterLinesOutput);
}
/**
* Segment an image based on hue, saturation, and value ranges.
*
* @param input The image on which to perform the HSL threshold.
* @param hue The min and max hue.
* @param sat The min and max saturation.
* @param val The min and max value.
* @param output The image in which to store the output.
*/
void GripPipeline::hsvThreshold(cv::Mat &input, double hue[], double sat[], double val[], cv::Mat &out) {
cv::cvtColor(input, out, cv::COLOR_BGR2HSV);
cv::inRange(out,cv::Scalar(hue[0], sat[0], val[0]), cv::Scalar(hue[1], sat[1], val[1]), out);
}
/**
* Finds contours in an image.
*
* @param input The image to find contours in.
* @param externalOnly if only external contours are to be found.
* @param contours vector of contours to put contours in.
*/
void GripPipeline::findContours(cv::Mat &input, bool externalOnly, std::vector<std::vector<cv::Point> > &contours) {
std::vector<cv::Vec4i> hierarchy;
contours.clear();
int mode = externalOnly ? cv::RETR_EXTERNAL : cv::RETR_LIST;
int method = cv::CHAIN_APPROX_SIMPLE;
cv::findContours(input, contours, hierarchy, mode, method);
}
/**
* Filters through contours.
* @param inputContours is the input vector of contours.
* @param minArea is the minimum area of a contour that will be kept.
* @param minPerimeter is the minimum perimeter of a contour that will be kept.
* @param minWidth minimum width of a contour.
* @param maxWidth maximum width.
* @param minHeight minimum height.
* @param maxHeight maximimum height.
* @param solidity the minimum and maximum solidity of a contour.
* @param minVertexCount minimum vertex Count of the contours.
* @param maxVertexCount maximum vertex Count.
* @param minRatio minimum ratio of width to height.
* @param maxRatio maximum ratio of width to height.
* @param output vector of filtered contours.
*/
void GripPipeline::filterContours(std::vector<std::vector<cv::Point> > &inputContours, double minArea, double minPerimeter, double minWidth, double maxWidth, double minHeight, double maxHeight, double solidity[], double maxVertexCount, double minVertexCount, double minRatio, double maxRatio, std::vector<std::vector<cv::Point> > &output) {
std::vector<cv::Point> hull;
output.clear();
for (std::vector<cv::Point> contour: inputContours) {
cv::Rect bb = boundingRect(contour);
if (bb.width < minWidth || bb.width > maxWidth) continue;
if (bb.height < minHeight || bb.height > maxHeight) continue;
double area = cv::contourArea(contour);
if (area < minArea) continue;
if (arcLength(contour, true) < minPerimeter) continue;
cv::convexHull(cv::Mat(contour, true), hull);
double solid = 100 * area / cv::contourArea(hull);
if (solid < solidity[0] || solid > solidity[1]) continue;
if (contour.size() < minVertexCount || contour.size() > maxVertexCount) continue;
double ratio = (double) bb.width / (double) bb.height;
if (ratio < minRatio || ratio > maxRatio) continue;
output.push_back(contour);
}
}
/**
* Finds all line segments in an image.
*
* @param input The image on which to perform the find lines.
* @param lineList The output where the lines are stored.
*/
void GripPipeline::findLines(cv::Mat &input, std::vector<Line> &lineList) {
cv::Ptr<cv::LineSegmentDetector> lsd = cv::createLineSegmentDetector(cv::LSD_REFINE_STD);
std::vector<cv::Vec4i> lines;
lineList.clear();
if (input.channels() == 1) {
lsd->detect(input, lines);
} else {
// The line detector works on a single channel.
cv::Mat tmp;
cv::cvtColor(input, tmp, cv::COLOR_BGR2GRAY);
lsd->detect(tmp, lines);
}
// Store the lines in the LinesReport object
if (!lines.empty()) {
for (int i = 0; i < lines.size(); i++) {
cv::Vec4i line = lines[i];
lineList.push_back(Line(line[0], line[1], line[2], line[3]));
}
}
}
/**
* Filters out lines that do not meet certain criteria.
*
* @param inputs The lines that will be filtered.
* @param minLength The minimum length of a line to be kept.
* @param angle The minimum and maximum angle of a line to be kept.
* @param outputs The output lines after the filter.
*/
void GripPipeline::filterLines(std::vector<Line> &inputs, double minLength, double angle[], std::vector<Line> &outputs) {
outputs.clear();
for (Line line: inputs) {
if (line.length()>abs(minLength)) {
if ((line.angle() >= angle[0] && line.angle() <= angle[1]) ||
(line.angle() + 180.0 >= angle[0] && line.angle() + 180.0 <=angle[1])) {
outputs.push_back(line);
}
}
}
}
} // end grip namespace