'Drawing with cv::circle's over a line Iterator in c++ with openCV
I'm creating an iterator line, which I pass through a for()
and draw with cv::circle
points. So far so good, form a line drawing, by the iterator's line points. But there is a small drawing in the upper left corner that is not my intention, does anyone know where I could be going wrong?
std::vector<cv::Point> createLineIterator(cv::Mat &frame)
{
cv::Point p1(400, 0);
cv::Point p2(200, 800);
cv::LineIterator line(frame, p1, p2, 8);
std::vector<cv::Point> points(line.count);
for (int i = 0; i <= line.count; i++, ++line)
{
points.push_back(line.pos());
}
return points; //points that I will iterate over to create circles and draw the line
}
int main(int argc, char const *argv[])
{
cv::Mat image(500, 1000, CV_8UC1); // cria imagem
std::vector<cv::Point> points = createLineIterator(image);
for (auto i : points)
{
cv::circle(image, i, 2, cv::Scalar(255, 100, 255)); //Point-by-point drawing of the iterator line
}
cv::imshow("image", image);
cv::waitKey(0);
return 0;
}
Solution 1:[1]
I got it by returning both cv::Point from the function
std::pair<std::pair<cv::Point, cv::Point>, std::vector<cv::Point>> createLineIterator(cv::Mat &frame){...}
and I called in main
cv::line(image, points.first.first, points.first.second, cv::Scalar(255, 0, 0));
I don't know the reason for the error before when drawing with cv::circle
, but see that the random drawing no longer exists with cv::line
Solution 2:[2]
This is a correct version of createLineIterator
that will eliminate the artifacts:
std::vector<cv::Point> createLineIterator(cv::Mat &frame)
{
cv::Point p1(400, 0);
cv::Point p2(200, 800);
cv::LineIterator line(frame, p1, p2, 8);
std::vector<cv::Point> points(line.count);
for (int i = 0; i < line.count; i++, ++line)
{
points[i] = line.pos();
}
return points; //points that I will iterate over to create circles and draw the line
}
Some explanations:
In line 4 inside the function (same as in your code) we allocate line.count
elements in the std::vector
.
This is the meaning of writing line.count
inside the ()
.
Using push_back
in the loop (like you did) added element to the vector,
in addtion to the ones allocated in the construction line (line 4 in the function).
You end up with double the number of elements, the first half default constructed to (0,0).
The (0,0) circles are the artifacts you obsevred.
Instead I assign to already allocated elements:
points[i] = line.pos();
Note - you could also use the default ctor of std::vector
, and then add the elements with push_back
.
But since you know the number of elements in advance it is less efficient that way.
Another important issue is the loop index being < line.count
, instead of <= line.count
in your code.
This is because std::vector
indices are 0..(n-1), where n is the number of elements.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | l12 |
Solution 2 |