2012-01-18 8 views
9

Estoy haciendo un trabajo de detección usando OpenCV, y necesito usar la transformación de distancia. Excepto que la función de transformación de distancia en opencv me da una imagen que es exactamente la misma que la imagen que uso como fuente. ¿Alguien sabe lo que estoy haciendo mal? Aquí está la porción de mi código:Transformación de distancia OpenCV que da salida a una imagen que se ve exactamente como la imagen de entrada

cvSetData(depthImage, m_rgbWk, depthImage->widthStep); 

//gotten openCV image in "depthImage"   

IplImage *single_channel_depthImage = cvCreateImage(cvSize(320, 240), 8, 1); 
cvSplit(depthImage, single_channel_depthImage, NULL, NULL, NULL); 

//smoothing 
IplImage *smoothed_image = cvCreateImage(cvSize(320, 240), 8, 1); 
cvSmooth(single_channel_depthImage, smoothed_image, CV_MEDIAN, 9, 9, 0, 0); 

//do canny edge detector 
IplImage *edges_image = cvCreateImage(cvSize(320, 240), 8, 1); 
cvCanny(smoothed_image, edges_image, 100, 200); 

//invert values 
IplImage *inverted_edges_image = cvCreateImage(cvSize(320, 240), 8, 1); 
cvNot(edges_image, inverted_edges_image); 

//calculate the distance transform 
IplImage *distance_image = cvCreateImage(cvSize(320, 240), IPL_DEPTH_32F, 1); 
cvZero(distance_image); 

cvDistTransform(inverted_edges_image, distance_image, CV_DIST_L2, CV_DIST_MASK_PRECISE, NULL, NULL); 

En pocas palabras, I grad la imagen desde el kinect, girar como una imagen de un canal en, alisarla, ejecute el detector de bordes de Canny, invertir los valores, y luego Hago la transformación de distancia. Pero la imagen transformada se ve exactamente igual que la imagen de entrada. ¿Qué pasa?

Gracias!

+0

no creo que es una buena idea usar un filtro de mediana antes de la detección de bordes: filtro de Gauss sería mucho mejor, ya que doesn' Presente cualquier artefacto, etc. – BIOStheZerg

Respuesta

20

Creo que la clave aquí es que mira lo mismo. Aquí es un pequeño programa que escribí para mostrar la diferencia:

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

using namespace std; 
using namespace cv; 

int main(int argc, char** argv) 
{ 
    Mat before = imread("qrcode.png", 0); 

    Mat dist; 
    distanceTransform(before, dist, CV_DIST_L2, 3); 

    imshow("before", before); 
    imshow("non-normalized", dist); 

    normalize(dist, dist, 0.0, 1.0, NORM_MINMAX); 
    imshow("normalized", dist); 
    waitKey(); 
    return 0; 
} 

En la imagen no normalizada, ve esto:
enter image description here

que en realidad no parece que cambió nada, pero el los pasos de distancia son muy pequeños en comparación con el rango general de valores [0, 255] (debido a imshow convirtiendo la imagen de flotador de 32 bits a 8 bits para visualización), no podemos ver las diferencias, así que normalicemos. ..

Ahora conseguimos esto:
enter image description here

Los valores en sí deberían ser los correctos, pero cuando se muestren, deberá normalizar la imagen para ver la diferencia.

EDIT: He aquí una pequeña muestra de 10x10 desde la esquina superior izquierda de la serie dist matriz que los valores son de hecho diferentes:

[10.954346, 10.540054, 10.125763, 9.7114716, 9.2971802, 8.8828888, 8.4685974, 8.054306, 7.6400146, 7.6400146; 
    10.540054, 9.5850525, 9.1707611, 8.7564697, 8.3421783, 7.927887, 7.5135956, 7.0993042, 6.6850128, 6.6850128; 
    10.125763, 9.1707611, 8.2157593, 7.8014679, 7.3871765, 6.9728851, 6.5585938, 6.1443024, 5.730011, 5.730011; 
    9.7114716, 8.7564697, 7.8014679, 6.8464661, 6.4321747, 6.0178833, 5.6035919, 5.1893005, 4.7750092, 4.7750092; 
    9.2971802, 8.3421783, 7.3871765, 6.4321747, 5.4771729, 5.0628815, 4.6485901, 4.2342987, 3.8200073, 3.8200073; 
    8.8828888, 7.927887, 6.9728851, 6.0178833, 5.0628815, 4.1078796, 3.6935883, 3.2792969, 2.8650055, 2.8650055; 
    8.4685974, 7.5135956, 6.5585938, 5.6035919, 4.6485901, 3.6935883, 2.7385864, 2.324295, 1.9100037, 1.9100037; 
    8.054306, 7.0993042, 6.1443024, 5.1893005, 4.2342987, 3.2792969, 2.324295, 1.3692932, 0.95500183, 0.95500183; 
    7.6400146, 6.6850128, 5.730011, 4.7750092, 3.8200073, 2.8650055, 1.9100037, 0.95500183, 0, 0; 
    7.6400146, 6.6850128, 5.730011, 4.7750092, 3.8200073, 2.8650055, 1.9100037, 0.95500183, 0, 0] 
+0

¡Gracias, gracias! –

+0

lo siento, pero he estado tratando de hacer esto por un tiempo y parece que no puedo resolverlo. ¿Cómo tomas la muestra que acabas de hacer arriba? Sigo intentando imprimir valores en píxeles a la pantalla con printf, pero me sale basura. ¿Cómo imprimo IPL_DEPTH_8U en la pantalla e IPL_DEPTH_32F en la pantalla?Gracias –

+0

haciendo la pregunta –

1

Puede imprimir estos valores utilizando este código antes normalizar la función:

for(int x=0; x<10;x++) 
    { 
    cout<<endl; 
    for(int y=0; y<10;y++) 
     cout<<std::setw(10)<<dist.at<float>(x, y); 
    } 
3

Acabo de descifrar esto. El OpenCV distanceTransform

calcula la distancia al píxel más cercano a cero para cada píxel de la imagen de origen .

y por lo que espera que su imagen de bordes sea negativa.

Todo lo que necesita hacer es negar su imagen bordes:

edges = 255 - edges; 
+0

por qué usar 'edges = 255 - edges;' en lugar de simplemente 'Not' (' bitwise_not')? – vaxquis

Cuestiones relacionadas