OpenCV - 矩阵操作 Part 1

本文最后更新于:2022年7月4日 上午

OpenCV 自带大量矩阵处理函数,本文记录相关内容。

简介

  • OpenCV 矩阵类的成员函数可以进行很多基本的矩阵操作,本文基于 《学习 OpenCV3 》中第五章的内容整理 Python OpenCV 矩阵操作函数。

内容列表

序号 函数 描述
1 cv2.absdiff() 计算两个矩阵差值的绝对值
2 cv2.add() 实现两个矩阵逐元素相加
3 cv2.addWeighted() 实现两个矩阵逐元素加权求和(以为混合值)
4 cv2.bitwise_and() 计算两个矩阵逐元素按位与
5 cv2.bitwise_not() 按位非
6 cv2.bitwise_or() 计算两个矩阵逐元素按位或
7 cv2.bitwise_xor() 计算两个矩阵逐元素按位异或
8 cv2.calcCovarMatrix() 计算一组n维向量的协方差
9 cv2.cartToPolar() 计算二维向量的角度和幅度
10 cv2.checkRange() 检查矩阵的无效值
11 cv2.compare() 对两个矩阵中的所有元素应用所选择的比较运算符
12 cv2.completeSymm() 通过将一半元素复制到另一半来使矩阵对称
13 cv2.convertScaleAbs() 缩放矩阵,取绝对值,然后转换为8位无符号数
14 cv2.countNonZero() 计算矩阵中非零元素个数
15 cv2.cvtColor() 转换图像颜色空间
16 cv2.dct() 计算矩阵的离散余弦变换
17 cv2.determinant() 计算方阵的行列式
18 cv2.dft() 计算矩阵的离散傅里叶变换
19 cv2.divide() 实现两个矩阵逐元素相除
20 cv2.eigen() 计算方阵的特征值和特征向量

矩阵操作

0. 基础引用

  • 之后对上述函数进行示例演示
  • 所有代码默认引用如下包
1
2
3
4
import cv2
import numpy as np
import mtutils as mt
from mtutils import PIS
  • 示例图片 img1.jpgimg2.jpg

1. cv2.absdiff()

计算两个矩阵差值的绝对值

1
2
3
4
matrix_a = np.random.random([5,5])
matrix_b = np.random.random([5,5])

res = cv2.absdiff(matrix_a, matrix_b)

2. cv2.add()

实现两个矩阵逐元素相加

1
2
3
4
matrix_a = np.random.random([5,5])
matrix_b = np.random.random([5,5])

res = cv2.add(matrix_a, matrix_b)

3. cv2.addWeighted()

实现两个矩阵逐元素加权求和(以为混合值)

  • 函数使用

    1
    addWeighted(src1, alpha, src2, beta, gamma)
    参数 说明
    src1 图像1
    alpha 图像1 权重 (例如 0.5)
    src2 图像2
    beta 图像2 权重 (例如 0.5)
    gamma 附加偏置
  • 函数实现功能

    $dst = src1alpha + src2beta + gamma$

  • 使用示例

1
2
3
4
5
6
7
8
image_1 = mt.cv_rgb_imread('img1.jpg')
image_1 = mt.image_resize(image_1, [300, 300])
image_2 = mt.cv_rgb_imread('img2.jpg')
image_2 = mt.image_resize(image_2, [300, 300])

res1 = cv2.addWeighted(image_1, 0.8, image_2, 0.3, 5)
res2 = cv2.addWeighted(image_1, 0.5, image_2, 0.5, 5)
PIS(image_1, image_2, res1, res2)

4. cv2.bitwise_and()

对应像素按位与

1
2
3
4
5
6
7
8
image_1 = mt.cv_rgb_imread('img1.jpg')
image_2 = mt.cv_rgb_imread('img2.jpg')

image_1 = mt.image_resize(image_1, [300, 300])
image_2 = mt.image_resize(image_2, [300, 300])

res = cv2.bitwise_and(image_1, image_2)
PIS(res)

  • 相当于所有数据分别按位与后的结果
1
2
3
4
(cv2.bitwise_and(image_1, image_2) == image_1 & image_2).all()

->
True

5. cv2.bitwise_not()

按位非

1
2
3
4
5
6
7
8
image_1 = mt.cv_rgb_imread('img1.jpg')
image_2 = mt.cv_rgb_imread('img2.jpg')

image_1 = mt.image_resize(image_1, [300, 300])
image_2 = mt.image_resize(image_2, [300, 300])

res = cv2.bitwise_not(image_1)
PIS(res)

6. cv2.bitwise_or()

计算两个矩阵逐元素按位或

1
2
3
4
5
6
7
8
image_1 = mt.cv_rgb_imread('img1.jpg')
image_2 = mt.cv_rgb_imread('img2.jpg')

image_1 = mt.image_resize(image_1, [300, 300])
image_2 = mt.image_resize(image_2, [300, 300])

res = cv2.bitwise_or(image_1, image_2)
PIS(res)

7. cv2.bitwise_xor()

计算两个矩阵逐元素按位异或

1
2
3
4
5
6
7
8
image_1 = mt.cv_rgb_imread('img1.jpg')
image_2 = mt.cv_rgb_imread('img2.jpg')

image_1 = mt.image_resize(image_1, [300, 300])
image_2 = mt.image_resize(image_2, [300, 300])

res = cv2.bitwise_xor(image_1, image_2)
PIS(res)

8. cv2.calcCovarMatrix()

给定一些向量,假设这些向量表示的点是近似高斯分布的,cv2.calcCovarMatrix() 将计
算这些点的均值和协方差矩阵。

  • 函数使用
1
cv2.calcCovarMatrix(samples, flags[, covar[, mean[, ctype]]]) → covar, mean
Flags 含义
CV_COVAR_SCRAMBLED 快速PCA“scrambled”协方差,转置位置不同的计算方式,与 CV_COVAR_NORMAL 互斥
CV_COVAR_NORMAL 计算均值和协方差,正常计算协方差,与 CV_COVAR_SCRAMBLED 互斥
CV_COVAR_USE_AVG 输入均值而不是计算均值(在均值已知情况下减少运算时间)
CV_COVAR_SCALE 重新缩放输出的协方差矩阵
CV_COVAR_ROWS 使用样本的行作为输入向量(如输入向量为 m * n 则需要指定)
CV_COVAR_COLS 使用样本的列作为输入向量(如输入向量为 m * n 则需要指定)
1
2
3
4
5
6
7
8
9
10
11
12
13
vector = np.array([[1,2,3], [4,5,6], [7, 8, 9]]).astype('float32')
covar, mean = cv2.calcCovarMatrix(vector, None, flags=cv2.COVAR_NORMAL | cv2.COVAR_COLS )

-->
covar
array([[2., 2., 2.],
[2., 2., 2.],
[2., 2., 2.]])

mean
array([[2.],
[5.],
[8.]])

9. cv2.cartToPolar()

计算二维向量的角度和幅度,笛卡尔坐标转极坐标

  • 函数使用
1
magnitude, angle = cv2.cartToPolar(x, y)
$$ \begin{array}{c} magnitude_{i}=\sqrt{{x}_{i}{ }^{2}+y_{i}{ }^{2}}\\ angle_{i}=\operatorname{atan} 2\left(y_{i}, x_{i}\right) \end{array} $$
  • 输入维度相同的 X, Y 向量 (float32 或 float64),返回相同维度的坐标转换结果
1
2
3
4
5
6
7
8
9
10
11
12
vector = np.array([[1,1,1],[1,1,1]]).astype('float32')
X =vector
Y = vector
mag, ang = cv2.cartToPolar(X, Y)

-->
mag
array([[1.4142135, 1.4142135, 1.4142135],
[1.4142135, 1.4142135, 1.4142135]], dtype=float32)
ang
array([[0.7852316, 0.7852316, 0.7852316],
[0.7852316, 0.7852316, 0.7852316]], dtype=float32)

10. cv2.checkRange()

函数 cv2.checkRange() 检查输入矩阵src的每个元素,并确定该元素是否在给定范围内。范围由minValmaxVal设置,但任何NaN或inf值也被认为超出范围。如果找到超出范围的值,除非将quiet设置为true,否则抛出异常。在这种情况下,如果所有值都在范
围内,返回值就为true;如果有任何值超出范围,返回值则为false。

1
2
image_1 = mt.cv_rgb_imread('img1.jpg')
cv2.checkRange(image_1, False, 0, 255)

11. cv2.compare()

该函数在两个矩阵src1src2中的对应元素之间进行逐元素比较,并将结果放在图像dst中。cv2.compare() 将最后一个参数作为比较运算符。在每种情况下,结果dst的每个像素都是一个8位序列,匹配的像素被标记为255,不匹配的像素被设置为0。

通过 numpy 的矩阵运算也完全可以实现。

  • 函数使用
1
cv2.compare(src1, src2, cmpop)
  • cmpop 参数说明
cmp_op 比较操作
cv2.CMP_EQ src1i == src2i
cv2.CMP_GT src1i > src2i
cv2.CMP_GE src1i >= src2i
cv2.CMP_LT src1i < src2i
cv2.CMP_LE src1i <= src2i
cv2.CMP_NE src1i != src2i
  • 代码示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
vector_1 = np.random.random([5,5,5,5])
vector_2 = np.random.random([5,5,5,5])

res = cv2.compare(vector_1, vector_2, cmpop=cv2.CMP_GE)

-->
res
array([[[[ 0, 0, 0, 255, 255],
[ 0, 0, 255, 255, 255],
[ 0, 255, 255, 255, 255],
[255, 255, 0, 255, 0],
[ 0, 255, 0, 0, 255]],

...

res.shape
(5, 5, 5, 5)

12. cv2.completeSymm()

给定一个(二维)矩阵 mtx, cv2.completeSymm() 通过复制来使矩阵对称注1。具体来说,来自上三角形的所有元素都被复制到它们在矩阵下三角形对应的转置位置。tx的对角元素保持不变。如果标志 lowerToUpper 设置为true,则来自下三角形的元素将被复制到上三角形中。

1
2
3
4
5
6
7
8
9
10
vector_1 = np.random.random([5,5])
res = cv2.completeSymm(vector_1, lowerToUpper=False)

-->
res
array([[0.2604316 , 0.57123429, 0.24625302, 0.51625787, 0.53749169],
[0.57123429, 0.2294393 , 0.17753148, 0.29501751, 0.34551 ],
[0.24625302, 0.17753148, 0.08954819, 0.3061089 , 0.57356678],
[0.51625787, 0.29501751, 0.3061089 , 0.54457652, 0.61120996],
[0.53749169, 0.34551 , 0.57356678, 0.61120996, 0.03919279]])

13. cv2.convertScaleAbs()

缩放矩阵,取绝对值,然后转换为8位无符号数

函数cv2.convertScaleAbs() 实际上融多种功能于一体。它将按顺序执行四个操作。第一个操作是通过因子alpha来重新调整源图像,第二个操作是通过(加)因子beta来偏移,第三个操作是计算上述所求和的绝对值,第四个操作是将该结果(饱和)映射到一个无符号字符型(8位)。

1
cv2.convertScaleAbs(src, alpha=1.0, beta=0.0)  

$$
d s t_{i}= saturate {u c h a r}\left(\left|\alpha^{*} s r c{i}+\beta\right|\right)
$$

1
2
3
4
5
6
7
8
9
10
11
12
vector = np.random.random([100, 100]) * 200
res = cv2.convertScaleAbs(vector, alpha=1.0, beta=0.0)

-->
res
array([[ 22, 155, 35, ..., 123, 98, 187],
[137, 191, 163, ..., 19, 65, 105],
[176, 128, 137, ..., 56, 44, 85],
...,
[130, 47, 113, ..., 165, 60, 174],
[169, 172, 47, ..., 97, 107, 144],
[ 66, 78, 86, ..., 154, 113, 82]], dtype=uint8)

14. cv2.countNonZero()

计算矩阵中非零元素个数

1
2
3
4
5
6
7
8
vector = np.random.random([100, 100]) 
vector = np.clip(vector - 0.3, 0, 1)

num = cv2.countNonZero(vector)

-->
num
7007

15. cv2.cvtColor()

cv2.cvtColor() 函数用于将图像在保留相同数据类型的同时从一个颜色空间(通道数)转换到另一个颜色空间。

  • 函数使用

    1
    dst = cv2.cvtColor(src, code, dstCn=0) 

    输入矩阵src可以是8位矩阵,16位无符号矩阵或32位浮点矩阵。输出矩阵dst将具有与输入矩阵相同的尺寸和深度。要完成的转换操作由编码参数指定。最终参数dstCn是目标图像中所需的通道数。如果给出默认值0,则通道数由src中的通道数和转换编码确定。

  • code 可选值

    在RGB或BGR颜色空间之间转换(包括或者不包括alpha通道 cv2.COLOR_BGR2RGB
    cv2.COLOR_RGB2BGR
    cv2.COLOR_RGBA2BGRA
    cv2.COLOR_BGRA2RGBA
    在RGB或BGR图像中加入alpha通道 cv2.COLOR_RGB2RGBA
    cv2.COLOR_BGR2BGRA
    从RGB或BGR图像中删除alpha通道 cv2.COLOR_RGBA2RGB
    cv2.COLOR_BGRA2BGR
    在加入或删除Alpha通道时将RGB转换为BGR颜色空间 cv2.COLOR_RGB2BGRA
    cv2.COLOR_RGBA2BGR
    cv2.COLOR_BGRA2RGB
    cv2.COLOR_BGR2RGBA
    转换RGB或BGR颜色空间为灰度空间 cv2.COLOR_RGB2GRAY
    cv2.COLOR_BGR2GRAY
    转换灰度空间为RGB或BGR颜色空间(在转换过程中可选择删除alpha通道) cv2.COLOR_GRAY2RGB
    cv2.COLOR_GRAY2BGR
    cv2.COLOR_RGBA2GRAY
    cv2.COLOR_BGRA2GRAY
    将灰度空间转换为RGB或BGR颜色空间,并加入alpha通道 cv2.COLOR_GRAY2RGBA
    cv2.COLOR_GRAY2BGRA
    将RGB或BGR颜色空间转换为BGR565颜色表示,可选择加入或删除alphai通道(16位图像) cv2.COLOR_RGB2BGR565
    cv2.COLOR_BGR2BGR565
    cv2.COLOR_BGR5652RGB
    cv2.COLOR_BGR5652BGR
    cv2.COLOR_RGBA2BGR565
    cv2.COLOR_BGRA2BGR565
    cv2.COLOR_BGR5652RGBA
    cv2.COLOR_BGR5652BGRA
    将灰度空间转换为BGR565颜色表示或者反变换(16位图像) cv2.COLOR_GRAY2BGR565
    cv2.COLOR_BGR5652GRAY
    从RGB或BGR颜色空间转换为BGR555颜色表示,可选择加入或删除alpha通道(16位图像) cv2.COLOR_RGB2BGR555
    cv2.COLOR_BGR2BGR555
    cv2.COLOR_BGR5552RGB
    cv2.COLOR_BGR5552BGR
    cv2.COLOR_RGBA2BGR555
    cv2.COLOR_BGRA2BGR555
    cv2.COLOR_BGR5552RGBA
    cv2.COLOR_BGR5552BGRA
    将灰度空间转换为BGR555颜色表示或者反变换(16位图像) cv2.COLOR_GRAY2BGR555
    cv2.COLOR_BGR5552GRAY
    将RGB或BGR图像转为CIE_XYZ表示或者反转(Rec709和D65白点) cv2.COLOR_RGB2XYZ
    cv2.COLOR_BGR2XYZ
    cv2.COLOR_XYZ2RGB
    cv2.COLOR_XYZ2BGR
    转换RGB或BGR图像到luma-chroma(a.k.a.YCC)颜色表示或反转 cv2.COLOR_RGB2YCrCb
    cv2.COLOR_BGR2YCrCb
    cv2.COLOR_YCrCb2RGB
    cv2.COLOR_YCrCb2BGR
    将RGB或BGR图像转为HSV(hue_saturation_value)颜色表示或反转 cv2.COLOR_RGB2HSV
    cv2.COLOR_BGR2HSV
    cv2.COLOR_HSV2RGB
    cv2.COLOR_HSV2BGR
    将RGB或BGR图像转为HLS(hue_lightness_saturation))颜色表示或反转 cv2.COLOR_RGB2HLS
    cv2.COLOR_BGR2HLS
    cv2.COLOR_HLS2RGB
    cv2.COLOR_HLS2BGR
    将RGB或BGR图像转换为CIE_Lab颜色表示或者反变换 cv2.COLOR_RGB2Lab
    cv2.COLOR_BGR2Lab
    cv2.COLOR_Lab2RGB
    cv2.COLOR_Lab2BGR
    将RGB或BGR图像转换为CIE_Luvi颜色表示或者反变换 cv2.COLOR_RGB2Luv
    cv2.COLOR_BGR2Luv
    cv2.COLOR_Luv2RGB
    cv2.COLOR_Luv2BGR
    从Bayer模式(单通道)转为RGB或BGR图像 cv2.COLOR_BayerBG2RGB
    cv2.COLOR_BayerGB2RGB
    cv2.COLOR_BayerRG2RGB
    cv2.COLOR_BayerGR2RGB
    cv2.COLOR_BayerBG2BGR
    cv2.COLOR_BayerGB2BGR
    cv2.COLOR_BayerRG2BGR
    cv2.COLOR_BayerGR2BGR
  • 示例代码

1
2
3
image = mt.cv_rgb_imread('img1.jpg')
bgr = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
PIS(image, bgr)

16. cv2.dct()

计算矩阵的离散余弦变换

  • 函数使用

    该函数根据flags参数的值执行离散余弦变换或离散余弦逆变换。源矩阵src必须是一维或二维的,并且尺寸应该是偶数(如果需要,可以填充矩阵)。结果矩阵dst将具有与src相同的类型和尺寸。参数flags是一个位域值,可以设置为cv2.DCT_INVERSEcv2.DCT_ROWS中的一个或两个。

1
cv2.dct(src, flags) --> dst
  • 参数说明

    • src 需要为一维或二维的 float32 或 float64 数据
    • flags 不设置默认正向变换
    • flags 如果设置为cv2.DCT_INVERSE,则实现逆变换而不是前向变换。
    • flags 如果设置标志为cv2.DCT_ROWS,则将二维n×m的输入视为长度为m的n个不同的一维向量。在这种情况下,每个这样的向量将被独立地变换。
  • 最佳尺寸

    cv2.dct() 的性能很大程度上取决于传递给它的矩阵的确切尺寸,这种关系(性能与尺寸的关系)并不是单调的。只有一些尺寸是比其他尺寸表现出的性能更好。建议在将矩阵传递给 cv2.dct() 时,首先在比当前矩阵大的尺寸中确定最佳尺寸,然后将矩阵扩展为该尺寸。OpenCV 为你提供了一个合适的例程来计算这个值,称为 cv2.getOptimalDFTSize()

  • 示例代码

1
2
3
4
5
6
7
8
image = mt.cv_rgb_imread('img1.jpg')
image = mt.image_resize(image, [300, 300]).astype('float32')
image = mt.to_gray_image(image)

dct_res = cv2.dct(image)
inverse_img = cv2.dct(dct_res, flags=cv2.DCT_INVERSE)

PIS(image, (dct_res*150).astype('uint8'), inverse_img.astype('uint8'))

17. cv2.determinant()

计算方阵的行列式

1
2
3
4
5
6
7
8
9
10
vector =(np.random.random([3, 3]) * 5).astype('int32').astype('float32')
res = cv2.determinant(vector)

-->
vector
array([[1., 2., 2.],
[0., 4., 3.],
[0., 3., 1.]], dtype=float32)
res
-5.0

18. cv2.dft()

计算矩阵的离散傅里叶变换

  • 函数使用

    cv2.dft()函数实现离散傅里叶变换以及其逆变换(取决于flags参数)。源矩阵src必须是一维或二维的。结果矩阵dst将具有与src相同的类型和尺寸。

    参数flags是一个位域值,可以设置为cv2.DFT_INVERSE,cv2.DFT_ROWS,cv2.DFT_SCALE,cv2.DFT_COMPLEX_OUTPUTcv2.DFT_REALOUTPUT中的一个或多个。

1
cv2.dft(src, flags=0, nonzeroRows=0)
  • flags 说明

    • 如果设置为cv2.DFT_INVERSE,则完成逆变换。

    • 如果设置标志为cv2.DFT_ROWS,则二维n×m输入被视为长度为m的n个不同的一维向量,并且每个这样的向量将独立变换。

    • 标志cv2.DFT_SCALE通过将结果除以矩阵中的元素数来标准化结果,这通常用于DFT_INVERSE,因为它保证逆的逆将具有正确的标准化。

    • 标志cv2.DFT_COMPLEX_OUTPUT:和cv2.DFT_REAL_OUTPUT是有用的,因为当计算实数矩阵的傅里叶变换时,结果将有复共轭对称性。因此,即使结果是复数,结果矩阵的元素数量等于输入矩阵中的元素数量,而不是该数量的两倍。这样的压缩是cv2.dft()的默认行为。

    • 若要强制输出复数的形式,则需设置标志cv2.DFT_COMPLEX_OUTPUT。在逆变换的情况下,输入(通常)为复数,输出也为复数。然而,如果输入矩阵(对逆变换的情况)具有复共轭对称性(例如,如果它本身是实数矩阵的傅里叶变换的结果),那么逆变换将是一个实数矩阵。如果知道是这种情况,并且希望结果矩阵表示为一个实数矩阵(从而使用一半的内存量),则可以设置cv2.DFT_REAL_OUTPUT标志。

    • 请注意,如果设置cv2.DFT_REAL_OUTPUT标志,cv2.dft()不会检查输入矩阵是否具有必要的对称性,它只是假定具有对称性。

  • nonzeroRows

    cv2.dft()的最后一个参数是nonzeroRows,它默认为0,但如果设置它为任何非0值,将导致cv2.dft()认为只有输入矩阵的前nonzeroRows行是有意义的。如果cv2.DFT_INVERSE被设置,那么就认为只有输出矩阵的前nonzeroRows行是非零的。在使用cv2.dft()计算卷积的互相关时,这个标志特别方便。

  • 最佳尺寸

    cv2.dft()的性能很大程度上取决于传递给它的矩阵的确切尺寸,这种关系(性能与尺寸的关系)并不是线性的。只有一些尺寸是比其他尺寸表现出的性能更好。建议在将矩阵传递给cv2.dft()时,首先在比当前矩阵大的尺寸中确定最佳尺寸,然后将矩阵扩展为该尺寸。OpenCV提供了一个合适的例程来计算这个值,称为cv2.getOptimalDFTSize()

  • 示例代码

1
2
3
4
5
6
7
8
image = mt.cv_rgb_imread('img1.jpg')
image = mt.image_resize(image, [300, 300]).astype('float32')
image = mt.to_gray_image(image)

dft_res = cv2.dft(image)
inverse_img = cv2.dft(dft_res, flags=cv2.DFT_INVERSE)

PIS(image, dft_res, inverse_img)

19. cv2.divide()

实现两个矩阵逐元素相除

1
2
3
4
mat_1 = np.random.random([5, 5, 5, 5])
mat_2 = np.random.random([5, 5, 5, 5])

res = cv2.divide(mat_1,mat_2)

20. cv2.eigen()

计算方阵的特征值和特征向量

  • 函数使用

    1
    cv2.eigen(mat, lowindex=-1, highindex=-1)

    给定一个对称矩阵mat,cv2.eigen()会计算出该矩阵的特征向量和特征值。矩阵必须为浮点类型之一。特征值矩阵以递减的顺序包含mat的特征值。如果要提供矩阵的特征向量,特征向量则以行的形式存储在矩阵中,并且与对应的特征值在特征值矩阵中的顺序相同。附加参数lowindexhighindex允许只计算一些特征值(两者必须一起使用)。例如,如果lowindex=0highindex=1,就只计算最大的两个特征向量。

  • 参考代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
mat = np.random.random([5, 5])
res = cv2.eigen(mat)

-->
res
(True, array([[ 2.38338798]...9424513]]), array([[ 0.48055992,...815113 ]]))
special variables
function variables
0:True
1:array([[ 2.38338798],
[ 0.95330573],
[ 0.09642702],
[-0.29716848],
[-0.99424513]])
2:array([[ 0.48055992, 0.47769814, 0.35204413, 0.55726429, 0.32617187],
[ 0.11930107, -0.17197101, 0.86940861, -0.32391572, -0.3088697 ],
[-0.1228634 , 0.55909817, 0.04237424, -0.67306158, 0.46637576],
[-0.49973229, -0.42185973, 0.30025171, 0.21678729, 0.65966218],
[ 0.70000117, -0.50167127, -0.16806823, -0.2907344 , 0.3815113 ]])
len():3

示例源码

参考资料

  • 《学习 OpenCV3》 第五章

OpenCV - 矩阵操作 Part 1
https://www.zywvvd.com/notes/study/image-processing/opencv/opencv-matrix-op/opencv-matrix-op-part1/
作者
Yiwei Zhang
发布于
2022年2月28日
许可协议