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()
сбруя.