Разница в отображении cv2 Mat - PullRequest
0 голосов
/ 06 ноября 2018

Почему существует разница при отображении всей матрицы Mat и матрицы в виде отдельных элементов?

cv::Point2f sour[4] = {Point(530,430), Point(670, 320), Point(870,430), Point(980, 320)};
cv::Point2f dest[4] = {Point(450,530), Point(450,420), Point(550,530), Point(550,420)};

cv::Mat hom(3, 3, CV_32F);
hom=getPerspectiveTransform(sour,dest);

cout << "hom: " <<hom << endl;

печать

hom: [0.4489795918367541, 1.122448979591883, -33.67346938776892;
  5.034167527284694e-15, 2.040816326530671, -68.48979591837563;
  1.505685767039244e-17, 0.001224489795918431, 1]

, а

for (int i1=0; i1<3; i1++){
    for (int i2=0; i2<3; i2++){
            cout << hom.at<float>(i1,i2) << " ";
        }
        cout <<endl;
    }

печать:

-1.32615e+23 1.72449 1.70011e-29 
0 0.0301113 -2.30304e-37 
0 0.0147314 -3.2706e+24 

1 Ответ

0 голосов
/ 06 ноября 2018

Я вижу вероятность того, что тип матрицы изменился с float на double после его присвоения (hom=getPerspectiveTransform(sour,dest);). Если это так, то CV_Assert(hom.type() == cv::DataType<float>::type); собирается сгенерировать исключение.

Чтобы решить эту проблему, необходимо обратиться к элементам матрицы по правильному типу, вероятно, double. Поэтому, когда вы печатаете матрицу, замените hom.at<float> на hom.at<double> и посмотрите, поможет ли это.

Кстати, я не вижу смысла сначала объявлять матрицу как cv::Mat hom(3, 3, CV_32F);. Вы можете, вероятно, напрямую сделать cv::Mat hom = getPerspectiveTransform(sour, dest);.

Другим решением этой проблемы является использование статически типизированной матрицы, то есть cv::Matx<float, 3, 3> hom = getPerspectiveTransform(sour, dest);. OpenCV автоматически преобразует значение, возвращаемое getPerspectiveTransform, в правильный тип в присваивании. Затем, когда вы печатаете элементы, вы можете заменить hom.at<float>(i1, i2) на hom(i1, i2), так как тип элемента теперь статически известен.

Обновление: Тот факт, что оператор <<, кажется, печатает элементы матрицы hom примерно с 16 десятичными цифрами, говорит о том, что точность равна double. Для одинарной точности (float) это было бы около 7 десятичных цифр.

...