OpenCV常见问题汇总
1、深度拷贝的问题
我对整张图像通过裁剪分别进行识别,出现识别结果与期望不同的问题,经过大量排查是OpenCV深度拷贝问题,我原来有问题的写法
cv::Mat matCrop = matZoom(roi);
cv::Mat matCrop1= matCrop(roi1);
cv::Mat matCrop2= matCrop(roi2);
InferOnnx(matCropR1);
InferOnnx(matCropR2);
经过深度拷贝没有问题的写法
cv::Mat matCrop = matZoom(roi);
cv::Mat matCrop1= matCrop(roi1);
cv::Mat matCrop2= matCrop(roi2);
cv::Mat matCropClone1=matCrop1.clone();
cv::Mat matCropClone2=matCrop2.clone();
InferOnnx1(matCropClone1);
InferOnnx1(matCropClone2);
问题分析:
在需要独立操作数据时,务必使用深拷贝(`clone()`或`copyTo()`),以避免意外的修改。- 浅拷贝效率高,因为不复制数据,但需要注意共享数据带来的副作用。- `copyTo()`方法还可以配合掩码使用,例如:`A.copyTo(B, mask);` 其中`mask`是一个二值图像,指定要复制的区域。
在 OpenCV 的 C++ 接口中,cv::Mat
是核心数据结构,用于存储图像和矩阵数据。复制 Mat
对象时需注意浅拷贝(共享数据)和深拷贝(独立数据)的区别。
浅拷贝 (Shallow Copy)
仅复制矩阵头(尺寸、类型等元数据),共享底层数据,修改副本会影响原矩阵
cv::Mat src = imread("image.jpg"); // 原始矩阵
cv::Mat shallowCopy1 = src; // 赋值操作(浅拷贝)
cv::Mat shallowCopy2(src); // 构造函数(浅拷贝)
深拷贝 (Deep Copy)
复制矩阵头 并创建独立的数据副本,修改副本不影响原矩阵
cv::Mat deepCopy1 = src.clone(); // 推荐方式
或者
cv::Mat deepCopy2;
src.copyTo(deepCopy2); // 复制到目标矩阵