OpenCV 形状分析(上):计算轮廓中心

1178 查看

5

今天,我们将开始由3部分构成的形状检测分析系列教程。

通过此系列教程,我们将学到如何:

  1. 计算轮廓/形状的中心;
  2. 仅使用轮廓特征识别出不同的形状,如:圆、正方形、长方形、三角形和五角形。
  3. 标记形状颜色

尽管今天的内容比较基础(相对于最近 PyImageSearch 博客讨论的更加高级的概念来说),但是也经常有人问我下边这个问题:

如何用 Python 和 OpenCV 计算轮廓的中心?

在今天的教程中,我将会回答这个问题。

在以后的教程中,我们将在轮廓知识的基础上进行图像的形状识别。

使用 OpenCV 计算轮廓中心

包含不同形状的待计算轮廓中心的示例图

图1:包含不同形状的待计算轮廓中心的示例图像

从上图中,你能看见几种不同的由图画纸裁出的形状。注意,这些形状并不完美——矩形不够方,圆形不够圆。它们都是先经手工描画然后再裁出来的,这意味着每种形状都存在着偏差。

明确了这一点之后,今天教程的目标是:(1)检测出图像中的每一种形状的轮廓(2)计算轮廓的中心——也叫形心。

为了达成以上目标,我们需要对图像进行以下预处理:

  • 转换成灰度图;
  • 滤波以减少高频噪声,使轮廓检测更加精确;
  • 图像二值化。边缘检测和阈值化经常被用于此过程,本教程采用阈值化。

开始写代码之前,请确保你的系统已经安装了 imutils Python 包[ 译注:该包为作者开发的一系列用 OpenCV 执行基本图像处理操作的简便函数]。

让我们继续!

新建一个文件,命名为 center_of_shape.py,然后开始写代码吧:

第2-4行代码导入必需的包,第7-10行代码解析命令行参数。此处只需要一个 --image 参数: 磁盘中待处理图像的路径。

随后程序从磁盘加载图像,然后进行预处理,执行灰度变换,5×5 内核的高斯平滑,最后阈值化(14-17行)。

阈值化操作后的输出如下图所示

图2:阈值化图像操作返回二值图像,其中形状被表示为黑色背景上的白块

图2:图像阈值化返回二值图像,其中形状被表示为黑色背景上的白块

注意阈值化后形状被表示成黑色背景上的白色前景。

下一步是使用轮廓检测去定位这些白色区域。

第 20-21 行代码调用 cv2.findContours 函数,该函数返回图像上每一个白块对应的边界点集合(即轮廓)。第22行基于我们使用 OpenCV 2.4 版本还是3.0 版本而取不同的元组值。获取更多 cv2.findContours 函数返回签名在不同 OpenCV 版本间的改变,请移步此文。[译注:OpenCV 2.4 版本的 cv2.findContours 函数返回的是一个二元元组,元组的第一个元素(索引 0)是轮廓列表。而在 OpenCV 3.0 版本中,该函数返回的是一个三元元组,元组的第二个元素(索引 1)才是轮廓列表]

我们已经准备去处理每一条轮廓:

第25行开始遍历轮廓,然后在第27行计算轮廓区域图像的矩

在计算机视觉和图像处理领域,图像的矩经常被用来描述图像中某个对象的形状。这些矩描述了形状的基本统计特征,包括对象的面积、形心(即对象的中心坐标 (x, y))、取向连同其他有用的特征。

我们只对图像的中心感兴趣,所以在第28-29行计算轮廓的中心。

随后,第32-34行完成以下任务:

  • 调用 cv2.drawContours 函数绘制包围当前形状的轮廓;
  • 在形状的中心 (cX, cY) 处绘制一个白色的小圆;
  • 在白色小圆的附近写上文字 center

要执行脚本,打开终端然后执行以下命令:

运行结果如下图所示:

图3:

图3:分别遍历每一个形状并计算每一个形状的中心 (x, y)。(点击图片有惊醒)

注意每一个形状都被成功地检测到,然后计算出轮廓中心并绘制在图像上。

总结

在这次教程中,我们学习了如何使用 OpenCV 和 Python 去计算轮廓的中心。

此教程是由三部分构成的形状分析系列教程的第一部分。

在下周的教程中,我们将学习如何识别图像中的形状

然后,在两周以后,我们将学习如何分析每一个形状的颜色并将其标记在形状上(即标记“红”、“绿”、“蓝”等等)。

为了确保这些教程写成的时候您能被通知到,请按照以下形式输入您的邮箱地址![译注:原博客提供代码下载和邮件提醒功能。戳我访问原文。]