2012-01-18 9 views
9

Wykonuję niektóre prace wykrywające przy użyciu OpenCV, i potrzebuję użyć transformacji odległości. Poza tym funkcja przekształcania odległości w opencv daje mi obraz, który jest dokładnie taki sam jak obraz, którego używam jako źródła. Czy ktoś wie, co robię źle? Oto fragment mojego kodu:Transformacja odległości OpenCV wyprowadzająca obraz, który wygląda dokładnie tak jak obraz wejściowy

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

W skrócie, to grad obraz z Kinect, przekształcić go w obrazie jednego kanału, wygładza ją, uruchom canny odwrócić wartości, a następnie Wykonuję transformację odległości. Jednak przekształcony obraz wygląda dokładnie tak samo, jak obraz wejściowy. Co jest nie tak?

Dzięki!

+0

Nie sądzę, że to dobry pomysł, aby użyć mediana filtr przed wykrywania krawędzi: filtr Gaussian byłoby znacznie lepiej, ponieważ nie robi” t wprowadzić żadnych artefaktów itp. – BIOStheZerg

Odpowiedz

20

Uważam, że kluczem jest to, że one wyglądają tak samo, jak. Oto mały program napisałem, aby pokazać różnicę:

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

W nieznormalizowaną obrazu, widać to:
enter image description here

który tak naprawdę nie wygląda to zmieniło wszystko, ale kroki odległości są bardzo małe w porównaniu do całkowitego zakresu wartości [0, 255] (z powodu konwersji obrazu z 32-bitowego zmiennopozycyjnego na 8-bitowy w przypadku wyświetlania), nie widzimy różnic, więc normalizujmy to. ..

Teraz otrzymujemy:
enter image description here

Same wartości powinny być prawidłowe, ale gdy są wyświetlane, trzeba znormalizować obraz, aby zobaczyć różnicę.

EDIT: Oto mała próbka 10x10 od lewego górnego rogu pokazują dist matrycy, że wartości są w rzeczywistości inna:

[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

Dziękuję, dziękuję! –

+0

Przepraszam, ale próbowałem to zrobić przez chwilę i nie mogę tego rozgryźć. Jak wziąć powyższą próbkę? Próbuję drukować wartości w pikselach na ekranie przy użyciu printf, ale po prostu dostaję śmieci. Jak wydrukować IPL_DEPTH_8U na ekranie i IPL_DEPTH_32F na ekranie?Dzięki –

+0

pytanie z pytaniem –

1

Można wydrukować te wartości za pomocą tego kodu przed funkcja normalizacji:

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

Właśnie wymyśliłem tę. OpenCV distanceTransform

oblicza odległość do najbliższego piksela zera dla każdego piksela obrazu źródłowego.

i dlatego oczekuje, że obraz krawędzi będzie ujemny.

Wszystko, co musisz zrobić, to neguje swoje krawędzie obrazu:

edges = 255 - edges; 
+0

po co używać 'edges = 255 - edges;' zamiast po prostu 'Not' (' bitwise_not')? – vaxquis

Powiązane problemy