openCV中Mat类对象以深拷贝方式存放到容器中,避免造成数据混乱

您所在的位置:网站首页 计算机丢失opencv_core249dll openCV中Mat类对象以深拷贝方式存放到容器中,避免造成数据混乱

openCV中Mat类对象以深拷贝方式存放到容器中,避免造成数据混乱

2023-07-13 02:49| 来源: 网络整理| 查看: 265

首先拿到一张图片,通过split()函数把图像的RGB值分别拿出来存到到一个vector容器中,然后以灰度图像(即单通道)的形式分别输出R,G,B的值,再把R,G,B的值单独以彩色图像(三通道)的形式输出,达到下图的效果

 写出代码如下:

int main() { Mat image = imread("F:/cv/1.bmp"); imshow("原图像", image); std::vector mv;//存储分离后的管道 split(image, mv); // 管道分离 imshow("蓝色通道", mv[0]); imshow("绿色通道", mv[1]); imshow("红色通道", mv[2]); std::vector blue(mv); std::vector green(mv); std::vector red(mv); Mat dst;//存储输出图像 blue[1] = 0; blue[2] =0; merge(blue, dst); imshow("蓝色图像", dst); green[0] = 0; green[2] =0; merge(green, dst); imshow("绿色图像", dst); red[0] = 0; red[1] = 0; merge(red, dst); imshow("红色图像", dst); }

上述代码创建一个容器对象mv存储分离后的通道值,mv[0] -> 蓝色,mv[1] -> 绿色,mv[2] -> 红色.

如果要以彩色图像分别输出图像的B,G,R值,再创建三个容器对象,blue,green,red.(此处创建方式有问题),要拿到blue的蓝色值,就要把红和绿全部过滤,代码实现为 (blue[1] = 0;    blue[2] = 0;),同理单独拿到green的绿色值,red的红色值,之后通过merge()函数合并三个通道的值,输出,结果却出了问题

 输出的红色图像和绿色图像全为黑色,这是因为创建容器对象blue,green,red的时候出了问题

std::vector blue(mv); std::vector green(mv); std::vector red(mv);

        因为Mat类并不是像int一样,是系统自带的数据类型,所以这种创建方式会调用vector的默认拷贝构造,即浅拷贝。造成的结果就是这个三个容器对象数据完全共享,这三个对象都指向mv,所以第一次输出彩色图像时可以正常输出,但第二次输出绿色图像时,green[1]的值已经全被 blue[1]=0; 的操作全被改为了0,此时只有green[0]还正常存储图像的蓝色值,但是后面的代码把蓝色值也赋值为0,最终导致这三个矩阵green[0],green[1],green[2]都是0,然后就输出了纯黑图像,代码运行到red,自然也是纯黑。

所以我们要创建三个相互独立的容器对象blue,green,red,只需把原来用来创建的的三行代码替换为下面的内容:

std::vector blue;//蓝 for (const Mat& m : mv) { blue.push_back(m.clone()); } std::vector green; for (const Mat& m : mv)//绿 { green.push_back(m.clone()); } std::vector red;//红 for (const Mat& m : mv) { red.push_back(m.clone()); }

 此处使用枚举循环进行构造,参考此文:(4条消息) C++:枚举循环,全局作用域,子类调用父类函数,const类成员赋值_头发乌黑茂密的博客-CSDN博客

创建的每个容器对象,都是通过mv的克隆函数构造的,彼此相互独立(也可以使用copyTo函数),这样就可以达到我们的目的了。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3