2012-06-15 13 views
7

No puedo obtener cv :: line para dibujar una línea antialias con las marcas CV_AA establecidas. Aquí es código de ejemplo para ilustrar:Al dibujar una línea en OpenCV con marcas CV_AA no se produce una línea antialias

#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; 
} 

He intentado usar cv :: POINT2D en lugar de cv :: Point2i y no encontró diferencias. (i == entero, d == doble) También intenté hacer que el ancho del píxel fuera mayor que 1, pero todavía no hay AA.

Sin embargo, esto sí funciona con una imagen CV_8U (8 bits sin signo), en oposición a la imagen CV_32F (flotador de 32 bits) que tengo aquí. (Para CV_8U, debe pasar cv :: Scalar (255) en lugar de cv :: Scalar (1.0) en la función de línea para comparar)

Supongo que una solución alternativa sería comenzar con una imagen CV_8U luego convertir, pero ¿hay una manera directa de hacerlo con solo una imagen CV_32F que no requiere que escriba mi propia función anti-aliasing?

¿Echo de menos algo?

docs OpenCV: cv::line reference

+1

Puede ser un problema en OpenCV, pero quiero señalarle un código extraño: puede mover el bucle exterior cv :: namedWindow y cv :: imshow, manteniendo la misma funcionalidad para una velocidad mucho mejor. – Sam

+0

Ah, sí, buen punto. Tiré eso para la pregunta. –

+1

en realidad, puede escribir c = cv :: waitKey(); return 0; Cuando presione una tecla, waitKey() regresará y cerrará el programa. – Sam

Respuesta

5

¿Puede proporcionar una imagen de muestra? También he probado a mí mismo y está funcionando perfectamente bien con este código:

#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 mi resultado:
enter image description here

+0

Esta es una línea AA, y lo que obtengo al establecer la imagen base en CV_8U: http://imgur.com/4wlea. Esta es una línea que no es de AA, y lo que obtengo al establecer la imagen base en CV_32F, a pesar de que CV_AA pasó a la función cv :: line: http://imgur.com/MSogk. Está utilizando una imagen CV_8U en su ejemplo. Quiero que la función funcione para CV_32F. –

7
./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 
} 

El código fuente afirma que mientras la profundidad no es CV_8U , dibujará usando el método 8 conectado.

Cuestiones relacionadas