关于感兴趣区域和掩膜的问题!

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/JiaFanChen/article/details/51149338

本文章主要对感兴趣区域ROI的操作(对于ROI区域图像叠加)说明


在图像处理的领域,我们常常需要去设置自己感兴趣的区域(ROI,region of interest),来专注或者简化工作过程。也就是从图像中选择的一个图像区域,这个区域是图像分析所关注的重点。我们圈定这个区域,以便进行下一步的处理.而且,使用ROI指定想读入的目标,可以减少处理时间,增加精度,给图像处理带来不小的便利。


利用opencv库进行编程实现对感兴趣区域ROI的操作

例如:将小图标复制到大图像的指定位置中

使用到的函数:矩形的表示:Rect类----》Rect(x,y,width,heigh)

对Rect类的解释:Rect类的成员变量有x、y、width、height,分别在左上角点的坐标和矩形的宽和高。


上述例题,第一种实现方法:在不使用图像掩码(掩膜)的情况下,通过Rect类去实现

#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;

int main()
{
 Mat srcImage = imread("dota_pa.jpg");//读取大图像
 Mat logoImage = imread("dota_logo.jpg");//读取logo图标

 //判断大图像文件是否存在
 if (!srcImage.data)
 {
  cout << "读取srcImage数据由错误~!" << endl;
  return false;
 }
 //判断logo图标是否存在
 if (!logoImage.data)
 {
  cout << "读取srcImage数据由错误~!" << endl;
  return false;
 }
 

 //使用Rect有两种用法,实现的效果都是一样的
 Mat ImageROI(srcImage,Rect(srcImage.cols - logoImage.cols, srcImage.rows - logoImage.rows, logoImage.cols, logoImage.rows));
 //Mat ImageROI=srcImage(Rect(srcImage.cols - logoImage.cols, srcImage.rows - logoImage.rows, logoImage.cols, logoImage.rows));
 
 //对上述指令的解释,对于Rect类中x=srcImage.cols- logoImage.cols;
                               //y = srcImage.rows - logoImage.rows;
                               //后面logoImage.cols, logoImage.rows为logo的总体的长跟宽(即行跟列)
 //**则上述指令指出感兴趣区域ROI,**其实ROI实际上就是一个Mat对象,它与它的父图像指向同一个数据缓冲区,并且有一个头部信息表示ROI的坐标,这时候,往这个感兴趣区域里存放数据点像素(即logo图片),则会自动在大图片srcImage对应的这个感兴趣区域中生成logo图片**

**


**加粗样式**  logoImage.copyTo(ImageROI);//将logo图标拷贝到ImageROI对象中,从而实现将小图标复制到大图像的指定位子中

 imshow("效果",srcImage);//显示图像

 waitKey(0);
 return 0;
}


第一种实现方法:使用图像掩码(掩膜)的情况下,通过Rect类去实现

注释:掩码:掩码是一个8位图像,如果掩码中某个位置的值不为0,在这个位置上的操作就会起作用;如果掩码中某些像素位置的值为0,那么对图像中相应位置的操作将不起作用。

这一句话就是解释下面为什么在logoImage.copyTo(ImageROI,mask);

程序:

#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;

int main()
{
 Mat srcImage = imread("dota_pa.jpg");//读取大图像
 Mat logoImage = imread("dota_logo.jpg");//读取logo图标

 //判断大图像文件是否存在
 if (!srcImage.data)
 {
  cout << "读取srcImage数据由错误~!" << endl;
  return false;
 }
 //判断logo图标是否存在
 if (!logoImage.data)
 {
  cout << "读取srcImage数据由错误~!" << endl;
  return false;
 }
 

 //使用Rect有两种用法,实现的效果都是一样的
 Mat ImageROI(srcImage,Rect(srcImage.cols - logoImage.cols, srcImage.rows - logoImage.rows, logoImage.cols, logoImage.rows));
 //Mat ImageROI=srcImage(Rect(srcImage.cols - logoImage.cols, srcImage.rows - logoImage.rows, logoImage.cols, logoImage.rows));
 
 //对上述指令的解释,对于Rect类中x=srcImage.cols- logoImage.cols;
                               //y = srcImage.rows - logoImage.rows;
                               //后面logoImage.cols, logoImage.rows为logo的总体的长跟宽(即行跟列)
 //则上述指令指出感兴趣区域ROI,其实ROI实际上就是一个Mat对象,它与它的父图像指向同一个数据缓冲区,并且有一个头部信息表示ROI的坐标,这时候,往这个感兴趣区域里存放数据点像素(即logo图片),则会自动在大图片srcImage对应的这个感兴趣区域中生成logo图片

 Mat mask = imread("dota_logo.jpg", 0);//mask一定要转灰度,这是一定要灰度是让后面根据掩码的定义,对所有像素点操作的时候,能对ROI区域进行所有像素点操作,不会出现极个别点不去操作。
 logoImage.copyTo(ImageROI,mask);//将logo图标拷贝到ImageROI对象中,从而实现将小图标复制到大图像的指定位子中

 imshow("效果",srcImage);//显示图像

 waitKey(0);
 return 0;
}


方式三:就是把Rect类转为用Range类

就是把上述程序中Rect指令改一下

改成:ImageROI=srcImage(Range(srcImage.rows-logo.rows,srcImage.rows),Range(srcImage.cols-logo.cols,srcImage.cols;))//也就是求感兴趣区域ROI中的面积区域的长跟宽的值。


总体效果图:



**爱仕达所**

对于函数srcImage.copyto(dstImage, mask),mask作为一个掩模板,如果在某个像素点(i, j)其值为1(只看第一通道,所以mask单通道即可)则把srcImage.at(i, j)处的值直接赋给dstImage.at(i, j),如果其值为0则dstImage.at(i, j)处保留其原始像素值。
其实ROI实际上就是一个Mat对象,它与它的父图像指向同一个数据缓冲区,并且有一个头部信息表示ROI的坐标,这时候,往这个感兴趣区域里存放数据点像素(即logo图片),则会自动在大图片srcImage对应的这个感兴趣区域中生成logo图片

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/JiaFanChen/article/details/51149338

猜你喜欢

转载自blog.csdn.net/qq_22070551/article/details/82849738
今日推荐