16 #include <mrpt/otherlibs/do_opencv_includes.h> 29 std::vector<cv::Vec4i> & segments,
33 cout <<
"CFeatureLines::extractLines... threshold " << threshold << endl;
38 int lowThreshold = 150;
42 cv::Canny(
image, canny_img, lowThreshold, lowThreshold*ratio, kernel_size);
49 std::vector<cv::Vec2f> lines;
50 cv::HoughLines(canny_img, lines, 1,
CV_PI / 180.0, threshold);
57 cv::Mat filteredCanny;
60 cv::dilate(canny_img, filteredCanny, cv::Mat());
68 extractLines_CannyHough(filteredCanny, lines, segments, threshold);
69 cout <<
" CFeatureLines::extractLines " << segments.size() <<
" took " << 1000*clock.
Tac() <<
" ms \n";
72 for(
auto line =
begin(segments); line !=
end(segments); ++line)
73 if((*line)[1] == (*line)[3]){
74 if((*line)[0] > (*line)[1])
75 *line = cv::Vec4i((*line)[2], (*line)[3], (*line)[0], (*line)[1]);
77 else if((*line)[1] < (*line)[3])
78 *line = cv::Vec4i((*line)[2], (*line)[3], (*line)[0], (*line)[1]);
84 image.convertTo(image_lines, CV_8UC1, 1.0 / 2);
85 for(
auto line =
begin(segments); line !=
end(segments); ++line)
89 cv::line(image_lines, cv::Point((*line)[0], (*line)[1]), cv::Point((*line)[2], (*line)[3]),
cv::Scalar(255, 0, 255), 1);
90 cv::circle(image_lines, cv::Point((*line)[0], (*line)[1]), 3,
cv::Scalar(255, 0, 255), 3);
91 cv::putText(image_lines,
string(
to_string(
distance(
begin(segments),line))), cv::Point(((*line)[0]+(*line)[2])/2,((*line)[1]+(*line)[3])/2), 0, 1.2,
cv::Scalar(200,0,0), 3 );
95 cv::imwrite(
"/home/efernand/lines.png", image_lines);
96 cv::imshow(
"lines", image_lines); cv::moveWindow(
"lines", 20,100+700);
102 const std::vector<cv::Vec2f> lines,
103 std::vector<cv::Vec4i> & segments,
108 double cosTheta, sinTheta;
118 for (
size_t n(0);
n < lines.size(); ++
n) {
122 if (lines[
n][0] < 0) {
124 theta = lines[
n][1] -
CV_PI;
131 if (rho == 0 && theta == 0) {
137 if (fabs(theta) < 0.00001)
139 x = xF =
static_cast<int>(rho + 0.5);
141 yF = canny_image.rows - 1;
145 cosTheta = cos(theta);
146 sinTheta = sin(theta);
147 m = -cosTheta / sinTheta;
148 c = rho * (sinTheta - m * cosTheta);
152 if (
c < canny_image.rows) {
155 y =
static_cast<int>(
c);
159 y = canny_image.rows - 1;
160 x =
static_cast<int>((
y -
c) / m);
165 x =
static_cast<int>(-
c / m);
169 cMax = m * (canny_image.cols - 1) +
c;
171 if (cMax < canny_image.rows) {
173 xF = canny_image.cols - 1;
174 yF =
static_cast<int>(cMax);
178 yF = canny_image.rows - 1;
179 xF =
static_cast<int>((yF -
c) / m);
184 xF =
static_cast<int>(-
c / m);
192 bool onSegment =
false;
194 int memoryX = 0, memoryY = 0;
195 int xPrev = 0, yPrev = 0;
200 int dx1, dy1, dx2, dy2 = 0;
202 int longest, shortest;
228 if (longest <= shortest)
242 numerator = longest / 2;
245 for (
int i(0); i <= longest; ++i)
249 if (canny_image.at<
char>(
y,
x) == 0 || i == longest)
253 if (nbPixels >= threshold) {
254 segments.push_back(cv::Vec4i(memoryX, memoryY, xPrev, yPrev));
264 else if (canny_image.at<
char>(
y,
x) != 0)
278 numerator += shortest;
279 if (numerator >= longest)
281 numerator -= longest;
double Tac() noexcept
Stops the stopwatch.
A high-performance stopwatch, with typical resolution of nanoseconds.
EIGEN_STRONG_INLINE iterator begin()
GLenum GLsizei GLenum GLenum const GLvoid * image
void extractLines(const cv::Mat &image, std::vector< cv::Vec4i > &segments, size_t threshold, const bool display=false)
GLubyte GLubyte GLubyte GLubyte w
void extractLines_CannyHough(const cv::Mat &canny_image, const std::vector< cv::Vec2f > lines, std::vector< cv::Vec4i > &segments, size_t threshold)
Classes for computer vision, detectors, features, etc.
std::string std::string to_string(T v)
Just like std::to_string(), but with an overloaded version for std::string arguments.
void Tic() noexcept
Starts the stopwatch.
double distance(const TPoint2D &p1, const TPoint2D &p2)
Gets the distance between two points in a 2D space.