OpenCV中几何形状识别与测量

OpenCV中几何形状识别与测量


写有代码的文章、做有情怀的人


经常看到有学习OpenCV不久的人提问,如何识别一些简单的几何形状与它们的颜色,其实通过OpenCV的轮廓发现与几何分析相关的函数,只需不到100行的代码就可以很好的实现这些简单几何形状识别与对象测量相关操作。本文就会演示给大家如何通过OpenCV 轮廓发现与几何分析相关函数实现如下功能:

  • 几何形状识别(识别三角形、四边形/矩形、多边形、圆)
  • 计算几何形状面积与周长、中心位置
  • 提取几何形状的颜色

在具体代码实现与程序演示之前,我们先要搞清楚一些概念。

一:基本概念与函数介绍

1. 轮廓(contours)

什么是轮廓,简单说轮廓就是一些列点相连组成形状、它们拥有同样的颜色、轮廓发现在图像的对象分析、对象检测等方面是非常有用的工具,在OpenCV中使用轮廓发现相关函数时候要求输入图像是二值图像,这样便于轮廓提取、边缘提取等操作。轮廓发现的函数与参数解释如下:

findContours(image, mode, method, contours=None, hierarchy=None, offset=None)
- image输入/输出的二值图像
- mode 返回轮廓的结构、可以是List、Tree、External
- method 轮廓点的编码方式,基本是基于链式编码
- contours 返回的轮廓集合
- hieracrchy 返回的轮廓层次关系
- offset 点是否有位移

2. 多边形逼近

多边形逼近,是通过对轮廓外形无限逼近,删除非关键点、得到轮廓的关键点,不断逼近轮廓真实形状的方法,OpenCV中多边形逼近的函数与参数解释如下:

approxPolyDP(curve, epsilon, closed, approxCurve=None)
- curve 表示输入的轮廓点集合
- epsilon 表示逼近曲率,越小表示相似逼近越厉害
- close 是否闭合

3. 几何距计算

图像几何距是图像的几何特征,高阶几何距中心化之后具有特征不变性,可以产生Hu距输出,用于形状匹配等操作,这里我们通过计算一阶几何距得到指定轮廓的中心位置,计算几何距的函数与参数解释如下:

moments(array, binaryImage=None)
- array表示指定输入轮廓
- binaryImage默认为None

二:代码实现与演示

基于轮廓发现与多边形逼近、几何距实现几何形状识别与对象测量,测量时候还用到另外两个相关API分别是计算轮廓的周长与面积。具体用法在代码中体现。整个代码实现分为如下几步完成: 1.图像二值化

# 二值化图像
print("start to detect lines...\n")
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
cv.imshow("input image", frame)

2.轮廓发现

out_binary, contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
for cnt in range(len(contours)):
    # 提取与绘制轮廓
    cv.drawContours(result, contours, cnt, (0, 255, 0), 2)

3.几何形状识别

# 轮廓逼近
epsilon = 0.01 * cv.arcLength(contours[cnt], True)
approx = cv.approxPolyDP(contours[cnt], epsilon, True)

# 分析几何形状
corners = len(approx)
shape_type = ""
if corners == 3:
    count = self.shapes['triangle']
    count = count+1
    self.shapes['triangle'] = count
    shape_type = "三角形"
if corners == 4:
    count = self.shapes['rectangle']
    count = count + 1
    self.shapes['rectangle'] = count
    shape_type = "矩形"
if corners >= 10:
    count = self.shapes['circles']
    count = count + 1
    self.shapes['circles'] = count
    shape_type = "圆形"
if 4 < corners < 10:
    count = self.shapes['polygons']
    count = count + 1
    self.shapes['polygons'] = count
    shape_type = "多边形"

4.测量周长、面积、计算中心

# 求解中心位置
mm = cv.moments(contours[cnt])
cx = int(mm['m10'] / mm['m00'])
cy = int(mm['m01'] / mm['m00'])
cv.circle(result, (cx, cy), 3, (0, 0, 255), -1)

# 计算面积与周长
p = cv.arcLength(contours[cnt], True)
area = cv.contourArea(contours[cnt])

5.颜色提取

# 颜色分析
color = frame[cy][cx]
color_str = "(" + str(color[0]) + ", " + str(color[1]) + ", " + str(color[2]) + ")"

运行显示原图如下:

分析结果:

控制台输出:

原文发布于微信公众号 - OpenCV学堂(CVSCHOOL)

原文发表时间:2018-04-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏量化投资与机器学习

从Seq2seq到Attention模型到Self Attention(二)

系列一介绍了Seq2seq和 Attention model。这篇文章将重点摆在Google於2017年发表论文“Attention is all you ne...

77950
来自专栏懒人开发

(10.3)James Stewart Calculus 5th Edition:Polar Coordinates

这个时候,我们知道半径r = 2 所有的角度都是适合的 我们很容易得到一个圆:

11230
来自专栏AI研习社

手把手教你用 PyTorch 辨别自然语言(附代码)

最近在学pyTorch的实际应用例子。这次说个简单的例子:给定一句话,判断是什么语言。这个例子是比如给定一句话: Give it to me 判断是 ENGLI...

37850
来自专栏CreateAMind

浅析互信息与特征选择

那么什么是互信息呢?变量x与变量y之间的互信息,可以用来衡量已知变量x时变量y的不确定性减少的程度,同样的,也可以衡量已知变量y时变量x的不确定性减少的程度。

63420
来自专栏专知

【ACL2018】什么都能GAN,无监督神经网络翻译新方法

30220
来自专栏cs

NLP问题之word2vec

其用于有如下的 从「中文分词」、「词云画像」、「词性分析」到「自动摘要」、「关系挖掘」、「情感分析」、「知识图谱」等

25820
来自专栏算法channel

机器学习|聚类算法之DBSCAN

DBSCAN,全称:Density-Based Spatial Clustering of Applications with Noise,是一个比较有代表性的...

56090
来自专栏用户2442861的专栏

python数字图像处理(17):边缘与轮廓

在前面的python数字图像处理(10):图像简单滤波 中,我们已经讲解了很多算子用来检测边缘,其中用得最多的canny算子边缘检测。

44110
来自专栏AI科技评论

开发|简单有趣的 NLP 教程:手把手教你用 PyTorch 辨别自然语言(附代码)

最近在学pyTorch的实际应用例子。这次说个简单的例子:给定一句话,判断是什么语言。这个例子是比如给定一句话: Give it to me 判断是 ENGLI...

32270
来自专栏贾志刚-OpenCV学堂

OpenCV中实现曲线与圆拟合

使用OpenCV做图像处理与分析的时候,经常会遇到需要进行曲线拟合与圆拟合的场景,很多OpenCV开发者对此却是一筹莫展,其实OpenCV中是有现成的函数来实现...

42940

扫码关注云+社区

领取腾讯云代金券