2012-08-01 10 views
6

he realizado Cierre de la operación morfológica y yo estoy recibiendo resultado diferente con la API de C y C++ (OpenCV 2.4.2)Resultado diferente con OPENCV C y C++ API (diferencia Frontera interpolación)

de entrada:

input http://i48.tinypic.com/35jm9n5.png

Con OpenCV 'C':

//Set ROI 
//Perform Gaussian smoothing 
//Perform Canny edge analysis 
cvMorphologyEx(src, dst, temp, Mat(), MORPH_CLOSE, 5); 

RESULTADO: http://i47.tinypic.com/33e0yfb.png

Con OPENCV C++

//Set ROI 
//Perform Gaussian smoothing 
//Perform Canny edge analysis 
cv::morphologyEx(src, dst, cv::MORPH_CLOSE, cv::Mat(), cv::Point(-1,-1), 5); 

RESULTADO: http://i50.tinypic.com/i5vxjo.png

Como se puede ver, la API C++ produce una salida con el color blanco de la frontera/gris. Por lo tanto, los resultados son diferentes para ambas API.

He intentado diferentes borderType con la API C++ pero siempre produce el mismo resultado.

¿Cómo puedo obtener el mismo resultado que C API en C++? Lo necesito porque afecta a los contornos detectados

Gracias de antemano

+0

¿Puede incluir la imagen original? –

+0

@ HåvardGeithus: Entrada: http://i47.tinypic.com/9kthzm.png; La imagen de entrada es una salida de borde astuta como se muestra. –

Respuesta

5

Gracias a todos por responder esta pregunta. He encontrado mi error Voy a describirlo en breve a continuación. Espero que ayude a otros a enfrentar este problema.

1) He ejecutado los comandos C y C++ en una imagen de ROI. Aparentemente, la forma en que las API OpenCV 'C' y 'C++' tratan el ROI es diferente.

2) En 'C', un ROI se trata como una imagen completamente diferente. Por lo tanto, cuando ejecuta funciones como cvSmooth, cvDilate, etc., donde es necesario mencionar los métodos de extrapolación de píxeles de borde, la API 'C' no hace referencia a la imagen original para píxeles más allá del píxel izquierdo/derecho/superior/inferior.En realidad, interpola los valores de píxel de acuerdo con el método que mencionaste.

3) Pero en 'C++', he encontrado que siempre se refiere a la imagen original para píxeles más allá de la izquierda/derecha/arriba/abajo del pixel. Por lo tanto, el método de extrapolación de píxeles de borde mencionado no afecta su resultado si hay píxeles en la imagen original alrededor de su ROI.

Creo que aplica el método de extrapolación de píxeles de pedido a la imagen original en lugar del ROI a diferencia de la API 'C'. No sé si esto es un error; No he leído completamente la documentación de la API OpenCV 2.4.2 C++. (Por favor, corríjanme si me equivoco)

para reclamar mi apoyo, me han publicado imágenes de entrada/salida por debajo de:

salida de 'C' y API C++:

ENTRADA:

input http://i48.tinypic.com/35jm9n5.png < --- entrada

OpenCV 'C' API:

IplImage *src = cvLoadImage("input.png", 0); 
cvSetImageROI(src, cvRect(33,19,250,110)); 
cvSaveImage("before_gauss.png", src); 
cvSmooth(src, src, CV_GAUSSIAN); 
cvSaveImage("after_gauss.png", src); 
IplConvKernel *element = cvCreateStructuringElementEx(3,3,1,1,CV_SHAPE_RECT); 
cvCanny(src, src, 140, 40); 
cvSaveImage("after_canny.png", src); 
cvDilate(src, src, element, 5); 
cvSaveImage("dilate.png", src); 

SALIDA:

before_gauss http://i45.tinypic.com/345lybm.png < - before_gauss

after_gauss http://i45.tinypic.com/2rg1jm0.png < --- after_gauss

after_canny http://i46.tinypic.com/2ymhyqw.png < --- after_canny

dilate http://i48.tinypic.com/5u4ec1.png < --- dilatar

OpenCV 'C++' API:

cv::Mat src = cv::imread("input.png", 0); 
cv::Mat src_ROI = src(cv::Rect(33,19,250,110)); 
cv::imwrite("before_gauss.png", src_ROI); 
cv::GaussianBlur(src_ROI, src_ROI, cv::Size(3,3),0); 
cv::imwrite("after_gauss.png", src_ROI); 
cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3), cv::Point(1,1)); 
cv::Canny(src_ROI, src_ROI, 140, 40); 
cv::imwrite("after_canny.png", src_ROI); 
cv::dilate(src_ROI, src_ROI, element, cv::Point(1,1), 5); 
cv::imwrite("dilate.png", src_ROI); 

SALIDA:

before_gauss http://i45.tinypic.com/345lybm.png < - before_gauss

after_gauss http://i50.tinypic.com/28gxzrb.png

^^^^^ after_gauss (NOTA: las fronteras no son una más completamente negro, son grisáceas)

after_canny http://i45.tinypic.com/2la7ecp.png

^^^^^ after_canny

dilate http://i50.tinypic.com/jhqxbm.png

^^^^^ dilatan

SOLUCIÓN:

Crear una copia ROI independiente y usarla para un análisis posterior;

src_ROI.copyTo(new_src_ROI); 

Utilice new_src_ROI para un análisis posterior. Si alguien tiene una mejor solución, publique debajo de

0

Los valores por defecto no son los mismos entre C y C++ - especialmente el elemento estructurante. En C: el elemento de estructuración por defecto es:

cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_RECT)

mientras que en C++, el elemento estructurante predeterminada es:

getStructuringElement(MORPH_RECT, Size(1+iterations*2,1+iterations*2));

Debe especificar todos los campos (incluyendo el ancla) si se quiero los mismos resultados

+0

El elemento estructurante también fue mi primer pensamiento. –

+0

@ go4sri: esta vez he construido el elemento estructurador como cv :: getStructuringElement (cv :: MORPH_RECT, cv :: Tamaño (3, 3), cv :: Punto (1,1)); y sigo obteniendo resultados diferentes: http://i45.tinypic.com/2j4x47q.png; A continuación probé solo la dilatación Resultado de la dilatación: http: //i48.tinypic.com/10o20ky.png; Como puede ver, hay un borde blanco en todos los lados. Este no debería ser el caso, ¿verdad? Traté de cambiar el borderType pero siempre produce el mismo resultado –

+0

@ HåvardGeithus: cierre morfológico: cv :: morphologyEx (src, src, cv :: MORPH_CLOSE, structuringElement, cv :: Point (1, 1), 5); –

0

Revise esto sample code de la documentación de OpenCV v2.4.2. También es posible que desee comprobar this code para utilizar el detector Canny Edge. Es de esperar que ayuden a rastrear el error :)

También tenga en cuenta que el cierre morfológico es un operador idempotente, por lo que se puede aplicar varias veces sin cambiar el resultado más allá de la aplicación inicial.