Реалізація методу головних компонент за допомогою бібліотеки OpenCV

[ виправити ] текст може містити помилки, будь ласка перевіряйте перш ніж використовувати.

скачати

Міністерство освіти і науки Російської Федерації
Південно-Уральський державний університет
Кафедра Автоматика та Управління
Курсова робота
на тему
Реалізація методу головних компонент за допомогою бібліотеки OpenCV
Виконав: Пушніков А.А.
Група: ПС-669
Перевірив різностатевої К.О.
Дата «____» _____________2006 р.
Челябінськ
2006 р
Зміст
Метод головних компонент 2
Реалізація методу головних компонент у OpenCV_ 3
Текст программи_ 4

Метод головних компонент

Метод головних компонент (Principal Component Analysis, PCA) застосовується для стиснення інформації без істотних втрат інформативності. Він полягає в лінійному ортогональному перетворенні вхідного вектора X розмірності N у вихідний вектор Y розмірності M, N. При цьому компоненти вектора Y є некоррелірованнимі і загальна дисперсія після перетворення залишається незмінною. Матриця X складається з усіх прикладів зображень навчального набору. Розв'язавши рівняння Gif 76x19, 964 байт , Отримуємо матрицю власних векторів Gif 17x15, 856 байт , Де Gif 14x15, 850 байт - Коваріаційна матриця для X, а Gif 15x17, 856 байт - Діагональна матриця власних чисел. Вибравши з Gif 17x15, 856 байт підматриць Gif 28x22, 896 байт , Відповідну M найбільшим власним числам, отримаємо, що перетворення Gif 62x24, 970 байт , Де Gif 60x17, 922 байт - Нормалізоване вектор з нульовим математичним очікуванням, характеризує велику частину загальної дисперсії і відображає найбільш суттєві зміни X.
Вибір перших M головних компонент розбиває векторний простір на головне (власне) простір Gif 69x26, 1001 байт , Що містить головні компоненти, і його ортогональноє доповнення Gif 86x26, 1030 байт .
Застосування для задачі розпізнавання зображень має наступний вигляд. Вхідні вектора є відцентрові і приведені до єдиного масштабу зображення. Власні вектори, обчислені для всього набору зображень, називаються власними об'єктами (eigenobject). З допомогою обчислених раніше матриць вхідне зображення розкладається на набір лінійних коефіцієнтів, званих головними компонентами. Сума головних компонент, помножених на відповідні власні вектора, є реконструкцією зображення.
Для кожного зображення обличчя обчислюються його головні компоненти. Зазвичай береться від 5 до 200 головних компонент. Інші компоненти кодують дрібні відмінності між еталоном і шум. Процес розпізнавання полягає в порівнянні головних компонент невідомого зображення з компонентами всіх інших зображень. Для цього зазвичай застосовують будь-яку метрику (найпростіший випадок - Евклідів відстань). При цьому передбачається, що зображення, відповідні одному еталону, згруповані в кластери у власному просторі. З бази даних (або тренувального набору) вибираються зображення-кандидати, що мають найменшу відстань від вхідного (невідомого) зображення.
Подальше вдосконалення полягала у використанні метрики Махаланобіса і гауссовского розподілу для оцінки близькості зображень. Для обліку різних ракурсів в цій же роботі використовувалося багатомодальну розподіл зображень у власному просторі.
Основна перевага застосування аналізу головних компонент - це збереження і пошук зображень у великих базах даних, реконструкція зображень.
Основний недолік - високі вимоги до умов зйомки зображень. Зображення повинні бути отримані в близьких умовах освітленості, однаковому ракурсі. Повинна бути проведена якісна попередня обробка, що призводить зображення до стандартних умов (масштаб, поворот, центрування, вирівнювання яскравості, відсікання фону).

Реалізація методу головних компонент у OpenCV

Бібліотека OpenCV реалізує описаний вище алгоритм наступними функціями:
Функція, обчислює власні об'єкти еталонів:
void cvCalcEigenObjects (int nObjects, void * input, void * output, int ioFlags, int ioBufSize, void * userData, CvTermCriteria * calcLimit, IplImage * avg, float * eigVals),
де
nObjects - число еталонів
input - покажчик на масив зображень-еталонів (зображення глибиною 8 біт)
output - (вихід функції) покажчик на масив власних об'єктів (зображення глибиною 32 біт)
ioFlags - прапори введення / виводу. Для роботи з пам'яттю.
ioBufSize - розмір буфера. Для роботи з пам'яттю.
userData - покажчик на структуру для роботи з пам'яттю.
calcLimit - критерій припинення обчислень. Два варіанти: за кількістю ітерацій і по ко точності (?)
avg - (вихід функції) усереднене зображення еталонів
eigVals (вихід функції) покажчик на власні числа (може бути NULL)
Функція, обчислює коефіцієнти розкладання:
void cvEigenDecomposite (IplImage * obj, int eigenvec_count, void * eigInput, int ioFlags, void * userData, IplImage * avg, float * coeffs),
де
obj - досліджуване зображення
eigenvec_count - число власних об'єктів
eigInput - покажчик на масив власних об'єктів (зображення глибиною 32 біт)
ioFlags - прапори введення / виводу. Для роботи з пам'яттю.
userData - покажчик на структуру для роботи з пам'яттю.
avg - (вихід функції) усереднене зображення еталонів
coeffs - (вихід функції) коефіцієнти розкладання (?)
Функція, обчислює проекцію досліджуваного зображення на простір власних об'єктів:
void cvEigenProjection (void * input_vecs, int eigenvec_count, int io_flags, void * userdata, float * coeffs, IplImage * avg, IplImage * proj),
де
input_vec - покажчик на масив власних об'єктів (зображення глибиною 32 біт)
eigenvec_count - число власних об'єктів
io_flags - прапори введення / виводу. Для роботи з пам'яттю.
userdata - покажчик на структуру для роботи з пам'яттю.
coeffs - коефіцієнти розкладу (?)
avg - усереднене зображення еталонів
proj - проекція досліджуваного зображення на простір власних об'єктів
В отриманій проекції має сенс прибрати зайві компоненти (наприклад, за допомогою функції cvThreshold - відсікання по порогу). Далі отриманий результат можна порівнювати з еталонами, для прийняття рішення. Способів порівняння багато, це може бути, наприклад, мінімальна відстань (Евклідів) або кореляція з еталонами.

Текст програми

//------------------------------------------------ ---------------------------
# Include <vcl.h>
# Pragma hdrstop
# Include "Unit1.h"
# Include "cxcore.h"
# Include "cv.h"
//------------------------------------------------ ---------------------------
# Pragma package (smart_init)
# Pragma resource "*. dfm"
TForm1 * Form1;
IplImage ** Objs, * Pro, * Object;
int obj_number = 3;
HINSTANCE highgui, cv, cvaux;
IplImage * (__stdcall * cvLoadImage) (const char * filename, int iscolor);
int (__stdcall * cvSaveImage) (const char * filename, const CvArr * image);
int (__stdcall * cvNamedWindow) (const char * name, int flags);
void (__stdcall * cvShowImage) (const char * name, const CvArr * image);
IplImage * (__stdcall * cvCreateImage_) (CvSize size, int depth, int channels);
double (__stdcall * cvDotProduct_) (const CvArr * src1, const CvArr * src2);
void (__stdcall * cvMul_) (const CvArr * src1, const CvArr * src2, CvArr * dst, double scale = 1);
void (__stdcall * cvThreshold_) (const CvArr * src, CvArr * dst, double threshold, double max_value, int threshold_type);
//------------------------------------------------ ---------------------------
__fastcall TForm1:: TForm1 (TComponent * Owner)
: TForm (Owner)
{
}
//------------------------------------------------ ---------------------------
void show_im (TCanvas * c, IplImage * p)
{
for (int i = 0; i <p-> width; i + +)
for (int j = 0; j <p-> height; j + +)
{
int a = p-> imageDataOrigin [p-> widthStep * j + i];
c-> Pixels [i] [j] = a & 0x0000ff | (a <<8) & 0x00ff00 | (a <<16) &0xff0000;
}
}
void pca (int obj_number, IplImage ** Objs, CvTermCriteria limit, IplImage * Object, IplImage * Pro)
{
CvSize size;
int m1 = obj_number;
IplImage ** EigObjs, * Avg;
float * coeffs;
HINSTANCE hDLL = LoadLibrary ("cvaux100.dll");
if (! hDLL) return;
void (__stdcall * cvCalcEigenObjects) (int nObjects, void * input, void * output, int ioFlags, int ioBufSize, void * userData, CvTermCriteria * calcLimit, IplImage * avg, float * eigVals);
cvCalcEigenObjects = (void (__stdcall *) (int nObjects, void * input, void * output, int ioFlags, int ioBufSize, void * userData, CvTermCriteria * calcLimit, IplImage * avg, float * eigVals)) GetProcAddress (hDLL, "cvCalcEigenObjects" );
if (! cvCalcEigenObjects) return;
void (__stdcall * cvEigenDecomposite) (IplImage * obj, int nEigObjs, void * eigInput, int ioFlags, void * userData, IplImage * avg, float * coeffs);
cvEigenDecomposite = (void (__stdcall *) (IplImage * obj, int nEigObjs, void * eigInput, int ioFlags, void * userData, IplImage * avg, float * coeffs)) GetProcAddress (hDLL, "cvEigenDecomposite");
if (! cvEigenDecomposite) return;
void (__stdcall * cvEigenProjection) (void * eigInput, int nEigObjs, int ioFlags, void * userData, float * coeffs, IplImage * avg, IplImage * proj);
cvEigenProjection = (void (__stdcall *) (void * eigInput, int nEigObjs, int ioFlags, void * userData, float * coeffs, IplImage * avg, IplImage * proj)) GetProcAddress (hDLL, "cvEigenProjection");
if (! cvEigenProjection) return;
EigObjs = new IplImage * [m1];
coeffs = new float [m1];
size.width = Object-> width; size.height = Object-> height;
Avg = cvCreateImage_ (size, IPL_DEPTH_32F, 1);
for (int i = 0; i <m1; i + +)
{
EigObjs [i] = cvCreateImage_ (size, IPL_DEPTH_32F, 1);
}
cvCalcEigenObjects (obj_number, (void *) Objs, (void *) EigObjs, 0, 0, NULL, & limit, Avg, NULL);
cvEigenDecomposite (Object, m1, (void *) EigObjs, 0, NULL, Avg, coeffs);
cvEigenProjection ((void *) EigObjs, m1, 0, NULL, coeffs, Avg, Pro);
FreeLibrary (hDLL);
/ / CvReleaseImage (& Avg);
/ / For (int i = 0; i <m1; i + +)
/ / {
/ / CvReleaseImage (& EigObjs [i]);
/ /}
/ / CvFree (& coeffs);
}
void __fastcall TForm1:: FormCreate (TObject * Sender)
{
highgui = LoadLibrary ("highgui100.dll");
if (! highgui) return;
cvLoadImage = (IplImage * (__stdcall *) (const char * filename, int iscolor)) GetProcAddress (highgui, "cvLoadImage");
if (! cvLoadImage) return;
cvSaveImage = (int (__stdcall *) (const char * filename, const CvArr * image)) GetProcAddress (highgui, "cvSaveImage");
if (! cvSaveImage) return;
cvNamedWindow = (int (__stdcall *) (const char * name, int flags)) GetProcAddress (highgui, "cvNamedWindow");
if (! cvNamedWindow) return;
cvShowImage = (void (__stdcall *) (const char * name, const CvArr * image)) GetProcAddress (highgui, "cvShowImage");
if (! cvShowImage) return;
cv = LoadLibrary ("cxcore100.dll");
if (! cv) return;
cvCreateImage_ = (IplImage * (__stdcall *) (CvSize size, int depth, int channels)) GetProcAddress (cv, "cvCreateImage");
if (! cvCreateImage_) return;
cvDotProduct_ = (double (__stdcall *) (const CvArr * src1, const CvArr * src2)) GetProcAddress (cv, "cvDotProduct");
if (! cvDotProduct_) return;
cvMul_ = (void (__stdcall *) (const CvArr * src1, const CvArr * src2, CvArr * dst, double scale = 1)) GetProcAddress (cv, "cvMul");
if (! cvMul_) return;
cvaux = LoadLibrary ("cv100.dll");
if (! cvaux) return;
cvThreshold_ = (void (__stdcall *) (const CvArr * src, CvArr * dst, double threshold, double max_value, int threshold_type)) GetProcAddress (cvaux, "cvThreshold");
if (! cvThreshold_) return;
Objs = new IplImage * [obj_number];
Objs [0] = cvLoadImage (". \ \ Et \ \ 1.bmp", 0);
show_im (Image1-> Canvas, Objs [0]);
Objs [1] = cvLoadImage (". \ \ Et \ \ 2.bmp", 0);
show_im (Image2-> Canvas, Objs [1]);
Objs [2] = cvLoadImage (". \ \ Et \ \ 3.bmp", 0);
show_im (Image3-> Canvas, Objs [2]);
String fname = "6.bmp";
Object = cvLoadImage ((". \ \ In \ \" + fname). C_str (), 0);
show_im (Image4-> Canvas, Object);
}
//------------------------------------------------ ---------------------------
void __fastcall TForm1:: Button1Click (TObject * Sender)
{
float e [3];
CvTermCriteria limit;
CvSize size;
size.width = Object-> width; size.height = Object-> height;
Pro = cvCreateImage_ (size, IPL_DEPTH_8U, 1);
limit.type = CV_TERMCRIT_EPS;
limit.max_iter = 1;
limit.epsilon = 0.1;
show_im (Image4-> Canvas, Object);
pca (obj_number, Objs, limit, Object, Pro);
show_im (Image5-> Canvas, Pro);
cvThreshold_ (Pro, Object, 200,255, CV_THRESH_BINARY);
show_im (Image6-> Canvas, Object);
cvMul_ (Object, Objs [0], Pro);
show_im (Image7-> Canvas, Pro);
cvMul_ (Object, Objs [1], Pro);
show_im (Image8-> Canvas, Pro);
cvMul_ (Object, Objs [2], Pro);
show_im (Image9-> Canvas, Pro);
e [0] = cvDotProduct_ (Object, Objs [0]) / cvDotProduct_ (Objs [0], Objs [0]);
e [1] = cvDotProduct_ (Object, Objs [1]) / cvDotProduct_ (Objs [1], Objs [1]);
e [2] = cvDotProduct_ (Object, Objs [2]) / cvDotProduct_ (Objs [2], Objs [2]);
Label1-> Caption = FloatToStr (int (e [0] * 1000) / 1000.);
Label2-> Caption = FloatToStr (int (e [1] * 1000) / 1000.);
Label3-> Caption = FloatToStr (int (e [2] * 1000) / 1000.);
if (e [0]> e [1])
if (e [0]> e [2])
ShowMessage ("1");
if (e [1]> e [0])
if (e [1]> e [2])
ShowMessage ("2");
if (e [2]> e [1])
if (e [2]> e [0])
ShowMessage ("3");
}
//------------------------------------------------ ---------------------------
void __fastcall TForm1:: Image1Click (TObject * Sender)
{
if (OpenPictureDialog1-> Execute ())
{
Objs [0] = cvLoadImage (OpenPictureDialog1-> FileName.c_str (), 0);
show_im (Image1-> Canvas, Objs [0]);
}
}
//------------------------------------------------ ---------------------------
void __fastcall TForm1:: Image2Click (TObject * Sender)
{
if (OpenPictureDialog1-> Execute ())
{
Objs [1] = cvLoadImage (OpenPictureDialog1-> FileName.c_str (), 0);
show_im (Image2-> Canvas, Objs [1]);
}
}
//------------------------------------------------ ---------------------------
void __fastcall TForm1:: Image3Click (TObject * Sender)
{
if (OpenPictureDialog1-> Execute ())
{
Objs [2] = cvLoadImage (OpenPictureDialog1-> FileName.c_str (), 0);
show_im (Image3-> Canvas, Objs [2]);
}
}
//------------------------------------------------ ---------------------------
void __fastcall TForm1:: Image4Click (TObject * Sender)
{
if (OpenPictureDialog1-> Execute ())
{
Object = cvLoadImage (OpenPictureDialog1-> FileName.c_str (), 0);
show_im (Image4-> Canvas, Object);
}
}
//------------------------------------------------ ---------------------------
Додати в блог або на сайт

Цей текст може містити помилки.

Програмування, комп'ютери, інформатика і кібернетика | Стаття
23.1кб. | скачати


Схожі роботи:
Розрахунок вихідний реакції лінійної ланцюга за допомогою операційного методу і методу прямої згортки
Реалізація функцій бібліотеки графіки для виводу тексту у графічному режимі OutTextXY SetTextStyle
Реалізація функцій бібліотеки графіки для виводу тексту у графічному режимі OutTextXY SetTextStyle 2
Обчислення інтеграла за допомогою методу трапецій на комп`ютері
Доказ Великої теореми Ферма за допомогою методу нескінченних невизначених спусків
Чисельне рішення системи лінійних рівнянь за допомогою методу виключення Гауса з вибором головного
Пошук максимуму однієї функції багатьох змінних методом покоординатного спуску і з допомогою методу
Вибір параметрів контролю з використанням методу динамічного програмування і методу гілок
Дослідження методу ортогоналізації й методу сполучених градієнтів
© Усі права захищені
написати до нас