Opencv mat усекает все двойные записи

Я заселяю свой cv::Mat matrix(size, size, cv::DataType<double>::type); (пробовал также CV_64F а также CV_64FC1 все дают одинаковый результат). Я перебираю size и делает это: matrix.data[x*size+y] = someFunc(); где someFunc() возвращает двойное Проблема в том, что по какой-то причине матрица усекает двойное и хранит только целую часть. Для тестирования я создал следующий фрагмент

cv::Mat mat(10, 10,  CV_64F);
for (int i=0; i<10; ++i){
    for (int j=0; j<10; ++j){
        mat.data[i*10 + j] = 1.9;
        std::cout << double(mat.data[i*10+j]) << std::endl; // outputs 1
    }
}

Что я делаю неправильно? Как я должен заполнить cv::Mat() с двойниками правильно?

2 ответа

Решение

cv::Mat::data это указатель на unsigned char, При обращении к данным таким образом вы уделяете особое внимание, т. Е. Приводите их к удвоению, чтобы смещения, добавленные к ним, были правильными.

Рекомендуемый способ доступа / изменения элементов cv::Mat как следует:

cv::Mat mat( 10, 10, CV_64F );
mat.at<double>( y, x ) = 123.; // Careful y before x!

Когда вы заранее знаете тип ваших данных, вы можете использовать основанные на шаблонах cv::Mat_, который имеет несколько удобных typedefs, Вышеупомянутый случай может быть переписан в:

cv::Mat1d mat( 10, 10 ); // 1 - one channel, d - double
mat( y, x ) = 123.;

Если все элементы изначально установлены на одно и то же значение, вы также можете использовать;

double value = 1.9;
cv::Mat1d mat = value * cv::Mat1d::ones( 10, 10 );

но, конечно, двойной for-перехвата, как тот, который вы используете, тоже хорошо.

И просто еще раз подчеркнуть, будьте осторожны с порядком y- а также xкоординаты в (y,x)оператор доступа выше. У меня слишком много людей, которые делают это неправильно и тратят время на это.

Mat::data является unsigned char*, В вашем случае этого будет достаточно, чтобы double перед доступом к каждому элементу матрицы:

((double*)mat.data)[i*10 + j] = 1.9;

а также

std::cout << ((double*)mat.data)[i*10+j] << std::endl;

Обратите внимание, что это немного быстрее, чем при использовании Mat::at() сбруя.

Другие вопросы по тегам