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 года слегка устарела.
Сейчас, имеет смысл использовать:
или же для С++:
Большое спасибо)) Поправил и работает))