Создание изображения cv :: Mat из двумерного массива - PullRequest
0 голосов
/ 08 апреля 2020

Когда я загружаю 3d-массив short int из двоичного файла, я хочу извлечь из него 2d-массив и отобразить изображение из 2d-массива в виде cv :: Mat. Я получаю сообщение о нарушении прав доступа по адресу 0x0000002DABD00000. Я видел похожие темы, но ни одна из них не помогла мне решить мою проблему. У меня заканчиваются идеи, как это исправить.

ifstream input("short.bin",ios::binary);

    input.read((char*)&X, sizeof(short));           //X - cols
    input.read((char*)&Y, sizeof(short));           //Y - rows
    input.read((char*)&Z, sizeof(short));           //Z 

    vector<vector<vector<short int>>>Array3D(X, vector<vector<short int>>(Y, vector<short int>(Z)));    
    vector<vector<short int>> Array2D(X, vector<short int>(Y));                             

    for (int i = 0; i < Z;i++)                          
    {
        for (int j = 0; j < Y; j++)
        {
            for (int k = 0; k < X; k++)
                input.read((char*)&Array3D[k][j][i],sizeof(Array3D[0][0][0]));
        }
    }

    input.close();

    for (int i = 0; i < X; i++)         
    {
        for (int j = 0; j < Y; j++)
            Array2D[i][j] = Array3D[i][j][0];
    }

    Mat image(X ,Y , CV_16U, &Array2D); 
    namedWindow("Obraz",WINDOW_AUTOSIZE);
    imshow("Obraz", image);
    waitKey(-1);

Ответы [ 2 ]

0 голосов
/ 09 апреля 2020

Я нашел (с некоторой помощью, если честно) другое решение этой проблемы. Проверьте код ниже. Может быть, это кому-нибудь поможет :)

ifstream input("short.bin", ios::binary);

    char* buff = (char*)malloc(312 * 45 * 248 *sizeof(ushort));
    input.read(buff, 3*sizeof(ushort));
    if (input) std::cout << "OK" << std::endl;
    input.read(buff, 312 * 45 * 248 * sizeof(ushort));
    if (input) std::cout << "OK" << std::endl;
    cv::Mat_<cv::Vec<ushort, 248>> hs(312, 45, (cv::Vec<ushort, 248>*)buff, 45 * 248);
    //hs(3,5)[120]
    std::vector<cv::Mat> vec;
    cv::split(hs, vec);
    free(buff);
    cv::Mat tmp;
    vec[120].convertTo(tmp, CV_8UC1, 1.0 / 256);
    cv::imshow("test", tmp);
    cv::waitKey();
0 голосов
/ 08 апреля 2020

Это утверждение неверно

Mat image(X ,Y , CV_16U, &Array2D);

Выражение &Array2D является указателем на векторную переменную, а не указателем на векторные данные. И в любом случае данные, передаваемые в Mat, должны находиться в непрерывной памяти, но такой гарантии для памяти в Array2D нет. Так что этот подход смертельно ошибочен.

Чтобы сделать эту работу, вы должны создать одномерный вектор и вручную рассчитать смещения для элементов в векторе. Затем используйте метод data для доступа к содержимому вектора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...