图像处理之ROI区域裁剪
2017-06-15 17:26
204 查看
图像ROI(region of intrest:感兴趣区域)的提取往往是图像处理中的第一步,而且也是非常关键的一步,ROI区域的提取能够在消除一些噪
声的同时减少后续图像处理的数据量,是非常常用的方法。
在OPENCV中可以利用数据结构Rect 来提取ROI区域,具体用法示例如下:
在这段程序中,原图是image,裁剪区域是以坐标(300,500)为左上角,宽为300,高为400的一个矩形区域,如下图:
原图:1.bmp
裁剪结果如下:RIO.bmp
那么现在就存在一个问题,对于大多数的图像处理项目来说,每幅图像的ROI并不一定是在固定的区域,甚至ROI区域的大小也可能是不一样的,
也就是说在具体裁剪的时候裁剪的位置及矩形区域都是要根据每幅图像来具体确定的,这里将举一个例子进行说明:如下图是一幅啤酒盖的图像,
在后续的检测或者分类中我们只关心啤酒盖所在的区域,也就是说我们ROI区域是包含且仅包含整个啤酒盖的一个矩形区域,如何提取呢?
我的做法,首先对原图进行二值化,然后提取整个图像区域内最大的连通区域,如下图:
在得到这个最大的连通区域,其实也就是啤酒盖所在的区域,我是通过遍历整个图像,找到0度,90度,180度及270度,
四个方向上连通域最靠近图像边缘的点,然后通过这四个点就能用一个矩形框将整个连通区域框出来,代码如下,
采用的是几种遍历方法中最高效的方法:
根据这两个坐标点,可以利用Rect数据类型对原图进行裁剪,如下:
显然通过以上办法,实现了对于感兴趣区域的裁剪。
声的同时减少后续图像处理的数据量,是非常常用的方法。
在OPENCV中可以利用数据结构Rect 来提取ROI区域,具体用法示例如下:
int main() { Mat image = imread("sources/1.bmp", 0); Rect ROI(10, 20, 300, 400); Mat img = image(ROI); imwrite("result/ROI.bmp", img); int aaa; cin >> aaa; return 0; }
在这段程序中,原图是image,裁剪区域是以坐标(300,500)为左上角,宽为300,高为400的一个矩形区域,如下图:
原图:1.bmp
裁剪结果如下:RIO.bmp
那么现在就存在一个问题,对于大多数的图像处理项目来说,每幅图像的ROI并不一定是在固定的区域,甚至ROI区域的大小也可能是不一样的,
也就是说在具体裁剪的时候裁剪的位置及矩形区域都是要根据每幅图像来具体确定的,这里将举一个例子进行说明:如下图是一幅啤酒盖的图像,
在后续的检测或者分类中我们只关心啤酒盖所在的区域,也就是说我们ROI区域是包含且仅包含整个啤酒盖的一个矩形区域,如何提取呢?
我的做法,首先对原图进行二值化,然后提取整个图像区域内最大的连通区域,如下图:
在得到这个最大的连通区域,其实也就是啤酒盖所在的区域,我是通过遍历整个图像,找到0度,90度,180度及270度,
四个方向上连通域最靠近图像边缘的点,然后通过这四个点就能用一个矩形框将整个连通区域框出来,代码如下,
采用的是几种遍历方法中最高效的方法:
int up = image.rows, left = image.cols, right = 0, down = 0; int flag = 0; int nr = image.rows, nc = image.cols; if (image.isContinuous()) { nr = 1; nc = nc*image.rows;//convert 2D to 1D if the image is continuous flag = 1; } //cout << "flag=" << flag << endl; if (flag == 1)//situation 1:the image is continuous { for (int i = 0; i < nr; i++) { const uchar* inData = region.ptr<uchar>(i); for (int j = 0; j < nc; j++) { if (*inData == 0 && *(inData + 1) == 255) { int row = (j + 1) / (region.cols); int col = (j + 1) - row*region.cols; if (row < up) { up = row; } if (col < left) { left = col; } } if (*inData == 255 && *(inData + 1) == 0) { int row = j / (region.cols); int col = j - row*region.cols; if (row > down) { down = row; } if (col > right) { right = col; } } inData++; } } } else//situation 2:the image is not continuous { for (int i = 0; i < nr; i++) { const uchar* inData = region.ptr<uchar>(i); for (int j = 0; j < nc; j++) { if (*inData == 0 && *(inData + 1) == 255) { int row = i; int col = j; if (row < up) { up = row; } if (col < left) { left = col; } } if (*inData == 255 && *(inData + 1) == 0) { int row = i; int col = j; if (row > down) { down = row; } if (col > right) { right = col; } } inData++; } } } bb[0] = Point2i(left, up); bb[1] = Point2i(right, down); }其中bb[0],bb[1]是两个坐标点,分别是确定要裁剪的矩形框的左上角与右下角在原图中的坐标,
根据这两个坐标点,可以利用Rect数据类型对原图进行裁剪,如下:
Rect roi(bb[0].x,bb[0].y,bb[1].x-bb[0].x,bb[1].y-bb[0].y)最终的裁剪结果如下:
显然通过以上办法,实现了对于感兴趣区域的裁剪。
相关文章推荐
- Matlab图像处理学习笔记(一):二值化、开操作、连通区域提取、重心、ROI
- Matlab图像处理学习笔记(一):二值化、开操作、连通区域提取、重心、ROI
- Matlab图像处理学习笔记(一):二值化、开操作、连通区域提取、重心、ROI
- OPENCV图像处理基础(二)感兴趣区域ROI
- OpenCV设置感兴趣区域ROI,对图像进行局部处理
- Matlab图像处理学习笔记(一):二值化、开操作、连通区域提取、重心、ROI
- Matlab图像处理(一):二值化、开操作、连通区域提取、重心,ROI(region of interest)
- 图像处理算法1——区域生长法
- 图形图像处理之——实现图像子区域图像的简单提取
- 图形图像处理之——实现图形图像之子区域提取2
- 【OpenCV入门教程之四】 ROI区域图像叠加&初级图像混合 全剖析
- PHP图像处理:缩略图,打水印,裁剪等功能
- 图像处理之计算连通区域的角度方向
- OpenCV图像处理->鼠标移动区域放大
- OpenCV:设置图像的感兴趣区域(ROI)
- 【OpenCV入门教程之四】 ROI区域图像叠加&初级图像混合 全剖析
- 图像处理之计算二值连通区域的质心
- 【数字图像处理】<纯C++>读取、裁剪、缩放、旋转和存储8位bmp灰度图像
- OpenCV_复制一个或多个ROI图像区域