Fig 1. An image with Region of Interest defined
To define Region of Interest, use the function:
cvSetImageROI( IplImage* img, CvRect rect )
Where
img
is the source image and rect
is the area within the source image. To reset Region of Interest, use the function:cvResetImageROI( IplImage* img )
Below are some samples where ROI is useful.
1. Crop an Object
Listing 1: Crop an object and save to new image
- /* load image */
- IplImage *img1 = cvLoadImage("elvita.jpg", 1);
- /* sets the Region of Interest
- Note that the rectangle area has to be __INSIDE__ the image */
- cvSetImageROI(img1, cvRect(10, 15, 150, 250));
- /* create destination image
- Note that cvGetSize will return the width and the height of ROI */
- IplImage *img2 = cvCreateImage(cvGetSize(img1),
- img1->depth,
- img1->nChannels);
- /* copy subimage */
- cvCopy(img1, img2, NULL);
- /* always reset the Region of Interest */
- cvResetImageROI(img1);
2. Adding Two Images with Different Size
Listing 2: Adding two images with different size
- /* load images
- Note that both images have different width & height */
- IplImage *img1 = cvLoadImage("elvita.jpg", 1); /* bigger image */
- IplImage *img2 = cvLoadImage("fifi.jpg", 1); /* smaller image */
- /* define rectangle for ROI */
- CvRect rect = cvRect(25, 25, img2->width, img2->height);
- /* sets Region of Interest */
- cvSetImageROI(img1, rect);
- /* Add both images
- Note that now both images have 'same' width & height */
- cvAdd(img1, img2, img1, NULL);
- /* always reset the region of interest */
- cvResetImageROI(img1);
3. Performing Template Matching in a Specific Area
Listing 3: Template Matching with Region of Interest defined
- IplImage *img = cvLoadImage("myphoto.jpg", 1);
- IplImage *tpl = cvLoadImage("eye.jpg", 1);
- CvRect rect = cvRect(25, 25, 120, 120);
- cvSetImageROI(img, rect);
- IplImage *res = cvCreateImage(cvSize(rect.width - tpl->width + 1,
- rect.height - tpl->height + 1),
- IPL_DEPTH_32F, 1);
- /* perform template matching */
- cvMatchTemplate(img, tpl, res, CV_TM_SQDIFF);
- /* find best matches location */
- CvPoint minloc, maxloc;
- double minval, maxval;
- cvMinMaxLoc(res, &minval, &maxval, &minloc, &maxloc, 0);
- /* draw rectangle */
- cvRectangle(img,
- cvPoint(minloc.x, minloc.y),
- cvPoint(minloc.x + tpl->width, minloc.y + tpl->height),
- CV_RGB(255, 0, 0), 1, 0, 0 );
- cvResetImageROI(img);
In this article, I have explained Region of Interest in OpenCV and provided some usage examples. There are many more problems in Image Processing where we find ROI is useful.
The morals:
- ROI segments object in an image.
- ROI respected by most of OpenCV functions.
- Always reset Region of Interest when it is no longer needed. This will saves you from hours of debugging.
Some readers asked me about accessing the image pixels in the ROI. The simplest method would be copying the subimage to another image, then you can access this new image as usual.
Listing 4: Accessing ROI pixels #1
/* assuming that you have 8-bit 3-channels img*/
/* here's the ROI */
CvRect rect = cvRect(10, 20, 50, 60);
/* dst image */
IplImage* subimg;
/* copy ROI to subimg */
cvSetImageROI(img, rect);
cvCopy(img, subimg, NULL);
cvResetImageROI(img);
/* now you have the ROI in subimg. access the pixels as usual */
Or you can access the image directly using the ROI boundaries:/* here's the ROI */
CvRect rect = cvRect(10, 20, 50, 60);
/* dst image */
IplImage* subimg;
/* copy ROI to subimg */
cvSetImageROI(img, rect);
cvCopy(img, subimg, NULL);
cvResetImageROI(img);
/* now you have the ROI in subimg. access the pixels as usual */
Listing 5: Accessing ROI pixels #2
/* assuming that you have 8-bit 3-channels img*/
/* here's the ROI */
CvRect rect = cvRect(10, 20, 50, 60);
cvSetImageROI(img, rect);
/* say you want to set all pixels in the ROI to 0 */
for (i = rect.y; i < (rect.y + rect.height); i++) {
for (j = rect.x; j < (rect.x + rect.width); j++) {
((uchar*)(img->imageData + i * img->widthStep))[j*3] = 0;
((uchar*)(img->imageData + i * img->widthStep))[j*3+1] = 0;
((uchar*)(img->imageData + i * img->widthStep))[j*3+2] = 0;
}
}
cvResetImageROI(img);
/* here's the ROI */
CvRect rect = cvRect(10, 20, 50, 60);
cvSetImageROI(img, rect);
/* say you want to set all pixels in the ROI to 0 */
for (i = rect.y; i < (rect.y + rect.height); i++) {
for (j = rect.x; j < (rect.x + rect.width); j++) {
((uchar*)(img->imageData + i * img->widthStep))[j*3] = 0;
((uchar*)(img->imageData + i * img->widthStep))[j*3+1] = 0;
((uchar*)(img->imageData + i * img->widthStep))[j*3+2] = 0;
}
}
cvResetImageROI(img);