2014-06-15 16:01:34

Amatorskie spojrzenie na EmguCV - podstawowe przekształcenia obrazów

W trzeciej części serii chciałbym ukazać łatwość z jaką przy pomocy EmguCV można dokonywać przekształceń obrazu. W tym poście skoncentruję się na 3 przekształceniach: Odbicie lustrzane (Flip), Obrocie, Skalowaniu.
Jednak zanim przejdę do właściwego tematu chciałbym wspomnieć o ręcznym zarządzaniu zasobami. Klasa Image<TColor, TDepth> implementuje interfejs IDisposable co wskazuje na konieczność zwalniania zasobów gdy tylko obiekt przestaje nam być potrzebny. Jednak dokumentacja Emgu mówi o braku takiej konieczności (prawdopodobnie jest to związane z faktem iż Emgu poprawnie implementuje ten interfejs a sama klasa posiada finalizer zwalniający zasoby gdy przyjdzie odpowiednia pora. Ja osobiście domyślnie wywołuję Dispose (czy to jawnie czy to przez konstrukcję using), chyba że mam wątpliwości czy zwalniany obiekt nie jest gdzieś jeszcze używany, dlatego w swoim projekciku raczej nie będę się stosował do zaleceń dostawcy.
 
Aby zrobić odbicie lustrzane obrazu należy na nim wywołać metodę Flip (albo _Flip), metoda ta jako parametr pobiera wartość FLIP.HORIZONTAL albo FLIP.VERTICAL gdzie FLIP jest Enum'em.
Przy okazji wrócę do tematu metod "podreślnikowych". Kilka moich eksperymentów potwierdziło że ich używanie zużywa mniej pamięci operacyjnej niż używanie ich odpowiedników bez podkreślnika na początku. Drugim spostrzeżeniem jakiego przy ich okazji dokonałem to fakt iż kontrolka ImageBox nie obserwuje zmian w obrazie i po wywołaniu metody z podkreślnikiem należy albo podstawić właściwość Image kontrolki ponownie albo wywołać na niej Invalidate. 
Wadą API Emgu CV jaką widać na przykładzie metod podkreślnikowych i ww. enuma jest nie trzymanie się konwencji nazewniczych przyjętych w C#.
Jednak odbicie lustrzane nie jest niczym nadzwyczajnym (nawet klasa System.Drawing.Bitmap posiada metodę RotateFlip), dlatego przechodzę do czegoś co w Windows Forms jest gorzej wspierane, a więc obrót. W Emgu CV dokonuje się go metodą Rotate (jakie zaskakujące), metoda ta nie posiada swojego "podkreślnikowego" odpowiednika prawdopodobnie ze względu na fakt iż zmienia ona rozmiar obrazu. Metoda ta posiada 3 przeciążenia w najprostrzym przypadku parametrami tej metody jest kąt obrotu w stopniach oraz kolor jakim zostaną wypełnione "dziury" w obrazie powstałe w wyniku niedopasowania, dodatkowo można zdefiniować czy wynikowy obraz ma być obcięty do oryginalnych rozmiarów (domyślnie obraz jest obcięty), środek obrotu - punkt niestety nie udało mi się ustalić sposobu jego interpretacji, a w dokumentacji którą znalazłem brakowało opisu tego przeciążenia metody Rotate. Ostatnim parametrem jest sposób interpolacji - pomijając obroty o wielokrotności 90 stopni jasnym jest że po obrocie piksele oryginalnego obrazu nie trafią idealnie w piksele obrazu wynikowego, więc kolory pikseli wynikowych należy obliczyć na podstawie kolorów pikseli które wylądowały w pobliżu. W zastosowaniach profesjonalnych może parametr ten może mieć znaczenie, jednak organoleptycznie nie udało mi się dostrzec różnic pomiędzy wynikami zastosowanymi z różnymi wynikami tego parametru.
Skalowanie obrazu wykonuje się przy pomocy metody Resize. Posiada ona 3 przeciążenia, wszystkie 3 mają parametr interpolationType interpretowany analogicznie jak taki sam parametr w obrocie. Najprostrze przeciążenie przyjmuje oprócz tego parametru także skalę. Drugie przeciążenie zamiast skali przyjmuje docelową szerokość i wysokość obrazu - przy czym obraz może się skalować inaczej wzdłóż osi X, a inaczej wzdłóż osi Y. Ostatnie przeciążenie do drugiego przeciążenia dodaje parametr preserveScale ustawienie go na true sprawi że obraz zostanie zeskalowany tak aby się zmieścił w docelowym prostokącie, nic z obrazu nie zostało obcięte oraz bez naruszenia proporcji, to przeciążenie świetnie się nadaje do generowania miniaturek (ponieważ takie warunki muszą one zazwyczaj spełnić.
Na koniec dodam że moim celem nie jest opisywanie na łamach tego bloga wszystkich elementów EmguCV - nie chcę powielać dokumentacji.
Przykładowy kod wykorzystujący ww metody znajduje się Tutaj 

Tagi

C Sharp EmguCV

Komentarze: