文章目录

  • 12.4 Hu矩
    • 12.4.1 Hu矩函数
    • 12.4.2 形状匹配

Python版本是Python3.7.3,OpenCV版本OpenCV3.4.1,开发环境为PyCharm

12.4 Hu矩

Hu矩是归一化中心矩的线性组合。Hu矩在图像旋转、缩放、平移等操作后,仍能保持矩的不变性,所以经常会使用Hu距来识别图像的特征。
在OpenCV中,使用函数cv2.HuMoments()可以得到Hu距。该函数使用cv2.moments()函数的返回值作为参数,返回7个Hu矩值。

12.4.1 Hu矩函数

函数cv2.HuMoments()的语法格式为:

hu = cv2.HuMoments( m )

式中返回值hu,表示返回的Hu矩值;参数m,是由函数cv2.moments()计算得到矩特征值。
eg1:计算图像的Hu矩,对其中第0个矩的关系进行演示。
分析:Hu矩是归一化中心矩的线性组合,每一个矩都是通过归一化中心矩的组合运算得到的。函数cv2.moments()返回的归一化中心矩中包含:
● 二阶Hu矩:nu20, nu11, nu02
● 三阶Hu矩:nu30, nu21, nu12, nu03
为了表述上的方便,将上述字母“nu”表示为字母“v”,则归一化中心矩为:
● 二阶Hu矩:v20, v11, v02
● 三阶Hu矩:v30, v21, v12, v03
上述7个Hu矩的计算公式为:

本例对Hu矩中的第0个矩ℎ0=v20+v02的关系进行验证,即Hu矩中第0个矩对应的函数cv2.moments()的返回值为:
ℎ0=nu20+nu02
根据题目的要求及分析,编写代码如下:

import cv2
o1 = cv2.imread('cs1.bmp')
gray = cv2.cvtColor(o1,cv2.COLOR_BGR2GRAY)
HuM1=cv2.HuMoments(cv2.moments(gray)).flatten()
print("cv2.moments(gray)=\n",cv2.moments(gray))
print("\nHuM1=\n",HuM1)
print("\ncv2.moments(gray)['nu20']+cv2.moments(gray)['nu02']=%f+%f=%f\n" %(cv2.moments(gray)['nu20'],cv2.moments(gray)['nu02'],cv2.moments(gray)['nu20']+cv2.moments(gray)['nu02']))
print("HuM1[0]=",HuM1[0])
print("\nHu[0]-(nu02+nu20)=",HuM1[0]-(cv2.moments(gray)['nu20']+cv2.moments(gray)['nu02']))

运行上述程序,结果如下所示:

cv2.moments(gray)={'m00': 2729265.0, 'm10': 823361085.0, 'm01': 353802555.0, 'm20': 256058984145.0, 'm11': 104985534390.0, 'm02': 47279854725.0, 'm30': 81917664997185.0, 'm21': 32126275537320.0, 'm12': 13822864338150.0, 'm03': 6484319942535.0, 'mu20': 7668492092.239532, 'mu11': -1749156290.667572, 'mu02': 1415401136.019806, 'mu30': 43285283824.25, 'mu21': -12028503719.705078, 'mu12': 13036213891.871826, 'mu03': -11670178717.88086, 'nu20': 0.0010294815371794503, 'nu11': -0.00023482114674224926, 'nu02': 0.00019001510593064523, 'nu30': 3.5174343862137483e-06, 'nu21': -9.774562821438012e-07, 'nu12': 1.0593444921254788e-06, 'nu03': -9.483381946207041e-07}HuM1=[ 1.21949664e-03  9.25267773e-07  4.05157060e-12  2.46555893e-112.41189094e-22  2.27497012e-14 -5.05282814e-23]cv2.moments(gray)['nu20']+cv2.moments(gray)['nu02']=0.001029+0.000190=0.001219HuM1[0]= 0.0012194966431100956Hu[0]-(nu02+nu20)= 0.0

程序运行结果显示“Hu[0]-(nu02+nu20)=0.0”。从该结果可知,关系ℎ0=nu20+nu02成立。

eg2:计算三幅不同图像的Hu矩,并进行比较。
根据题目的要求,编写代码如下:

import cv2
#----------------计算图像1的Hu矩-------------------
o1 = cv2.imread('cs1.bmp')
gray1 = cv2.cvtColor(o1,cv2.COLOR_BGR2GRAY)
HuM1=cv2.HuMoments(cv2.moments(gray1)).flatten()
#----------------计算图像2的Hu矩-------------------
o2 = cv2.imread('cs3.bmp')
gray2 = cv2.cvtColor(o2,cv2.COLOR_BGR2GRAY)
HuM2=cv2.HuMoments(cv2.moments(gray2)).flatten()
#----------------计算图像3的Hu矩-------------------
o3 = cv2.imread('lena.bmp')
gray3 = cv2.cvtColor(o3,cv2.COLOR_BGR2GRAY)
HuM3=cv2.HuMoments(cv2.moments(gray3)).flatten()
#---------打印图像1、图像2、图像3的特征值------------
print("o1.shape=",o1.shape)
print("o2.shape=",o2.shape)
print("o3.shape=",o3.shape)
print("cv2.moments(gray1)=\n",cv2.moments(gray1))
print("cv2.moments(gray2)=\n",cv2.moments(gray2))
print("cv2.moments(gray3)=\n",cv2.moments(gray3))
print("\nHuM1=\n",HuM1)
print("\nHuM2=\n",HuM2)
print("\nHuM3=\n",HuM3)
#---------计算图像1与图像2、图像3的Hu矩之差----------------
print("\nHuM1-HuM2=",HuM1-HuM2)
print("\nHuM1-HuM3=",HuM1-HuM3)
#---------显示图像----------------
cv2.imshow("original1",o1)
cv2.imshow("original2",o2)
cv2.imshow("original3",o3)
cv2.waitKey()
cv2.destroyAllWindows()

运行上述程序,会显示各个图像的shape属性、moments属性、HuMoments属性,以及不同图像的Hu矩之差。

o1.shape= (425, 514, 3)
o2.shape= (425, 514, 3)
o3.shape= (512, 512, 3)
cv2.moments(gray1)={'m00': 2729265.0, 'm10': 823361085.0, 'm01': 353802555.0, 'm20': 256058984145.0, 'm11': 104985534390.0, 'm02': 47279854725.0, 'm30': 81917664997185.0, 'm21': 32126275537320.0, 'm12': 13822864338150.0, 'm03': 6484319942535.0, 'mu20': 7668492092.239532, 'mu11': -1749156290.667572, 'mu02': 1415401136.019806, 'mu30': 43285283824.25, 'mu21': -12028503719.705078, 'mu12': 13036213891.871826, 'mu03': -11670178717.88086, 'nu20': 0.0010294815371794503, 'nu11': -0.00023482114674224926, 'nu02': 0.00019001510593064523, 'nu30': 3.5174343862137483e-06, 'nu21': -9.774562821438012e-07, 'nu12': 1.0593444921254788e-06, 'nu03': -9.483381946207041e-07}
cv2.moments(gray2)={'m00': 1755675.0, 'm10': 518360685.0, 'm01': 190849140.0, 'm20': 156229722135.0, 'm11': 55624504050.0, 'm02': 21328437150.0, 'm30': 47992502493915.0, 'm21': 16559578863270.0, 'm12': 6135747671370.0, 'm03': 2448843661890.0, 'mu20': 3184426306.518524, 'mu11': -723448129.1111069, 'mu02': 582345624.6666679, 'mu30': -14508249198.71875, 'mu21': 3955540976.4630127, 'mu12': -4161129804.772583, 'mu03': 3747496072.099121, 'nu20': 0.001033101406743052, 'nu11': -0.00023470327398074646, 'nu02': 0.00018892636416872798, 'nu30': -3.5522595786074026e-06, 'nu21': 9.684909688107435e-07, 'nu12': -1.0188281855633918e-06, 'nu03': 9.175523962659349e-07}
cv2.moments(gray3)={'m00': 32524520.0, 'm10': 8668693016.0, 'm01': 8048246168.0, 'm20': 3012074835288.0, 'm11': 2188197716912.0, 'm02': 2697437187672.0, 'm30': 1162360702630328.0, 'm21': 771188127583648.0, 'm12': 737629807045152.0, 'm03': 1024874860779368.0, 'mu20': 701626022956.6519, 'mu11': 43115319152.083496, 'mu02': 705885386731.4578, 'mu30': -14447234840442.0, 'mu21': 2862363425762.25, 'mu12': -2650458863973.0, 'mu03': 8044566997348.25, 'nu20': 0.00066326013744609, 'nu11': 4.075771361264021e-05, 'nu02': 0.0006672865932933317, 'nu30': -2.3947351703101695e-06, 'nu21': 4.744577382167515e-07, 'nu12': -4.3933300241295835e-07, 'nu03': 1.3334460006519109e-06}HuM1=[ 1.21949664e-03  9.25267773e-07  4.05157060e-12  2.46555893e-112.41189094e-22  2.27497012e-14 -5.05282814e-23]HuM2=[ 1.22202777e-03  9.32974010e-07  4.19762083e-12  2.44520029e-112.44855011e-22  2.27298009e-14 -3.76120600e-23]HuM3=[ 1.33054673e-03  6.66097722e-09  1.16744767e-12  1.13004583e-11-2.02613532e-24 -8.54504575e-16  4.09952009e-23]HuM1-HuM2= [-2.53112780e-06 -7.70623675e-09 -1.46050222e-13  2.03586345e-13-3.66591675e-24  1.99003443e-17 -1.29162214e-23]HuM1-HuM3= [-1.11050088e-04  9.18606796e-07  2.88412294e-12  1.33551309e-112.43215229e-22  2.36042058e-14 -9.15234823e-23]

同时,还会显示三幅原始图像,如下图所示:
● 左图是图像o1。
● 中间的是图像o2。
● 右图是图像o3。

从上述输出结果可以看到,由于Hu矩的值本身就非常小,因此在这里并没有发现两个对象的Hu矩差值的特殊意义。

12.4.2 形状匹配

我们可以通过Hu矩来判断两个对象的一致性。例如,上一节计算了两个对象Hu矩的差,但是结果比较抽象。为了更直观方便地比较Hu矩值,OpenCV提供了函数cv2.matchShapes(),对两个对象的Hu矩进行比较。
函数cv2.matchShapes()允许我们提供两个对象,对二者的Hu矩进行比较。这两个对象可以是轮廓,也可以是灰度图。不管是什么,cv2.matchShapes()都会提前计算好对象的Hu矩值。
函数cv2.matchShapes()的语法格式为:

    retval = cv2.matchShapes( contour1, contour2, method, parameter )

式中retval是返回值。
该函数有如下4个参数:
● contour1:第1个轮廓或者灰度图像。
● contour2:第2个轮廓或者灰度图像。
● method:比较两个对象的Hu矩的方法,具体如下表所示。

在表中,A表示对象1, B表示对象2:

式中,

● parameter:应用于method的特定参数,该参数为扩展参数,目前(截至OpenCV 4.1.0版本)暂不支持该参数,因此将该值设置为0。

eg3:使用函数cv2.matchShapes()计算三幅不同图像的匹配度。
:代码如下:

import cv2
#--------------读取3幅原始图像--------------------
o1 = cv2.imread('cs1.bmp')
o2 = cv2.imread('cs2.bmp')
o3 = cv2.imread('cc.bmp')
#----------打印3幅原始图像的shape属性值-------------
print("o1.shape=",o1.shape)
print("o2.shape=",o2.shape)
print("o3.shape=",o3.shape)
#--------------色彩空间转换--------------------
gray1 = cv2.cvtColor(o1,cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(o2,cv2.COLOR_BGR2GRAY)
gray3 = cv2.cvtColor(o3,cv2.COLOR_BGR2GRAY)
#-------------进行Hu矩匹配--------------------
ret0 = cv2.matchShapes(gray1,gray1,1,0.0)
ret1 = cv2.matchShapes(gray1,gray2,1,0.0)
ret2 = cv2.matchShapes(gray1,gray3,1,0.0)
#--------------打印差值--------------------
print("相同图像的matchShape=",ret0)
print("相似图像的matchShape=",ret1)
print("不相似图像的matchShape=",ret2)
#--------------显示3幅原始图像--------------------
cv2.imshow("original1",o1)
cv2.imshow("original2",o2)
cv2.imshow("original3",o3)
cv2.waitKey()
cv2.destroyAllWindows()

运行上述程序,会显示三幅原始图像,如下图所示。其中:



● original1 是图像o1。
● original2 是图像o2。
● original3 是图像o3。
同时,程序还会显示如下运行结果:

o1.shape= (425, 514, 3)
o2.shape= (42, 51, 3)
o3.shape= (425, 514, 3)
相同图像的matchShape= 0.0
相似图像的matchShape= 0.0001154058519395873
不相似图像的matchShape= 0.012935752303635306

从以上结果可以看出:
● 同一幅图像的Hu矩是不变的,二者差值为0。
● 相似的图像即使发生了平移、旋转和缩放后,函数cv2.matchShapes()的返回值仍然比较接近。例如,图像o1和图像o2, o2是对o1经过缩放、旋转和平移后得到的,但是对二者应用cv2.matchShapes()函数后,返回值的差较小。
● 不相似图像cv2.matchShapes()函数返回值的差较大。例如,图像o1和图像o3的差别较大,因此对二者应用cv2.matchShapes()函数后,返回值的差也较大。

win10+Python3.7.3+OpenCV3.4.1入门学习(十二 图像轮廓)————12.4 Hu矩相关推荐

  1. win10+Python3.7.3+OpenCV3.4.1入门学习(二十章 K近邻算法)————20.1理论基础

    Python版本是Python3.7.3,OpenCV版本OpenCV3.4.1,开发环境为PyCharm 文章目录 第20章 K近邻算法 20.1 理论基础 第20章 K近邻算法 机器学习算法是从数 ...

  2. win10+Python3.7.3+OpenCV3.4.1入门学习(十二 图像轮廓)————12.7 利用形状场景算法比较轮廓

    Python版本是Python3.7.3,OpenCV版本OpenCV3.4.1,开发环境为PyCharm 文章目录 12.7 利用形状场景算法比较轮廓 12.7.1 计算形状场景距离 12.7.2 ...

  3. win10+Python3.7.3+OpenCV3.4.1入门学习(八)————8.7 礼帽运算

    Python版本是Python3.7.3,OpenCV版本OpenCV.3.4.1,开发环境为PyCharm 礼帽运算是用原始图像减去其开运算图像的操作.礼帽运算能够获取图像的噪声信息,或者得到比原始 ...

  4. win10+Python3.7.3+OpenCV3.4.1入门学习(七)————7.1均值滤波(上)

    Python版本是Python3.7.3,OpenCV版本OpenCV.3.4.1,开发环境为PyCharm 均值滤波是指用当前像素点周围N·N个像素值的均值来代替当前像素值.使用该方法遍历处理图像内 ...

  5. Linux入门学习(十二)

    软件安装 软件名称识别 [abrt-addon-ccpp]-[2.1.11-19].[el7].[x86_64].rpm :rpm结尾的适用与redhat操作系统 软件名 abrt-addon-ccp ...

  6. Oracle入门(十二)之SQL的DDL

    一.数据类型 Character 数据类型 Number 数据类型 Date 数据类型 Raw 和 Long Raw 数据类型 LOB 数据类型 注:Oracle数据类型详解 二.表 (1)创建表 c ...

  7. TIA博途SCL入门学习(二)常用基本控制语句用法和举例

    TIA博途SCL入门学习(二)常用基本控制语句用法和举例 FOR循环语句 FOR循环可以指定循环的次数,在使用这种循环的时候需要先定义一个INT型变量,并指定计数范围,即循环次数,直到循环次数到达设定 ...

  8. Reflex WMS入门系列十二:Reflex里的Location

    Reflex WMS入门系列十二:Reflex里的Location 玩过SAP系统里的人都知道,在SAP系统里库存管理分为IM Level和WM Level.IM Level的仓库,在SAP里被定义为 ...

  9. 无人驾驶汽车系统入门(十二)——卷积神经网络入门,基于深度学习的车辆实时检测

    无人驾驶汽车系统入门(十二)--卷积神经网络入门,基于深度学习的车辆实时检测 上篇文章我们讲到能否尽可能利用上图像的二维特征来设计神经网络,以此来进一步提高识别的精度.在这篇博客中,我们学习一类专门用 ...

最新文章

  1. RecyclerView 的findFirstVisibleItemPosition()与findLastVisibleItemPosition()
  2. css html 优化,CSS Animation性能优化
  3. 管理者如何提升下属执行力---视频学习记录
  4. 如何去除Windows8测试版界面“水印”
  5. git push的时候报411问题
  6. HTTP 1.1与HTTP 1.0的比较
  7. extractCSS – 帮助你从 HTML 中快速分离出 CSS
  8. WinCE的开发流程
  9. [APIO2017]商旅——分数优化+floyd+SPFA判负环+二分答案
  10. /var/spool/clientmqueue目录下存在大量文件的原因及解决方法
  11. sqlyog怎么查找表_sqlyog各种搜索方法
  12. 关于软件逆向工程的一些不错博客
  13. Java面试知识点概览(持续更新)
  14. Transformer Transducer 论文笔记
  15. (附源码)ssm市级疫情防控管理 毕业设计 030957
  16. 明日书苑|硬笔书法临写指南
  17. python计算器教程vscode_第3天 | 12天搞定Python,用VSCode编写代码
  18. 秒杀品牌数据线的开博尔USB3.1Gen2 Type-C数据线评测
  19. android 路由器 操作系统,小米全新路由器操作系统是什么?支持什么语言?
  20. Flutter Missing parentheses in call to ‘print‘. Did you mean print(‘Insert‘, text,‘to line‘, line_nu

热门文章

  1. Python爬虫问题汇总(持续更新)
  2. http/https服务器安全:嗅探漏洞url路径
  3. Channel 接口EventLoop 接口 ChannelFuture 接口
  4. EASYRECOVERY_3.3.29包含注册机、都教授数据恢复含注册码
  5. 电子商务垂直化与纵深化发展的创新之路
  6. 【持续更新】1999-2023年英伟达历代桌面GeForce显卡列表,GeForce显卡发布日期
  7. 互联网日报 | 快手向港交所递交上市申请;苏宁双十一退货上门取件免费;小米明年扩招5000名工程师...
  8. RFC1945 超文本传输协议--HTTP/1.0 之一
  9. 推荐个免费ppt模板下载网站
  10. Linux关于ssh: connect to host xxx.xxx.xxx.xxx port 22: Operation timed out问题