OpenCV矩阵与Eigen矩阵相互转换
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV矩阵与Eigen矩阵相互转换相关的知识,希望对你有一定的参考价值。
参考技术A OpenCV 矩阵结构为: cv::Mat ,或者 cv::Mat_ 等,当需要与 Eigen 的矩阵结构相互转换时主要使用函数:cv::eigen2cv 和 cv::cv2eigen ,需要头文件:
#include<opencv2/core/eigen.hpp>
包含头文件(顺序不能错!!!先包含eigen相关库,再包含opencv库!)
备注:经笔者实验,该转换存在矩阵精度损失的问题,具体是由于什么原因造成的,待查更新。
更详细的相关内容参看这篇博客: eigen与opencv矩阵转换,eigen与matlab函数比照
将特征矩阵转换为无符号字符 *
【中文标题】将特征矩阵转换为无符号字符 *【英文标题】:Converting Eigen matrix to unsigned char * 【发布时间】:2019-06-20 17:13:43 【问题描述】:我正在尝试使用 Eigen 与 unsigned char * 类型进行交互。我可以转换为 Eigen,然后再转换为浮点数,但是当我转换回 unsigned char 时,结果是错误的。 我需要 Eigen 矩阵为浮点类型,以便可以对其执行算术运算。然后我需要把它带回 unsigned char 以便我可以保存它。
#include <Eigen/Dense>
#include <iostream>
int main()
unsigned char* data;
for (int i=0;i<9;++i)
data[i]= i;
//Map data to Eigen
Map<Matrix<unsigned char,3,3> ,RowMajor> img(data,3,3);
//Convert to float
MatrixXf gray = img.cast<float>();
//Convert back to unsigned char*
float *gray_array = gray.data();
unsigned char *gray_UC = (unsigned char*)gray_array;
std::cout<<"Eigen matrix converted to unsigned char:"<<(float)*(gray_UC+1)<<std::endl;
std::cout<<"Eigen matrix as float: "<<*(gray_array+i)<<std::endl;
std::cout<<"Original data converted to float: "<<(float)*(data+1)<<std::endl;
数据是 unsigned char* 类型。
我希望 gray_UC 和 data 相同,但事实并非如此。更重要的是,gray_array 打印了正确的浮点值,所以可能是转换为 unsigned char 是错误的。
【问题讨论】:
我无法复制并粘贴提供的代码并对其进行编译。它不是独立的。 minimal reproducible example 在这里会很有帮助。问题可能是指针别名。提供的演员阵容相当可疑。 强制转换数组不会强制转换条目。见this question。或者干脆使用 Eigen 的cast
方法返回。但您可能希望自定义转换包含舍入。
【参考方案1】:
当你这样做时:
(float)*(gray_UC+1)
您正在获取指针gray_UC
并根据pointer arithmetic 向其添加一个。如果unsigned char
是一个字节,则意味着在gray_UC
之后只有一个字节。然后你取消引用它,将下一个字节作为unsigned char
,然后将该值转换为float
。我认为结果应该是 0 到 255 之间的浮点数。
这里:
(float)*(data+1)
您将指针data
加1,但在本例中是指向float
的指针,它是4 个字节,会将指针向前4 个字节。接下来,您取消引用并将其强制转换为浮点数(无论如何都不应该有任何影响),因此您将获得 data
指向的浮点缓冲区中的第二个浮点值。
为了从gray_UC
获得相同的结果,您可以执行以下操作:
*(((float*) gray_UC) + 1)
【讨论】:
我不明白为什么(float)*(gray_UC+1)
会给出错误的结果。 gray_UC+1
是下一个字节的地址,然后转换为浮点数。它应该给出正确的结果,除非gray_UC
从一开始就错了
@Bubble float
值占用四个字节。如果您将gray_UC+1
解释为float
指针,您将获得一个float
值的三个字节和下一个值的一个字节,这不会产生任何有意义的结果。【参考方案2】:
这是一个适合我的解决方案,灵感来自@Nico Schertler 的评论。我在 for 循环中进行强制转换。但是我必须先使用一个数组,然后将第一个元素的地址提供给我的unsigned char *
。
将来我应该考虑尝试std::transform
@Nico Schertler 的链接中的建议。
请注意,我没有将 Eigen 数组直接转换为 unsigned char,因为我的实际应用程序正在使用一个大数组。当我尝试它时,我得到了一个与内存问题有关的错误。
这是我的解决方案:
unsigned char gray_UC_tmp[size];
for (int i=0; i<9;++i)
gray_UC_tmp[i] = static_cast<unsigned char> (gray_array[i]);
gray_UC = gray_UC_tmp;
【讨论】:
以上是关于OpenCV矩阵与Eigen矩阵相互转换的主要内容,如果未能解决你的问题,请参考以下文章