使用opencv和numpy实现矩阵相乘和按元素相乘 matrix multiplication vs element-wise multiplication

in 编程
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

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

opencv and numpy matrix multiplication vs element-wise multiplication

<!--more-->

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

Copyright

关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9
扫一扫关注公众号添加购物返利助手,领红包
Comments are closed.

推荐使用阿里云服务器

超多优惠券

服务器最低一折,一年不到100!

朕已阅去看看