首先说一下我的整体思路:

① 首先定义了一个识别器类型,封装了计算边长,识别形状和展示结果三个函数。

② 主函数先读入图片,然后将图片转化为灰度图片,然后高斯滤波平滑处理,然后将灰度图片转化为黑白两色图片。

③ 调用函数识别图片中所有的轮廓,然后列表形式返回图片,轮廓等信息,然后只取轮廓的所有点信息(每个点的信息为平面坐标)作为一个列表程序(第91,92,93行代码)

④ 用之前创建的识别器实例对每个轮廓中的点进行多边形拟合,得到顶点的坐标的列表中去(class中28~32行代码)

⑤ 输出识别结果

以下是代码部分:(注意,这里是opencv3的代码,请先检查自己的opencv版本)

import cv2
import mathTHRESHOLE_VALUE=60
COEFFICIENT=0.02class ShapeDetector:#初始化类def __init__(self):#字典类型对应每一种图形的计数器self.counter = {"unrecognized image": 0, "triangle": 0, "rhombus": 0, "rectangle": 0, "pentagon": 0,"hexagon": 0, "circle": 0}#初始化图形类型为不可识别self.shape = "unrecognized image"#图形顶点集置空self.approx = []#初始化该图形的周长为0self.peri = 0# 计算欧式距离(主要作用通过计算边长区分菱形和长方形)def distance(self, x1, y1, x2, y2):return math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)def detect(self, c):#cv2.arcLength函数返回周长self.peri = cv2.arcLength(c, True)#cv2.approxPolyDP用多边形取拟合,返回的是顶点的列表self.approx = cv2.approxPolyDP(c, COEFFICIENT * self.peri, True)#3个顶点,三角形if len(self.approx) == 3:self.shape = "triangle"#同理,四个顶点,四边形elif len(self.approx) == 4:#计算相邻两边的长度,做差判在误差范围内是否相等dist1 = self.distance(self.approx[0][0][0], self.approx[0][0][1], self.approx[1][0][0],self.approx[1][0][1])dist2 = self.distance(self.approx[0][0][0], self.approx[0][0][1], self.approx[3][0][0],self.approx[3][0][1])result = math.fabs(dist1 - dist2)# print(result)#误差小于10,可近似认为相等,为菱形if result <= 10:self.shape = "rhombus"else:self.shape = "rectangle"#五边形elif len(self.approx) == 5:self.shape = "pentagon"#六边形elif len(self.approx) == 6:self.shape = "hexagon"#圆else:self.shape = "circle"#相应形状计数器加一self.counter[self.shape] += 1#返回形状return self.shapedef Display(self):#展现结果for kind in self.counter.keys():print("The number of {} is {}".format(kind, self.counter[kind]))def main():#读入图片testID = "test.png"image = cv2.imread(testID)#将图片转换为灰度图片gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 高斯滤波,图像平滑处理blurred = cv2.GaussianBlur(gray, (5, 5), 0)#根据阈值,将灰度图片转化为黑白两色图片thresh = cv2.threshold(blurred, THRESHOLE_VALUE, 255, cv2.THRESH_BINARY_INV)[1]#返回图片和图中轮廓信息,列表形式返回到cnts中cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)#只需要取轮廓上点的信息cnts = cnts[1]#创建一个识别器实例sd = ShapeDetector()#分别对每个轮廓进行处理for c in cnts:#得到形状shape = sd.detect(c)#print(shape)#输出结果sd.Display()if __name__=="__main__":main()

以下为本程序用到的函数表:
(第9行)init(self) (类初始化函数)

(第23行)distance(self, x1, y1, x2, y2): (计算(x1,y1),(x2,y2)两点之间的距离,点为像素坐标)

(第24行)math.sqrt() (数学开平方运算)

(第26行)detect(self, c): (判断轮廓的形状)

(第28行)cv2.arcLength()(计算周长函数。一参数c是轮廓的点集;二参数true代表闭合,false代表开放。)
链接:https://blog.csdn.net/u011854789/article/details/79836242

(第31行) cv2.approxPolyDP()(多边形拟合函数。
一参数c是轮廓的点集;

二参数代表图形边长允许的偏差范围,因为图片中的图形边长上是凹凸不平的,但是电脑是根据标准的直线来进行边的拟合,所以难免每个点处都有和标准直线偏差的距离,此参数便是设置最大偏差距离不能超过多少,不然就会用一个新的边拟合,此处设置的是边长的百分之二;

三参数为true指示拟合的多边闭合,false为开放。 返回值为拟合出来的所有图形顶点坐标,用列表表示)

链接:https://blog.csdn.net/brooknew/article/details/103512228

(有好几行) len()(计算可迭代对象的长度)

(第71行)Display(self)(输出结果)

(第74行) print()(通过标准输出流将缓冲区信息输出到控制台(str.format的用法自己查))

(第79行) cv2.imread()(读入图片,
一参数图片路径;
二参数加载形式,可缺省)
链接:https://blog.csdn.net/lccrun/article/details/95594268

(第83行) cv2.cvtColor(转换颜色空间函数,
一参数为原图片;
二参数为转换的方法,常见的转化方法见链接)
链接:https://blog.csdn.net/m0_37192554/article/details/81946430

(第85行) cv2.GaussianBlur()(高斯滤波函数,图像平滑处理。
一参数是源图片;
二参数是高斯矩阵的大小;
三参数表示标准差。此函数用用就行不用搞懂具体干啥,如果感兴趣可以看下面的链接)
链接:https://blog.csdn.net/weixin_44657197/article/details/102679434

(第87行) cv2.threshold()(图像阈值处理函数,
一参数为源图片;
二参数为阈值;
三参数为设置颜色的最大RGB值;
四参数为划分的方法。

此函数的目的是为了将图片转化为黑白二色图,根据常识,颜色深的是黑色,颜色浅的是白色对吧,那么如何定义颜色的深浅呢?先补充一下:
***RGB:***计算机中常用的表示颜色的方法。计算机上每一个像素点都是三个颜色不同比例得到的,由一个元组来表示(R,G,B),分别代表红色,绿色和蓝色。
主流的划分是每个位置划分为256个段位,用0~255的整数表示,比如(255,255,255)就是最白的白色,(0,0,0)就是最黑的黑色,(255,0,0)就是最亮的红色。                            ***灰度:***前面的cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)就是将RGB彩色图片转换为灰度图片。具体的转换公式不用管,但是灰度为50的图片RGB值为(50,50,50)这个知道就行了。

第二参数阈值:对图片的每个像素点,根据RGB值计算其灰度,如果灰度大于这个阈值,那么就变成黑色(或者白色),小于等于就变成白色(或者黑色)。

第三参数最大RGB值:就是把灰度变成255,说白了就是白色 第四参数划分方法:见下图
dst(x,y)是(x,y)处像素之后的灰度,src(x,y)是源图片在(x,y)坐标像素的灰度)

链接:https://blog.csdn.net/a19990412/article/details/81172426

(第90行) cv2.findContours()(寻找图片中的所有轮廓,
一参数为带轮廓的图片;
二参数为找到的轮廓的输出形式;
三参数为指定轮廓的近似方法,返回值的话只需要取列表中的第二个,即可获得所有轮廓的所有点坐标。详细见链接)

链接:https://blog.csdn.net/u014120499/article/details/99675967

备注:
1、在使用cv2.threshold()函数时,第四个参数划分方法,当背景为白色时要用cv2.THRESH_BINARY_INV但是背景为黑色是要去掉_INV,用cv2.THRESH_BINARY。其他背景颜色自己想一想吧。。。。。。
2、要是统计的个数出现了问题的话,这是精度的问题,比如我当前设置下,圆的边数是8,改变精度只需要调整全局变量COEFFICIENT的大小就行

祝学习愉快~

评价(涂红):* * * * *

基于python OpenCV多边形图像识别的实现相关推荐

  1. 基于python+OpenCV的车牌号码识别

    基于python+OpenCV的车牌号码识别 车牌识别行业已具备一定的市场规模,在电子警察.公路卡口.停车场.商业管理.汽修服务等领域已取得了部分应用.一个典型的车辆牌照识别系统一般包括以下4个部分: ...

  2. 基于python opencv人脸识别的签到系统

    基于python opencv人脸识别的签到系统 前言 先看下效果 实现的功能 开始准备 页面的构建 功能实现 代码部分 总结 前言 一个基于opencv人脸识别和TensorFlow进行模型训练的人 ...

  3. 基于Python+OpenCV车道线检测(直道和弯道)

    基于Python+OpenCV车道线检测(直道和弯道) 基于Python+OpenCV车道线检测(直道和弯道)

  4. 基于python 使用sikuli图像识别

    基于python使用sikuli图像识别 import time from jpype import * 参考如下代码段: if __name__ == '__main__':startJVM(r'C ...

  5. 【开源分享】基于Python+OpenCV+PyQt5车牌识别(GUI界面)

    亲测无错:基于Python+OpenCV+PyQt5车牌识别(GUI界面)绝对可以用的!!!!! 基于Python+OpenCV+PyQt5车牌识别(GUI界面) 参考文档

  6. 基于python+opencv+pyautogui的图像识别点击

    第一次发文没啥经验 很多都是借鉴若有侵权请告知 必更改 开源代码只供学习交流请勿用作其他用途!!! get_img()#这个函数是获取rgb格式屏幕截图,可用于截图一次识别多个元素 imgclick( ...

  7. 基于python+opencv的图像目标区域自动提取

    向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程   公众号:datayx 一.提取纸张中的内容 一张照片中的感兴趣区域总是沿着x,y,z三个轴都有一定倾斜(如下图),要 ...

  8. 基于python+openCV的中值滤波

    先直接来一个3×3的吧 def median(src_img, filter_size, channels):# 首先,定义一个大小为9的0数组# list = [[0, 0, 0, 0, 0, 0, ...

  9. python drawline_基于python,OPenCv中基本的绘图函数

    (一)OpenCv中,python接口的基本的绘图函数 1-用于绘制直线的--------cv2.line()函数 2-用于绘制椭圆的--------cv2.ellipse()函数 3-用于绘制矩形的 ...

最新文章

  1. linq.designer.cs学习笔记
  2. 在水晶报表中实现任意选择指定字段显示-模板及C#升级版
  3. Docker导入、导出、删除容器
  4. 信息学奥赛一本通C++语言——1002:输出第二个整数
  5. jquery mysql表格_使用jQuery设计数据表格:设计表格基类
  6. Hadoop集群搭建过程中ssh免密码登录(二)
  7. 【word】为什么word分两栏的最后一页左边一栏没写完跑到右边去了
  8. 数据库服务器系统崩溃,mssql数据库系统崩溃后的一般处理步骤与方法
  9. PotPlayer+SVP4视频补帧简易教程
  10. 曝光三要素:光圈、快门、ISO
  11. 如何给 ReactJS 应用增加配置文件?
  12. Java实现碧蓝航线连续作战
  13. PS进阶篇——如何PS软件给房间地板换颜色(五)
  14. 计算机网络部分知识梳理
  15. python雪花_用 Python 实现雪花效果
  16. 简单易懂且有趣的pycharm运行小游戏
  17. 在Windows Embedded Standard中阻止安装提示和OOBE
  18. 关于w5500客户端和服务器的调试心得
  19. 施努卡:机器视觉产业前景(机器视觉技术的发展及应用)
  20. Origin如何绘制三维图形?

热门文章

  1. vmware-nat模式下网络模型
  2. Python爬虫——爬虫是什么都可以爬的吗?Robots协议!
  3. 弓形锯床主传动及工作机构设计
  4. 51单片机的智能灯光控制系统
  5. 一个完整的Django入门指南 - 第1部分
  6. C++:乱码之字符串编码
  7. C++嵌套循环打印字母表
  8. Golang实现文件搜索器
  9. 我们以为长大了就很懂得爱,却不明白小孩子才是最懂爱的(小王子,豆瓣9.0)
  10. 工具篇:Java中邮件类MimeMessage说明