为 const 数据创建 cv::Mat 标头
Posted
技术标签:
【中文标题】为 const 数据创建 cv::Mat 标头【英文标题】:Create cv::Mat header for const data 【发布时间】:2011-04-13 19:40:44 【问题描述】:通常,如果我的数据是非常量的,我可以在它上面初始化一个 cv::Mat 标头以进行代数操作。
float awesome_data[24] = 0;
cv::Mat awesome_mat = cv::Mat(6, 4, CV_32F, awesome_data);
但是,如果我的数据是 const
const float awesome_data[24] = 0;
cv::Mat awesome_mat = cv::Mat(6, 4, CV_32F, awesome_data);
会有错误:unable to convert from const void * to void *
。我知道我不会更改 awesome_mat,最好的方法是什么?
目前,我必须做一个 const cast
const float awesome_data[24] = 0;
cv::Mat awesome_mat = cv::Mat(6, 4, CV_32F, const_cast<float *>(awesome_data));
【问题讨论】:
你想达到什么目的? 如果对象是 cv::Mat,我可以执行任何线性代数、图像处理等操作。我不能用它做什么? :-) 我不是那个意思。 const_cast 有效 - 还有其他您想要或期望的东西吗? @fazo:一点也不。 const_cast 在语义上是错误的。通过抛弃 constness,您移除了防止您意外更改数据的保护层。 没有 cv::Mat 构造函数可以让你传递一个 const 指针,所以不,这是不可能的。也没有特殊的 const_Mat... 【参考方案1】:cv::Mat
中的数据随时可以修改。为了更安全,您应该复制数据:
const float awesome_data[24] = 0;
cv::Mat awesome_mat = cv::Mat(6, 4, CV_32F, const_cast<float *>(awesome_data)).clone();
对于const cv::Mat
,只有矩阵标题是只读的,而不是数据(Differences of using "const cv::Mat &", "cv::Mat &", "cv::Mat" or "const cv::Mat" as function parameters?):
const cv::Mat mat = cv::Mat::zeros(6, 4, CV_32F);
mat += 1; // compiles and runs fine!
【讨论】:
【参考方案2】:完全安全地执行此操作的唯一方法是复制awesome_data
(一种或另一种方式)。 @R1tschY 的 solution 使用 OpenCV 方法复制数据,该方法本身需要 const_cast
。为了完全避免const_cast
,应该将内存复制到 OpenCV 之外(因为 OpenCV 不尊重 const 数据)。这是一种方式:
const float awesome_data[24] = 0;
cv::Mat awesome_mat = cv::Mat(6, 4, CV_32F); //Allocates its own memory
memcpy(awesome_mat.data, awesome_data, 24*sizeof(float)); //Copy into the allocated memory.
【讨论】:
【参考方案3】:据我所知,OpenCV 没有 const_Mat 类。但是,通过使用
const float awesome_data[24] = 0;
const cv::Mat awesome_mat = cv::Mat(6, 4, CV_32F, const_cast<float *>(awesome_data));
你保持不变。
【讨论】:
您的帖子似乎与@R1tschY 的帖子(以及我的经验)不一致。您能否评论一下您的意思是什么“恒定性”,以免混淆任何人? 我认为这是个坏建议。使用此解决方案,下一行可能会修改 awsome_data 本身。这不是任何有意义的 const 数据。以上是关于为 const 数据创建 cv::Mat 标头的主要内容,如果未能解决你的问题,请参考以下文章
如何使用模板函数从缓冲区(T* 数据数组)创建 cv::Mat?