Обратная матрица OpenCV. Matrix.inv() не работает должным образом

У меня есть одна проблема, для которой я не мог найти никакого решения.

Мне нужно сделать некоторые вычисления с обратной одной известной матрицей.

Matrix homography=

1.1688, 0.23, 62.2,

-0.013,1.225, -6.29,

0, 0, 1, 

а потом:

Mat homoInv=homography.inv();

Содержимое матрицы будет таким:

1.81381e-29, 15.1628, -7.57361e+17, 

0, -0, 0, 

5.4561e-33, -2.40123e+34, -1.38198e-05

Это, конечно, неправильно, так как я уже проверил результат в Matlab. Обе матрицы отображаются и читаются как числа с плавающей запятой, а их глубина равна 64FC1.

Кто-нибудь знает, что можно сделать?

Спасибо всем

Больше кода:

int main(int argc, char ** argv )
{ 
  Mat homogra(3,3,CV_64FC1);
  Mat coord(3,1,CV_64FC1);
  Mat result(target.size(),CV_8UC1);
  homogra.at<float>(0,0)=1.1688;
  homogra.at<float>(0,1)=0.23;
  homogra.at<float>(0,2)=(-62.20);
  homogra.at<float>(1,0)=(-0.013);
  homogra.at<float>(1,1)=1.225;
  homogra.at<float>(1,2)=-6.29;
  homogra.at<float>(2,0)=0;
  homogra.at<float>(2,1)=0;
  homogra.at<float>(2,2)=1;
  printMatrix(homogra);

  Mat inverse=homogra.inv();
  printMatrix(inverse);
}

функция printMatrix:

void printMatrix(Mat M){
cout<<"Tipo de matriz:"<<M.type()<<endl;
 // dont print empty matrices
  if (M.empty()){
    cout << "---" << endl;
    return;
  }
  // loop through columns and rows of the matrix
  for(int i=0; i < M.rows; i++){
      for(int j=0; j < M.cols ; j++){
      cout << M.at<float>(i,j) << ", "<<endl;
      }
    cout<<"Change\n"<<endl;
}
  }

Но ошибка не в printMatrix, так как если я печатаю элементы отдельно, я получаю тот же странный результат в числах, обратных.


person Ivánovick    schedule 13.06.2012    source источник
comment
У вас где-то ошибка в коде. Если вам нужна дополнительная помощь, вам придется опубликовать больше кода.   -  person Peter    schedule 13.06.2012
comment
Вы уверены, что эта матрица обратима? Если нет, возможно, вместо этого Matlab вычисляет псевдоинверсию.   -  person Ian Medeiros    schedule 13.06.2012
comment
Это может быть поздно и бесполезно, но если вы сделаете std::cout << your_cv_mat << std::endl;, будет напечатана матрица. вам не нужна какая-либо функция, такая как printMatrix :)   -  person Bastienm    schedule 21.11.2017


Ответы (1)


Проблема была, как указал Питер, в моем коде. Я до сих пор не понимаю причину глубоко, но это похоже на:

Я обрабатывал данные CV_64F как числа с плавающей запятой, это ошибка, их нужно обрабатывать как двойные для записи значений и их чтения. (<double>)

Однако CV_32F можно рассматривать как число с плавающей запятой, доступ будет с <float>.

person Ivánovick    schedule 14.06.2012
comment
Это поможет понять почему. Я уверен, что Opencv использует этот тип для получения позиции в памяти. Для индекса (i,j) в 2D-массиве (при условии, что основная строка непрерывна) позиция в памяти обычно будет по индексу ( i * number_of_columns + j) * (sizeof_variable_type) от позиции начала данных. Индексация указателя C++ по умолчанию использует тип указателя, чтобы узнать количество байтов, которые нужно пропустить. Таким образом, если тип не соответствует ожидаемому, вы в конечном итоге присваиваете значения неправильному пространству памяти, как в вашем вопросе. Итог: ваш обратный расчет не соответствует ожидаемым данным. - person I L; 25.08.2016
comment
Число в типах CV_ — это количество битов. Вам нужно будет проверить, сколько бит float и double в вашей системе. Вы можете сделать это с помощью sizeof, который вернет количество байтов. Кстати, для небольших матриц известного размера следует использовать cv::Matx. Удобно было бы избежать этой проблемы, потому что тогда вы говорите cv::Matx<double, 3, 3> homography и легко получаете доступ к элементам с помощью homography(0, 0) = 1.1688; - person darda; 03.12.2020