'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?

enter image description here

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));

enter image description here

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