Выполнение простых обратных операций и операций умножения над матрицами Mat

Я обнаружил ряд точек из 2 изображений. Я пытаюсь найти матрицу преобразования между этими двумя изображениями. Поэтому мне нужно сделать обратную матрицу координат одной матрицы, а затем умножить ее на координаты другой матрицы Mat. Я использовал очень простые методы opencv, но получаю эту ошибку http://i.imgur.com/eDF1e9p.jpg< /а>. Я не понимаю почему. Вот мой код http://pastebin.com/Tef42E2Q. Может ли кто-нибудь направить меня сюда, пожалуйста?


person Steph    schedule 04.02.2014    source источник


Ответы (1)


Вы должны убедиться, по крайней мере, в двух вещах, прежде чем мат инвертировать.

  1. Матрица должна быть квадратной.

  2. Матрица должна быть невырожденной, то есть определитель должен быть ненулевым.

Например:

    Mat A(3,3,CV_32FC1);
    A=(Mat_<float>(3,3)<< 0,2,3,\
                          4,5,6,\
                          7,8,9);
    cout<<A <<endl;

    if(determinant(A)!=0){
    Mat B=A.inv();
    cout<<B <<endl;
    }

Также см. ответ Mat.inv(), дающий все нули в opencv

Изменить:-

Вот ошибка, которую я нашел в вашем коде

Кусок кода

    Mat matrix_f(2,3,CV_32F);
    matrix_f=Mat(coordinates_f);

следует изменить на

    Mat matrix_f(2,3,CV_32F);
    matrix_f=Mat(coordinates_f);
    matrix_f=matrix_f.reshape(1,2);

потому что позже вы собираетесь умножать с ковриком 3X3, поэтому мы сделаем его ряды до 3

А дальше меняем строчки

    Mat new_left(3,3,CV_32F);
    new_left=Mat(coordinates_l_new);

to

      Mat new_left(3,3,CV_32F);
      new_left=Mat(coordinates_l_new);
      new_left=new_left.reshape(1,3);

поскольку вы собираетесь найти инверсию new_left, это должна быть квадратная матрица.

И, наконец, убедитесь, что мат неособый, найдя определитель

 if(determinant(new_left)!=0) {
        Mat T(3,3,CV_32F);
        T=matrix_f * (new_left.inv());
  } 
person Haris    schedule 04.02.2014
comment
ваш фрагмент кода работает отлично, если я вручную ввожу элементы матрицы A. Но моя проблема в том, что когда я беру матрицу, найденную ранее в коде, я не могу найти ее обратную и не могу выполнить с ней умножение , выдавая мне ошибку выше - person Steph; 04.02.2014
comment
Можете ли вы показать свой полный код?... В ссылке, которую вы указали в своем вопросе, вы можете использовать код Mat T=matrix_f * (new_left.inv());, посмотрите, работает ли он. - person Haris; 04.02.2014
comment
Если вы опубликуете свое изображение, это поможет мне отладить ваш код - person Haris; 04.02.2014
comment
Хорошо, спасибо! Еще одна вещь ... когда я применяю эту матрицу преобразования к исходному левому изображению, и когда я пытаюсь его отобразить, оно показывает желтое изображение с обнаруженными зелеными пикселями. Я добавил эту часть в оператор if: Mat left_transformed=Mat::zeros(left.size(),left.type()); left_transformed=left.mul(T); imshow(left_trans,left_transformed); Почему преобразованное левое изображение отображается неправильно? - person Steph; 04.02.2014
comment
Для Mat::mul оба Mat должны быть одного типа и размера См. Документ OpenCV - person Haris; 05.02.2014
comment
хорошо!! Я пытался применить матрицу преобразования ко всему изображению, чтобы оно стало таким, как i.imgur .com/DXxKu5V.jpg. Но после просмотра документа opencv это невозможно. Есть ли у вас какие-либо предложения? Поскольку я также пробовал affineTransform, это не сработало: с - person Steph; 05.02.2014
comment
Вы можете применить affinTransfor со своим собственным матом, например Mat warp_dst = Mat::zeros( front.rows, front.cols, front.type() ); warpAffine( front, warp_dst, T, warp_dst.size() ); imshow("warp_dst",warp_dst); - person Haris; 05.02.2014
comment
это именно то, что я сделал, но я получаю это сообщение об ошибке i.imgur.com/DXxKu5V.jpg - person Steph; 05.02.2014
comment
давайте продолжим это обсуждение в чате - person Haris; 05.02.2014