Randel 0 Жалоба Опубликовано December 18, 2012 Добрый день! Может кто-нибудь прояснить ситуацию с обращением матрицы средствами OpenCV...Вот код: Mat VecT(2,1,CV_64F); Mat VecY(2,1,CV_64F); Mat MatSamp (2,2,CV_64F); Mat Covar,Mean,InvCovar; VecT.at<double>(0,0)=28.7; VecT.at<double>(1,0)=16.3; VecY.at<double>(0,0)=64.4; VecY.at<double>(1,0)=21.52; MatSamp.at<double>(0,0)=VecT.at<double>(0,0); MatSamp.at<double>(1,0)=VecT.at<double>(1,0); MatSamp.at<double>(0,1)=VecY.at<double>(0,0); MatSamp.at<double>(1,1)=VecY.at<double>(1,0); calcCovarMatrix(MatSamp,Covar,Mean,CV_COVAR_NORMAL+CV_COVAR_ROWS+CV_COVAR_SCALE); //Covar.at<double>(0,0)=38.44; //Covar.at<double>(0,1)=132.92; //Covar.at<double>(1,0)=132.92; //Covar.at<double>(1,1)=459.67; invert(Covar,InvCovar,DECOMP_SVD); double IC11=InvCovar.at<double>(0,0); double IC12=InvCovar.at<double>(0,1); double IC21=InvCovar.at<double>(1,0); double IC22=InvCovar.at<double>(1,1); Ковариационная матрица считается верно, это я проверял. Но вот ее обращение дает совершенно неправильный реультат (смотрю по IC11-IC22). То есть, единичной матрицы при перемножении Covar*InvCovar не получается. В то же время, если получившиеся значения ковариационной матрицы задать напрямую перед обращением (закомментированные строчки), то обратная матрица рассчитывается абсолютно верно. В чем может быть дело? Интуитивно мне кажется, что что-то не так с типами данных, но что - понять не могу. Подскажите, пожалуйста! *updated: Похоже, дело в том, что при количестве значащих знаков у double-чисел после запятой более трех - детерминант рассчитывается, как нулевой, то есть матрица начинает считаться сингулярной. До трех знаков - все в порядке. Грубо говоря, если подставлять округленные до целых значения - то все считается нормально... Что-то я совсем запутался Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано December 18, 2012 38.44 132.92 132.92 459.67 Это плохо обращаемая матрица, из за слабой главной диагонали. Смотрите какая чувствительность: A = 38.4400 132.9200 132.9200 459.6700 >> inv(A) ans = 231.1758 -66.8477 -66.8477 19.3321 Теперь добавим 0.01 ко всем элементам: A=A+0.01 A = 38.4500 132.9300 132.9300 459.6800 >> inv(A) ans = 106.6271 -30.8344 -30.8344 8.9188 Теперь усилим диагональ: A = 380.4400 132.9200 132.9200 459.6700 >> inv(A) ans = 0.0029 -0.0008 -0.0008 0.0024 Добавим 0.01 как и в прошлый раз >> inv(A+0.01) ans = 0.0029 -0.0008 -0.0008 0.0024 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Randel 0 Жалоба Опубликовано December 18, 2012 Ага... Я,главное, это же наблюдал, но выводы неправильные сделал! Спасибо за помощь! Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах