Что такое OpenCV? По этому поводу википедия говорит следующее:
OpenCV (англ. Open Source Computer Vision Library, библиотека компьютерного зрения с открытым исходным кодом) — библиотека алгоритмов компьютерного зрения, обработки изображений и численных алгоритмов общего назначения с открытым кодом. Реализована на C/C++, так же разрабатывается для Python, Ruby, Matlab и других языков. Может свободно использоваться в академических и коммерческих целях — распространяется в условиях лиценции BSD.
Direct link
Это действительно мощная библиотека, равных которой мне неизвестно. Хоть она используется в компьютерном "зрении", библиотека находит свое применение в работе с графикой (пример такой реализации - Photo Editor). Впрочем, если быть точным, то работа с видео сводится к обработке статических изображений (фреймов). Собственно, скачать и попробовать OpenCV можно отсюда.
Улыбочку, вас снимает камера
Простота и изящество библиотеки позволяет уже спустя несколько минут после знакомства отображать видео-картинку с веб-камеры. Вот так все просто! Давайте глянем на эту реализацию (как всегда, важные моменты помечены комментариями):
#include "stdafx.h"
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <iostream>
using namespace std;
void processFrame(IplImage*& image);
int main(int argc, char** argv)
{
// Инициализируем источник наших изображений.
// В данном случае - это видеокамера, подключенная по
// одному из интерфейсов. 0 означает, что надо
// выбрать первую попавшуюся камеру. У нас их одна,
// поэтому не стоит волноваться по этому поводу :)
CvCapture* capture = 0;
capture = cvCreateCameraCapture(0);
if (!capture)
{
cout << "Initialization failed" << endl;
return EXIT_FAILURE;
}
// Работа с GUI упрощена до невозможного. Необходимо
// определить идентификатор (по совместительству -
// заголовок окна), по которому мы будем определять
// наши окна.
const char *windowName = "First steps with OpenCV";
cvNamedWindow(windowName, CV_WINDOW_AUTOSIZE);
while(true)
{
// Опрашиваем камеру для получения следующего кадра
IplImage* frame = cvQueryFrame( capture );
if(!frame)
break;
// processFrame(frame);
// Отобразим наш фрейм в окне (не забыли, как мы его
// определили? - через идентификатор)
cvShowImage(windowName, frame);
// По нажатию ESC - выход из цикла
char c = cvWaitKey(33);
if (c == 27)
break;
}
// Никогда не забываем освобождать память!
cvReleaseCapture( &capture );
cvDestroyWindow(windowName);
return 0;
}
Замечание. Я не перегружаю пост указанием подготовительных действий. Библиотека исключительна проста в установке. Если возникают вопросы — можно спросить в комментариях.
Стоит заметить, что не OpenCV единым жив человек :) Можно задействовать и другие способы для работы с камерой. Тот же DirectShow имеет такие возможности. Но если глянуть на подобную реализацию (вот здесь), то сразу станет ясным — нам такой радости не надо.
Вернемся к нашему примеру. Чем он так хорош? А тем, что уже сейчас можно приниматься за обработку кадров! Чем мы сейчас и займемся :)
Обработка фреймов
Издеваться над кадрами мы будем в функции processFrame. Встроенных функций в OpenCV - уйма, и данной статьи на их описание не хватит. Но мы сделаем следующие: отобразим картинку (чтобы видеть себя как в зеркале), создадим копию фрейма в серых тонах и отобразим в новом окне. А перед тем, как выводить - вырежем центр изображения (если издеваться, то по полной :) ). И вот что мы получим:
void processFrame(IplImage*& image)
{
// Стандартный флип
cvFlip(image,image,1);
// Создадим новое изображение
CvSize size = cvSize(image->width, image->height);
// Здесь 1 - количество каналов
IplImage* newImage = cvCreateImage(size, image->depth, 1);
// Копируем изображение с переводом в grayscale
cvCvtColor(image, newImage, CV_RGB2GRAY);
// Определяем центр изображения
CvRect rect = cvRect(image->width/4,image->height/4,
image->width/2,image->height/2);
// Определяем region of interest, который мы затем обнулим
cvSetImageROI(newImage, rect);
cvZero(newImage);
cvResetImageROI(newImage);
// Отобразим наше изображение
cvNamedWindow("newImage");
cvShowImage("newImage",newImage);
// Ох не забывайте про эту функцию :)
cvReleaseImage(&newImage);
}
Стоит наверно пояснить, что такое ROI. Это очень удобная штука. Можно задать этот прямоугольник и все действия будут производится только над ним, не затрагивая другие части фрейма.
На этом я закончу, в скором ждите продолжения - будем определять предметы на изображении.
Disclaimer. Я не претендую на исключительную правильность и на глубокое понимание библиотеки: сам имею небольшой опыт общения с ней. Выкладываю свои наработки с целью немного расширить скудный материал по OpenCV на русском. Есть вопросы - велкам в комменты! :)

