OpenCV Mat基础运算总结
OpenCV Mat基础运算总结
矩阵加法
使用重载的“+”运算符
矩阵的加法是指两个矩阵对于位置的数值相加,使用OpenCv重载的 “+” 运算符,假设两个矩阵都为uchar类型,例如:
1 | Mat src1 = (Mat_<uchar>(2,3) << 23, 123, 90, 100, 250, 0); |
123+150应该等于273, 因为两个矩阵的类型都是uchar, 所以"+“运算计算出来的和也是uchar类型, 但是uchar类型范围的最大值是255, 所以273限制为了255。
利用”+“运算符计算计算Mat的和需注意:两个Mat的数据类型必须是一样的, 否则会报错。
一个数值与一个Mat对象相加, 也可以使用”+"运算符, 但是无论这个数值是什么数据类型, 返回的Mat的数据类型都与输入的Mat相同,且结果是矩阵中的每个元素都与这个数值相加:
1 | float value = 100.0; |
使用add函数
函数原型
1 | void add |
举例
1 | Mat src1 = (Mat_<uchar>(2,3) << 23, 123, 90, 100, 250, 0); |
使用add函数时, 输入矩阵的数据类型可以不同, 二输出矩阵的数据类型可以根据情况自行指定, 只有当src1和src2的数据类型相同时, 才能令dtype = -1, 否则仍然会报错。
Vector之间的加法
1 | Vec3f v1 = Vec3f(1, 2, 3); |
### 线性相加scaleAdd
1 | C++: void scaleAdd |
它计算一个缩放数组和另一个数组的和: dst(I) = alpha * src(I) + src2(I)
如:
1 | scaleAdd(imageA,k,imageB,resultC); |
用矩阵表达式模拟为
1 | Mat A(3, 3, CV_64F); |
两个数组的加权和addWeighted
1 | C++: void addWeighted |
该函数可替换为矩阵表达式: dst = src1 * alpha + src2 * beta + gamma;
如
1 | Mat img1=imread("./a1.jpg"); |
矩阵减法
使用重载“-”运算符
1 | Mat a= Mat::eye(Size(3,2), CV_32F); |
如果图像是uchar类型的,144-240不会是 - 96,而是uchar能表示的最小值0
减法函数substract
计算两个数组或数组与标量之间的每个元素的差。
函数原型
1 | C++: void subtract |
如
1 | imshow("img1",img1); |
元素的绝对差absdiff
计算两个数组或数组与标量之间的每个元素的绝对差。
1 | C++: void absdiff |
dst = saturate(|src1 - src2|)
如
1 | imshow("img1",src1); |
矩阵乘法
矩阵乘*
是以数学运算中矩阵相乘的方式实现的,即Mat矩阵A和B被当做纯粹的矩阵做乘法运算,这就要求A的列数等于B的行数时,才能定义两个矩阵相乘。如A是m×n矩阵,B是n×p矩阵,它们的乘积AB是一个m×p矩阵。
1 | Mat A=Mat::ones(2,3,CV_32FC1); |
点乘dot
参与点乘的两个Mat矩阵的数据类型(type)只能是 CV_32F、 CV_64FC1、 CV_32FC2、 CV_64FC2 这4种类型中的一种。若选用其他类型,比如CV_8UC1,编译器会报错。
A.dot(B)操作相当于数学向量运算中的点乘,也叫向量的内积、数量积。 对两个向量执行点乘运算,就是对这两个向量对应位一一相乘之后求和的操作,点乘的结果是一个标量。 Mat矩阵的dot方法扩展了一维向量的点乘操作,把整个Mat矩阵扩展成一个行(列)向量,之后执行向量的点乘运算,仍然要求参与dot运算的两个Mat矩阵的行列数完全一致。
dot方法声明中显示返回值是double,所以A.dot(B)结果是一个double类型数据,不是Mat矩阵,不能把A.dot(B)结果赋值给Mat矩阵!
1 | Mat A=Mat::ones(2,3,CV_8UC1); |
dot操作不对参与运算的矩阵A、B的数据类型做要求,CV_8UC1、CV_32FC1等,可以是任何Opencv定义的类型,如在2中使用的就是CV_8UC1。
若参与dot运算的两个Mat矩阵是多通道的,则计算结果是所有通道单独计算各自.dot之后,再累计的和,结果仍是一个double类型数据。
计算两个Mat矩阵对应位的乘积A.mul(B)
要求参与运算的矩阵A的行列和B的行列数一致。计算结果是跟A或B行列数一致的一个Mat矩阵。 mul说明:
1、mul操作不对参与运算的两个矩阵A、B有数据类型上的要求,但要求A,B类型一致,不然报错; 2、Mat AB=A.mul(B),若声明AB时没有定义AB的数据类型,则默认AB的数据类型跟A和B保存一致; 3、若AB精度不够,可能产生溢出,溢出的值被置为当前精度下的最大值;
如
1 | Mat A=Mat::ones(2,3,CV_8UC1); |
矩阵与标量相乘
使用“*”示矩阵与标量相乘;
## 矩阵除法
使用重载的“/”运算符
A/B; alpha/A; A/alpha都是点除
1 | Mat src1 = (Mat_<int>(2, 3) << 4, 7, 1, 5, 20, 24); //2行3列的矩阵 |
矩阵转置
由Mat类t()函数实现矩阵的转置
1 | Mat m1 = Mat::eye(4,6,CV_32FC1); |
矩阵的逆
其中inv(A)表示矩阵A的逆矩阵
1 | Mat m1 = Mat::eye(5,5,CV_32FC1); |
矩阵中非零元素个数
使用 countNonZero() 函数实现物体的像素或面积常需要用到计算矩阵中的非零元素个数
1 | Mat m1 = Mat::eye(6,6,CV_32FC1); |