【Emgu CV教程】2.10、基本方法之图像的ROI

本文介绍了ROI(感兴趣区域)在图像处理中的重要性,如何在监控中仅处理特定区域以提高效率和准确性。并通过EmguCV库举例说明了ROI选取和深浅拷贝的区别,提醒开发者在实践中选择深拷贝以避免后续处理的混乱。
摘要由CSDN通过智能技术生成

ROI,不是return on investment(投资回报率)或者Rate of Interest(利润率)的缩写,而是region of interest的缩写,中文翻译就是感兴趣区域。

ROI的意义就在于,一张照片里面,我需要进行图像处理的部分,可能只是图像的一小部分。我们只需要对这一小部分区域进行处理,就可以得出结果,而不用处理整个一张照片。设定ROI后,不仅可以加快图像处理速度,也能提高算法准确性,减少外部的干扰。

举个例子,以紫禁城的城门为例。如果皇帝想对大门进行监控,防止夜间有人随便进出大门。那么就可以在大门附近安装一个摄像机,24小时拍摄大门的视频。就像这样:

但是,既然是是监控大门有没有人进出,那计算机只处理大门那块区域就好了,其它区域是分本不用管的。所以Emgu CV就提供了ROI选取的功能,选出来的ROI区域就是下面这部分:

这个ROI的图像尺寸就小了很多,计算机只需要判断它里面有没有出现人员,就可以实现大门的监控了。 但是,如果有刺客翻墙而入呢,正好在ROI的外面,摄像机拍摄到了,但是计算机不会对他进行分析。这个时候就得扩大ROI的面积,将其放大到如下图所示的绿色框大小,不就可以了。

相应的代码也很简单,首先要通过起点X坐标、起点Y坐标,矩形高度、矩形宽度四个参数定义一个矩形,然后有两种方法获取到ROI,第一种是这样定义ROI Mat的:

public Mat(Mat mat, Range rowRange, Range colRange); 

rowRange就是起点Y坐标 + 高度,colRange就是起点X坐标 + 宽度。第二种定义方法就是直接使用矩形,如下:

public Mat(Mat mat, Rectangle roi); 

以城门为例,截取到ROI的两种方式代码如下:

Mat dstMat = srcMat.Clone();
int x = Convert.ToInt32(TextBoxX.Text.ToString());
int y = Convert.ToInt32(TextBoxY.Text.ToString());
int width = Convert.ToInt32(TextBoxWidth.Text.ToString());
int height = Convert.ToInt32(TextBoxHeight.Text.ToString());
Rectangle rect = new Rectangle(x, y, width, height);

Mat roi1 = new Mat(dstMat, new Range(y, y + height), new Range(x, x + width)); // 这是浅拷贝,当对roi1操作时,会造成原始的dstMat也改变
Mat roi2 = new Mat(dstMat, rect).Clone(); // 这是深拷贝,当对roi2操作时,不会造成原始的dstMat也改变
CvInvoke.Rectangle(roi1, new Rectangle(10, 10, 50, 20), new MCvScalar(0, 0, 255), 1, LineType.EightConnected, 0);
CvInvoke.Rectangle(roi2, new Rectangle(10, 50, 50, 20), new MCvScalar(0, 255, 0), 1, LineType.EightConnected, 0);
CvInvoke.Rectangle(dstMat, rect, new MCvScalar(255, 0, 0), 1, LineType.EightConnected, 0);
CvInvoke.Imshow("ROI1, " + roi1.Size.ToString(), roi1);
CvInvoke.Imshow("ROI2, " + roi2.Size.ToString(), roi2);
Image1.Source = dstMat.ToBitmapSource();

代码运行效果如下图所示:

要注意上述代码定义的roi1是dstMat中浅拷贝过来的,如果后续对roi1进行操作,比如ROI内画一个蓝色的矩形,则dstMat也会随之改变,通过代码就可以看出来:roi1定义完成后,在内部画了一个红色矩形,最后dstMat内也出现了红色矩形。而roi2是深拷贝,虽然后续在roi2内画了绿色矩形,但是dstMat不会改变。

       再说一遍:

  • 浅拷贝是两个Mat名字相同,共用同相同的内存,改动一个,另一个也会改变。
  • 深拷贝是两个Mat名字相同,图像占用的内存不同,改动一个不会影响另外一个。

因此读者们在实际使用过程中,获取ROI时尽量用深拷贝的形式,否则会造成后续的处理出现混乱的情况。这又是一个坑,注意了!!!。那roi1要怎么写呢,只需要这样:

Mat roi1 = new Mat(dstMat, new Range(y, y + height), new Range(x, x + width)).Clone();

用修改过后的代码再运行一下lena.jpg,获取她的头部照片,效果如下:

是不是再在roi1中画红色矩形,不会影响到dstMat了。

原创不易,请勿抄袭。共同进步,相互学习。 

  • 19
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值