将特征矩阵转换为无符号字符 *

Posted

技术标签:

【中文标题】将特征矩阵转换为无符号字符 *【英文标题】: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;

【讨论】:

以上是关于将特征矩阵转换为无符号字符 *的主要内容,如果未能解决你的问题,请参考以下文章

将字符串转换为无符号字符 []

将 VARIANT 转换为无符号字符数组

如何将字符串转换为无符号字符数组 [关闭]

如何将带有尾随x的数字字符串转换为无符号数字列表

将 std::string 转换为无符号字符数组

将图像转换为无符号字符*