OpenCV4.5.5学习笔记(八):访问图像中的像素、ROI区域图像叠加和图像混合

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

笔者本科时候有幸接触了OpenCV3.2.0版本的学习,后因考研压力不得不暂时停下学习的脚步,现在考研任务结束了,未来的导师也是从事的该方向,笔者又开始了新一轮的学习。回来发现OpenCV已经出到了4.5.5版本,遂重新下载新版本并决定记录这一学习历程。由于笔者水平有限,可能有错误之处还请诸位大佬多多包涵并烦请指出,让我们一起学习,共同进步。
首先需要说明的是:我是按着毛星云前辈编写的OpenCV3编程入门进行学习的,我会尽力把星云前辈的程序转成符合OpenCV4.5.5版本的。毛星云前辈于2021年12月11日不幸过世,他是我非常敬仰的一位业内大佬,我也是看他的书才开始接触OpenCV。


一、访问图像中的像素

1.图像矩阵是如何存储在内存中的?

正如在Mat部分中学到的那样,矩阵的大小取决于所使用的颜色系统。更准确地说,它取决于使用的通道数。在灰度图像的情况下如下图所示存储(图来源于官网):
在这里插入图片描述
对于多通道图像,列包含与通道数一样多的子列。例如, RGB颜色如下图所示存储(图来源于官网):
在这里插入图片描述
请注意,通道的顺序是相反的:BGR 而不是 RGB。因为在许多情况下,内存足够大,可以以连续的方式存储行,所以行可能会一个接一个地跟随,从而创建一个长行。因为一切都在一个接一个的地方,这可能有助于加快扫描过程。

2.颜色空间的缩减

通过使用 unsigned char C 和 C++ 类型来存储矩阵项,一个像素通道可以有多达 256 个不同的值。对于三通道图像,这可能会形成太多颜色(准确地说是 1600 万)。使用如此多的色调可能会对我们的算法性能造成沉重打击。但是,有时只需使用更少的它们来获得相同的最终结果就足够了。
在这种情况下,我们通常会进行色彩空间缩减。这意味着我们将颜色空间当前值除以一个新的输入值,最终得到更少的颜色。例如,0 到 9 之间的每个值都取新值 0,10 到 19 之间的每个值取值 10,依此类推(这其实有点像采样,多少区间用一个数来表示)。
当用uchar(无符号字符 - 即 0 到 255 之间的值)值除以int值时,结果也将是char。这些值可能只是 char 值。因此,任何分数都将向下舍入。利用这一事实,uchar域中的上层运算可以表示为:
在这里插入图片描述
值得注意的是,这其中进行了除法和乘法运算。这些操作对于一个系统来说是非常麻烦的的。如果可能的话,通过使用更便简单的操作来代替它们,例如一些减法、加法或最好的情况是一个简单的赋值。因此,对于较大的图像,明智的做法是事先计算所有可能的值,并在分配期间通过使用查找表进行分配。查找表是简单的数组(具有一维或多维),对于给定的输入值变化保存最终输出值。它的优点是不需要进行计算,只需要读取结果。

3.访问图中像素的三种方法

  1. C 风格 operator[](指针)访问
  2. 迭代器(安全)方法
  3. 动态地址

二、ROI区域图像叠加

感兴趣区域ROI(region of interest),从图像中选择一个图像区域,这个区域是图像分析的重点。定义ROI区域有两种方法:
(非常抱歉我没在官方文档中找到相关信息,只能按星云前辈的书籍来了)

  1. 使用矩形表示区域的Rect:
    通过指定矩形的左上角坐标和矩形的长宽以定义一个矩形区域。
// 定义一个Mat类型并给定其设定ROI区域
Mat imageROI;
// 方法一
imageROI = image(Rect(500, 250, logo.cols, logo.rows));
  1. 指定感兴趣行或列的范围:
    使用Range是从起始索引到终止索引的一连段连续序列。
// 方法二
imageROI = image( Range(250, 250+logoImage.rows), Range(200, 200+logoImage.cols));

三、图像混合

线性混合操作是一种二元(两个输入)的像素操作,它的公式如下所示:
在这里插入图片描述
通过改变a的值,来对两张具有相同的大小(宽度和高度)和类型图片产生时间上的叠化效果,在其中使用了添加加权和函数:addWeighted()
在OpenCV官方文档中是这么写的:
void cv::addWeighted (
InputArray src1,
double alpha,
InputArray src2,
double beta,
double gamma,
OutputArray dst,
int dtype = -1
)
第一个参数是第一个输入数组,
第二个参数是第一个数组元素的权重,
第三个参数是与第一个数组大小和通道号相同的第二个输入数组,
第四个参数是第二个数组元素的权重,
第五个参数是添加到每个总和的标量,
第六个参数是与输入数组具有相同大小和通道数的输出数组,
第七个参数是输出数组的可选深度;当两个输入数组具有相同的深度时,可以将 dtype 设置为 -1

即:
在这里插入图片描述


总结

今天学习了有关如何访问图像中的像素的三种方法,并且也学习了如何使图像混合起来。最后附上我的运行结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43264167/article/details/124298855
今日推荐