zoukankan      html  css  js  c++  java
  • 使用opencv和numpy实现矩阵相乘和按元素相乘 matrix multiplication vs element-wise multiplication

    本文首发于个人博客https://kezunlin.me/post/1e37a6/,欢迎阅读最新内容!

    opencv and numpy matrix multiplication vs element-wise multiplication

    Guide

    opencv

    Matrix multiplication is where two matrices are multiplied directly. This operation multiplies matrix A of size [a x b] with matrix B of size [b x c] to produce matrix C of size [a x c].

    In OpenCV it is achieved using the simple * operator:

    C = A * B  // Aab * Bbc = Cac
    

    Element-wise multiplication is where each pixel in the output matrix is formed by multiplying that pixel in matrix A by its corresponding entry in matrix B. The input matrices should be the same size, and the output will be the same size as well. This is achieved using the mul() function:

    output = A.mul(B); // A B must have same size !!!
    

    code

    cv::Mat cv_matmul(const cv::Mat& A, const cv::Mat& B)
    {
    	// matrix multipication    m*k,  k*n ===> m*n
    	cv::Mat C = A * B; 
    	return C; 
    }
    
    cv::Mat cv_mul(const cv::Mat& image, const cv::Mat& mask)
    {
    	// element-wise multiplication  output[i,j] = image[i,j] * mask[i,j]
    	cv::Mat output = image.mul(mask, 1.0); // m*n,  m*n
    	return output;
    }
    
    cv::Mat cv_multiply3x1(const cv::Mat& mat3, const cv::Mat& mat1)
    {
    	std::vector<cv::Mat> channels;
    	cv::split(mat3, channels);
    
    	std::vector<cv::Mat> result_channels;
    	for(int i = 0; i < channels.size(); i++)
    	{
    		result_channels.push_back(channels[i].mul(mat1));
    	}
    
    	cv::Mat result3;
    	cv::merge(result_channels, result3);
    	return result3;
    }
    
    cv::Mat cv_multiply3x3(const cv::Mat& mat3_a, const cv::Mat& mat3_b)
    {
    	cv::Mat a;
    	cv::Mat b;
    	cv::Mat c;
    
    	std::vector<cv::Mat> a_channels;
    	std::vector<cv::Mat> b_channels;
    	std::vector<cv::Mat> c_channels;
    
    	cv::split(mat3_a, a_channels);
    	cv::split(mat3_b, b_channels);
    
    	for(int i = 0; i < a_channels.size() || b_channels.size(); i++)
    	{
    		c_channels.push_back(a_channels[i].mul(b_channels[i]));
    	}
    
    	cv::merge(c_channels, c);
    	return c;
    }
    

    numpy

    numpy arrays are not matrices, and the standard operations *, +, -, / work element-wise on arrays.

    Instead, you could try using numpy.matrix, and * will be treated like matrix multiplication.

    code

    Element-wise multiplication code

    >>> img = np.array([1,2,3,4,5,6,7,8]).reshape(2,4)
    >>> mask = np.array([1,1,1,1,0,0,0,0]).reshape(2,4)
    >>> img * mask 
    array([[1, 2, 3, 4],
           [0, 0, 0, 0]])
    >>> 
    >>> np.multiply(img, mask)
    array([[1, 2, 3, 4],
           [0, 0, 0, 0]])
    

    for numpy.array, *and multiply work element-wise

    matrix multiplication code

    >>> a = np.array([1,2,3,4,5,6,7,8]).reshape(2,4)
    >>> b = np.array([1,1,1,1,0,0,0,0]).reshape(4,2)
    >>> np.matmul(a,b)
    array([[ 3,  3],
           [11, 11]])
    
    >>> np.dot(a,b)
    array([[ 3,  3],
           [11, 11]])
    
    >>> a = np.matrix([1,2,3,4,5,6,7,8]).reshape(2,4)
    >>> b = np.matrix([1,1,1,1,0,0,0,0]).reshape(4,2)
    >>> a
    matrix([[1, 2, 3, 4],
            [5, 6, 7, 8]])
    >>> b
    matrix([[1, 1],
            [1, 1],
            [0, 0],
            [0, 0]])
    >>> a*b
    matrix([[ 3,  3],
            [11, 11]])
    
    >>> np.matmul(a,b)
    matrix([[ 3,  3],
        	[11, 11]])
    

    for 2-dim, np.dot equals np.matmul
    for numpy.array, np.matmul means matrix multiplication;
    for numpy.matrix, * and np.matmul means matrix multiplication;

    Reference

    History

    • 20190109: created.

    Copyright

  • 相关阅读:
    牛客网 剑指Offer JZ16 合并两个排序的链表
    牛客网 剑指Offer JZ15 反转链表
    牛客网 剑指Offer JZ14 链表中倒数最后k个结点
    牛客网 剑指Offer JZ12 数值的整数次方 经典快速幂
    牛客网 剑指offer-JZ10 矩形覆盖
    牛客网 剑指offer-JZ9 跳台阶扩展问题
    牛客网 剑指offer-JZ8 跳台阶
    牛客网 剑指offer-JZ7 斐波那契数列
    牛客网 剑指offer-JZ6 旋转数组的最小数字
    codility_ BinaryGap
  • 原文地址:https://www.cnblogs.com/kezunlin/p/12014628.html
Copyright © 2011-2022 走看看