2013-04-25 10 views
5

Nie mogę uruchomić tej funkcji. Zasadniczo robię wykrywanie funkcji i dopasowywanie do obrazu referencyjnego. Chcę nakładać dopasowane funkcje na obraz wejściowy. Oto mój kod:Android OpenCV: rysowanie zapałek z feature2d

public Mat startProcessing(Mat inputImage) { 

    Imgproc.cvtColor(inputImage, rgb, Imgproc.COLOR_GRAY2RGB); 
    myFeatures.detect(rgb, keypoints); 
    descriptorExtractor.compute(inputImage, keypoints, imageDescriptors); 
    descriptorMatcher.match(templateDescriptors, imageDescriptors, matches); 

    Features2d.drawMatches(rgb, keypoints, templateImage, templateKeypoints, matches, rgb); 

    Imgproc.cvtColor(rgb, outputImage, Imgproc.COLOR_RGB2RGBA); 
    return outputImage; 
} 

To funkcja2d.drawMatches, który jest szczególnie problem. Zgodnie z błędem Androida, niektóre wymiary nie są wyrównane. Prawdę powiedziawszy, nie jestem nawet pewien, jak drawMatches ma działać na Androida, ponieważ nigdzie nie ma żadnej dokumentacji.

Co mogę zrobić, to narysować dopasowania na szczycie obrazu wejściowego. Otrzymałem Feature2d.drawKeypoints do pracy, ale nie jestem pewien, w jaki sposób chciałbym przekonwertować obiekt MatOfDMatch matches na obiekt MatOfKeypoint. Również nie jestem nawet pewien, czy tak działa MatOfDMatch - czy nie ma w nim skojarzeń odpowiadających deskryptorom?

Przykro mi z tego, że jestem w tym miejscu, bardzo ciężko pracuję przy użyciu OpenCV z Androidem. Dokumentacja w C++ jest dobra, ale niewiele ma materiałów z Androidem. Dzięki za pomoc!

Odpowiedz

6

Pierwszą rzeczą, którą zauważyłem jest to, że konwertujesz obrazy z jednej przestrzeni kolorów na drugą. To trochę mylące. Jeśli chcesz rysować dopasowania na obrazach w skali szarości, nie trzeba wykonywać tej konwersji obrazu. Co innego, wykrywasz punkty kluczowe na obrazie RGB, a następnie wyodrębniasz deskryptory z oryginalnego obrazu (jak widzę to jest w skali szarości)

Sugeruję również sprawdzenie wnętrza funkcji, jeśli obrazy są tego samego typu. Po prostu wydrukuj obiekt z logu inputImage i sprawdź, czy oba są typu CV_8UC3 lub równoważne. Zasadniczo Twój kod powinien wyglądać następująco:

Mat imageOut = inputImage.clone(); 
Features2d.drawMatches(inputImage, keypoints, templateImage, templateKeypoints, matches, imageOut); 
Highgui.imwrite("result_match.jpeg", imageOut); 

Odpowiadając na kolejne pytania:

Q: Jestem pewien, jak pójdę o konwersji MatOfDMatch mecze do MatOfKeypoint obiektu. A: Nie musisz tego robić, ponieważ funkcja drawMatches odbiera MatOfKeypoint obrazu wejściowego, a także obraz szablonu. Następnie, przesyłając MatOfDMatch, rysuje dopasowania pomiędzy dopasowanymi otrzymanymi kypunktami.

P: Nie jestem nawet pewien, czy tak działa MatOfDMatch - czy nie ma w nim powiązania odpowiadającego deskryptorom? O: Tak, tak. Jeśli wykonasz matches.toList(0).queryIdx i matches.toList(0).trainIdx otrzymasz indeks punktu kluczowego inputImage, który pasuje do punktu kluczowego templateImage pierwszego dopasowania.

+0

Dzięki dotychczasowe. Zacząłem używać imageOut = inputImage.clone(), dzięki czemu można korzystać z funkcji drawMatches. Jednak chcę zwrócić ten obraz, ale to, co widzi użytkownik w aparacie, ale wymiary są nieco inne - to 704 * 480, a nie rozdzielczość aparatu 640 * 480. Biorąc pod uwagę, że mój obraz szablonu ma szerokość 64, wygląda na to, że drawMatches umieszcza je obok siebie. Czy mogę po prostu pokazać prostokąt lub coś w dopasowanym obszarze na obrazie wejściowym? – JDS

+2

Tak, myślę, że tak. Przekształć mecze i punkty kluczowe w listę 'List matches_list = matches.toList(); Lista kp_list = keypoints.toList();' a następnie iteruj listę 'kp_list.get (matches_list.get (i) .queryIdx)' i znajdź minimalne i maksymalne X i Y dopasowanych punktów kluczowych, aby spotkać się z dwoma punktami definiującymi twój prostokąt.Następnie zdefiniuj prostokąt 'Rect roi = new Rect (nowy punkt (minX, minY), nowy punkt (maxX, maxY))', ​​a następnie po prostu wykonaj 'Mat imageFinal = new Mat (inputImage, roi);' i będzie tylko przycinać dopasowany obszar – andriy

Powiązane problemy