2010-12-17 7 views
7

초보자를위한 질문이 있습니다.매트릭스 곱셈

20x2 행렬에 C++의 2x2 행렬을 곱하려고합니다.

내가 OpenCV의 그것을 시도했지만 내가 오류를 얻을 수

다음


cvarrToMat에서

잘못된 인수 (알 수없는 배열 타입) 내가에서 OpenCV의에 사용 된 코드는

내 코드 또는 openCV의 문제가있는 경우 문제를 확인하기 위해 주문했지만 오류가 발생하여 컴파일 할 수 있지만 코드를 테스트 할 때 "잘못된 인수 (알 수없는 배열 유형)가 cvarrToMat에 있습니다. "

#include <stdio.h> 
#include <stdlib.h> 
//#include "/usr/include/opencv/cv.h" 
#include <cv.h> 
#include <cvaux.h> 
#include <highgui.h> 
#include <math.h> 
#include <iostream> 

    int main() 
{ 


double a[] = {1, 2, 3, 4}; 
CvMat Ma; 
cvInitMatHeader(&Ma, 2, 2, CV_32FC1, a); 


double b[] ={0, -1, 1, 0}; 

CvMat Mb; 
cvInitMatHeader(&Mb, 2, 2, CV_32FC1, b); 

CvMat Mc; 
CvMat Mc1; 
cvMatMul(&Ma, &Mb, &Mc); 

return 0; 
} 
+0

손으로하는 법을 알고 있습니까? 손으로가 아닌 다른 방법을 찾고 있습니까? – Falmarri

+0

내가 왜이 곱셈을 필요로하는지 질문 할 수 있습니까? 그냥 궁금해서. –

+9

아마도 답을 받아 들여야합니다. – GWW

답변

-3

전화를 걸고있는 함수의 프로토 타입은 물론 행렬 및 호출의 선언을 게시해야 할 수도 있습니다. 나는 모든 사람들이 openCV에 익숙하다고 생각하지 않는다.

+1

출력 매트릭스를 만들어야합니다. 귀하의 예에서 Mc의 선언을 CvMat에서 CvMat *로 변경하고 초기화하십시오. CvMat * Mc = cvCreateMat (2, 2, CV_32FC1); 나는 이것이 효과가있을 것이라고 생각한다. 정적 형식 검사가 통과하므로 컴파일러에서 초기화되지 않은 배열을 catch 할 수 없습니다. –

4

음. 이 질문에 대한 대답은 실제로 몇 가지 사항에 달려 있습니다. 당신은 이것을 손으로하는 법을 알고 있다고 말했 읍니다. 코드에서 이것을하기 위해서는 행렬을 나타내는 방법에 달려 있습니다. 이제 이것이 일회성이고 그것에 대한 해답이 필요하다면, 이것을 위해 만들어진 MATLAB과 같은 언어를 제안 할 것입니다. 이 프로그램이 더 큰 프로그램의 일부이고 효율적이어야하는 많은 행렬 곱셈을 수행하는 경우 boost::ublas과 같은 고품질 최적화 라이브러리를 사용하는 것이 좋습니다.

일회성이고 C++에서 실제로하고 싶다면 ublas와 같은 타사 라이브러리를 사용하는 방법을 정말로 원하지도/모르는 경우 (최적화되지 않은) 행렬 곱셈은 다음과 같이됩니다. 다음

template<typename T> 
struct matrix2d 
{ 
private: 
    std::vector<std::vector<T>> data; 
    size_t _rows, _columns; 
public: 
    matrix2d(size_t rows, size_t columns) 
     :_rows(rows) 
     ,_columns(columns) 
    { 
     data.resize(_rows, std::vector<T>(_columns)); 
    } 

    size_t rows() const { return _rows; } 
    size_t columns() const { return _columns; } 

    T& operator()(size_t row, size_t column) 
    { 
     return data[row][column]; 
    } 

    const T& operator()(size_t row, size_t column) const 
    { 
     return data[row][column]; 
    } 
}; 

template<typename T> 
void mmult(const matrix2d<T>& m1, const matrix2d<T>&m2, matrix2d<T>& result) 
{ 
    for (size_t r = 0 ; r<m1.rows() ; ++r) 
     for (size_t c = 0; c<m2.columns() ; ++c) 
      for (size_t n = 0; n<m1.columns() ; ++n) 
       result(r, c) = m1(r, n) * m2(n, c); 
} 


int main() 
{ 

    matrix2d<double> m1(20, 2); 
    matrix2d<double> m2(2, 2); 
    matrix2d<double> result(m1.rows(), m2.columns()); 
    mmult(m1, m2, result); 
} 
5

example in the OpenCV docs과 코드를 비교, 당신이 출력 매트릭스 Mc 초기화하는 것을 잊었다 것으로 보인다 : 워드 프로세서에 따르면

double a[] = { 1, 2, 3, 4, 
       5, 6, 7, 8, 
       9, 10, 11, 12 }; 

double b[] = { 1, 5, 9, 
       2, 6, 10, 
       3, 7, 11, 
       4, 8, 12 }; 

double c[9]; 
CvMat Ma, Mb, Mc ; 

cvInitMatHeader(&Ma, 3, 4, CV_64FC1, a); 
cvInitMatHeader(&Mb, 4, 3, CV_64FC1, b); 
cvInitMatHeader(&Mc, 3, 3, CV_64FC1, c); 

cvMatMulAdd(&Ma, &Mb, 0, &Mc); 
// the c array now contains the product of a (3x4) and b (4x3) 

cvMatMul(&Ma, &Mb, &Mc)는과 동일.