 
Systemy Wizyjne
Kurs OpenCV
Instrukcja 2
Przetwarzanie obrazu
Skala szarości
Binaryzacja
Filtracja
Histogram
Opracował:
Ziemowit Dworakowski
zdw@agh.edu.pl
 
Informacja o ćwiczeniu:
Ta instrukcja wprowadza informacje i funkcje służące do podstawowego przetwarzania
obrazów   i   filmów:   Konwersję   obrazu   do   skali   szarości,   binaryzację   obrazu,   wyznaczenie 
histogramu obrazu oraz podstawowe filtry
Potrzebne funkcje:
W poniższej instrukcji należy skorzystać z bibliotek cv oraz highgui
Skala szarości
W celu konwersji obrazu kolorowego do skali szarości wykorzystujemy funkcję  cvtColor, która 
przyjmuje   informację   o   obrazie   źródłowym,   obrazie   wyjściowym   oraz   wykorzystanej   funkcji. 
Konwersja koloriwego obrazu  
Mat frame;
do obrazu w skali szarości
Mat grayframe;
zostanie
wykonana za pomocą następującej linii:
cvtColor(frame,grayframe,CV_RGB2GRAY);
Binaryzacja obrazu
Binaryzacja obrazu w skali szarości wykonywana jest za pomocą funkcji threshold która przyjmuje 
informację o obrazie źródłowym, wyjściowym, progu binaryzacji, maksymalnej wartości obrazu po 
binaryzacji oraz rodzaju binaryzacji. Standardowa binaryzacja z progiem 125 obrazu 
Mat grayframe
z zapisem go do obrazu
Mat grayframe
wykonana zostanie za pomocą następującej linii:
threshold(grayframe, binaryframe, 125, 255,0);
Podmieniając ostatni argument funkcji threshold uzyskujemy różne rodzaje binaryzacji. (Sprawdź w 
tutorialu i przetestuj pozostałe sposoby binaryzacji!)
Histogram obrazu
Histogram pozwala w graficzny sposób przedstawić ilość poszczególnych kolorów lub poziomów 
jasności   na   obrazie.   Aby   narysować   histogram   potrzebować   będziemy   Mat-pliku   do 
przechowywania wyniku, rozmiaru histogramu oraz zakresu danego kanału barwnego:
Mat hist;
int
histSize = 256;
float
range[] = { 0, 255 };
const
float
* histRange = { range };
W tym przykładzie wyznaczymy histogram obrazu uprzednio skonwertowanego na skalę szarości - 
zawierającego tylko jeden kanał barwny - przechowujący informację o poziomie szarości każdego 
piksela:
calcHist( &grayframe, 1, 0, Mat(), hist, 1, &histSize, &histRange, 1, 0 );
Powyższa funkcja wyznacza histogram dla klatki
Mat grayframe
, wynik zapisuje w obrazie
Mat
hist
. (Sprawdź w tutorialu co przekazywane jest do funkcji w pozostałych argumentach!)
 
Po wyznaczeniu hitogramu należy go wyświetlić. W tym celu tworzymy obraz a następnie w każdej 
kolumnie obrazu rysujemy linię reprezentującą dany poziom szarości:
Mat histImage( histSize, 256, CV_8UC3, Scalar( 0,0,0) );
for
(
int
i = 1; i < histSize; i++ )
{
line( histImage,Point(i,255),Point(i,256-hist.at<
float
>(i)),Scalar(0,200,230),1,8);
}
Rozmywanie obrazu
W celu ograniczenia ilości szumów stosuje się rozmycie obrazu. 
Rozmycie   gaussowskie   wykonujemy   korzystając   z   funkcji   przyjmującej   obraz   wejściowy, 
wyjściowy oraz rozmiar maski wykorzystywanej w algorytmie - tutaj 5x5:
GaussianBlur( grayframe, filtered, Size( 5, 5 ), 0, 0 );
Filtry morfologiczne
W celu wykorzystania filtrów erozji, dylacji, otwarcia i zamknięcia trzeba najpierw określić maskę, 
która zostanie wykorzystana w procesie filtracji. Maska powinna mieć kształt i rozmiar. W tym 
przypadku korzystamy z maski prostokątnej o rozmiarach 4x4:
Mat kernel = getStructuringElement( MORPH_RECT, Size( 4, 4 ));
Po   zdefiniowaniu   maski   wykonujemy   filtrację   poprzez   wykorzystanie   odpowiedniej   funkcji   z 
argumentami: obraz wejściowy, obraz wynikowy, rodzaj filtracji, maska:
morphologyEx( frame, filtered, 0, kernel );
Rodzaje filtrów morfologicznych do wyboru:
0 - Erozja
1 - Dylatacja
2 - Otwarcie
3 - Zamknięcie
4 - Gradient
5 - Tophat
6 - Blackhat
Detekcja krawędzi
W celu wykrywania krawędzi na obrazie korzystać można z szeregu różnych filtrów. Filtry Sobel i 
Scharr wyznaczają aproksymację dyskretnej pochodnej obrazu w dwóch kierunkach, ...
Poniżej przedstawiona jest implementacja funkcji Sobel i Scharr:
Scharr( grayframe, edgedetection, CV_8UC1, 1, 0, scale, 0, BORDER_DEFAULT );
Sobel( grayframe, edgedetection, CV_8UC1, 0, 1, 3,scale, 0, BORDER_DEFAULT );
Mat grayframe
to obraz wejściowy,
Mat edgedetection
to obraz wyjściowy,
CV_8UC1
oznacza głębię
kolorów, dwie kolejne liczby oznaczają kierunek filtracji. (Wykrywanie krawędzi pionowych lub 
poziomych). ( 
int scale
) oznacza skalę. Sprawdź jakie efekty uzyskasz zmieniając głębię kolorów
na
CV_16UC1
 
Implementacja Laplasjanu wygląda następująco:
Laplacian(grayframe, edgedetection, CV_8UC1, kernel_size, scale, 0, BORDER_DEFAULT );
Jak poprzednio, argumentami funkcji są obraz wejściowy, wynikowy i głębia kolorów. Dodatkowo 
zdefiniować należy rozmiar maski.( 
int kernel_size
)
Detekcja krawędzi z zastosowaniem algorytmu Canny Edge Detection wykonywana jest komendą:
Canny(grayframe, edgedetection, 50, 150, kernel_size );
Argumentami   funkcji   są   obraz   wejściowy,   obraz   wynikowy,   górny   i   dolny   próg   znajdowania 
krawędzi oraz rozmiar maski.