opencv编程中错误提示:不存在从mat到cvmat适当的转换函数。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opencv编程中错误提示:不存在从mat到cvmat适当的转换函数。相关的知识,希望对你有一定的参考价值。
是在cvMat*到Mat形式转换过程中出现的,希望大侠能提出建设性的意见,cvMat*到Mat形式数据转换中不能直接转换,具体应该怎么转换才可以,用什么函数。急!!
参考技术A Mat x;&(cvMat)x就可以得到cvMat的指针了 参考技术B opencv中常见的与图像操作有关的数据容器有Mat,cvMat和IplImage,这三种类型都可以代表和显示图像,但是,Mat类型侧重于计算,数学性较高,openCV对Mat类型的计算也进行了优化。而CvMat和IplImage类型更侧重于“图像”,opencv对其中的图像操作(缩放、单通道提取、图像阈值操作等)进行了优化。在opencv2.0之前,opencv是完全用C实现的,但是,IplImage类型与CvMat类型的关系类似于面向对象中的继承关系。实际上,CvMat之上还有一个更抽象的基类----CvArr,这在源代码中会常见。
1. IplImage
opencv中的图像信息头,该结构体定义:
View Code
typedef struct _IplImage
int nSize;
int ID;
int nChannels;
int alphaChannel;
int depth;
char colorModel[4];
char channelSeq[4];
int dataOrder;
int origin;
int align;
int width;
int height;
struct _IplROI *roi;
struct _IplImage *maskROI;
void *imageId;
struct _IplTileInfo *tileInfo;
int imageSize;
char *imageData;
int widthStep;
int BorderMode[4];
int BorderConst[4];
char *imageDataOrigin;
IplImage;
dataOrder中的两个取值:交叉存取颜色通道是颜色数据排列将会是BGRBGR...的交错排列。分开的颜色通道是有几个颜色通道就分几个颜色平面存储。roi是IplROI结构体,该结构体包含了xOffset,yOffset,height,width,coi成员变量,其中xOffset,yOffset是x,y坐标,coi代表channel of interest(感兴趣的通道),非0的时候才有效。访问图像中的数据元素,分间接存储和直接存储,当图像元素为浮点型时,(uchar *) 改为 (float *):
View Code 参考技术C CvMat
首先,我们需要知道,第一,在OpenCV中没有向量(vector)结构。任何时候需要向量,都只需要一个列矩阵(如果需要一个转置或者共轭向量,则需要一个行矩阵)。第二,OpenCV矩阵的概念与我们在线性代数课上学习的概念相比,更抽象,尤其是矩阵的元素,并非只能取简单的数值类型,可以是多通道的值。
Mat
Mat是opencv2.0推出的处理图像的新的数据结构,现在越来越有趋势取代之前的cvMat和lplImage,相比之下Mat最大的好处就是能够更加方便的进行内存管理,不再需要程序员手动管理内存的释放。opencv2.3中提到Mat是一个多维的密集数据数组,可以用来处理向量和矩阵、图像、直方图等等常见的多维数据。 之前的图像一般都是用IplImage*表示
///////////////////////////////背景知识结束///////////////////////////////////////
这里是CvMat和Mat的互相转换公式,基本上是复制数据块。
CvMat -> Mat
Mat::Mat(const CvMat* m, bool copyData=false); /*类似IplImage -> Mat,可选择是否复制数据*/
Mat -> CvMat
例子(假设Mat类型的imgMat图像数据存在):
CvMat cvMat = imgMat;/*Mat -> CvMat, 类似转换到IplImage,不复制数据只创建矩阵头本回答被提问者和网友采纳
opencv 将数据从 *Mat 复制到 Mat
【中文标题】opencv 将数据从 *Mat 复制到 Mat【英文标题】:opencv copy data from a *Mat to a Mat 【发布时间】:2016-02-09 12:53:14 【问题描述】:我有两个cv::Mat
对象:
cv::Mat *frameLeftRemap;
cv::Mat frameLeft2;
数据从相机流入 *frameLeftRemap。我需要将数据复制到 frameLeft2,然后删除 frameLeftRemap,以避免我看到的帧伪影。 (这是相机制造商支持台建议的。)
功能是:
void ProcessImageLeft(AVT::VmbAPI::FramePtr pFrame)
VmbUchar_t *pBuffer;
VmbUint32_t FrameWidth;
VmbUint32_t FrameHeight;
//prepare frame information:
pFrame->GetWidth(FrameWidth);
pFrame->GetHeight(FrameHeight);
pFrame->GetImage(pBuffer);
//edited
Mat1b imageL(FrameHeight, FrameWidth, (uchar*)pBuffer);
cv::remap(imageL, *frameLeftRemap, mx1, my1, cv::INTER_LINEAR);
frameLeft2 = frameLeftRemap->clone();
//frameLeftRemap->copyTo(frameLeft2);
cv::imshow("right", frameLeft2);
cv::waitKey(1);
delete frameLeftRemap;
copyTo 和 clone 都报错:
this is nullPtr. read access violation
我在这里做错了什么?
【问题讨论】:
请发帖minimal reproducible example。正如已经指出的那样,如果您的图像仍然有效,这应该可以正常工作。此外,使用Mat*
通常是个坏主意,因为您可能会破坏内部引用计数(就像您在这里所做的那样)
你为什么还要使用IplImage
?请避免使用过时的 C api。请重构此代码以仅使用 Mat
。错误可能已经解决了
该部分是来自相机制造商的代码。我将如何将 *pBuffer 直接变成 Mat?谢谢。
Mat1b m(rows, cols, (uchar*)buffer, step)
另外,你应该交换FrameWidth
和FrameHeight
:Mat1b copyimageL(FrameHeight, FrameWidth, (uchar*)pBuffer);
【参考方案1】:
frameL= frameLeftRemap->clone();
应该可以正常工作。看来你在frameL
有问题。尝试使用cv::imshow
或cv::imwrite
显示它,以确保它在克隆之前已损坏。然后解决原来的问题。如果您发布代码,我们会为您提供更多帮助。
【讨论】:
以上是关于opencv编程中错误提示:不存在从mat到cvmat适当的转换函数。的主要内容,如果未能解决你的问题,请参考以下文章
OpenCV - Mat::convertTo() 断言错误。
opencv 报错:Error: Assertion failed (data) in cv::Mat::at, file ... mat.inl.hpp, line 897(访问了不存在矩阵的像素)