Преобразование собственной матрицы в беззнаковый символ * - PullRequest
1 голос
/ 20 июня 2019

Я пытаюсь использовать Eigen для взаимодействия с неподписанными типами char *.Я могу конвертировать в Eigen, а затем плавать, но когда я конвертирую обратно в 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 печатает правильное значение с плавающей запятой, так что это может быть неправильное преобразование в unsigned char.

Ответы [ 2 ]

1 голос
/ 20 июня 2019

Когда вы делаете:

(float)*(gray_UC+1)

Вы берете указатель gray_UC и добавляете его в соответствии с арифметикой указателя .Если unsigned char является одним байтом, это означает, что только один байт после gray_UC.Затем вы разыменовываете это, получая следующий байт как unsigned char, а затем приводите это значение к float.Я полагаю, что результатом должно быть число с плавающей точкой от 0 до 255.

Здесь:

(float)*(data+1)

Вы берете указатель data и увеличиваете его на единицу, но в этом случаеэто указатель на float, который, будучи 4 байтами, будет брать указатель на четыре байта вперед.Затем вы разыменовываете это и приводите его к float (который не должен иметь никакого эффекта), так что вы получаете второе значение float в буфере float, на которое указывает data.

Для того, чтобы получить то же самое отgray_UC, вы бы сделали что-то вроде:

*(((float*) gray_UC) + 1)
0 голосов
/ 03 июля 2019

Вот решение, которое работает для меня, вдохновленное комментариями @Nico Schertler. Я делаю бросок в течение цикла. Однако сначала мне пришлось использовать массив, а затем передать адрес первого элемента моему 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;
...