ROI相关简介

ROI是什么

ROI是region of interest首字母的简写,翻译为感性趣的区域。其实在写本篇之前应该写一篇关于图片是什么的学习笔记,但又感觉里面没多少东西还不能承载一篇学习笔记,所以这里只简单提一下。

图片是什么

其实大家也应该能猜到图片就是一个二维数组,只不过这个二维数组有点特殊,它有头信息,在头信息里会有描述这个二维数组的大小、图片类型和数组元素的数据类型等。下面是一张从官方教程里获取的一张辅助理解的图片。

图片就是一个二维数组

上面的图片只是一张灰色的图片而我们经常用的图片彩色的图片,在灰图片中一个像素我们用一个值就可以表示了,但在彩色的图片中一个像素要用3个值或4个值(有的图片有alpha通道)来表示。下面就是一个由三个值表示一个像素的辅助理解图。

BGR格式的图片

这张图片是从官网获取的。是不是觉得颜色的排序有点不对呀,我们想的应该是红在前才对,其实在OpenCV中很多图片都是BGR格式的和我们常见的到RGB格式的存储方式是相反的。具体为什么要用BGR格式还不清楚如有大神知道还请科普。其他图片的格式有很多种如,HVS、CyCbCr、HSI等格式,后续可能会专门写一篇关于图片格式的学习笔记,这里先对图片格式的介绍写这么多。

为什么要设置ROI

上面我已经介绍过图片是一个二维数组,而我们有时处理图片的时候只对其中的一部分图片的区域进行处理,例如我们想在图片某个区域打马赛克,为了性能考虑我们可以只让程序对这一部分信息进行处理而将其他部分忽略,这时我们就要设置图片感性趣的区域。设置完感性趣的区域后其实是指针指到了ROI区域的左上角,好像我们截取了一张小图片一样,我们只对这张小图片进行处理就可以了,因其ROI指向的还是原图只在告诉它图片的起始位置和大小变了,所以在对ROI区操作会影响原图。

设置ROI

在OpenCV中有C和C++的代码,最早OpenCV是用C写的,在开发中C的代码写起来不太方便在版本进入2.0之后后续加入的代码改用C++,所以设置ROI的方法有两种即C和C++的,C的已不常用不过这里还会列出已方便了解。

C++

- (void)setImageROI:(cv::Mat)image{

// 设置ROI

// 方法一

cv::Mat roiImage = image(cv::Rect(100, 100, 200, 100));

// 方法二,第一个range表示起始行和终止行,第二个range是起始列和终止列

//cv::Mat roiImage = testImage(cv::Range(100, 100 + 100), cv::Range(100, 200 + 100));

// 画一个矩形

cv::rectangle(roiImage, cv::Rect(0, 0, 200, 100), cv::Scalar(255, 0, 0), 10);

}

设置ROI其实就是在原来图片上指定一个区域,而这个区域只是新创建了一个图片文件的头信息而已并没有产生新的图片,文件头里的图片区域的起始位置指向了ROI区域的左上角位置,所以在ROI上做的任何操作都会影响原图片。

C

- (void)setImageROI:(IplImage *)image{

// 记录图片的大小和区域

CvRect currentRect = cvGetImageROI(image);

// 设置ROI区域

cvSetImageROI(image, cvRect(100, 100, 200, 100));

// 画一个矩形

cvRectangleR(image, cvRect(0, 0, 200, 100), CvScalar(255, 0, 0), 10);

// 还原ROI区域

cvSetImageROI(image, currentRect);

// 上面的还原ROI区域要一个临时变量,也可通过下面的方法,还原ROI区域而不用创建临时变量

//cvResetImageROI(image);

}

对于C的代码没有生成一个文件头信息而是修改原来的文件头信息,所以要把文件头信息改回去。现在是不是觉得C++比C简单多了。

代码实战

一、设置ROI并画矩形

以下代码是核心代码,其他简单的显示代码将不再列出。首先请导入以下头文件。

#import

#import

#import

然后下面是具体的ROI代码都有注释,原理上面已说明。

- (UIImage *)getOpenCVImage{

// 获取测试用的图片路径

NSString * path = [[NSBundle mainBundle] pathForResource:@"test" ofType:nil];

// 读取图片

cv::Mat testImage = cv::imread([path cStringUsingEncoding:NSUTF8StringEncoding]);

// 设置ROI

cv::Mat roiImage = testImage(cv::Rect(100, 100, 100, 100));

// 在ROI区域做操作,画一个矩形

cv::rectangle(roiImage, cv::Rect(5, 5, 50, 50), cv::Scalar(255, 255, 255), 10);

// 将图片的格式从BGR转换成RGB,如果不转会造成显示的图片颜色出错

cv::cvtColor(testImage, testImage, cv::COLOR_BGR2RGB);

// 返回UIImage类型的图片

return MatToUIImage(testImage);

}

运行结果如下第一张是原图,第二张是处理后的图片:

原始图

可以看到我们在ROI的(0,0)位置开始画矩形,但在大图中实际效果却不在左上角,这就是设置ROI的效果。

运行结果

超出ROI的效果

我们将上面代码改成正以下代码,让画矩形区域的高度大于ROI的高度。

// 放大矩形的高度,让其超出ROI的区域

cv::rectangle(roiImage, cv::Rect(0, 0, 200, 150), cv::Scalar(255, 0, 0), 10);

超出ROI操作的效果

可以看出,超出ROI的操作是被丢弃的。

二、设置ROI实现图片移位

上面说过设置ROI后我们就可以只对该区域进行操作。我们练习一下将一ROI区域的数据放到另一个ROI区域。

- (UIImage *)getOpenCVImage{

// 获取测试用的图片路径

NSString * path = [[NSBundle mainBundle] pathForResource:@"test" ofType:nil];

// 读取图片

cv::Mat testImage = cv::imread([path cStringUsingEncoding:NSUTF8StringEncoding]);

// 设置ROI区域A

cv::Mat roiImageA = testImage(cv::Rect(100, 100, 200, 100));

// 设置ROI区域B

cv::Mat roiImageB = testImage(cv::Rect(300, 30, 200, 100));

// 将roiImageB数据放到roiImageA的区域以实现图片区域移动效果

roiImageB.copyTo(roiImageA);

// 将图片的格式从BGR转换成RGB,如果不转会造成显示的图片颜色出错

cv::cvtColor(testImage, testImage, cv::COLOR_BGR2RGB);

// 将图片转成UIImage并返回

return MatToUIImage(testImage);

}

代码运行后结果:

实现图片区域移动

以上是我学习后的个人总结,如有错误还请大神指出。

mat opencv 修改roi_设置图片ROI(OpenCV学习笔记之二)相关推荐

  1. OpenCV学习笔记(二十六)——小试SVM算法ml OpenCV学习笔记(二十七)——基于级联分类器的目标检测objdect OpenCV学习笔记(二十八)——光流法对运动目标跟踪Video Ope

    OpenCV学习笔记(二十六)--小试SVM算法ml 总感觉自己停留在码农的初级阶段,要想更上一层,就得静下心来,好好研究一下算法的东西.OpenCV作为一个计算机视觉的开源库,肯定不会只停留在数字图 ...

  2. opencv学习笔记(二):基于肤色的人手检测

    opencv学习笔记(二):基于肤色的人手检测 原文:http://blog.csdn.net/wzmsltw/article/details/50849810 先写了人手的检测程序,下一步基于检测程 ...

  3. OpenCV学习笔记(二十一)——绘图函数core OpenCV学习笔记(二十二)——粒子滤波跟踪方法 OpenCV学习笔记(二十三)——OpenCV的GUI之凤凰涅槃Qt OpenCV学习笔记(二十

    OpenCV学习笔记(二十一)--绘图函数core 在图像中,我们经常想要在图像中做一些标识记号,这就需要绘图函数.OpenCV虽然没有太优秀的GUI,但在绘图方面还是做得很完整的.这里就介绍一下相关 ...

  4. opencv学习笔记之二值化

    opencv学习笔记之二值化 1.什么是二值化 二值化,从名词意义上可以看出来,是将一共物体转化成两个值.二值即:0或255.即一个白色一个黑色.即一个图片经过二值化之后会显示成白色和黑色的形式. 2 ...

  5. OpenCV学习笔记(二):3种常用访问图像中像素的方式

    OpenCV学习笔记(二):3种常用访问图像中像素的方式 #include <opencv2/opencv.hpp>using namespace cv; using namespace ...

  6. OpenCV学习笔记(十二)——图像分割与提取

    在图像处理的过程中,经常需要从图像中将前景对象作为目标图像分割或者提取出来.例如,在视频监控中,观测到的是固定背景下的视频内容,而我们对背景本身并无兴趣,感兴趣的是背景中出现的车辆.行人或者其他对象. ...

  7. python做直方图-python OpenCV学习笔记实现二维直方图

    本文介绍了python OpenCV学习笔记实现二维直方图,分享给大家,具体如下: 官方文档 – https://docs.opencv.org/3.4.0/dd/d0d/tutorial_py_2d ...

  8. mysql循环查询一个表中的数据并进行修改_JavaScript学习笔记(二十四)-- MYSQL基础操作...

    MYSQL mysql 是一个数据库的名字 和 php 合作的比较好的数据库 之前我们说过一个问题,前端向后端索要数据,后端就是去数据库中查询数据,返回给前端 接下来就聊聊使用 php 操作数据库 M ...

  9. java+opencv修改白色背景为图片

    原图: 背景: 最终效果: 代码: package com.machao;import com.machao.util.OpenCvUtils; import org.opencv.core.Core ...

最新文章

  1. 什么是MySQL锁?有哪些锁类型?如何使用?
  2. 使用Nomad和OpenFaaS提供FaaS服务
  3. 蜂鸟智游大数据:为什么出国购物慢慢“OUT”了?
  4. Redis的五大数据类型
  5. Spark入门(十二)之最值
  6. html5 服务器手机编程,html5实现服务器发送事件
  7. Windows如何查看局域网内所有设备的ip
  8. hprose-php教程,hprose php用户手册
  9. POJ 3253.Fence Repair
  10. java开发小公司跳槽华为od笔试面试过程
  11. 怎么生成html链接,终于认识如何创建网页超链接
  12. 超详细:将iPhone中音乐导出到电脑里的简单方法(完美支持最新iOS15.2系统)
  13. 数据库运行sql文件
  14. 《今日美国》Twitter账号遭遇黑客攻击
  15. 大唐西域记 唐朝时代的世界划分 Re: [转载]悟空的仕途生涯(长)
  16. 上海财经大学如何构建量化高频数据中心?
  17. 温州又一知名企业宣布倒闭破产
  18. nasm寄存器xmm[0~8使用]
  19. 网站服务器日常管理,网站管理员的日常生活
  20. html不刷新页面更新js和图片

热门文章

  1. 【.NET Core项目实战-统一认证平台】第十一章 授权篇-密码授权模式
  2. DDD理论学习系列(9)-- 领域事件
  3. 微软开源基于云的生理学研究工具
  4. Asp.net Core基于MVC框架实现PostgreSQL操作
  5. rest_framework09:自动生成接口文档(简略)
  6. tinycore php,tinycore中文支持
  7. 心电图计算心率公式_心电图到底能反应啥问题,看过之后你也能当“医生”
  8. CSDN,CNBLOGS博客文章一键转载插件 终于更新了!
  9. Android Studio开发基础之细节问题笔记
  10. 【经典回放】多种语言系列数据结构算法:希尔排序(C/C#版)