矩阵乘法

7
我有一个问题可能适合初学者。我想在c ++中将一个20x2矩阵乘以一个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;
}

你知道如何手动完成吗?你是否在寻找其他方法而不是手动操作? - Falmarri
我可以问一下,你为什么需要这个乘法?只是好奇。 - Alexander Rafferty
9
也许你应该接受一些答案。 - GWW
嘿,大家好,我想要进行乘法运算,我知道如何手动计算,但在编程方面不太擅长。 - Mario
4
请发布产生此错误的代码。 - Charles Salvia
3个回答

5
与OpenCV文档中的示例相比,您似乎忘记初始化输出矩阵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)cvMatMulAdd(&Ma, &Mb, 0, &Mc)是相同的。

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);
}

-3
也许你应该发布你正在调用的函数的原型,以及你矩阵的声明和调用。我认为并不是每个人都熟悉openCV。

1
看起来你需要创建输出矩阵。在你的例子中,将Mc的声明从CvMat改为CvMat*并进行初始化:CvMat *Mc = cvCreateMat(2, 2, CV_32FC1); 我认为这样会起作用。编译器无法捕获未初始化的数组,因为静态类型检查将通过。 - Virtually Real

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接