将特征矩阵转换为 unsigned char *
Converting Eigen matrix to unsigned char *
我正在尝试使用 Eigen 与 unsigned char * 类型进行交互。我可以转换为 Eigen 然后再转换为 float,但是当我转换回 unsigned 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;
}
数据为 unsigned char* 类型。
我希望gray_UC和数据相同,但事实并非如此。更重要的是,gray_array 打印出正确的 float 值,因此可能是错误的转换为 unsigned char。
当你这样做时:
(float)*(gray_UC+1)
您正在取指针 gray_UC
并根据 pointer arithmetic 对其加一。如果 unsigned char
是一个字节,则表示 gray_UC
之后只有一个字节。然后你取消引用它,将下一个字节作为 unsigned char
,然后将该值转换为 float
。我推测结果应该是一个介于 0 和 255 之间的浮点数。
这里:
(float)*(data+1)
您将指针 data
加一,但在本例中是指向 float
的指针,它有 4 个字节,会使指针向前移动四个字节。接下来取消引用并将其转换为 float(无论如何都不应该有任何影响),因此您在 data
.
指向的 floats 缓冲区中获得第二个 float 值
为了从 gray_UC
获得相同的结果,您需要执行以下操作:
*(((float*) gray_UC) + 1)
这是一个对我有用的解决方案,灵感来自@Nico Schertler 的评论。我在 for 循环中进行转换。但是我必须先使用数组,然后将第一个元素的地址提供给我的 unsigned char *
.
将来我应该考虑尝试 std::transform
,正如@Nico Schertler 在 link 中所建议的那样。
请注意,我没有直接将 Eigen 数组转换为 unsigned char,因为我的实际应用程序使用的是大数组。当我尝试它时,我收到一个错误 linked 内存问题。
这是我的解决方案:
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;
我正在尝试使用 Eigen 与 unsigned char * 类型进行交互。我可以转换为 Eigen 然后再转换为 float,但是当我转换回 unsigned 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;
}
数据为 unsigned char* 类型。
我希望gray_UC和数据相同,但事实并非如此。更重要的是,gray_array 打印出正确的 float 值,因此可能是错误的转换为 unsigned char。
当你这样做时:
(float)*(gray_UC+1)
您正在取指针 gray_UC
并根据 pointer arithmetic 对其加一。如果 unsigned char
是一个字节,则表示 gray_UC
之后只有一个字节。然后你取消引用它,将下一个字节作为 unsigned char
,然后将该值转换为 float
。我推测结果应该是一个介于 0 和 255 之间的浮点数。
这里:
(float)*(data+1)
您将指针 data
加一,但在本例中是指向 float
的指针,它有 4 个字节,会使指针向前移动四个字节。接下来取消引用并将其转换为 float(无论如何都不应该有任何影响),因此您在 data
.
为了从 gray_UC
获得相同的结果,您需要执行以下操作:
*(((float*) gray_UC) + 1)
这是一个对我有用的解决方案,灵感来自@Nico Schertler 的评论。我在 for 循环中进行转换。但是我必须先使用数组,然后将第一个元素的地址提供给我的 unsigned char *
.
将来我应该考虑尝试 std::transform
,正如@Nico Schertler 在 link 中所建议的那样。
请注意,我没有直接将 Eigen 数组转换为 unsigned char,因为我的实际应用程序使用的是大数组。当我尝试它时,我收到一个错误 linked 内存问题。
这是我的解决方案:
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;