用图片拼接实例熟悉CV矩阵操作(2)
我们的目标是:使用代码把两张图片拼接在一起
本节内容:拷贝图片数据
上一节介绍了OpenCV用于处理图像数据的容器Mat的组织结构和几种遍历方法:https://blog.csdn.net/qq_33904382/article/details/109891363
要实现图片的拼接,一定会用到图像数据的拷贝——具体来说,就是怎样把两张图片的数据装到同一个容器中。因为我们使用Mat
作为图像数据的容器,所以先了解一下Mat
数据的拷贝是很有必要的。
Mat数据复制
从一个数据容器采集数据到放到另一个容器中,无非有两种情况——部分采集和全部复制。
第二种情况十分普通,OpenCV应该提供了标准的函数/方法。
果不其然,官方文档的确注明Mat提供了名为copyTo的方法用于将Mat中的数据复制到另一个容器中。
不过,这并不满足我们的需要——我们需要把两个Mat
对象中的数据复制到一个更大的Mat
中,这个Mat
的容量至少是要能比这两个Mat
的容量之和等大的。同时,两张图片的数据的顺序都不能被打乱。
依据这样的要求,我们自然地想到首先要确定合并后的Mat
的大小,然后依次把两张图片的数据复制到那个Mat
中。
让结果看起来像是这样:
数据复制到这个Mat的顺序如下图所示,先蓝后红,按行把图片数据复制到这里面:
上述过程对应着下面的
代码
:
for (int i = 0;i < dstx.rows;i++) {
for (int j = 0;j < dstx.cols;j++) {
/* 按行顺序复制第一张图片 */
if (i < src1.rows) {
if (j < src1.cols) {
for (int c = 0;c < src1.channels();c++)
dstx.at<Vec3b>(i, j)[c] = src1.at<Vec3b>(i, j)[c];
}
}
/* 按行顺序复制第二张图片 */
else if (i < src2.rows + src1.rows) {
if (j < src2.cols) {
for (int c = 0;c < src2.channels();c++)
dstx.at<Vec3b>(i, j)[c] = src2.at<Vec3b>(i - src1.rows, j)[c];
}
}
}
}
这段代码你应该很熟悉了,就是把第一节:【速览OpenCV】用图片拼接实例熟悉CV矩阵操作(1)中的遍历过程改成了读取数据并幅值给dstx的对应像素点的对应通道;因为有两张图片,所以实际上是按划分的区域把同样的过程执行了两遍。