Распознавание образов для программистов

ВНИМАНИЕ! БЛОГ ПЕРЕЕХАЛ ПО АДРЕСУ
RECOG.RU

30 Ноябрь 2009

6. Можно ли с помощью OpenCV идентифицировать человека по лицу?

написано в рубрике: OpenCV — Кручинин Александр @ 9:35 ДП

После того, как удалось детектировать лицо человека и его глаза на изображении, возникает закономерный вопрос: можно ли идентифицировать человека? К сожалению, встроенных функций идентификации нет. Но вы можете использовать следующий подход.

В различных работах [1, 2, 3] и др. предложены алгоритмы распознавания лиц людей в частности на основе выделения характеристических точек: центров глаз, уголков глаз, кончика носа и т.п. Однако данные методы невозможно использовать в автоматизированной системе распознавания без алгоритма выделения данных точек.

Для нахождения уголков глаз, между ними проводится линия, относительно которой наблюдается изменение яркости. При использовании фотографии, представленной на рисунке 5.1, график изменения яркости между центрами глаз показан на рисунке 6.1.

Рис. 6.1. Зависимость яркости Y от номера пикселя n относительно линии
Рис. 6.1. Зависимость яркости Y от номера пикселя n относительно линии

По левому и правому краям графика находятся минимумы, соответствующие зрачкам глаз. Резкое возрастание яркости означает переход к белку глаза. Последующее уменьшение яркости соответствует уголку глаза.

При нахождении кончика носа необходимо найти центр между глазами, от которого построить перпендикуляр в нижнюю сторону лица. После чего также построить зависимость яркости (Рис. 6.2).

 

Рис. 6.2. Зависимость яркости Y от номера пикселя n относительно линии для определения кончика носа
Рис. 6.2. Зависимость яркости Y от номера пикселя n относительно линии для определения кончика носа

Как видно из рисунка 6.2, первое значительное снижения яркости означает искомый кончик носа, затем усы и другие части лица. В результате найдены три значимые характеристические точки (Рис. 6.3). Аналогичным образом можно найти и любые другие точки.

Рис. 6.3. Найденные характеристические точки
Рис. 6.3. Найденные характеристические точки

 Предложенный подход определения характеристических точек по изменению яркости позволяет в автоматизированном режиме, например при анализе потока видеоинформации с Web-камеры, осуществлять идентификацию лиц. Недостатком данного подхода является то, что функция cvHaarDetectObjects недостаточно точно функционирует на большинстве изображениях. Поэтому целесообразность использования библиотеки OpenCV для решения задачи идентификации лиц вызывает сомнения. Хотя на начальном этапе, при проведении исследований, OpenCV безусловно вам пригодится.

 

1. Аралбаев Т.З., Африн А.Г. Контроль и управление доступом в АСУ ТП на основе биометрических характеристик пользователя / Т.З. Аралбаев, А.Г. Африн. – Уфа: Гилем, 2008. – 124 с.

2. Wiskott L., Fellous J.-M., Krueger N and Malsburg C. Face Recognition by Elastic Bunch Graph Matching. IEEE Transactions on Pattern Analysis and Machine Intelligence 1997, Vol. 19, pp. 775-779.

3. Самаль Д.И., Старовойтов В.В. Подходы и методы распознавания людей по фотопортретам. – Минск, ИТК НАНБ, 1998. – 54 с.

26 Ноябрь 2009

5. Детектирование лиц и глаз

написано в рубрике: OpenCV — Кручинин Александр @ 11:50 ПП
Рис. 5.1. Выделение лица и глаз с помощью средств OpenCV

Рис. 5.1. Выделение лица и глаз с помощью средств OpenCV

OpenCV обладает возможностью детектировать лица и глаза на изображениях. Для того, чтобы понять, как это делается, обратимся к следующему примеру (Листинг 5.1). Данный пример модифицирован их стандартного, поставляемого с OpenCV.

Листинг 5.1. Детектирование лиц и глаз

#include “cv.h”

 

#include “highgui.h”

 

 

 

#include <stdio.h>

 

#include <stdlib.h>

 

#include <string.h>

 

#include <assert.h>

 

#include <math.h>

 

#include <float.h>

 

#include <limits.h>

 

#include <time.h>

 

#include <ctype.h>

 

 

 

#define MAX_EYE 10

 

 

 

static CvMemStorage* storage = 0;

 

static CvHaarClassifierCascade* cascade = 0;

 

static CvHaarClassifierCascade* nested_cascade = 0;

 

int use_nested_cascade = 0;

 

 

 

void detect_and_draw( IplImage* image);

 

 

 

const char* cascade_name =

 

“data/haarcascades/haarcascade_frontalface_alt.xml”;

 

const char* nested_cascade_name =

 

“data/haarcascades/haarcascade_eye_tree_eyeglasses.xml”;

 

double scale = 1;

 

 

 

CvSeq* contours = 0;

 

 

 

void Init();

 

 

 

int _tmain(int argc, _TCHAR* argv[])

 

{

 

Init();

 

return 0;

 

}

 

 

 

void Init()

 

{

 

CvCapture* capture = 0;

 

IplImage  *frame_copy = 0;

 

IplImage *image = 0;

 

 

 

int i;

 

const char* input_name = 0;

 

 

 

//Загрузка базы данных, обученной на детектирование лиц в Фас

 

cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );

 

//Загрузка быза данных, обученной для детектирования глаз

 

nested_cascade = (CvHaarClassifierCascade*)cvLoad( nested_cascade_name, 0, 0, 0 );

 

 

 

if( !cascade )

 

{

 

return ;

 

}

 

//Создание хранилища памяти

 

storage = cvCreateMemStorage(0);

 

 

 

 

 

char *array_1[4]={

 

“picture03.jpg”,

 

“image.jpg”,

 

“26.jpg”,

 

“27.jpg”

 

};

 

 

 

cvNamedWindow( “result”, 1 );

 

 

 

for(i=0;i<4;i++)

 

{

 

//Загружаем картинку

 

image = cvLoadImage( array_1[i], 1 );

 

if( image )

 

{

 

//Производим детектирование

 

detect_and_draw( image);

 

//Удаляем картинку

 

cvReleaseImage( &image );

 

}

 

}

 

}

 

 

 

void detect_and_draw( IplImage* img )

 

{

 

static CvScalar colors[] =

 

{

 

{{0,0,255}},

 

{{0,128,255}},

 

{{0,255,255}},

 

{{0,255,0}},

 

{{255,128,0}},

 

{{255,255,0}},

 

{{255,0,0}},

 

{{255,0,255}}

 

};

 

 

 

IplImage *gray, *small_img;

 

int i, j;

 

 

 

gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );

 

small_img = cvCreateImage( cvSize( cvRound (img->width/scale),

 

cvRound (img->height/scale)), 8, 1 );

 

 

 

cvCvtColor( img, gray, CV_BGR2GRAY );

 

cvResize( gray, small_img, CV_INTER_LINEAR );

 

cvEqualizeHist( small_img, small_img );

 

cvClearMemStorage( storage );

 

 

 

if( cascade )

 

{

 

double t = (double)cvGetTickCount();

 

CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,

 

1.1, 2, 0

 

//|CV_HAAR_FIND_BIGGEST_OBJECT

 

//|CV_HAAR_DO_ROUGH_SEARCH

 

|CV_HAAR_DO_CANNY_PRUNING

 

//|CV_HAAR_SCALE_IMAGE

 

,

 

cvSize(30, 30) );

 

t = (double)cvGetTickCount() – t;

 

printf( “detection time = %gms\n”, t/((double)cvGetTickFrequency()*1000.) );

 

for( i = 0; i < (faces ? faces->total : 0); i++ )

 

{

 

CvRect* r = (CvRect*)cvGetSeqElem( faces, i );

 

CvMat small_img_roi;

 

CvSeq* nested_objects;

 

CvPoint center;

 

CvScalar color = colors[i%8];

 

int radius;

 

center.x = cvRound((r->x + r->width*0.5)*scale);

 

center.y = cvRound((r->y + r->height*0.5)*scale);

 

radius = cvRound((r->width + r->height)*0.25*scale);

 

cvCircle( img, center, radius, color, 3, 8, 0 );

 

if( !nested_cascade )

 

continue;

 

cvGetSubRect( small_img, &small_img_roi, *r );

 

nested_objects = cvHaarDetectObjects( &small_img_roi, nested_cascade, storage,

 

1.1, 2, 0

 

//|CV_HAAR_FIND_BIGGEST_OBJECT

 

//|CV_HAAR_DO_ROUGH_SEARCH

 

//|CV_HAAR_DO_CANNY_PRUNING

 

//|CV_HAAR_SCALE_IMAGE

 

,

 

cvSize(0, 0) );

 

for( j = 0; j < (nested_objects ? nested_objects->total : 0); j++ )

 

{

 

CvRect* nr = (CvRect*)cvGetSeqElem( nested_objects, j );

 

center.x = cvRound((r->x + nr->x + nr->width*0.5)*scale);

 

center.y = cvRound((r->y + nr->y + nr->height*0.5)*scale);

 

radius = cvRound((nr->width + nr->height)*0.25*scale);

 

cvCircle( img, center, radius, color, 3, 8, 0 );

 

}

 

}

 

}

 

 

 

cvShowImage( “result”, img );

 

cvWaitKey(1000);

 

cvReleaseImage( &gray );

 

cvReleaseImage( &small_img );

 

}

Первоначально с помощью функции cvLoad() загружаются базы для детектирования лиц и глаз (OpenCV\data\haarcascades\). Вы можете скопировать эти базы в свой каталог или указать на точный путь до OpenCV. Помимо базы для детектирования лиц в фас, есть ещё база для детектирования лиц в профиль. Если базы нормально загружаются, то переходим к созданию хранилища памяти. Затем с помощью функции cvNamedWindow() создаём окно, в которое будут выводиться результаты детектирования, и программа входит цикл в котором последовательно выполняется загрузка изображения в память, детектирование его с использованием функции detect_and_draw(), удаление изображения из памяти.

Опишем подробнее процесс детектирования в функции detect_and_draw().

Первоначально определяется массив colors – в нём содержатся цвета для окружностей, которыми будут выделяться лица и глаза. С помощью функции cvCreateImage() создаются два дополнительных изображения (IplImage *gray, *small_img;), на которых и будет осуществляться детектирование. Эти изображения представлены в градациях серого, для перевода в этот формат использовалась функция cvCvtColor(). Далее обнуляется хранилище памяти cvClearMemStorage().

С использованием функции cvHaarDetectObjects() в последовательность faces возвращаются все участки на картинке, которые соответствуют лицу человека. Параметры этой функции вы можете посмотреть в документации OpenCV, но если вкратце, то они характеризуют шаг, через который просматриваются объекты лица, минимальный размер области лица и дополнительные флаги. Посчитав время на детектирование лиц, и выведя его в стандартный поток печати, программа переходит к циклу, где перебираются все участки, соответствующие лицам, которые нашлись.

Первоначально на экран исходное изображение img выводится с помощью cvCircle() окружность. Затем, если база для детектирования глаз загрузилась успешно, программа с использованием cvGetSubRect() устанавливает границы, внутри которых будут искаться глаза. А затем, использую ту же функцию cvHaarDetectObjects() детектируются глаза внутри области лица. Программа опять входит в цикл, в котором перебираются все найденные глаза и обводятся окружностью.

Если глаз всего один – значит это циклоп, если глаза больше чем три – пришелец. А если серьёзно, то областей глаз может быть больше – и вам придётся выбирать  самим, которые реальные, а в которых программа ошиблась.

Используя cvShowImage() выводим на экран результат детектирования лица. Ждём секунду (cvWaitKey(1000)) и, не забывая удалять созданные картинки, выходим из функции.

 

Детектирование лиц и глаз завершено. Правда просто?

18 Ноябрь 2009

4. OpenCV 2.0: проблемы при установке в Windows

написано в рубрике: OpenCV — Кручинин Александр @ 7:51 ДП

Безусловно OpenCV является отличным программным продуктом, однако, и он не лишён недостатков. Многие всё ещё пользуются версиями 1.0 или 1.1. Мы знаем, что при установке OpenCV 1.1. надо скачать и установить следующие обновления для Windows (если их нет):

http://www.microsoft.com/downloads/details.aspx?FamilyID=200b2fd9-ae1a-4a14-984d-389c36f85647&displaylang=en

или

http://www.microsoft.com/downloads/details.aspx?FamilyId=32BC1BEE-A3F9-4C13-9C99-220B62A191EE&displaylang=en

Тогда всё работает прекрасно. Перейдём ко второй версии (2.0.0a). Вы установили библиотеку, но… обнаружили, что нет ни .lib файлов ни знакомых вам .dll файлов. Оказывается, чтобы добраться для них надо откомпилировать всю библиотеку, например так как показано здесь:

http://mirror2image.wordpress.com/2009/10/20/switching-to-opencv-2-0-with-vs2005/

Вкратце прокомментирую:

1) инсталлируем OpenCV 2.0a;

2) инсталлируем CMake (http://www.cmake.org/files/v2.6/cmake-2.6.4-win32-x86.exe);

3) перезагружаемся;

4) запускаем cmake-gui.exe;

5) выбираем места, где находится начальный и конечный (после компиляции) код;

6) нажимаем кнопку «Configure» и выбираем, например Visual Studio 2005 (естественно она у вас должна присутствовать);

7) нажимаем «Generate» – после этого должен быть сгенерирован проект;

8 ) запускаем проект OpenCV в Visual Studio 2005 и компилируем – ждём несколько минут результата;

9) ну всё – у вас есть dll и lib файлы, которые вы можете поместить куда хотите (а именно в те же папки lib и bin OpenCV 2.0).

Все пользователи, у которых есть лицензионные Visual Studio 6.0 или 2003, могут идти покупать новые версии, т.к. откомпилировать в них программу для OpenCV 2.0a вы не сможете. Ну или продолжать пользоваться версией 1.1.

Надеемся, что со следующей версией OpenCV будет меньше проблем с установкой и использованием.

12 Ноябрь 2009

3. HighGUI: видео ввод/вывод

написано в рубрике: OpenCV — Кручинин Александр @ 10:51 ДП

Важным понятие при работе с графикой в OpenCV является структура CvCapture. Данная структура устанавливает связь с видео-потоком. В таблице 3.1 приведены функции для работы с видео. Далее опишем основные функции.

 

Табл.3.1. Функции для работы с видео

Функция

Назначение

cvCreateFileCapture Создаёт и инициализирует структуру CvCapture для чтения видео-потока из файла.
cvCreateCameraCapture Создаёт и инициализирует структуру CvCapture для чтения видео-потока с камеры.
cvReleaseCapture Освобождает структуру CvCapture.
cvGrabFrame Захватывает фрейм из видео-потока.
cvRetrieveFrame Возвращает указатель на изображение захваченного фрейма.
cvQueryFrame Захватывает фрейм, осуществляет декомпрессию и возвращает картинку.
cvGetCaptureProperty Возвращает настройки камеры или характеристику видео-файла.
cvSetCaptureProperty Устанавливает настройки камеры или характеристику видео-файла.
cvCreateVideoWriter Создаёт структуру для видеозаписи.
cvReleaseVideoWriter Заканчивает запись в видео-файл и освобождает структуру видеозаписи.
cvWriteFrame Добавляет один фрейм к видео-файлу.

 

cvCreateFileCapture

 

CvCapture* cvCreateFileCapture(

const char* filename

);

 

Параметры:

filename 

Имя видеофайла.

Возвращает указатель на структуру CvCapture.

 

cvCreateCameraCapture

 

CvCapture* cvCreateCameraCapture(

int index

);

 

Параметры:

index

Номер камеры для использования. Если камера только одна или неважно какой камерой пользоваться, то можно указать значение -1.

Возвращает указатель на структуру CvCapture. Только два интерфейса камер могут использоваться в Windows: Video for Windows (VFW) и Matrox Imaging Library (MIL); и два в Linux: V4L и FireWire (IEEE1394).

 

cvQueryFrame

 

IplImage* cvQueryFrame(

CvCapture* capture

);

 

Параметры:

capture

Структура видео-потока.

Функция захватывает фрейм, осуществляет декомпрессию и возвращает картинку. Она является комбинацией функций cvGrabFrame и cvRetrieveFrame за один вызов. Возвращаемое изображение не может модифицироваться пользователем и освобождаться.

 

cvGetCaptureProperty

 

double cvGetCaptureProperty(

CvCapture* capture,

int property_id

);

 

Параметры:

capture

Структура видео-потока.

property_id

Номер свойства, может быть следующим:

CV_CAP_PROP_POS_MSEC Текущая позиция фильма в миллисекундах или отметка времени видео-потока.
CV_CAP_PROP_POS_FRAMES Индекс фрейма, начиная с нулевого, который должен быть следующим декодирован или захвачен.
CV_CAP_PROP_POS_AVI_RATIO Относительное положение в файле (0 – начало, 1 – конец).
CV_CAP_PROP_FRAME_WIDTH Ширина фреймов в видео-потоке.
CV_CAP_PROP_FRAME_HEIGHT Высота фреймов в видео-потоке.
CV_CAP_PROP_FPS Фреймовый показатель.
CV_CAP_PROP_FOURCC 4-х символьный код кодека.
CV_CAP_PROP_FRAME_COUNT Количество фреймов в видео файле.

Функция cvGetCaptureProperty извлекает определенное свойство камеры или видео файла.

 

cvSetCaptureProperty

 

int cvSetCaptureProperty(

CvCapture* capture,

int property_id,

double value

);

 

Параметры:

capture

Структура видео-потока.

property_id

Номер свойства, может быть следующим:

CV_CAP_PROP_POS_MSEC Позиция в миллисекундах фильма с начала файла.
CV_CAP_PROP_POS_FRAMES Позиция в фреймах (только для видео-файла).
CV_CAP_PROP_POS_AVI_RATIO Относительное положение в файле (0 – начало, 1 – конец).
CV_CAP_PROP_FRAME_WIDTH Ширина фреймов в видео-потоке (только для камеры).
CV_CAP_PROP_FRAME_HEIGHT Высота фреймов в видео-потоке (только для камеры).
CV_CAP_PROP_FPS Фреймовый показатель (только для камеры).
CV_CAP_PROP_FOURCC 4-х символьный код кодека (только для камеры).

value

Значение свойства.

Функция cvSetCaptureProperty устанавливает определенное свойство видео. К настоящему времени функция поддерживает для видео-файлов только: CV_CAP_PROP_POS_MSEC, CV_CAP_PROP_POS_FRAMES, CV_CAP_PROP_POS_AVI_RATIO.

 

cvCreateVideoWriter

 

CvVideoWriter* cvCreateVideoWriter(

const char* filename,

int fourcc,

double fps,

CvSize frame_size,

int is_color=1

);

 

Параметры:

filename

Имя выходного видео-файла.

fourcc

4-х символьный код кодека, используемого для сжатия фреймов. Например, CV_FOURCC(’P',’I',’M',’1′) – MPEG-1 кодек, motion-jpeg кодек – CV_FOURCC(’M',’J',’P',’G'). Есть два специальных значения, которые могут быть пропущены и ведут себя следующим образом:

CV_FOURCC_PROMPT – открывает диалоговое окно, где пользователь может выбрать метод сжатия и его параметры (только Win32);

CV_FOURCC_DEFAULT – использует метод сжатия по умолчанию для данного файлового расширения (только Linux).

fps

Частота кадров для созданного видео-потока.

frame_size

Размер фреймов.

is_color

Если не равен нулю, то кодировщик будет кодировать цвета, иначе он будет работать с градациями серого (этот флаг поддерживается только в Windows).

В случае удачного вызова функция cvCreateVideoWriter создаёт структуру видео-записи.

 

cvWriteFrame

 

int cvWriteFrame(

CvVideoWriter* writer,

const IplImage* image

);

 

Параметры:

writer

Структура видеозаписи.

image

Фрейм для записи.

Функция cvWriteFrame записывает/добавляет один фрейм к видео-файлу.

 

Далее приведены три примера использования видео:

●       работа с Web-камерой (листинг 3.1);

●       открытие видео-файла и проигрывание его (листинг 3.2);

●       сохранение изображения с web-камеры в файл (листинг 3.3).

Листинг 3.1. Работа с Web-камерой

#include “cv.h”

#include “highgui.h”

 

int _tmain(int argc, _TCHAR* argv[])

{

CvCapture* capture = 0;

IplImage *frame, *frame_copy = 0;

 

      //Получается видео-поток с камеры

      capture = cvCreateCameraCapture( 0);

 

      //Создаётся окно вывода изображения на экран

      cvNamedWindow( “VideoOut”, 1 );

 

if( capture )

{

            for(;;)

{

                  //Захватывается фрейм

if( !cvGrabFrame( capture )) break;

                  //Получается указатель на изображение

frame = cvRetrieveFrame( capture );

if( !frame ) break;

                  //Если изображение получается в первый раз, то создаётся

                  //копия

if( !frame_copy )

frame_copy = cvCreateImage( cvSize(frame->width,

frame->height),IPL_DEPTH_8U, frame->nChannels );

//копируется изображение или если нужно отображается его

//относительно оси X

                  if( frame->origin == IPL_ORIGIN_TL )

cvCopy( frame, frame_copy, 0 );

else

cvFlip( frame, frame_copy, 0 );

                  //отображается изображение в окно

                  cvShowImage( “VideoOut”, frame_copy);               

                  //ожидание нажатия клавишы для завершения

if( cvWaitKey( 10 ) >= 0 ) goto _cleanup_;

}

cvWaitKey(0);

_cleanup_:

            cvReleaseImage( &frame_copy );

cvReleaseCapture( &capture );

            cvDestroyWindow(”VideoOut”);

      }

      return 0;

}

 

Листинг 3.2. Открытие видео-файла и проигрывание его

#include “cv.h”

#include “highgui.h”

 

//Позиция ползунка

int g_slider_position = 0;

CvCapture* g_capture = NULL;

//Функция обработки выбора позиции

void onTrackbarSlide(int pos) {

      cvSetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES,pos);

}

 

int _tmain(int argc, _TCHAR* argv[])

{

cvNamedWindow(”Example”, CV_WINDOW_AUTOSIZE );

      //Открывается видео-файл

      g_capture = cvCreateFileCapture(”test.avi”);

      //Определяется общее число фреймов

      int frames = (int) cvGetCaptureProperty(

            g_capture,

            CV_CAP_PROP_FRAME_COUNT

      );

      //Если фреймов больше, чем ноль, то создаётся ползунок

      if( frames!= 0 ) {

            cvCreateTrackbar(

                  “Position”,

                  “Example”,

                  &g_slider_position,

                  frames,

                  onTrackbarSlide

            );

      }

      IplImage* frame;

      //Вход в цикл проигрывания фильма

      while(1) {

            //Получение фрейма

            frame = cvQueryFrame( g_capture );

            if( !frame ) break;

            cvShowImage( “Example”, frame );

            //Ожидание нажатия ESCAPE

            char c = cvWaitKey(33);

            if( c == 27 ) break;

      }

      cvReleaseCapture( &g_capture );

      cvDestroyWindow( “Example” );

      return 0;

}

 

Листинг 3.3. Cохранение изображения с web-камеры в файл

#include “cv.h”

#include “highgui.h”

 

int _tmain(int argc, _TCHAR* argv[])

{

CvCapture* capture = 0;

IplImage *frame, *frame_copy = 0;

      CvVideoWriter* cvVideoWriter=0;         

 

      //Получается видео-поток с камеры

      capture = cvCreateCameraCapture( 0);

 

      //Создаётся окно вывода изображения на экран

      cvNamedWindow( “VideoOut”, 1 );

 

if( capture )

{          

            for(;;)

{

                  //Захватывается фрейм

if(!cvGrabFrame( capture )) break;

                  //Получается указатель на изображение

frame = cvRetrieveFrame( capture );

if( !frame ) break;

                  //Если изображение получается в первый раз, то создаётся

//копия

           if( !frame_copy )

                      frame_copy = cvCreateImage( cvSize(frame->width,

                      frame->height),IPL_DEPTH_8U, frame->nChannels );

                  //Создаётся объект записи

                  if (!cvVideoWriter)

                        cvVideoWriter=cvCreateVideoWriter(”test.avi”,

                        CV_FOURCC(’P',’I',’M',’1′),25,

           cvSize(frame->width,frame->height),1);

           //Копируется изображение или если нужно отображается его

           //относительно оси X

           if( frame->origin == IPL_ORIGIN_TL )

                      cvCopy( frame, frame_copy, 0 );

           else

                  cvFlip( frame, frame_copy, 0 );               

                  //Запись фрейма в файл

                  cvWriteFrame(cvVideoWriter,frame_copy);             

                  //Отображается изображение в окно

                  cvShowImage( “VideoOut”, frame_copy);               

                  //Ожидание нажатия клавишы для завершения

                   if( cvWaitKey( 25 ) >= 0 ) goto _cleanup_;

           }

           cvWaitKey(0);

_cleanup_:     

           cvReleaseVideoWriter(&cvVideoWriter);

            cvReleaseImage( &frame_copy );

           cvReleaseCapture( &capture );     

            cvDestroyWindow(”VideoOut”);

      }

      return 0;

}

 

 

2. HighGUI: простой GUI

написано в рубрике: OpenCV — Кручинин Александр @ 2:23 ДП

Модуль HighGUI (High-level Graphical User Interface) предоставляет функции, которые позволяют взаимодействовать с операционной системой, файловой системой и аппаратными средствами ЭВМ такими, как камеры. HighGUI позволяет открывать окна, показывать изображения, читать и записывать графические файлы и видео, просто обращаться с мышью и клавиатурой.

В таблице 2.1 представлены функции простого GUI для работы с окнами, клавиатурой и мышью.

Табл. 2.1. Функции простого GUI

Функция

Назначение

cvNamedWindow Создание окна.
cvDestroyWindow Уничтожение окна.
cvDestroyAllWindows Уничтожение всех окон созданных с помощью HighGUI.
cvResizeWindow Изменить размеры окна.
cvMoveWindow Изменить позицию окна.
cvGetWindowHandle Получить указатель на окно.
cvGetWindowName Получить имя окна по указателю.
cvShowImage Отобразить картинку в окно.
cvCreateTrackbar Создать ползунок и добавить его к окну.
cvGetTrackbarPos Узнать позицию ползунка.
cvSetTrackbarPos Установить позицию ползунка.
cvSetMouseCallback Установить функцию обработки события от мыши.
cvWaitKey Ожидание нажатия клавиши на клавиатуре.

Опишем основные функции, которые вы будете использовать при проектировании и тестировании приложений.

 

cvNamedWindow

 

int cvNamedWindow(

const char* name,

int flags=CV_WINDOW_AUTOSIZE

);

 

Параметры:

name

Название окна, которое будет использоваться для обращения к нему.

flags

Флаг окна. На настоящий момент поддерживается только CV_WINDOW_AUTOSIZE. Если он установлен, то окно автоматически подстраивается под загружаемое на него с помощью функции cvShowImage изображение.

Если окно с таким именем уже существует, то функция не делает ничего. Иначе создается окно, которое поддерживает место для картинки и для ползунка.

 

cvResizeWindow

 

void cvResizeWindow(

const char* name,

int width,

int height

);

 

Параметры:

name

Имя окна, размеры которого меняются.

width

Новая ширина.

height

Новая высота.

 

cvShowImage

 

void cvShowImage(

const char* name,

const CvArr* image

);

 

Параметры:

name

Имя окна.

image

Указатель на изображение, которое должно быть отображено.

 

cvWaitKey

 

int cvWaitKey(

int delay=0

);

 

Параметры:

delay

Задержка в миллисекундах.

Функция ожидает нажатия клавиши или пока не окончится задержка. Возвращает код нажатой клавиши или -1, если ничего не было нажато за время задержки.

 

Загрузка и сохранение изображений

 

Для загрузки и сохранения изображений существуют всего две функции cvLoadImage и cvSaveImage.

 

cvLoadImage

 

IplImage* cvLoadImage(

const char* filename,

int flags=CV_LOAD_IMAGE_COLOR

);

 

Параметры:

filename

Имя файла, который необходимо загрузить.

flags

Определяет цвет и глубину загруженного изображения. Цвет определяет, должно ли загруженное изображение быть преобразовано на 3 канала (CV_LOAD_IMAGE_COLOR), 1 канал (CV_LOAD_IMAGE_GRAYSCALE), или оставлено без изменений так, как это было настроено во входном файле.

Глубина определяет, должно ли загруженное изображение будет преобразовано к 8-битному цветовому формату, как было общепринято в предыдущих версиях OpenCV или оставить так, как это было настроено во входном файле. Если выбрано CV_LOAD_IMAGE_ANYDEPTH то формат пикселей может быть 8-битный беззнаковый, 16-битный беззнаковый, 32-битный знаковый или 32 битный с плавающей точкой. Если Вы хотите загрузить изображение настолько близко к находящемуся в файле, насколько это возможно, то необходимо установить CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR.

Функция cvLoadImage загружает изображение из указанного файла и возвращает указатель на загруженное изображение. В настоящее время поддержаны следующие форматы файлов:

Windows bitmaps – BMP, DIB;

JPEG files – JPEG, JPG, JPE;

Portable Network Graphics – PNG;

Portable image format – PBM, PGM, PPM, PXM, PNM;

Sun rasters – SR, RAS;

TIFF files – TIFF, TIF;

OpenEXR HDR images – EXR;

JPEG 2000 images – jp2.

 

cvSaveImage

 

int cvSaveImage(

const char* filename,

const CvArr* image

);

 

Параметры:

filename

Имя файла, куда будет сохраняться изображение.

image

Указатель на изображение, которое должно быть сохранено.

Функция cvSaveImage сохраняет изображение в указанный файл. Формат изображения выбирается в зависимости от расширения файла указанного в параметре filename.

В листинге 2.1 приведен пример загрузки изображения, отображения его в графическом окне, ожидание нажатия клавиши и сохранение изображения в файле другого формата.

Листинг 2.1. Загрузка, вывод на экран и преобразование изображения

#include “cv.h”

#include “highgui.h”

 

int _tmain(int argc, _TCHAR* argv[])

{

      IplImage* img = cvLoadImage( “test.jpg”);//Загрузка изображения в формате JPEG

      cvNamedWindow(”Example1″, CV_WINDOW_AUTOSIZE );//Создание окна

      cvShowImage(”Example1″, img );//Вывод изображения в окно

      cvWaitKey(0);//Ожидание нажатия любой клавиши

      cvSaveImage(”test.png”,img);//Сохранение изображения в формате PNG

      cvReleaseImage( &img );//Удаление изображения из памяти

      cvDestroyWindow(”Example1″);//Удаление окна

 

      return 0;

}

Старые записи »

Работает на WordPress