Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing a line in OpenCV with CV_AA flags is not producing an anti-aliased line

Tags:

opencv

I am unable to get cv::line to draw an anti-aliased line with CV_AA flags set. Here is example code to illustrate:

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;

int main(int argc, char* argv[])
{
    cv::Mat base(100, 100, CV_32F);

    cv::Point2i p1(20, 20);
    cv::Point2i p2(70, 90);

    cv::line(base, p1, p2, cv::Scalar(1.0), 1, CV_AA); // 1 pixel thick, CV_AA == Anti-aliased flag

    cv::namedWindow("line test", CV_NORMAL);
    cv::imshow("line test", base);
    cv::waitKey(0);

    return 0;
}

I have tried using cv::Point2d instead of cv::Point2i and found no difference. (i == integer, d == double) I have also tried making the pixel width larger than 1, but there is still no AA.

However, this does work with a CV_8U (8-bit unsigned) image, as opposed to CV_32F (32-bit float) image that I have here. (For CV_8U, you must pass cv::Scalar(255) instead of cv::Scalar(1.0) into the line function to compare)

I suppose a current work-around would be to start with a CV_8U image then convert, but is there a straightforward way to do it with just an CV_32F image that doesn't require me to write my own anti-aliasing function?

Am I missing something?

OpenCV docs: cv::line reference

like image 745
Matteo Mannino Avatar asked Jun 15 '12 17:06

Matteo Mannino


2 Answers

./core/src/drawing.cpp:1569
void line( Mat& img, Point pt1, Point pt2, const Scalar& color,
       int thickness, int line_type, int shift )
{
    if( line_type == CV_AA && img.depth() != CV_8U )
        line_type = 8;
    //omitted
}

The source code states that as long as the depth is not CV_8U, it will draw using 8-connected method.

like image 156
lanpa Avatar answered Oct 19 '22 17:10

lanpa


Can you provide a sample image? I also tried it myself and it's working perfectly fine with this code:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

int main(int argc, char *argv[])
{
  cv::Mat img = cv::Mat::zeros(500, 500, CV_8UC3);

  // red line, which is not anti-aliased
  cv::line(img, cv::Point(100, 100), cv::Point(400, 105), cv::Scalar(0,0,200), 3, 4);  

  // green line, which is not anti-aliased
  cv::line(img, cv::Point(100, 200), cv::Point(400, 205), cv::Scalar(0,200,0), 5, 8);

  // blue line, which is anti-aliased
  cv::line(img, cv::Point(100, 300), cv::Point(400, 305), cv::Scalar(200,0,0), 10, CV_AA);

  cv::namedWindow("drawing", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO);
  cv::imshow("drawing", img);

  cv::waitKey(0);
}

That'y my outcome:
enter image description here

like image 21
dom Avatar answered Oct 19 '22 15:10

dom