如何将 Mat A * B 相乘?

Posted

技术标签:

【中文标题】如何将 Mat A * B 相乘?【英文标题】:How to multiply Mat A * B? 【发布时间】:2017-08-07 19:06:55 【问题描述】:

我试图在不使用 multiply() 函数的情况下将两个 Mat 类型 A 和 B(灰度)相乘。 到目前为止,我开发了以下代码,但它不起作用。我检查了 multiply(A,B,AB) 函数,但下面的代码不起作用。

Mat A,B,AB, src;
float AB_yx;
src = imread("as.jpg", CV_LOAD_IMAGE_GRAYSCALE);
Sobel(src , A, CV_32FC1 , 1, 0, 3, BORDER_DEFAULT);
Sobel(src , B, CV_32FC1 , 0, 1, 3, BORDER_DEFAULT);
// multiply(A, B, AB); //worked
AB= src.clone();

for (int y = 0; y < A.rows; y++) 
    for (int x = 0; x < B.cols; x++) 
         AB_yx= 0;
         for (int y = 0; y < B.rows; y++) 
         // for (int k = 0; k < B.rows; k++) 

            AB.at<float>(y, x) = A.at<float>(y, x) * B.at<float>(y, x); //sturkmen's method
            //AB_yx = AB_yx + A.at<float>(y, k) * B.at<float>(k, x);//
        
        //AB.at<float>(y, x) = AB_yx; 
    





namedWindow("AB");
imshow("AB", AB);

问题 Visual Studio 给出的 abort() 已被调用

OpenCV Error: Assertion failed (((((sizeof(size_t)<<28)|0x8442211) >> ((DataType<_Tp>::depth) & ((1 << 3) - 1))*4) & 15) == elemSize1()) in cv::Mat::at, file d:\opencv\opencv\build\include\opencv2\core\mat.inl.hpp, line 957

【问题讨论】:

“下面的代码不起作用”你能说得更具体点吗? 你知道如何将矩阵相乘吗? 您编写的代码执行每个成员的乘法,而不是矩阵乘法。这完全是错误的算法。 您能向我们展示您的全部功能吗?这里有很多缺失的代码。 AB是怎么产生的? AB_yx 是什么?见***.com/help/mcve @komto909 问题仍然存在:您需要向我们提供完整的multiply() 功能。除非我们可以重现编译器中止,否则我们根本没有足够的信息来帮助您。 【参考方案1】:

这是为了改进概念

    Mat A = (Mat_<float>(3, 4) << 1, 2, 3, 4, 5, 6, 7, 8, 9, 0.1, 0.1, 0.3);
    Mat B = (Mat_<float>(3, 4) << 1, 2, 3, 4, 5, 6, 7, 8, 9, 0.1, 0.1, 0.3);

    Mat AB0;
    multiply(A, B, AB0);
    cout << A << endl;
    cout << B << endl;
    cout << AB0 << endl;
    Mat AB1 = Mat(A.size(), CV_32FC1);

        for (int x = 0; x < B.cols; x++)
        
            for (int y = 0; y < B.rows; y++)
            
                AB1.at<float>(y, x) = A.at<float>(y, x) * B.at<float>(y, x);
            
        

    cout << AB1 << endl;

这应该对你有用

Mat A, B, AB, src;
src = imread("as.jpg", CV_LOAD_IMAGE_GRAYSCALE);
Sobel(src, A, CV_32FC1, 1, 0, 3, BORDER_DEFAULT);
Sobel(src, B, CV_32FC1, 0, 1, 3, BORDER_DEFAULT);

AB = Mat(A.size(), CV_32FC1);

for (int x = 0; x < B.cols; x++)

    for (int y = 0; y < B.rows; y++)
    
        AB.at<float>(y, x) = A.at<float>(y, x) * B.at<float>(y, x);
    



namedWindow("AB");
imshow("AB", AB);
waitKey();

但请记住,此代码运行缓慢。你需要使用指针来加快进程

【讨论】:

Visual Studio 给出的同样问题 abort() 已被调用 我尝试了你的最终代码,它可以工作,我得到了输出,但我仍然遇到这个问题 abort() 已被调用 我更新了代码。我尝试了相同的代码,你给它的工作但得到了 abort()。然后在我的代码中进行了更改,图像仍然没有输出并得到 abort() for (int y = 0; y 【参考方案2】:

最大的问题来自int AB_yx; 变量的管理。它未初始化,也应在每次 x 迭代开始时重置为 0。

另一个问题是 AB 也未初始化使用,您应该在开始在其中的任意索引处分配数据之前将其调整到适当的尺寸。

【讨论】:

我做了修改,没有编译同样的问题【参考方案3】:

AB.at&lt;float&gt; 是错误的,因为ABsrc 的副本,它很可能是CV_8UC1 matrix,所以它必须是AB.at&lt;uchar&gt;,否则您必须先将AB 转换为@987654327 @(CV_32FC1)

【讨论】:

以上是关于如何将 Mat A * B 相乘?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SSE 更有效地将 A*B^T 或 A^T*B^T(T 表示转置)矩阵相乘?

GLSL:与mat4相乘后三角形消失

如何使用numpy将矩阵与另一个矩阵中的每一行相乘

请问JavaScript中如何处理数字和字符串相乘的情况?

Pytorch 上的 1D CNN:mat1 和 mat2 形状不能相乘(10x3 和 10x2)

如何理解矩阵相乘的几何意义或现实意义