文章目录

  • 引言
  • 矩的定义
  • OpenCV中的矩(moments)
  • OpenCV中的Hu不变矩(HuMoments)
  • 矩的应用
  • 代码示例
  • 参考链接

引言

我们在图像处理的任务中,常常需要对某些形状区域进行描述,比如形状的质心、面积、方向等等。还需要为形状选取合适的特征描述符,用于进行形状的分类任务等等。

图像矩就是用于分析、描述分割后的形状的一种经典方法。

所以,本文会整理下OpenCV是如何定义矩、如何计算矩、如何应用矩的相关知识点,并配上原理公式和代码,方便你用的时候进行查阅。

首先,你需要理解,矩的定义是什么?

矩的定义

在图像处理、计算机视觉和相关领域中,图像矩(image moments)定义为图像像素强度的某个特定加权平均值(矩),或者是此类矩的函数。

图像矩通常用于分析、描述分割后的形状。

通过图像矩可以获取一些形状的简单属性,比如面积、质心和方向信息。

对于像素强度为 I(x,y)I ( x , y )I(x,y) 的标量(灰度)图像,原始图像矩 MijM_{ij}Mij​ 由下式计算:
Mij=∑x∑yxiyiI(x,y)M_{ij} = \sum _{x}\sum_{y} {x^i y^i I ( x , y )} Mij​=x∑​y∑​xiyiI(x,y)

图像的中心矩定义为:
μpq=∑x∑y(x−xˉ)p(y−yˉ)qI(x,y)\mu_{pq}=\sum_x \sum_y (x-\bar{x})^p(y-\bar{y})^q I(x,y) μpq​=x∑​y∑​(x−xˉ)p(y−yˉ​)qI(x,y)
通过证明可得:中心矩 μpq\mu_{pq}μpq​ 是平移不变的。

你现在了解了矩的计算原理,那么在实际应用中,我们可以利用 OpenCV 的现成函数直接计算得出矩。

OpenCV中的矩(moments)

OpenCV 采用以下函数计算向量形状或栅格形状的矩,结果返回在结构cv::Moments中。

轮廓的矩以相同的方式定义,但使用格林公式计算。

C++:

#include <opencv2/imgproc.hpp>
Moments cv::moments(InputArray  array,bool binaryImage = false)

Python:

import cv2 as cv
cv.moments( array[, binaryImage] ) ->    retval
  • 参数
    array:栅格图,单通道、8位或2D点阵列(Point2f)
    binaryImage:如果为true,图像的非零像素会被当做1,这个参数仅在处理images时使用。

  • 返回
    moments.

OpenCV中的 Moments 包含以下矩定义:

// 空间矩 spatial moments
double  m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;
// 中心矩 central moments
double  mu20, mu11, mu02, mu30, mu21, mu12, mu03;
// 中心归一化矩 central normalized moments
double  nu20, nu11, nu02, nu30, nu21, nu12, nu03;
  • 空间矩的计算:
    mji=∑x,y(array(x,y)⋅xj⋅yi)\texttt{m} _{ji}= \sum _{x,y} \left ( \texttt{array} (x,y) \cdot x^j \cdot y^i \right ) mji​=x,y∑​(array(x,y)⋅xj⋅yi)

  • 中心矩的计算:
    muji=∑x,y(array(x,y)⋅(x−xˉ)j⋅(y−yˉ)i)\texttt{mu} _{ji}= \sum _{x,y} \left ( \texttt{array} (x,y) \cdot (x - \bar{x} )^j \cdot (y - \bar{y} )^i \right ) muji​=x,y∑​(array(x,y)⋅(x−xˉ)j⋅(y−yˉ​)i)
    任何阶的中心矩都有平移不变性。

  • 中心归一化矩的计算:
    nuji=mujim00(i+j)/2+1\texttt{nu} _{ji}= \frac{\texttt{mu}_{ji}}{\texttt{m}_{00}^{(i+j)/2+1}} nuji​=m00(i+j)/2+1​muji​​
    中心归一化矩还具有尺度不变形。

OpenCV中的Hu不变矩(HuMoments)

Hu不变矩 (Hu invariants) 是对平移、缩放、镜像和旋转都不敏感的7个二维不变矩的集合。常被用作于特征描述符。

C++:

void HuMoments(const Moments& m, OutputArray hu)
void HuMoments(const Moments& moments, double hu[7])

Python:

import cv2 as cv
cv.HuMoments(m[, hu]) → hu

7个二维不变矩的定义如下:
hu[0]=η20+η02hu[1]=(η20−η02)2+4η112hu[2]=(η30−3η12)2+(3η21−η03)2hu[3]=(η30+η12)2+(η21+η03)2hu[4]=(η30−3η12)(η30+η12)[(η30+η12)2−3(η21+η03)2]+(3η21−η03)(η21+η03)[3(η30+η12)2−(η21+η03)2]hu[5]=(η20−η02)[(η30+η12)2−(η21+η03)2]+4η11(η30+η12)(η21+η03)hu[6]=(3η21−η03)(η21+η03)[3(η30+η12)2−(η21+η03)2]−(η30−3η12)(η21+η03)[3(η30+η12)2−(η21+η03)2]\begin{array}{l} hu[0]= \eta _{20}+ \eta _{02} \\ hu[1]=( \eta _{20}- \eta _{02})^{2}+4 \eta _{11}^{2} \\ hu[2]=( \eta _{30}-3 \eta _{12})^{2}+ (3 \eta _{21}- \eta _{03})^{2} \\ hu[3]=( \eta _{30}+ \eta _{12})^{2}+ ( \eta _{21}+ \eta _{03})^{2} \\ hu[4]=( \eta _{30}-3 \eta _{12})( \eta _{30}+ \eta _{12})[( \eta _{30}+ \eta _{12})^{2}-3( \eta _{21}+ \eta _{03})^{2}]+(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ hu[5]=( \eta _{20}- \eta _{02})[( \eta _{30}+ \eta _{12})^{2}- ( \eta _{21}+ \eta _{03})^{2}]+4 \eta _{11}( \eta _{30}+ \eta _{12})( \eta _{21}+ \eta _{03}) \\ hu[6]=(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}]-( \eta _{30}-3 \eta _{12})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ \end{array} hu[0]=η20​+η02​hu[1]=(η20​−η02​)2+4η112​hu[2]=(η30​−3η12​)2+(3η21​−η03​)2hu[3]=(η30​+η12​)2+(η21​+η03​)2hu[4]=(η30​−3η12​)(η30​+η12​)[(η30​+η12​)2−3(η21​+η03​)2]+(3η21​−η03​)(η21​+η03​)[3(η30​+η12​)2−(η21​+η03​)2]hu[5]=(η20​−η02​)[(η30​+η12​)2−(η21​+η03​)2]+4η11​(η30​+η12​)(η21​+η03​)hu[6]=(3η21​−η03​)(η21​+η03​)[3(η30​+η12​)2−(η21​+η03​)2]−(η30​−3η12​)(η21​+η03​)[3(η30​+η12​)2−(η21​+η03​)2]​

其中,ηjiη_{ji}ηji​ 表示 Moments::nujinu_{ji}nuji​。

hu[0]hu[0]hu[0] 类似于图像质心周围的惯性矩,其中像素的强度类似于物理密度。
hu[0]hu[0]hu[0] 到 hu[5]hu[5]hu[5] 是反射对称的,即如果图像变成镜像,值也不会改变。
hu[6]hu[6]hu[6] 是反射反对称的,即在反射下会改变符号。

矩的应用

比较常用的是质心、面积、方向

(1) 质心坐标:
xˉ=m10m00,yˉ=m01m00\bar{x} = \frac{\texttt{m}_{10}}{\texttt{m}_{00}} , \; \bar{y} = \frac{\texttt{m}_{01}}{\texttt{m}_{00}} xˉ=m00​m10​​,yˉ​=m00​m01​​
(2) 面积:
area=m00area = \texttt{m}_{00} area=m00​
(3)方向:

图像的方向信息可以通过二阶中心矩构造协方差矩阵获得

μ20′=μ20/μ00=M20/M00−xˉ2\mu_{20}'=\mu_{20}/\mu_{00}=M_{20}/M_{00}-\bar{x}^2μ20′​=μ20​/μ00​=M20​/M00​−xˉ2
μ02′=μ02/μ00=M02/M00−yˉ2\mu_{02}'=\mu_{02}/\mu_{00}=M_{02}/M_{00}-\bar{y}^2μ02′​=μ02​/μ00​=M02​/M00​−yˉ​2
μ11′=μ11/μ00=M11/M00−xˉyˉ\mu_{11}'=\mu_{11}/\mu_{00}=M_{11}/M_{00}-\bar{x}\bar{y}μ11′​=μ11​/μ00​=M11​/M00​−xˉyˉ​

图像的协方差矩阵
cov[I(x,y)]=[μ20′μ11′μ11′μ02′]cov[I(x,y)]=\begin{bmatrix} \mu_{20}' & \mu_{11}' \\ \mu_{11}'& \mu_{02}' \end{bmatrix} cov[I(x,y)]=[μ20′​μ11′​​μ11′​μ02′​​]
该矩阵的特征向量对应于图像强度的长轴和短轴。
角度可以由下式给出:
θ=12arctan(2μ11′μ20′−μ02′)\theta=\frac{1}{2} arctan(\frac{2\mu_{11}'}{\mu_{20}'-\mu_{02}'}) θ=21​arctan(μ20′​−μ02′​2μ11′​​)
特征值大小的相对差异表示图像的偏心率,或图像的拉长程度,偏心度可以由下式给出:
1−λ2λ1\sqrt{1-\frac{\lambda_2}{\lambda_1}} 1−λ1​λ2​​​

代码示例

获取图像中某些区域的轮廓,并计算每个轮廓形状的面积和质心。

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
import math# 获取亮度高于阈值的区域
select = (srcMat >= thresh)
select_img = select.astype(np.uint8)# 膨胀,填补孔洞
kernel = cv.getStructuringElement(cv.MORPH_RECT, (2, 2))
dilate_img = cv.dilate(select_img, kernel)# 提取轮廓
_, contours, hierarchy = cv.findContours(dilate_img.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)# 准备可视化
vis = dilate_img.copy()*150
vis = cv.merge([vis,vis,vis])
title = ""# 遍历轮廓
for cnt in contours:# 跳过点特别少的轮廓if cnt.shape[0] < 8:continue# 质心M = cv.moments(cnt)cx = int(M['m10'] / M['m00'])cy = int(M['m01'] / M['m00'])# 面积area = M['m00']# 方向mu20 = M['m20']/M['m00']-cx**2mu02 = M['m02']/M['m00']-cy**2mu11 = M['m11']/M['m00']-cx*cyangle = 1/2*math.atan(2*mu11/(mu20-mu02))degree = math.degrees(angle)cv.circle(vis, (cx,cy), 1, (0, 255, 0), -1)print(f"area={area},center=({cx},{cy})")plt.title(title)
plt.imshow(vis)

输出这个轮廓的相关信息,并画出了轮廓的质心位置:

参考链接

https://docs.opencv.org/3.4/d8/d23/classcv_1_1Moments.html#a8b1b4917d1123abc3a3c16b007a7319b
Hu. Visual Pattern Recognition by Moment Invariants, IRE Transactions on Information Theory, 8:2, pp. 179-187, 1962.
http://en.wikipedia.org/wiki/Image_moment

OpenCV 中的矩(moments)和 Hu不变矩(HuMoments)相关推荐

  1. opencv入门:矩特征,Hu矩

    矩特征 比较两个轮廓最简单的方法是比较二者的轮廓矩,轮廓矩代表了一个轮廓,一副图像,一组点集的全局特征,矩信息包含了对应对象不同类型的集合特征,例如大小,位置,角度,形状等,矩特征广泛应用在模式识别, ...

  2. opencv之图像矩 image moments

    矩的概念介绍 几何矩 几何矩 中心矩 中心归一化矩 图像中心 x0=m10÷m00x_0=m10\div m00x0​=m10÷m00 y0=m01÷m00y_0=m01\div m00y0​=m01 ...

  3. opencv学习(四十三)之图像的矩moments()

    1.概述 图像识别的一个核心问题是图像的特征提取,简单描述即为用一组简单的数据(数据描述量)来描述整个图像,这组数据月简单越有代表性越好.良好的特征不受光线.噪点.几何形变的干扰,图像识别技术的发展中 ...

  4. 机器学习图像特征提取—Hu矩(Hu不变矩)原理及代码

    目录 1 矩的概念 2 Hu不变矩 3 利用opencv-python计算Hu矩 1 矩的概念 图像识别的一个核心问题是图像的特征提取,简单描述即为用一组简单的数据(图像描述量)来描述整个图像,这组数 ...

  5. Hu不变矩+BP神经网络,实现对图像的分类(pytorch实现)

    文章目录 1.网络模型 2.数据集制作 3.模型训练.保存.加载和使用 1.网络模型 方案,如图所示. 先对图片,用hu矩进行特征提取,每个图片产生7个特征值.这7个特征值作为数据,再加上一个标签值. ...

  6. opencv中Hu矩的学习心得

    Hu矩的确很神奇,它具有平移不变性.旋转不变性和缩放不变性,是图形匹配的一个不错的工具. 通过大致对Hu矩的学习,我认为对Hu矩的学习应该有一下几步,第一步要了解什么是矩:第二步再开始了解Hu矩.为了 ...

  7. 探究opencv中的moments函数和HuMoments函数

    用过opencv的人都可能接触过轮廓,一般获取轮廓后我们都需要根据轮廓的特征来筛选出我们要找的目标物体,而筛选轮廓的常用办法都是基于轮廓的周长和面积,然后返回目标轮廓的最小矩阵把目标在原图像上标框出来 ...

  8. OpenCV-Python 中文教程15——OpenCV 中的轮廓

    OpenCV-Python 中文教程15--OpenCV 中的轮廓 一.初识轮廓 目标 • 理解什么是轮廓 • 学习找轮廓,绘制轮廓等 • 函数: cv2.findContours(), cv2.dr ...

  9. Hu不变矩原理及opencv实现

    http://blog.csdn.net/qq_26898461/article/details/47123405 几何矩是由Hu(Visual pattern recognition by mome ...

最新文章

  1. 【mysql】使用tpcc-mysql进行压力测试
  2. 解决锚点在IE8中失效
  3. c语言的单行注释范围,c语言中的注释,multi-line comment
  4. WordPress自动采集插件:WP-CTspider(长腿蜘蛛)
  5. 对“车库咖啡的网络现状改造”的一点个人看法
  6. oracle19c 安装权限_Oracle 数据库安装系列一:19C 软件安装和补丁升级
  7. java websocket 生存期_Java WebSocket生命周期
  8. python之路_django分页及session介绍
  9. Android P Beta!您想要知道的所有更新内容都在这里
  10. linux 进入recovery 命令行,liunx-fastboot命令行的使用方法
  11. SQL*Plus 系统变量之36 - PAGES[IZE]
  12. jQuery-对联广告
  13. 2017年的6个大数据发展趋势
  14. 人工神经网络 经验公式_不会算工程成本?建筑测算一本通+全套自动计算表,公式可套定额...
  15. 冒泡排序原理以及算法
  16. 某电信运营商客户是否会流失的预测分析
  17. 【ios开发技术研究】Xcode8 及iOS10适配问题整理汇总
  18. KMP算法(字符串匹配)
  19. Vulhub漏洞靶场搭建
  20. js如何获取jwt信息_企业舆情要怎么获取,如何处理负面舆情信息?

热门文章

  1. java调用espeak_espeak-example Java for windows文本转语音,用 引擎 Other systems 其他 244万源代码下载- www.pudn.com...
  2. 学习管理!!中国历史上最经典的7个智慧案例
  3. 战舰少女服务器不显示,老玩家告诉你游戏战舰少女连不上网的解决方法
  4. 怎么算程序框图的计算机程序,算法与程序框图导学案
  5. 《Universal Language Model Fine-tuning for Text Classification》翻译
  6. 信数金服决策引擎分享(一):来聊聊冠军/挑战者试验,一个数字游戏
  7. 文献 | 你的狗狗是否也很擅长“察言观色”?
  8. 很经典的600句人生至理格言
  9. Camera,音频录制与Vitamio框架
  10. COGNOS安装笔记