From Krzysztof Krawiec

RO: Przetwarzanie i Rozpoznawanie Obrazów - Laboratoria

Strona laboratorium

Gdy brakuje TBB

DLLki można ściągnąć tutaj

Ćwiczenia 1

OpenCV to bardzo rozbudowana biblioteka graficzna implementująca ponad 500 algorytmów przetwarzania i rozpoznawania obrazów. Jest ona zaimplementowana w języku C/C++ z interfejsami m.in. do języka Pythona.

Oficjalna strona OpenCV: http://opencv.willowgarage.com
Dokumentacja OpenCV 2.3: http://opencv.itseez.com/

OpenCV od wersji 2.3 w Pythonie do reprezentowania obrazów używa tablic z pakietu NumPy. Dlatego wszystkie podstawowe operacje na obrazach (np. odczytanie wartości jakiegoś piksela) można wykonywać tak jak na zwykłych tablicach wielowymiarowych.

Wprowadzenie do OpenCV

Wiele modułów:

Praktyczne zapoznanie się z biblioteką warto zacząć od oficjalnych tutoriali (ze strony z dokumentacją):

Szybka pomoc do API biblioteki

Indeks C++ - tutaj znajduje się spis wszystkich(?) funkcji/typów/itp. z API.

Tutaj (pdf) można znaleźć "ściągę" z API C++ do biblioteki.

Przykładowy program

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;

int main(int argc, char* argv[])
{
  // wczytaj jako obraz 3-kanałowy (BGR, nie RGB!)
  Mat image = imread("lena.jpg"); <- uwaga na plik z obrazkiem
  if (image.empty()) // nie udało się wczytać
    return 1;

  // wczytaj jako obraz w odcieniach szarości (1 kanał)
  Mat grey = imread("lena.jpg", 0);

  // stwórz okienka z obrazkami
  imshow("obrazek 1", image);
  imshow("obrazek 2", grey);

  // wyświetlaj i obsługuj okienka
  // (są one prawidłowo odświeżana TYLKO w trakcie
  // działania poniższej funkcji)
  waitKey(0); // 0 - czekaj na klawisz
              // x - czekaj na klawisz lub x ms

  return 0;
}

Mat - klasa do przechowywania obrazków i macierzy (z automatycznym zwalnianiem pamięci)
imread - wczytuje obraz z pliku (domyślnie 3 kanały: BGR)
imshow - tworzy okienko z obrazkiem
waitKey - czeka na klawisz oraz umożliwia obsługę okienek

Kompilacja/linkowanie/uruchamianie

Kompilatorowi należy podać ścieżkę w której ma szukać plików nagłówkowych biblioteki (np. ścieżka_do/OpenCV2.3/include)

Linkerowi należy podać ścieżkę w której ma szukać bibliotek OpenCV (np. ścieżka_do/OpenCV2.3/lib) oraz konkretne moduły biblioteki które ma zlinkować - w powyższym przykładzie będą to:

Do uruchomienia potrzebne są biblioteki .dll - jeśli OpenCV nie był instalowany to ścieżki do tych bibliotek nie są ustawione w zmiennych środowiskowych. Dlatego najprościej skopiować je (OpenCV2.3/bin) do katalogu z projektem.
Przy uruchamianiu np. z Visual Studio należy zwrócić uwagę gdzie jest ustawiony "working directory" i tam wgrać biblioteki .dll oraz plik z obrazkiem.

Typy macierzy

Typ elementów macierzy określa się w trakcie jej tworzenia poprzez odpowiednią stałą:
CV_<liczba bitów><typ>C<liczba kanałów>

Przykład:

Tworzenie macierzy

Proszę spojrzeć do ściągi (C++ Cheatsheet.pdf)

Dostęp do elementu macierzy:

image.at<TYP>(WIERSZ, KOLUMNA) - uwaga na współrzędne: najpierw nr wiersza potem kolumny!

Przykładowo:
image.at<Vec3b>(11,22)[0] = 255;
spowoduje ustawienie wartości pierwszego (0) kanału (niebieski w formacie BGR) piksela o współrzędnych (x=22,y=11) na 255

Zadania

  1. Zamalować cały obrazek na czerwono i go wyświetlić.
  2. Na obrazku o rozmiarach 400x300 namalować biało-żółte, pionowe pasy, każdy o szerokości 10 pikseli.
  3. Kolor każdego piksela ustawić w zależności od jego współrzędnych następująco:
    • kanał czerwony ustawić na wartość y-100,
    • kanał zielony ustawić na wartość x,
    • kanał niebieski ustawić na wartość x+y.
  4. Zrobić to samo ale tym razem z użyciem saturate_cast
    saturate_cast<TYP> - "nasyca" wartość do odpowiedniego zakresu zależnego od typu
  5. Przekonwertuj obraz z przestrzeni BGR na HSV używając funkcji cvtColor. Następnie wyświetl tylko kanał Hue (do wyodrębnienia pojedynczego kanału użyj mixChannels albo split).
  6. Napisać funkcję (zwracany typ: uchar) obliczającą stopień podobieństwa jednego koloru do innego koloru (funkcja z dwoma argumentami typu Vec3b).
    Podobieństwo należy policzyć jako odległość euklidesowa w przestrzeni RGB a następnie odpowiednio przeskalować w przedział [0;255] gdzie wartość 255 oznacza maksymalne podobieństwo (brak różnicy).
  7. Napisać funkcję która jako argument przyjmuje dowolny obraz BGR oraz kolor. Funkcja ma zwrócić nowy obraz (w odcieniach szarości czyli z jednym kanałem) będący "mapą" podobieństwa pikseli oryginalnego obrazu do wskazanego koloru.
  8. Napisać analogiczną funkcję ale tym razem wszystkie obliczenia należy przeprowadzać dla całego obrazu równocześnie (wykorzystując funkcje jak np. absdiff, add, multiply, sqrt itp.) a nie na pojedynczych pikselach jak w poprzednim ćwiczeniu.
    • Uwaga 1: potrzebne będą bitmapy na wyniki cząstkowe.
    • Uwaga 2: niektóre wyniki pośrednie (np. podnoszenie do kwadratu) mogą nie zmieścić się na liczbach 8 bitowych dlatego konieczne jest przeprowadzanie tych operacji na macierzach innych typów, np. CV_32SC3 (konwersja przy wykorzystaniu metody Mat::convertTo).
  9. Porównaj ze sobą działanie obu funkcji z wcześniejszych dwóch punktów:
    1. Czy generują identyczne wyniki? Sprawdź wykorzystując takie funkcje jak compare lub absdiff i sum.
    2. Która z tych funkcji działa szybciej? Czasy wykonywania sprawdź funkcją getTickCount i getTickFrequency.
Retrieved from http://www.cs.put.poznan.pl/kkrawiec/wiki/?n=RO.Lab-C1
Page last modified on February 22, 2012, at 08:59 AM