首页 > 其他分享 >Opencv中Mat矩阵相乘——点乘、dot、mul运算详解

Opencv中Mat矩阵相乘——点乘、dot、mul运算详解

时间:2023-04-12 16:26:17浏览次数:40  
标签:AB Mat 矩阵 Opencv mul CV dot

Mat矩阵点乘——A*B

Opencv重载了运算符“*”,姑且称之为Mat矩阵“点乘”,其中一个重载声明为:

CV_EXPORTS MatExpr operator * (const Mat& a, const Mat& b);

点乘说明:

1.  A*B是以数学运算中矩阵相乘的方式实现的,即Mat矩阵A和B被当做纯粹的矩阵做乘法运算,这就要求A的列数等       于B的行数时,才能定义两个矩阵相乘。如A是m×n矩阵,B是n×p矩阵,它们的乘积AB是一个m×p矩阵。

 


 

如上图所示,C=AB。C中第i行第j列所在元素C(i,j)等于A中第i行所有元素跟B中第j列所有元素一一对应的乘积之和。

更具有代表性的的:对于A、B都是2行2列矩阵的情况:


Opencv验证:

定义两个Mat矩阵A和B点乘,A为2行3列,B为3行2列:

 
  #include "core/core.hpp"   #include "iostream"       using namespace std;   using namespace cv;       int main(int argc,char *argv[])   {   Mat A=Mat::ones(2,3,CV_32FC1);   Mat B=Mat::ones(3,2,CV_32FC1);   Mat AB;       A.at<float>(0,0)=1;   A.at<float>(0,1)=2;   A.at<float>(0,2)=3;   A.at<float>(1,0)=4;   A.at<float>(1,1)=5;   A.at<float>(1,2)=6;       B.at<float>(0,0)=1;   B.at<float>(0,1)=2;   B.at<float>(1,0)=3;   B.at<float>(1,1)=4;   B.at<float>(2,0)=5;   B.at<float>(2,1)=6;       AB=A*B;       cout<<"A=\n"<<A<<endl<<endl;   cout<<"B=\n"<<B<<endl<<endl;   cout<<"AB=\n"<<AB<<endl<<endl;       system("pause");   }
 
输出:

 


 

务必保证两个Mat矩阵中第一个矩阵A的列数等于第二个矩阵B的行数。

2.  参与点乘的两个Mat矩阵的数据类型(type)只能是 CV_32F、 CV_64FC1、 CV_32FC2、 CV_64FC2 这4种类        型中的一种。若选用其他类型,比如CV_8UC1,编译器会报错:

 

Mat矩阵dot——A.dot(B)

Opencv中.dot操作才算得上是真正的“点乘”,A.dot(B)操作相当于数学向量运算中的点乘,也叫向量的内积、数量积。

函数声明:

 
  //! computes dot-product   double dot(InputArray m) const;
 

dot说明:

1.  对两个向量执行点乘运算,就是对这两个向量对应位一一相乘之后求和的操作,点乘的结果是一个标量。 

对于向量a和向量b:

     

a和b的点积公式为:

 

 

要求向量a和向量b的行列数相同。

 

Mat矩阵的dot方法扩展了一维向量的点乘操作,把整个Mat矩阵扩展成一个行(列)向量,之后执行向量的点乘运算,仍然要求参与dot运算的两个Mat矩阵的行列数完全一致

2.  dot方法声明中显示返回值是double,所以A.dot(B)结果是一个double类型数据,不是Mat矩阵,不能把A.dot(B)结       果赋值给Mat矩阵!

 

Opencv验证:

 
  #include "core/core.hpp"   #include "iostream"       using namespace std;   using namespace cv;       int main(int argc,char *argv[])   {   Mat A=Mat::ones(2,3,CV_8UC1);   Mat B=Mat::ones(2,3,CV_8UC1);       A.at<uchar>(0,0)=1;   A.at<uchar>(0,1)=2;   A.at<uchar>(0,2)=3;   A.at<uchar>(1,0)=4;   A.at<uchar>(1,1)=5;   A.at<uchar>(1,2)=6;       B.at<uchar>(0,0)=1;   B.at<uchar>(0,1)=2;   B.at<uchar>(0,2)=3;   B.at<uchar>(1,0)=4;   B.at<uchar>(1,1)=5;   B.at<uchar>(1,2)=6;       double AB=A.dot(B);       cout<<"A=\n"<<A<<endl<<endl;   cout<<"B=\n"<<B<<endl<<endl;   cout<<"double类型的AB=\n"<<AB<<endl<<endl;       system("pause");   }
 
 

运行结果:

若对AB声明为Mat,则在编译阶段就会报错。

3.  dot操作不对参与运算的矩阵A、B的数据类型做要求,CV_8UC1、CV_32FC1等,可以是任何Opencv定义的类         型,如在2中使用的就是CV_8UC1。

4.  若参与dot运算的两个Mat矩阵是多通道的,则计算结果是所有通道单独计算各自.dot之后,再累计的和,结果仍是一个double类型数据。

 

Mat矩阵mul——A.mul(B)

 

Opencv中mul会计算两个Mat矩阵对应位的乘积,所以要求参与运算的矩阵A的行列和B的行列数一致。计算结果是跟A或B行列数一致的一个Mat矩阵。

 

Opencv中mul声明:

 
  //! per-element matrix multiplication by means of matrix expressions   MatExpr mul(InputArray m, double scale=1) const;
 

以简单的情况为例,对于2*2大小的Mat矩阵A和B:

对A和B执行mul运算:

mul说明:

 

1.  mul操作不对参与运算的两个矩阵A、B有数据类型上的要求,但要求A,B类型一致,不然报错;

2.  Mat AB=A.mul(B),若声明AB时没有定义AB的数据类型,则默认AB的数据类型跟A和B保存一致

3.  若AB精度不够,可能产生溢出,溢出的值被置为当前精度下的最大值;

 

Opencv验证:

 
  #include "core/core.hpp"   #include "iostream"       using namespace std;   using namespace cv;       int main(int argc,char *argv[])   {   Mat A=Mat::ones(2,3,CV_8UC1);   Mat B=Mat::ones(2,3,CV_8UC1);       A.at<uchar>(0,0)=60;   A.at<uchar>(0,1)=2;   A.at<uchar>(0,2)=3;   A.at<uchar>(1,0)=4;   A.at<uchar>(1,1)=5;   A.at<uchar>(1,2)=6;       B.at<uchar>(0,0)=60;   B.at<uchar>(0,1)=2;   B.at<uchar>(0,2)=3;   B.at<uchar>(1,0)=4;   B.at<uchar>(1,1)=5;   B.at<uchar>(1,2)=6;       Mat AB=A.mul(B);       cout<<"A=\n"<<A<<endl<<endl;   cout<<"B=\n"<<B<<endl<<endl;   cout<<"AB=\n"<<AB<<endl<<endl;       system("pause");   }
 

输出:


AB中第一个元素应该为60*60=360,但AB默认的类型为CV_8UC1,即最大值只能是255;所以执行mul运算一定要定义AB足够的精度,防止溢出。

 

 

标签:AB,Mat,矩阵,Opencv,mul,CV,dot
From: https://www.cnblogs.com/lidabo/p/17309749.html

相关文章

  • 现代计算机图形学——P3. Transformation-2D
    P3.TransformationP3.Transformation 矩阵和变换联系起来 ReflectionMatrix(反射矩阵(名字不重要)):切变:旋转:推导:旋转矩阵中的B和D可以用(0,1)这个点来推算线性变换:(先不管这个M)齐次坐标为什么要用齐次坐标:......
  • 论文解析 -- AIOps- A Multivocal Literature Review
    这篇综述是基于ASystematicMappingStudyinAIOps的基础上的补充和更新。除了论文,还涵盖greyliterature(e.g.,blogposts,videos,andwhitepapers) ,所以称MultivocalOurworkwillcomplementtheworkperformedbytheseauthorsaddingalsoinsightsfromgre......
  • mysql——date_format(),str_to_date()函数
    date_format():类似python中的strftime: 将给定格式的日期时间对象转换为字符串。日期时间对象=>字符串,控制输出格式selectdate_format(datetime的字段,‘%Y-%m-%d’)括号中前面是你要格式化的字段,后面是具体要格式化成什么样式。 str_to_date():类似python中的strptime:将字......
  • 论文解析 -- A Systematic Mapping Study in AIOps
    AIOPS论文的综述如何挑选论文,如何选取keywords 搜索的3个论文库, Weselectthreeonlinesearchdatabasesthatareappropriateforthescopeofinvestigation:IEEEXplore,ACMDigitalLibraryandarXiv. 对于挑选出的论文进行分类,分类标准是,targetcomponents......
  • R语言中的matrix(矩阵),list(列表),data.frame(数据框)总结
    一、R语言中的矩阵matrix是一个二维的数组array,因此数组array的一些操作它也适用。①它与array相比,特有的是矩阵的一些运算,例如:求维度:dim(A)转置:t(A)求行列式:det(A)矩阵相乘:x%*%y对角运算:diag(A)求逆:solve(A,b)求特征值和特征向量:eigen(A)奇异值分解:svd(A)②在多维数组中,apply函数......
  • UVa 457 Linear Cellular Automata (water ver.)
    457-LinearCellularAutomataTimelimit:3.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=94&page=show_problem&problem=398AbiologistisexperimentingwithDNAmodificationofbacterialcolonies......
  • UVa 11375 Matches (DP&高精度)
    11375-MatchesTimelimit:2.000secondshttp://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=2370Wecanmakedigitswithmatchesasshownbelow:Given N matches,findthenumberofdifferentnumbersrepresentableusing......
  • 在pycharm中使用Matplotlib的pyplot时报错MatplotlibDeprecationWarning
    本文为joshua317原创文章,转载请注明:转载自joshua317博客 https://www.joshua317.com/article/298在使用飞浆平台,练习平台上的demo:实践:手写数字识别任务,出现了下面的错误,demo地址: https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/beginner/quick_start_cn.html......
  • MATLAB代码:基于DBSCAN密度聚类的风电-负荷场景削减方法
    MATLAB代码:基于DBSCAN密度聚类的风电-负荷场景削减方法关键词:密度聚类场景削减DBSCAN场景生成与削减kmeans 参考文档:《氢能支撑的风-燃气耦合低碳微网容量优化配置研究》第3章:完美复现仿真平台:MATLAB主要内容:代码主要做的是一个基于DBSCAN密度聚类的风电-负荷场景生成与......
  • scala match的运用
    单个变量varclusterManager:Int=argmatch{case"yarn"=>YARNcase"yarn-client"|"yarn-cluster"=>println(s"Master${arg}isdeprecatedsince2.0."+......