OpenCV逆矩阵

时间:2016-02-17 15:16:02

标签: python opencv matrix

不知怎的,我使用numpy的linalg.inv和OpenCv的Mat::inv获得了不同的结果,例如给定矩阵S

[747.8561839552103, 359.9317804054358, 204.6165451419812, 241.7376332155144, 126.132733370211, 81.57610562583466;
  359.9317804054358, 204.6165451419812, 140.4788277943211, 126.132733370211, 80.55127348381332, 47.7506303038364;
  204.6165451419812, 140.4788277943211, 116.7472083846913, 80.55127348381332, 63.86033402962857, 35.56970826526131;
  241.7376332155144, 126.132733370211, 80.55127348381332, 81.57610562583466, 47.7506303038364, 29.55106507912703;
  126.132733370211, 80.55127348381332, 63.86033402962857, 47.7506303038364, 35.56970826526131, 20.31193086803655;
  81.57610562583466, 47.7506303038364, 35.56970826526131, 29.55106507912703, 20.31193086803655, 12]

OpenCV S.inv()导致

[-19562262532715.65, 137.3094415699439, -44015090698406.93, 78249050130618.84, 88030181396160.73, -78249050129617.47;
 124.2797501878658, 19.14093204142484, 301.2737811201993, -531.0713785028685, -686.3332686269306, 655.5356524828615;
 -44015090698424.45, 330.6065529853437, -99033954070961.39, 176060362793110.9, 198067908140346.2, -176060362790691.7;
 78249050130642.06, -583.2397919514979, 176060362793093.2, -312996200521532.5, -352120725583424.9, 312996200517305.3;
 88030181396256.19, -744.9706630355842, 198067908140482.2, -352120725583702.1, -396135816277430.2, 352120725578288.9;
 -78249050129732.52, 707.7008280168318, -176060362790880.5, 312996200517672.6, 352120725578424.8, -312996200512573.6]

numpy的linalg.inv导致:

[[2685109332201.37, -23.46, 6041495997420.42, -10740437328763.82, -12082991994731.51, 10740437328597.41]
 [-32.56, 19.14, -51.60, 96.23, 19.43, 28.24]
 [6041495997407.60, -31.13, 13593365994129.85, -24165983989574.97, -27186731988120.73, 24165983989366.80]
 [-10740437328747.65, 59.84, -24165983989589.86, 42961749314884.59, 48331967978891.43, -42961749314440.71]
 [-12082991994663.29, -21.50, -27186731988024.93, 48331967978691.32, 54373463976152.90, -48331967978849.60]
 [10740437328516.33, 64.62, 24165983989235.66, -42961749314181.06, -48331967978757.62, 42961749314608.99]]

好的,现在我偶然发现了一些细节: 我正在研究一个例程,在给定点集的情况下拟合椭圆;我已将代码从http://nicky.vanforeest.com/misc/fitEllipse/fitEllipse.html转移到C ++:

  template <typename InputIt>                                                     
  std::array<double, 6> fit_ellipse(InputIt first, InputIt last) {                
       typedef double value_type;                                                  

       auto num_points = std::distance(first, last);                               

       cv::Mat_<value_type> D(num_points, 6);                                      
       size_t row(0);                                                              
       for (auto it(first); it != last; ++it, ++row) {                             
           auto &point = *it;                                                      
           auto &x = std::get<0>(point);                                           
           auto &y = std::get<1>(point);                                           
           D(row, 0) = x * x;                                                      
           D(row, 1) = x * y;                                                      
           D(row, 2) = y * y;                                                      
           D(row, 3) = x;                                                          
           D(row, 4) = y;                                                          
           D(row, 5) = 1.f;                                                        
       }                                                                           

       auto S = D.t() * D;                                                         

       cv::Mat_<value_type> C = cv::Mat_<value_type>::zeros(6, 6);                 
       C(0, 2) = C(2, 0) = 2; C(1, 1) = -1;                                        

       cv::Mat Sinv = S.inv();                                                     
       std::cout << "Sinv:" << Sinv << std::endl;                      
       cv::Mat_<value_type> E, V; cv::eigen(Sinv * C, E, V);                       
       int n;                                                                      
       cv::minMaxIdx(cv::abs(E), nullptr, nullptr, nullptr, &n);                   

       return {{V(n, 0), V(n, 1), V(n, 2), V(n, 3), V(n, 4), V(n, 5)}};            
   }

比较Python代码:

import numpy as np
from numpy.linalg import eig, inv

def fitEllipse(x,y):
    x = x[:,np.newaxis]
    y = y[:,np.newaxis]
    D =  np.hstack((x*x, x*y, y*y, x, y, np.ones_like(x)))
    S = np.dot(D.T,D)
    C = np.zeros([6,6])
    C[0,2] = C[2,0] = 2; C[1,1] = -1
    Sinv = inv(S)
    print("Sinv: %s" % Sinv)
    E, V = eig(np.dot(Sinv, C))
    n = np.argmax(np.abs(E))
    a = V[:,n]
    return a

代码运行初始化以下几点:

TEST(fit_ellipse, test_example) {
    namespace bmc = boost::math::constants;

    typedef std::array<double, 2> point_type;
    std::vector<point_type> points;

    auto arc = .8;
    for (size_t i(0); i < 12; ++i) {
        auto r = i * arc * bmc::pi<double>() / 12;
        points.push_back({1.5 * std::cos(r) + 2, std::sin(r) + 1});
    }
    auto a = fit_ellipse(points.begin(), points.end());
    std::cout << "Parameters: "
    for (auto &p : a)
        std::cout << p << ' ';
    std::cout << std::endl;
}

在Python中相同:

R = np.arange(0, arc * np.pi, arc * np.pi / 12)
x = 1.5 * np.cos(R) + 2
y = np.sin(R) + 1.
print("Parameters: %s" % fitEllipse(x,y))

任何想法我错过了什么?

0 个答案:

没有答案