2013-03-11 13 views
7

Funkcja OpenCV cvtColor konwertuje przestrzeń kolorów macierzy (np. Z RGB na skalę szarości). C podpis funkcyjnego ++ jestCzy można użyć funkcji OpenCV cvtColor do konwersji macierzy w miejscu?

void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0) 

Czy ta funkcja jest używana konwertować matrycę w miejscu, to znaczy z src tego samego obiektu jako dst?

cv::Mat mat = getColorImage(); 
cvtColor(mat, mat, CV_RGB2GRAY); 

(Zdaję sobie sprawę, że tak czy inaczej, jako miejsce przeznaczenia ma różną liczbę kanałów niż źródła, to nadal będą musiały przeznaczyć nowy blok pamięci do miejsca przeznaczenia.)

Więcej ogólnie, czy istnieje konwencja w ramach API OpenCV, aby określić, kiedy funkcja może być używana w ten sposób?

+1

To można zrobić, gdy źródłowy i docelowy mają taką samą liczbę kanałów. np. RGB do YUV, RGB do YCbCr i na odwrót itd. ... – sgarizvi

Odpowiedz

3

Może jest za późno na odpowiedź, ale chcę powiedzieć, że nie zgadzam się z niektórymi sprawami, które tu napisano.
Możesz umieścić tę samą matę jako źródło i cel, bez problemu, nawet jeśli docelowa macierz nie ma "tej samej liczby kanałów" lub nawet jeśli macie docelowa nie została jeszcze utworzona.
Programiści OpenCV zaprojektowali go dokładnie.
Wszyscy użytkownicy tej funkcji muszą upewnić się, że źródłowa mata jest poprawna, pod względem liczby kanałów i rodzaju danych, i pamiętać, że po wywołaniu funkcji mogliby się zmienić.

Dowód pochodzi od patrzenia na source code, na linii 2406, tylko w pierwszej linii wewnątrz funkcji cv::cvtColor(…),

Mat src = _src.getMat(); 

nazywa, następnie Mat DST jest tworzony (i dst = _dst = _scr).
Tak więc podczas wywoływania w miejscu występuje sytuacja wewnątrz cv::cvtColor(…): punkty src do starej macierzy, _src, _dst, dst wszystkie wskazują na tę samą nową przydzieloną macierz, która będzie docelową macierzą.
Oznacza to, że teraz nowe zmienne src i dst (nie te z funkcji function _src i _dst) są gotowe do przekazania do rzeczywistej funkcji konwersji.
Kiedy funkcja void cv::cvtColor(…) jest zrobione, jest umieszczony src i _src, _dst i dst wszystko wskazuje na ten sam Mat i RefCount z _dst trafi do 1.

+0

Tak, zgadzam się z tym, chociaż nie mam czasu, aby go przetestować w tej chwili. Ale jak widzę, przekazywanie przez InputArray jest równoznaczne z przekazywaniem wartości przez cv :: Mat, co oznacza, że ​​dwie macierze wskazują na ten sam zestaw danych. Jeśli zajdzie potrzeba ponownego przydzielenia, nie wpłynie to na oryginalny nagłówek matrycy, który wskazuje oryginalne dane. –

+0

Tak i po ponownym przydzieleniu nowa macierz jest matą docelową, podczas gdy mata źródłowa jest tymczasowa i zostanie utracona po zakończeniu funkcji. Właśnie to przetestowałem i ten schemat lokalny wydaje się być typowym (prawie standardowym) w ramach OpenCv. –

3

Jeśli spojrzysz na kod here, zobaczysz, że w linii 2420 jest wywoływana create na macierzy dst. Oznacza to, że sekcja danych, jak również nagłówki dla tej macierzy zostały przepisane. Dlatego może nie być wskazane wywoływanie tej funkcji z tą samą macierzą w src i dst.

Co do konwencji w OpenCV, spójrz na InputArray and OutputArray, wydaje się to sugerować, że jeśli istnieją wywołania funkcji z tymi typami danych wejściowych i wyjściowych, prawdopodobnie powinieneś używać różnych zmiennych Mat.

+0

Hmm Rozumiem, co masz na myśli. Ale może się zdarzyć, że gdy macierz zostanie przekonwertowana na InputArray, otrzyma nowy nagłówek? Zapewnienie nowego nagłówka jest tworzone za pomocą wskaźnika. Ponadto, patrząc na nagłówek dla _InputArray https://github.com/Itseez/opencv/blob/9b7dfd677db5818b8dd699e2059c886a1e7ce24f/modules/core/include/opencv2/core/core.hpp sugeruje, że funkcja getMat() zwraca również Mat z jego własny nagłówek zamiast odniesienia do tych samych danych nagłówka. –

+0

tak ... dokładnie ... więc powinieneś prawdopodobnie używać różnych zmiennych Mat ... debugowanie tych aplikacji może być trochę trudne, jeśli nie masz jasnego pojęcia, gdzie zmienia się nagłówek i gdzie znajdują się dane. – subzero

2

Musi działać w miejscu w takim znaczeniu, że dst będzie zawierać poprawnie skonwertowaną macierz po wywołaniu cv::cvtColor. Ale jeśli liczba kanałów wejściowych różni się od liczby kanałów wyjściowych, wówczas dane macierzy zostaną ponownie przydzielone.

Jeśli masz próbkę gdzie dst nie zostały poprawnie przekształca obraz po wywołaniu w miejscu do cvtColor następnie prześlij ją jako błąd na http://code.opencv.org

Bardziej ogólnie, istnieje konwencja w API OpenCV ustalić, kiedy funkcja może być używana w ten sposób?

Nie ma takiej konwencji. Można jednak oczekiwać, że większość podstawowych funkcji przetwarzania obrazu może działać w miejscu. Dlatego wszystkie konwersje, filtry, progi, transformacje afiniczne/perspektywy obsługują połączenia lokalne.

Powiązane problemy