本文最后更新于:2024年5月7日 下午
OpenCV 自带大量矩阵处理函数,本文记录相关内容。
简介
OpenCV 矩阵类的成员函数可以进行很多基本的矩阵操作,本文基于 《学习 OpenCV3 》中第五章的内容整理 Python OpenCV 矩阵操作函数。
内容列表
序号
函数
描述
1
cv2.phase()
计算二维向量的方向
2
cv2.polarToCart()
已知角度和幅度,求出对应的二维向量
3
cv2.pow()
对矩阵内的每个元素求幂
4
cv2.randu()
用均匀分布的随机数填充给定的矩阵
5
cv2.randn()
用正态分布的随机数填充给定的矩阵
6
cv2.randShuffle()
随机打乱矩阵元素
7
cv2.reduce()
通过特定的操作将二维矩阵缩减为向量
8
cv2.repeat()
将一个矩阵的内容复制到另一个矩阵
9
cv2.setIdentity()
将矩阵中对角线上的元素设为1,其他置0
10
cv2.solve()
求出线性方程组的解
11
cv2.solveCubic()
找到三次方程的实根
12
cv2.solvePoly()
找到多项式方程的复根
13
cv2.sort()
在矩阵中排序任意行或列的元素
14
cv2.sortIdx()
与 cv2.sort()
的目的相同,除了矩阵是未修改的,并返回索引
15
cv2.split()
将一个多通道矩阵分割成多个单通道矩阵
16
cv2.sqrt()
计算矩阵逐元素的平方根
17
cv2.subtract()
实现两个矩阵逐元素相减
18
cv2.trace()
计算一个矩阵的迹
19
cv2.transform()
在矩阵的每个元素上应用矩阵变换
20
cv2.transpose()
矩阵的转置运算
矩阵操作
0. 基础引用
之后对上述函数进行示例演示
所有代码默认引用如下包
1 2 3 4 import cv2import numpy as npimport mtutils as mtfrom mtutils import PIS
查看 opencv 某函数 func
文档可以运行:
1 print (cv2.<func>.__doc__)
1. cv2.phase()
计算二维向量的方向
对二维矢量场计算笛卡尔一极坐标转换的方位角(角度)部分。该矢量场是由两个独立的单通道矩阵组成。当然这两个输入矩阵的尺寸相同。(如果你有一个二通道的矩阵,那么调用cv2.phase()
将会做你所需要的。)然后,dst
中的每一个元素都从x
和y
的相应元素中计算两者的反正切值得到。
1 2 3 4 5 6 7 8 9 x = np.array ([1, 0, -1] , dtype='float32' ) y = np.array ([1, -1, 1] , dtype='float32' ) res = cv2.phase (x, y) --> resarray ([[0.7852316] , [4.712389 ] , [2.3563612] ], dtype=float32)
上述结果分别为 $\frac{\pi}{4}$, $\frac{3\pi}{2}$, $\frac{3\pi} { 4 }$
2. cv2.polarToCart()
已知角度和幅度,求出对应的二维向量
1 cv2.polarToCart(magnitude, angle, angleInDegrees =False )
$$
\begin{array}{c}
x_{i}= magnitude _{i} \cos \left(\right. angle \left._{i}\right) \\
y_{i}= magnitude _{i} \sin \left(\right. angle \left._{i}\right)
\end{array}
$$
cv2.polarToCart()
从向量场的极坐标中计算笛卡尔坐标(x,y)
。输入具有相同尺寸和类型的两个矩阵:幅度和角度,指定每个点处向量的幅度和角度。输出类似的两个矩阵,它们与输入具有相同的尺寸和类型,并且将包含每个点处向量的x
和y
投影。附加标志angleInDegrees
将使角度矩阵中的数值以度为单位,而不是弧度。
1 2 3 4 5 6 7 8 mag = np.array(2 **0.5 ) angle = np.array(np.pi /4 ) res = cv2.polarToCart(mag, angle) res (array([[1.]] ), array([[1.]] ))
3. cv2.pow()
对矩阵内的每个元素求幂
1 2 3 4 5 6 7 8 9 10 data = np.reshape (np.arange (20 ), [4, 5] ) res = cv2.pow (data, 2 ) --> resarray ([[ 0, 1, 4, 9, 16] , [ 25, 36, 49, 64, 81] , [100, 121, 144, 169, 196] , [225, 256, 289, 324, 361] ], dtype=int32)
4. cv2.randu()
用均匀分布的随机数填充给定的矩阵
注意: 该函数内联修改,输入数据会直接变为随机矩阵
1 cv2 .randu(data , low, high)
内联产生 low
high
之间的均匀分布随机数矩阵
1 2 3 4 5 6 7 8 9 10 data = np.zeros([5 , 5 ]) cv2.randu(data, low=2 , high=3 ) --> data array([[2.16117805 , 2.03818934 , 2.42586133 , 2.84612762 , 2.88760448 ], [2.26471239 , 2.27078305 , 2.95266639 , 2.6751313 , 2.81021636 ], [2.18396021 , 2.0944562 , 2.81590329 , 2.52451766 , 2.38083885 ], [2.41199476 , 2.25553534 , 2.9448959 , 2.90012348 , 2.45789156 ], [2.84130697 , 2.28030013 , 2.3854357 , 2.45190146 , 2.87543355 ]])
5. cv2.randn()
用正态分布的随机数填充给定的矩阵
注意: 该函数内联修改,输入数据会直接变为随机矩阵
1 cv2 .randn(data , mean, stddev)
内联产生以mean
为均值,stddev
为标准差的正态分布随机数矩阵
1 2 3 4 5 6 7 8 9 10 data = np.zeros([5 , 5 ]) cv2.randn(data, mean=5 , stddev=1 ) --> data array([[6.27751625 , 6.43329835 , 4.49584228 , 3.92785478 , 6.10956049 ], [5.49447021 , 4.10116905 , 4.46068269 , 4.88458967 , 4.05134571 ], [5.52288508 , 5.11468363 , 5.03454646 , 4.02846879 , 5.8627224 ], [6.25682068 , 4.23800135 , 5.5566175 , 7.2824192 , 7.58638453 ], [6.67061222 , 4.90155111 , 6.18168759 , 3.01809192 , 6.19408202 ]])
6. cv2.randShuffle()
随机打乱矩阵元素
1 2 3 4 5 6 7 8 9 10 data = np.reshape (np.arange (25 ), [5, 5] ) cv2.randShuffle (data) --> dataarray ([[14, 5, 1, 13, 2] , [23, 20, 21, 3, 8] , [22, 4, 16, 7, 6] , [18, 17, 19, 24, 15] , [10, 11, 9, 12, 0] ])
7. cv2.reduce()
通过特定的操作将二维矩阵缩减为向量
1 cv2.reduce(src, dim, reduceOp=cv2.REDUCE_SUM) --> vec
简化是指使用一些reduceOp
所代表的组合规则,对输入矩阵src
的每一行(或列)进行系统的转化,直到只剩一行(或列)为止,使之成为向量vec
。参数dim
决定如何进行简化。
src
接受参数为 float 类型的一维、二维数据
reduceOp
参数
含义
cv2.REDUCE SUM
计算向量的总和
cv2.REDUCE AVG
计算向量的平均值
cv2.REDUCE MAX
计算向量中的最大值
cv2.REDUCE MIN
计算向量中的最小值
dim
1 2 3 4 5 6 7 data = np.reshape (np.arange (25 , dtype='float32' ), [5, 5] ) res = cv2.reduce (data, 0 , rtype=cv2.REDUCE_SUM) --> resarray ([[50 ., 55 ., 60 ., 65 ., 70 .]], dtype=float32)
8. cv2.repeat()
将一个矩阵的内容复制到另一个矩阵
将src 数据 x 方向重复 nx 次, y 方向重复 ny 次
1 2 3 4 5 6 7 8 9 data = np.reshape (np.arange (4 , dtype='float32' ), [2, 2] ) res = cv2.repeat (data, 2 , 3 ) --> resarray ([[0., 1., 0., 1., 0., 1.] , [2., 3., 2., 3., 2., 3.] , [0., 1., 0., 1., 0., 1.] , [2., 3., 2., 3., 2., 3.] ], dtype=float32)
9. cv2.setIdentity()
将矩阵中对角线上的元素设为1,其他置0
1 2 3 4 5 6 7 8 9 10 mtx = np.random .random ([5,6] ) res = cv2.setIdentity (mtx) --> resarray ([[1., 0., 0., 0., 0., 0.] , [0., 1., 0., 0., 0., 0.] , [0., 0., 1., 0., 0., 0.] , [0., 0., 0., 1., 0., 0.] , [0., 0., 0., 0., 1., 0.] ])
10. cv2.solve()
求出线性方程组的解
1 cv2.solve (src1, src2, flags)
$$
C=\operatorname{argmin}_{X}\|\quad A \cdot X-B\|
$$
其中 src1
为 $A$, src2
为 $B$
flags
取值
含义
cv2.DECOMP_LU
高斯消元法(LU分解)
cv2.DECOMP_SVD
奇异值分解(SVD)
cv2.DECOMP_CHOLESKY
对于对称正定矩阵
cv2.DECOMP_EIG
特征值分解,只用于对称矩阵
cv2.DECOMP_OR
QR因式分解
cv2.DECOMP_NORMAL
可选附加标志;表示要求解标准方程
表中的前五个参数是互斥的,但最后一个参数cv2.DECOMP_NORMAL
可以与前五个中的任何一个组合(例如,通过逻辑OR)。如果使用该参数,那么cv2.solve()
将尝试解决标准方程:$hsT·Ihs·dst=lhsT·rhs$, 而不是一般方程$Ihs·dst=rhs$。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 A = np.array ([[1,2] , [2,1] ], dtype='float32' ) B = np.array ([[0] , [1] ], dtype='float32' ) res = cv2.solve (A, B) --> res (True, array ([[ 0.6666667 ] ...e=float32)) special variables function variables0 :True1 :array ([[ 0.6666667 ] , [-0.33333334] ], dtype=float32) special variables[0:2] :[array([0.6666667] , d...e=float32), array ([-0.33333334] ,...e=float32)] dtype:dtype ('float32' )
解方程成功, $x = \frac {2}{3}, y=-\frac{1}{3}$
11. cv2.solveCubic()
找到三次方程的实根
给定由三或四个元素向量系数表示的三次多项式,cv2.solveCubic()
将计算该多项式的实根。如果coeffs有四个元素,则计算以下多项式的根:
$$
\operatorname{coeffs}_{0} x^{3}+\operatorname{coeffs}_{1} x^{2}+\operatorname{coeffs}_{2} x+\operatorname{coeffs}_{3}=0
$$
如果coeffs只有三个元素,则计算以下多项式的根:
$$
x^{3}+\operatorname{coeffs}_{0} x^{2}+\operatorname{coeffs}_{1} x+\operatorname{coeffs}_{2}=0
$$
返回结果将具有一个或三个元素,具体取决于多项式具有多少个实根。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 coeffs = np.array([1,1,-12,0], dtype ='float32' ) res = cv2.solveCubic(coeffs) --> res (3, array([[-4.0000000e+.. .e =float32)) special variables function variables 0:3 1:array([[-4.0000000e+00], [ 3.0000000e+00], [ 8.3266727e-16]], dtype =float32) special variables [0:3] :[array([-4.], dtype =float32), array([3.], dtype =float32), array([8.3266727e-16.. .e =float32)] special variables function variables
得到 $x3+x 2-12x=0$ 的三个解 ${-4, 3, 0}$
12. cv2.solvePoly()
找到多项式方程的复根
给定以系数向量表示的任意阶数的多项式,cv2.solvePoly()
将尝试计算该多项式的根。给定系数矩阵,计算以下多项式的根:
$$
\operatorname{coeffs}_{n} x^{n}+\operatorname{coeffs}_{n-1} x^{n-1}+\cdots+\operatorname{coeffs}_{1} x+\operatorname{coeffs}_{0}=0
$$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 coeffs = np.array([4 , 0 , 1 ], dtype='float32' ) res = cv2.solvePoly(coeffs) res (0.0 , array([[[ 0., -2.]] ,...e=float32)) special variablesfunction variables 0:0.0 1:array ([[[ 0., -2.]], [[ 0., 2.]]], dtype=float32) special variables [0 :2 ] :[array([[ 0., -2.]] , ...e=float32), array([[0., 2.]] , dt...e=float32)] special variables
解得 $x^2+4=0$ 方程的解为虚数 $2j,-2j$
13. cv2.sort()
在矩阵中排序任意行或列的元素
可以通过使用cv2.SORT_EVERY_ROW
或cv2.SORT_EVERY_COLUMN
标志对每一行或每一列进行排序。排序可以是升序或者降序,分别由cv2.SORT_ASCENDING
或cv2.SORT_DESCENDING
标志指定。需要从每一组中各选一个标志。
1 2 3 4 5 6 7 8 9 10 11 data = cv2.randShuffle (np.reshape (np.arange (36 ), [6,6] )) res = cv2.sort (data, flags=cv2.SORT_EVERY_ROW) --> resarray ([[ 1, 4, 8, 12, 30, 35] , [ 0, 5, 10, 11, 15, 22] , [ 3, 7, 16, 20, 25, 29] , [19, 21, 23, 24, 31, 34] , [ 9, 14, 18, 28, 32, 33] , [ 2, 6, 13, 17, 26, 27] ], dtype=int32)
14. cv2.sortIdx()
与 cv2.sort()
的目的相同,除了矩阵是未修改的,并返回索引
1 2 3 4 5 6 7 8 9 10 11 12 data = cv2.randShuffle (np.reshape (np.arange (36 ), [6,6] )) res = cv2.sortIdx (data, flags=cv2.SORT_EVERY_ROW) --> resarray ([[0, 1, 3, 2, 5, 4] , [3, 2, 4, 5, 1, 0] , [0, 2, 4, 5, 3, 1] , [1, 5, 3, 2, 0, 4] , [4, 1, 3, 0, 2, 5] , [1, 2, 0, 5, 4, 3] ], dtype=int32)
15. cv2.split()
将一个多通道矩阵分割成多个单通道矩阵
image = mt.cv_rgb_imread('img1.jpg')
res = cv2.split(image)
PIS(image, *res)
16. cv2.sqrt()
计算矩阵逐元素的平方根
1 2 3 4 5 6 7 8 9 data = cv2.randShuffle(np.reshape(np.arange(16 , dtype='float32'), [4 , 4 ])) res = cv2.sqrt(data) --> res array([[3.3166249 , 3 . , 2.6457512 , 1.4142135 ], [2.4494898 , 3.6055512 , 2 . , 1.7320508 ], [3.4641016 , 1 . , 0 . , 3.1622777 ], [2.828427 , 3.7416575 , 2.236068 , 3.8729835 ]], dtype=float32)
17. cv2.subtract()
实现两个矩阵逐元素相减
1 2 3 4 5 6 7 8 9 10 11 mat_1 = np.ones ([3,3] ) mat_2 = np.zeros ([3,3] ) cv2.setIdentity (mat_2) res = cv2.subtract (mat_1, mat_2) --> resarray ([[0., 1., 1.] , [1., 0., 1.] , [1., 1., 0.] ])
18. cv2.trace()
计算一个矩阵的迹
1 2 3 4 5 6 mat_1 = np.ones([3 ,4 ], dtype='float32' ) res = cv2.trace(mat_1) --> res (3.0 , 0.0 , 0.0 , 0.0 )
在矩阵的每个元素上应用矩阵变换
函数cv2.transform()
可用于计算任意线性图像变换。它将多通道输入矩阵src
视为向量的集合,你可以将其视为“通道空间”,然后将这些向量乘以“小”矩阵mt
×,以实现此通道空间中的转换。
$$
d s t _ { c , i ,j} = \sum m t x _ {c,c'} s r c _ { c ',i,j}
$$
1 2 3 4 image = mt.cv_rgb_imread ('img1.jpg' ) mtx = cv2.flip (cv2.setIdentity (np.zeros ([3, 3] , dtype='float32' )), flipCode=0 ) gbr = cv2.transform (image, mtx)PIS (image, gbr)
20. cv2.transpose()
矩阵的转置运算
1 2 3 4 5 6 7 8 9 mat = np.reshape (np.arange (16 , dtype='float32' ), [4, 4] ) res = cv2.transpose (mat) --> resarray ([[ 0., 4., 8., 12.] , [ 1., 5., 9., 13.] , [ 2., 6., 10., 14.] , [ 3., 7., 11., 15.] ], dtype=float32)
示例源码
参考资料
文章链接:
https://www.zywvvd.com/notes/study/image-processing/opencv/opencv-matrix-op/opencv-matrix-op-part3/