1. OpenCV шаг за шагом. Введение.
2. Установка.
3. Hello World.
4. Загрузка картинки.
5. Вывод видео
6. Ползунок
7. Захват видео с камеры
8. Запись видео
9. События от мышки
10. Обработка изображения — сглаживание
11. Обработка изображения — изменение размеров
12. ROI — интересующая область изображения

ROI (Region Of Interest — регион интересов — интересующая область изображения) — один из фундаментов OpenCV.
ROI позволяет пользователю задать определённую прямоугольную область изображения (т.е. ROI всегда должна находится внутри исходного изображения).
Почти все функции должны поддерживать работу с ROI, т.е. работу с выделенной областью изображения, что полезно для ускорения работы алгоритмов. Т.о. если нас интересует только определённая область изображения — можно её выделить и работать только с ней, не затрагивая всё изображение целиком.
Вот какие функции для работы с ROI предоставляет OpenCV:
CVAPI(void) cvSetImageROI( IplImage* image, CvRect rect );
— установка интересующей области рисунка (COI не меняется)
image — указатель на изображение
rect — прямоугольник интересующей области
CVAPI(void) cvResetImageROI( IplImage* image );
— сбрасывает область интересов (и COI)
image — указатель на изображение
CVAPI(CvRect) cvGetImageROI( const IplImage* image );
— возвращает область интересов изображения
image — указатель на изображение
Если ROI не установлена функция вернёт cvRect(0,0,image->width,image->height)
ROI можно использовать для вырезания части изображения или, наоборот, добавления изображения.
Пример работы с ROI — программа загружает изображение и по заданным координатам устанавливает ROI с помощью функции cvSetImageROI(). Затем вызывается функция cvAddS(), которая добавляет к элементам массива (пикселям изображения) заданную скалярную величину. Результатом является цветовое выделение квадрата ROI.
//
// пример работы с ROI
//
#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>
IplImage* image = 0;
int main(int argc, char* argv[])
{
// имя картинки задаётся первым параметром
char* filename = argc >= 2 ? argv[1] : "Image0.jpg";
// получаем картинку
image = cvLoadImage(filename,1);
printf("[i] image: %s\n", filename);
assert( image != 0 );
cvNamedWindow("origianl", CV_WINDOW_AUTOSIZE);
cvNamedWindow("ROI", CV_WINDOW_AUTOSIZE);
// задаём ROI
int x = argc >= 3 ? atoi(argv[2]) : 40;
int y = argc >= 4 ? atoi(argv[3]) : 20;
int width = argc >= 5 ? atoi(argv[4]) : 100;
int height = argc >= 6 ? atoi(argv[5]) : 100;
// добавочная величина
int add = argc >= 7 ? atoi(argv[6]) : 200;
cvShowImage( "origianl", image);
// устанавливаем ROI
cvSetImageROI(image, cvRect(x,y,width,height));
cvAddS(image, cvScalar(add), image);
// сбрасываем ROI
cvResetImageROI(image);
// показываем изображение
cvShowImage("ROI", image);
// ждём нажатия клавиши
cvWaitKey(0);
// освобождаем ресурсы
cvReleaseImage( &image );
cvDestroyAllWindows();
return 0;
}
CVAPI(void) cvAddS( const CvArr* src, CvScalar value, CvArr* dst,
const CvArr* mask CV_DEFAULT(NULL));
— рассчёт сумма массива и скаляра (скаляр добавляется к каждому элементу массива)
формула:
dst(I)=src(I)+value if mask(I)!=0
src — исходный массив
value — скаляр для суммирования
dst — массив для сохранения результата
mask — маска (8-битный 1-канальный массив, определяющий какие элементы массива подлежат изменению)
А вот другой, более наглядный пример работы с ROI:
Программа принимает 4 параметром название изображения, которое накладывается в ROI область первого изображения.
Для этого область интересов сначала обнуляется с помощью cvZero(), а затем туда копируется содержимое массива второго изображения при помощи cvCopyImage().
//
// пример работы с ROI 2
// вывод в ROI другого изображения
//
#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>
IplImage* image = 0;
IplImage* src = 0;
int main(int argc, char* argv[])
{
// имя картинки задаётся первым параметром
char* filename = argc >= 2 ? argv[1] : "Image0.jpg";
// получаем картинку
image = cvLoadImage(filename,1);
printf("[i] image: %s\n", filename);
assert( image != 0 );
cvNamedWindow("origianl", CV_WINDOW_AUTOSIZE);
cvNamedWindow("ROI", CV_WINDOW_AUTOSIZE);
// задаём ROI
int x = argc >= 3 ? atoi(argv[2]) : 120;
int y = argc >= 4 ? atoi(argv[3]) : 50;
// добавочное изображение
char* filename2 = argc >= 5 ? argv[4] : "eye.jpg";
src = cvLoadImage(filename2,1);
assert( src != 0 );
// размер ROI
int width = src->width;
int height = src->height;
cvShowImage( "origianl", image);
// устанавливаем ROI
cvSetImageROI(image, cvRect(x,y,width,height));
// обнулим изображение
cvZero(image);
// копируем изображение
cvCopyImage(src, image);
// сбрасываем ROI
cvResetImageROI(image);
// показываем изображение
cvShowImage("ROI", image);
// ждём нажатия клавиши
cvWaitKey(0);
// освобождаем ресурсы
cvReleaseImage( &image );
cvReleaseImage( &src );
cvDestroyAllWindows();
return 0;
}
Вот видите, как здорово? Всего несколько строчек кода, а у меня уже открылся третий глаз 🙂
Крррасота!
CVAPI(void) cvSetZero( CvArr* arr ); #define cvZero cvSetZero
— очищает все элементы массива arr (устанавливает их в 0)

Далее: 13. Типы данных OpenCV

6 комментариев на «“12. OpenCV шаг за шагом. ROI — интересующая область изображения”»
У меня второй пример прекрасно работает без cvSetZero
Согласен — этот метод там совсем не обязателен 🙂
Мне кажется или статья слегка устарела? На:
cvCopyImage(src, image);
Ругается:
Ошибка C3861 cvCopyImage: идентификатор не найден…
Проблемм с openCv нету- все остальные работают)
Разумеется, статья от 2010 года слегка устарела.
Сейчас, имеет смысл использовать:
или же для С++:
Большое спасибо)) Поправил и работает))
// // пример работы с ROI 2 // вывод в ROI другого изображения // #include <cv.h> #include <highgui.h> #include <stdlib.h> #include <stdio.h> IplImage* image = 0; IplImage* src = 0; int main(int argc, const char* argv[]) { // имя картинки задаётся первым параметром const char* filename = argc >= 2 ? argv[1] : "Image0.jpg"; // получаем картинку image = cvLoadImage(filename,1); printf("[i] image: %s\n", filename); assert(image != 0); cvNamedWindow("origianl", CV_WINDOW_AUTOSIZE); cvNamedWindow("ROI", CV_WINDOW_AUTOSIZE); // задаём ROI int x = argc >= 3 ? atoi(argv[2]) : 120; int y = argc >= 4 ? atoi(argv[3]) : 120; const char* filename2 = argc >= 5 ? argv[4] : "eye.jpg"; // добавочное изображение // устанавливаем ROI int rx = 95; int ry = 195; int rdx = 45; cvSetImageROI(image, cvRect(rx, ry, rdx, rdx)); cvSaveImage("eye.jpg", image); src = cvLoadImage(filename2,1); assert(src != 0); // размер ROI int width = src->width; int height = src->height; cvShowImage("origianl", image); // устанавливаем ROI cvSetImageROI(image, cvRect(x,y,width,height)); // обнулим изображение cvZero(image); // копируем изображение cvCopyImage(src, image); // сбрасываем ROI cvResetImageROI(image); // показываем изображение cvShowImage("ROI", image); // ждём нажатия клавиши cvWaitKey(0); // освобождаем ресурсы cvReleaseImage(&image); cvReleaseImage(&src); cvDestroyAllWindows(); return 0; }