一文弄懂图像的矩和相关应用

01

引言

在数字图像处理、计算机视觉与相关领域中,图像矩(Image moments)是指图像的某些特定像素灰度的加权平均值(矩),或者是图像具有类似功能或意义的属性。

图像矩通常用来描述 分割 后的图像对象。可以通过图像的矩来获得图像的部分性质,包括面积(或总体亮度),以及有关几何中心方向的信息 。

02

原始矩

对于灰度图像f,其(p+q)阶矩(有时称为'原始矩'),定义如下:

原始矩中包含以下有关原始图像属性的信息:

  • 二值图像或者或度图像的像素总和,可以表示为:  ,即

  • 图像的几何中心也叫质心  ,计算公式如下:

03

中心矩

中心矩是以质心为中心的矩,相比原始矩,只要添加一个平移即可,中心矩的定义如下:

上述公式中的   为图像的质心.

有了中心矩的定义,我们可以得到图像f的协方差矩阵,其定义为:

接着我们可以计算该协方差矩阵的特征向量,最大特征值对应的特征向量就是物体长轴的角度,我们可以将其定义为物体的方向.

该角度计算公式如下:

04

中心矩的性质

接下来我们推导一下阶数较低的中心矩的性质:

04

应用

推导了一堆公式,不知道小伙伴有没有觉得很枯燥。

好的吧,接下来我们来举个栗子,进入轻松的写代码实战环节.

本节的目的在于利用矩求出前景物体的中心点以及长轴的角度.

1) 读取图像

我们这里以一群飞翔的大雁组成的图像为例来进行讲解,首先我们读入图像并执行灰度化,代码如下:

img_file = './images/bird_swarm.jpg'img = cv2.imread(img_file,cv2.IMREAD_COLOR)gray_img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)

效果如下:

上图中,左侧为原始输入图,右侧为灰度化后的图像.

2) 二值化 

通过第二章节我们知道,二值图像的原始矩就是所有像素值之和,所以我们可以先进行二值化来提取我们的前景物体,二值化代码如下:

retval, bin_img = cv2.threshold(gray_img, 50, 1, cv2.THRESH_BINARY)show_img = bin_img * 255

结果如下:

可以看出,我们使用较低的阈值,将前景大雁(白色部分)通过二值化提取出来.

3) 图像矩的计算

接下来我们来计算图像矩,我们得到的二值化图中,对于前景大雁来说  ,对于背景黑色像素值来说  .

根据上文矩的定义,编写代码如下:

m00 = m01 = m10 = m11 = m20 = m02 = m21 = m12 = 0height, width = bin_img.shapefor y in range(height): for x in range(width): m00 += bin_img[y, x] m10 += x * bin_img[y, x] m01 += y * bin_img[y, x] m11 += x * y * bin_img[y, x] m20 += x * x * bin_img[y, x] m02 += y * y * bin_img[y, x] m21 += x * x * y * bin_img[y, x] m12 += x * y * y * bin_img[y, x]

进而利用以下代码可以得到中心点的位置坐标:

cx = m10/m00cy = m01/m00print('Centriod: ({0:.2f}, {1:.2f})'.format(cx, cy))

输出如下:

Centriod: (1039.64, 660.24)

画到图像上,结果如下:

上图中的红色小圆圈即为计算出来的大雁群的中心点.

4) 计算角度

根据上述中心矩的定义和物体长轴角度的定义,我们可以计算出大雁群长轴和水平线的夹角,代码如下:

mu00 = m00mu11 = m11 - cx*m01mu20 = m20 - cx*m10mu02 = m02 - cy*m01theta = 1/2*np.arctan2(2*mu11/mu00, (mu20 - mu02)/mu00)print('Angle {0:.2f}'.format(theta*180/np.pi))

输出如下:

Angle 37.96

5) 结果可视化

虽然通过上述代码,我们可以计算出大雁群的质心和长轴角度,但是只有数值不太直观,那么我们接下来来可视化上述输出.

我们现在在原始图像上绘制长轴和短轴(这里设置默认长度)以可视化说明质心和角度的位置。

代码如下:

# visualrho = 800dx_major = rho * np.cos(theta)dy_major = rho * np.sin(theta)dx_minor = 0.3 * rho * np.cos(theta - np.pi / 2)dy_minor = 0.3 * rho * np.sin(theta - np.pi / 2)# shortshort_axis=[(int(cx-dx_minor),int(cy-dy_minor)),(int(cx),int(cy)),(int(cx+dx_minor),int(cy+dy_minor))]for i in range(len(short_axis)-1):    cv2.line(img,short_axis[i],short_axis[i+1],color=(255,0,0),thickness=2)for pt in short_axis:    cv2.circle(img,pt,radius=5,color=(255,0,0),thickness=3,lineType=-1)# longlong_axis = [(int(cx - dx_major), int(cy - dy_major)), (int(cx), int(cy)), (int(cx + dx_major), int(cy + dy_major))]for i in range(len(long_axis) - 1):    cv2.line(img, long_axis[i], long_axis[i + 1], color=(0, 0, 255), thickness=2)for pt in long_axis:    cv2.circle(img,pt,radius=5,color=(0,0,255),thickness=3,lineType=-1)# centercv2.circle(img, (int(cx),int(cy)), radius=5, color=(0, 255, 0), thickness=3, lineType=-1)# showcv2.imshow('img',img)cv2.waitKey(0)

运行结果如下:

上图中,蓝色边为大雁群的短轴,红边为大雁群的长轴,绿色圆圈为大雁群的几何中心.

05

总结

本文介绍了图像矩和中心矩的相关定义和一些基本性质,并举例来实现对图像矩的求解和可视化得到的结果,并给出了完整代码实现。

您学废了吗?

(0)

相关推荐

  • 基于OpenCV的图像翻转和镜像

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本期,我们将解释如何在Python中实现图像的镜像或翻转.大家只需 ...

  • SLAM程序阅读(第8讲 稀疏直接法)

    距离上次读程序好像已经过去了好久,因为有一门考试需要复习.上次读的LK光流法程序主要调用了CV内置的LK光流法求解函数calcOpticalFlowPyrLK,进行了光流法跟踪特征点的一些演示.本次阅 ...

  • OpenCV-Python,计算机视觉开发利器

    人工智能,一个已经被谈论了几十年的概念(最早是图灵在1950年提出).如今这几年,相关技术的发展速度是越来越快.高大上如无人驾驶.智能安防.AI辅助诊断,接地气如刷脸支付.内容推荐.自动翻译等,众多领 ...

  • python 图像处理:一福变五福

    快过年了,各种互联网产品都出来撒红包.某宝一年一度的集五福(shua hou)活动更是成为每年的必备活动.虽然到最后每人大概也就分个两块钱,但作为一个全民话题,大多数人还是愿意凑凑热闹.毕竟对于如今生 ...

  • (9条消息) ocr图像预处理

    说明:文字方向校正(fft方式和放射变换方式)参考了网上的代码,只做了少量修改 只针对医疗影像图像,自然场景下的另说 因为处理的图像都很大很大,居然有11000*12000这种分辨率的,有90M大小, ...

  • 图像旋转90/180 opencv坐标系

    问题描述: 图像旋转90.180.270等 使用类似下面的代码,会有黑边,图像变形之类的问题 其实windows系统自带类似的功能,但是我需要批量处理图像,因此尝试自己写 算法基础: 这种直角的旋转, ...

  • 实战:使用 OpenCV 和 PyTesseract 对文档进行OCR

    重磅干货,第一时间送达 随着世界各地的组织都希望将其运营数字化,将物理文档转换为数字格式是非常常见的.这通常通过光学字符识别 (OCR) 完成,其中文本图像(扫描的物理文档)通过几种成熟的文本识别算法 ...

  • python+opencv图像处理(四十二)

    Kirsch算子 1.Kirsch算子 Kirsch算子是R.Kirsch提出来一种边缘检测新算法,它采用8个模板对图像上的每一个像素点进行卷积求导数,这8个模板代表8个方向,对图像上的8个特定边缘方 ...

  • python+opencv图像处理(十二)

    图像仿射变换和透视变换 天晴了...... 1.仿射变换 图像的仿射变换就是图像的旋转加上拉升,说直白点,就是把矩形变成平行四边形. 要把矩形变成平行四边行,只需要拉伸其四个角点就行了,事实上,只需要 ...

  • 使用OpenCV实现图像增强

    重磅干货,第一时间送达 本期将介绍如何通过图像处理从低分辨率/模糊/低对比度的图像中提取有用信息. 下面让我们一起来探究这个过程: 首先我们获取了一个LPG气瓶图像,该图像取自在传送带上运行的仓库.我 ...