OpenCV - 矩阵操作 Part 3

2022-08-09 14:30:32 浏览数 (1)

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. 基础引用
  • 之后对上述函数进行示例演示
  • 所有代码默认引用如下包
代码语言:javascript复制
import cv2
import numpy as np
import mtutils as mt
from mtutils import PIS

  • 示例图片 img1.jpgimg2.jpg
  • 查看 opencv 某函数 func 文档可以运行:
代码语言:javascript复制
print(cv2.<func>.__doc__)

1. cv2.phase()

计算二维向量的方向

  • 函数使用
代码语言:javascript复制
cv2.phase(x, y)  --> dst

对二维矢量场计算笛卡尔一极坐标转换的方位角(角度)部分。该矢量场是由两个独立的单通道矩阵组成。当然这两个输入矩阵的尺寸相同。(如果你有一个二通道的矩阵,那么调用cv2.phase()将会做你所需要的。)然后,dst中的每一个元素都从xy的相应元素中计算两者的反正切值得到。

  • 代码示例
代码语言:javascript复制
x = np.array([1, 0, -1], dtype='float32')
y = np.array([1, -1, 1], dtype='float32')
res = cv2.phase(x, y)

-->
res
array([[0.7852316],
       [4.712389 ],
       [2.3563612]], dtype=float32)

上述结果分别为 frac{pi}{4}, frac{3pi}{2}, frac{3pi} { 4 }

2. cv2.polarToCart()

已知角度和幅度,求出对应的二维向量

  • 函数使用
代码语言:javascript复制
cv2.polarToCart(magnitude, angle, angleInDegrees=False) 

cv2.polarToCart() 从向量场的极坐标中计算笛卡尔坐标(x,y)。输入具有相同尺寸和类型的两个矩阵:幅度和角度,指定每个点处向量的幅度和角度。输出类似的两个矩阵,它们与输入具有相同的尺寸和类型,并且将包含每个点处向量的xy投影。附加标志angleInDegrees将使角度矩阵中的数值以度为单位,而不是弧度。

  • 代码示例
代码语言:javascript复制
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()

对矩阵内的每个元素求幂

代码语言:javascript复制
data = np.reshape(np.arange(20), [4, 5])
res = cv2.pow(data, 2)


-->
res
array([[  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()

用均匀分布的随机数填充给定的矩阵 注意: 该函数内联修改,输入数据会直接变为随机矩阵

  • 函数使用
代码语言:javascript复制
cv2.randu(data, low, high) 

内联产生 low high 之间的均匀分布随机数矩阵

  • 示例代码
代码语言:javascript复制
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()

用正态分布的随机数填充给定的矩阵 注意: 该函数内联修改,输入数据会直接变为随机矩阵

  • 函数使用
代码语言:javascript复制
cv2.randn(data, mean, stddev) 

内联产生以mean为均值,stddev 为标准差的正态分布随机数矩阵

  • 示例代码
代码语言:javascript复制
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()

随机打乱矩阵元素

代码语言:javascript复制
data = np.reshape(np.arange(25), [5, 5])
cv2.randShuffle(data) 

-->
data
array([[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()

通过特定的操作将二维矩阵缩减为向量

  • 函数使用
代码语言:javascript复制
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

参数

含义

0

合并为1行

1

合并为1列

  • 示例代码
代码语言:javascript复制
data = np.reshape(np.arange(25, dtype='float32'), [5, 5])
res = cv2.reduce(data, 0, rtype=cv2.REDUCE_SUM)


-->
res
array([[50., 55., 60., 65., 70.]], dtype=float32)

8. cv2.repeat()

将一个矩阵的内容复制到另一个矩阵

  • 函数使用
代码语言:javascript复制
cv2.repeat(src, nx, ny)

将src 数据 x 方向重复 nx 次, y 方向重复 ny 次

  • 示例代码
代码语言:javascript复制
data = np.reshape(np.arange(4, dtype='float32'), [2, 2])
res = cv2.repeat(data, 2, 3)

-->
res
array([[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

代码语言:javascript复制
mtx = np.random.random([5,6])
res = cv2.setIdentity(mtx)

-->
res
array([[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()

求出线性方程组的解

  • 函数用法
代码语言:javascript复制
cv2.solve(src1, src2, flags) 

  • 其中 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

  • 示例代码
代码语言:javascript复制
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 variables
0:True
1: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()

找到三次方程的实根

  • 函数用法
代码语言:javascript复制
cv2.solveCubic(coeffs)

给定由三或四个元素向量系数表示的三次多项式,cv2.solveCubic()将计算该多项式的实根。如果coeffs有四个元素,则计算以下多项式的根:

如果coeffs只有三个元素,则计算以下多项式的根:

返回结果将具有一个或三个元素,具体取决于多项式具有多少个实根。

  • 示例代码
代码语言:javascript复制
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 x2-12x=0 的三个解 {-4, 3, 0}

12. cv2.solvePoly()

找到多项式方程的复根

  • 函数使用
代码语言:javascript复制
cv2.solvePoly(coeffs)

给定以系数向量表示的任意阶数的多项式,cv2.solvePoly()将尝试计算该多项式的根。给定系数矩阵,计算以下多项式的根:

  • 示例代码
代码语言:javascript复制
coeffs = np.array([4, 0, 1], dtype='float32')
res = cv2.solvePoly(coeffs)


-->
res
(0.0, array([[[ 0., -2.]],...e=float32))
special variables
function 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()

在矩阵中排序任意行或列的元素

  • 函数使用
代码语言:javascript复制
cv2.sort(src, flags)

可以通过使用cv2.SORT_EVERY_ROWcv2.SORT_EVERY_COLUMN 标志对每一行或每一列进行排序。排序可以是升序或者降序,分别由cv2.SORT_ASCENDINGcv2.SORT_DESCENDING标志指定。需要从每一组中各选一个标志。

  • 示例代码
代码语言:javascript复制
data = cv2.randShuffle(np.reshape(np.arange(36), [6,6]))
res = cv2.sort(data, flags=cv2.SORT_EVERY_ROW)

-->
res
array([[ 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() 的目的相同,除了矩阵是未修改的,并返回索引

代码语言:javascript复制
data = cv2.randShuffle(np.reshape(np.arange(36), [6,6]))
res = cv2.sortIdx(data,  flags=cv2.SORT_EVERY_ROW)


-->
res
array([[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()

将一个多通道矩阵分割成多个单通道矩阵

代码语言:javascript复制
image = mt.cv_rgb_imread('img1.jpg')
res = cv2.split(image)
PIS(image, *res)
16. cv2.sqrt()

计算矩阵逐元素的平方根

代码语言:javascript复制
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()

实现两个矩阵逐元素相减

代码语言:javascript复制
mat_1 = np.ones([3,3])
mat_2 = np.zeros([3,3])
cv2.setIdentity(mat_2)
res = cv2.subtract(mat_1, mat_2) 


-->
res
array([[0., 1., 1.],
       [1., 0., 1.],
       [1., 1., 0.]])

18. cv2.trace()

计算一个矩阵的迹

代码语言:javascript复制
mat_1 = np.ones([3,4], dtype='float32')
res = cv2.trace(mat_1)

-->
res
(3.0, 0.0, 0.0, 0.0)

19. cv2.transform()

在矩阵的每个元素上应用矩阵变换

  • 函数使用
代码语言:javascript复制
cv2.transform(src, mtx)

函数cv2.transform()可用于计算任意线性图像变换。它将多通道输入矩阵src视为向量的集合,你可以将其视为“通道空间”,然后将这些向量乘以“小”矩阵mt×,以实现此通道空间中的转换。

  • 示例代码
代码语言:javascript复制
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()

矩阵的转置运算

代码语言:javascript复制
mat = np.reshape(np.arange(16, dtype='float32'), [4, 4])
res = cv2.transpose(mat)

-->
res
array([[ 0.,  4.,  8., 12.],
       [ 1.,  5.,  9., 13.],
       [ 2.,  6., 10., 14.],
       [ 3.,  7., 11., 15.]], dtype=float32)

示例源码

  • https://github.com/zywvvd/Python_Practise

参考资料

  • 《学习 OpenCV3》 第五章

0 人点赞