昊虹AI笔记网

 找回密码
 立即注册
搜索
查看: 1139|回复: 0
收起左侧

OpenCV的函数normalize()的两个作用:调整矩阵的值范围(归一化处理)、规范化矩阵的范数为某个值

[复制链接]

238

主题

241

帖子

931

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
931
昊虹君 发表于 2023-1-11 22:55 | 显示全部楼层 |阅读模式
OpenCV的函数normalize()的两个作用:调整矩阵的值范围(归一化处理)、规范化矩阵的范数为某个值

函数normalize()有两个原型:
原型一:
  1. void cv::normalize(InputArray         src,
  2.                    InputOutputArray dst,
  3.                    double         alpha = 1,
  4.                    double         beta = 0,
  5.                    int         norm_type = NORM_L2,
  6.                    int         dtype = -1,
  7.                    InputArray         mask = noArray() )
复制代码
  1. dst=cv.normalize(src, dst[, alpha[, beta[, norm_type[, dtype[, mask]]]]])
复制代码

原型二:
  1. void cv::normalize(const SparseMat &         src,
  2.                    SparseMat &         dst,
  3.                    double         alpha,
  4.                    int         normType )
复制代码
  1. dst=cv.normalize(src, dst[, alpha[, beta[, norm_type[, dtype[, mask]]]]])
复制代码

原型一的适用对象是密集矩阵,通常我们的矩阵都是密集矩阵。
原型二的适用对象是稀疏矩阵,在这篇博文中暂不作介绍。

在介绍各参数的意义前,先说下函数normalize()的作用。

函数normalize()有两个作用:
第一个作用:规范化矩阵的范数为某个值;
第二个作用:规范化矩阵的值范围,即我们常说的对矩阵进行归一化处理。

究竟函数normalize()发挥什么作用,这取决于参数norm_type取什么值。

当它起第一个作用时,即用于规范化矩阵的范数为某个值时,它通过线性缩放和平移操作实现如下目标:

当p=Inf时,对应的参数normType取值为NORM_INF,此时函数normalize()会把src矩阵所有元素的最大绝对值调整为参数alpha的值。
当p=1时,对应的参数normType取值为NORM_L1,此时函数normalize()会把src矩阵所有元素的绝对值之和调整为参数alpha的值。
当p=2时,对应的参数normType取值为NORM_L2,此时函数normalize()会把src矩阵所有元素的绝对值的平方和进行开方后的值调整为参数alpha的值。

当它起第二个作用时,即对矩阵进行归一化处理时,它通过线性缩放和平移操作实现如下目标

即此时函数normalize()会把原矩阵中的值范围从[min(src), max(src)]按比例线性变换到[alpha, beta]的范围。
根据上面的这个目标,可知实现的具体数学表达式如下:

根据上式,可以得到dst(i,j)的表达式,如下:


有了上面的准备知识后,接下来,开始介绍其原型一各参数的意义,这里再把原型一复制如下:
  1. void cv::normalize(InputArray         src,
  2.                    InputOutputArray dst,
  3.                    double         alpha = 1,
  4.                    double         beta = 0,
  5.                    int         norm_type = NORM_L2,
  6.                    int         dtype = -1,
  7.                    InputArray         mask = noArray() )
复制代码

各参数意义如下:
src---输入矩阵。
dst---输出矩阵。
alpha---在第一个作用中,它表示目标范数值(Norm Value);在第二个作用中,函数normalize()会把原矩阵中的值范围从[min(src), max(src)]按比例线性变换到[alpha, beta]的范围。
beta---在第一个作用中,此参数没有作用,是一个无效参数。在第二个作用的情况中,函数normalize()会把原矩阵中的值范围从[min(src), max(src)]按比例线性变换到[alpha, beta]的范围。
norm_type---这个参数决定了函数normalize()对输入矩阵作哪种规范化操作。其可取值如下表所示:


我们常常用这个函数对矩阵进行归一化处理,即上面说的第二个作用,此时norm_type取NORM_MINMAX。
当norm_type取NORM_MINMAX时,需要注意两点:
①当norm_type=NORM_MINMAX时,矩阵src只能为密集矩阵。
②当有掩码矩阵参数时,它是在掩码矩阵所选取的子矩阵上进行操作,包括最大值,最小值的选取也是在子矩阵的范围内,而不是整个原矩阵的范围内进行最大值最小值的选取。

在上面的norm_type取值表中,NORM_INF、NORM_L1、NORM_L2、NORM_L2SQR 情况下都存在src2的情况,可是函数normalize()并没有两个输入参数啊,这是怎么回事呢?
是因为并不是只有函数normalize()取这些枚举值,其它函数也会取这些枚举值,比如norm()的参数也需要取这些枚举值。norm()的OpenCV4.4.0官方文档链接:https://docs.opencv.org/4.4.0/d2 ... d990af775d378e7e46c

dtype—输出矩阵的数据类型,当它为负值时,和输入矩阵的数据类型一样。否则,按它指定的数据类型生成输出矩阵。
mask—操作掩码矩阵。如果操作掩码矩阵存在,则掩码值为0的矩阵元素不参与运算,掩码值为1矩阵元素参与运算。

接下来上示例代码:

首先是利用函数normalize()将原矩阵的范数规范化为某个值的Python代码:
  1. # -*- coding: utf-8 -*-
  2. # 出处:昊虹AI笔记网(hhai.cc)
  3. # 用心记录计算机视觉和AI技术

  4. # 博主微信/QQ 2487872782
  5. # QQ群 271891601
  6. # 欢迎技术交流与咨询

  7. # OpenCV的版本为4.4.0

  8. import cv2 as cv
  9. import numpy as np

  10. A = np.array([[1, 2, 4],
  11.               [8, 16, 32]], dtype='int8')

  12. B1 = A.copy()
  13. B2 = A.copy()
  14. B3 = A.copy()

  15. alpha1 = 100

  16. # 将矩阵A的所有元素的最大绝对值调整为参数alpha1的值
  17. cv.normalize(A, B1, alpha1,  norm_type=cv.NORM_INF)

  18. # 将矩阵A的所有元素的绝对值之和调整为参数alpha1的值
  19. cv.normalize(A, B2, alpha1,  norm_type=cv.NORM_L1)

  20. # 将矩阵A的所有元素绝对值的平方和进行开方后的值调整为参数alpha1的值
  21. cv.normalize(A, B3, alpha1,  norm_type=cv.NORM_L2)
复制代码

运行结果如下:


从上面的结果中可以看出:
B1的所有元素的最大绝对值为100;
B2的所有元素的值加起来为100,验证截图如下:
2+3+6+13+25+51


B3的所有元素绝对值的平方和进行开方后的值为100,验证截图如下:
(3**2+5**2+11**2+22**2+43**2+87**2)**0.5


然后是利用函数normalize()将原矩阵的值归一化到某个区间的Python代码:
  1. # -*- coding: utf-8 -*-
  2. # 出处:昊虹AI笔记网(hhai.cc)
  3. # 用心记录计算机视觉和AI技术

  4. # 博主微信/QQ 2487872782
  5. # QQ群 271891601
  6. # 欢迎技术交流与咨询

  7. # OpenCV的版本为4.4.0

  8. import cv2 as cv
  9. import numpy as np

  10. # 注意矩阵A的数据类型设置为uint8
  11. # 昊虹君测试过如果设置为int8,得不到想要的结果
  12. A = np.array([[1, 2, 4],
  13.               [8, 16, 32]], dtype='uint8')

  14. B1 = A.copy()

  15. alpha1 = 100
  16. beta1 = 200

  17. # 将矩阵A的元素值范围调整到区间[alpha1  beta1]
  18. cv.normalize(A, B1, alpha1, beta1,  norm_type=cv.NORM_MINMAX)
复制代码

运行结果如下:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|昊虹AI笔记网 ( 蜀ICP备2024076726 )

GMT+8, 2024-5-19 11:31 , Processed in 0.026680 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表