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

时间:2019-06-20 17:13:43

标签: c++ casting eigen

我正在尝试使用Eigen与未签名的char *类型进行接口。我可以先转换为Eigen,然后再转换为float,但是当我转换回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;
}

数据是未签名的char *类型。

我希望gray_UC和数据相同,但事实并非如此。甚至更多,gray_array输出正确的float值,因此可能是对unsigned char的转换是错误的。

2 个答案:

答案 0 :(得分: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个字节,将使指针向前四个字节。接下来,您将其取消引用并将其强制转换为float(无论如何应该没有任何作用),因此您将在data所指向的floats缓冲区中获得第二个float值。

为了从gray_UC中获得相同的信息,您需要执行以下操作:

*(((float*) gray_UC) + 1)

答案 1 :(得分:0)

在@Nico Schertler的评论的启发下,这是一个对我有用的解决方案。我在for循环中进行转换。但是,我必须先使用数组,然后将第一个元素的地址提供给我的unsigned char *

将来,我应该考虑按照@Nico Schertler的链接中的建议尝试使用std::transform

请注意,我没有将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;