opencv之基本形状识别
文章目录
- opencv之基本形状识别
- 各种博客上的现有方法
- 新方法——从信号的角度分析
- 实验结果
- 通过上面这些图可以得到图下结论:
- 附代码
opencv之基本形状识别
各种博客上的现有方法
- https://blog.csdn.net/xuxunjie147/article/details/76577298 这篇博客只是展示了代码,并没有讲解解决问题的思路。笔者通过阅读其代码,将其思路总结如下:
- https://www.cnblogs.com/long5683/p/9694983.html 这篇博客使用面积和多边形拟合后的顶点数进行各种形状的分类。但是这种方法只是适应于他给的那张图片。
- https://blog.51cto.com/gloomyfish/2104134?lb 这篇博客的方法主要是通过arcLength计算原始轮廓的周长,然后通过多边形拟合逼近原始周长。最后使用多边形拟合得到的顶点数进行分类。三个顶点就是三角形,4个顶点就是矩形,4-10个顶点是不规则多边形,10个以上是圆。但是对于不规则的四边形,这种方法显然会失效。因为该方法并没有考虑每个顶点处的角度。
- https://www.jianshu.com/p/2731f42882f4 这篇博客所使用的方法思路与上一篇博客基本类似。
新方法——从信号的角度分析
- 具体步骤如下:
- 使用findcontours找到所要识别的图形的轮廓。
- 在轮廓的基础上,使用图形的矩(moments)计算得到图形的重心。
- 使用drawcontours绘制轮廓,并得边缘的坐标位置
- 计算边缘上所有的点到重心的距离,按照逆时针绕重心转动的方向绘制距离随角度变化的图。
- 进行距离归一化
实验结果
- 圆形及其对应的距离-角度变化图
- 椭圆及其对应的距离-角度变化图
- 五边形及其对应的距离-角度变化图
- 矩形及其对应的距离-角度变化图
- 正方形及其对应的距离-角度变化图
- 平行四边形及其对应的距离-角度变化图
- 三角形及其对应的距离-角度变化图
通过上面这些图可以得到图下结论:
- 多边形(不包括圆和椭圆)的距离-角度图像存在大量导数不存在的点,且不可导点的数量等于顶点的个数。
- 多边形的顶点对应的角度越大,其不可导点的尖锐程度越小,即左导数和右导数的差距越小。
- 对称图形的距离-角度图像呈现高度的对称性甚至周期性。
附代码
程序是早些时候写得,没有封装成独立的函数,还有些啰嗦。代码是进行批处理的,读者可以稍微改一下程序中使用的路径。
大体的思路是先找到轮廓,然后根据轮廓计算重心位置和轮廓各个点到重心的距离。但是opencv的findcontours只会返回决定轮廓的几个重要的点,比如矩形轮廓只会返回4个顶点的坐标。为了得到所有轮廓的点,使用drawcontours先把轮廓画出来,然后根据像素值找到轮廓所有点的坐标位置。由于轮廓是画出来的,所以drawcontours的linewidth参数相当于控制绘制轮廓精细程度的一个参数。
代码中还使用fft和差分这两种时间序列分析手段分析我们的得到的数据。希望能对读者有所帮助。
代码很久没有运行,如果有bug,还望海涵。
# -*- coding:utf8 -*-
# @TIME : 2019/7/11 16:03
# @Author : SuHao
# @File : main.pyimport numpy as np
import cv2
import os
import matplotlib.pyplot as plt
import scipy.fftpack as fftpath_pic = "./pic"
filename = os.listdir(path_pic)
path_result = "./result"
if not os.path.exists(path_result):os.mkdir(path_result)for i in range(len(filename)):image = cv2.imread(path_pic + "/" + filename[i], 0)ret, thresh = cv2.threshold(image, 100, 255, 0)#计算轮廓out, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)drawing = np.zeros(image.shape) + 255imgnew = cv2.drawContours(drawing, contours, 1, (0, 255, 255), 0)#确定轮廓的重心mu = cv2.moments(contours[1])cx = int(mu['m10']/mu['m00']) #表示列数,是横坐标cy = int(mu['m01']/mu['m00'])#计算轮廓到重心的距离'''这里遇到一个问题:轮廓不总是一个像素点,也就是说轮廓是有厚度的'''label = np.where(drawing == 0)#注意此处矩阵元素的下标与在二维平面的坐标是反的,行表示纵坐标location = np.array(label).Tlocation = location[:, ::-1]location = location.astype("int64")center = np.array([[cx, cy]])center = np.tile(center, (location.shape[0], 1))center = center.astype("int64")dist = (location - center)**2dist = np.sqrt(dist.sum(axis=1))up = location[:, 1] <= cy #注意在重心以上,对应纵坐标是小down = location[:, 1] > cylocation_up = location[up, :]location_down = location[down, :]dist_up = dist[up]dist_down = dist[down]angle_up = location_up[:, 0] - cxangle_up = np.arccos(angle_up / dist_up)angle_down = location_down[:, 0] - cxangle_down = np.arccos(angle_down / dist_down) * (-1) + np.pi * 2location = np.vstack((location_up, location_down))dist = np.hstack((dist_up, dist_down))angle = np.hstack((angle_up, angle_down))order = np.argsort(angle, axis=0)dist = dist[order]location = location[order]angle = angle[order]plt.figure()plt.plot(angle, dist / max(dist))plt.title(filename[i])plt.ylim(0, 1.2)plt.savefig(path_result + "/" + filename[i])plt.close()# 离散DCTtime_domain = fft.dct(dist / max(dist))plt.figure()plt.plot(np.arange(0, 20, 1), np.abs(time_domain)[0:20])plt.xticks(np.arange(20))plt.title(filename[i])plt.savefig(path_result + "/ifft_" + filename[i])plt.close()# 差分diff_1 = np.gradient(dist / max(dist))diff_2 = np.gradient(dist / max(dist), 2)plt.figure()plt.plot(np.arange(0, diff_1.shape[0], 1), diff_1)plt.plot(np.arange(0, diff_2.shape[0], 1), diff_2)plt.title(filename[i])plt.legend(["order_1", "order_2"])plt.plot(np.arange(0, diff_2.shape[0], 1), 0*np.arange(0, diff_2.shape[0], 1))plt.savefig(path_result + "/diff_" + filename[i])plt.close()print(i)# cv2.circle(drawing, (cx, cy), 2, (0, 255, 255), -1)# cv2.imwrite(path_result + "/contour_" + filename[i], drawing)# cv2.waitKey(1000)# cv2.destroyAllWindows()
opencv之基本形状识别相关推荐
- java识别图片中的图形形状_基于Java+OpenCV技术对几何图像颜色与形状识别
基于 Java+OpenCV 技术对几何图像颜色与形状识别 杨思阳 黄军 吴春秋 (黔东南民族职业技术学院,贵州 凯里 556000) [摘 要] 通过 Java 调用 OpenCV 视觉库实现几何图 ...
- 猿创征文|OpenCV 如何提高条形码识别率
猿创征文|OpenCV 如何提高条形码识别率 今天介绍一个使用OpenCV提高条形码识别率的算法 平台及OpenCV库简介 强烈建议:先学习一下OpenCV的课程 步入正题:从图片读取到条码截取部分( ...
- 基于Python+opencv实现的人脸识别系统
前言:因为python课设我选择的是关于人脸识别的这个课题,然后做出来也是根据一些博客主们的经验,其中自己也踩了一些坑,然后自己也想写一个关于这个课题的一些总结,讲一下在其中存在的一些问题,以及怎样解 ...
- opencv学习—简单车牌识别操作(python)
opencv学习-简单车牌识别操作(python) 目录 opencv学习-简单车牌识别操作(python) 利用opencv进行车牌识别的详细流程如下: 1.车牌检测 2.分割车牌号并进行识别 3. ...
- 几何图形识别 python_OpenCV中几何形状识别与测量
经常看到有学习OpenCV不久的人提问,如何识别一些简单的几何形状与它们的颜色,其实通过OpenCV的轮廓发现与几何分析相关的函数,只需不到100行的代码就可以很好的实现这些简单几何形状识别与对象测量 ...
- 形状识别——内六角螺丝内六角识别
注:本解决方案使用OpenCV4和OpenCV3实现过,写有非常详细的注释,现在贴出的是OpenCV4的代码,需要在OpenCV3中运行需要更改HOUGH_GRADIENT.COLOR_BGR2GRA ...
- 二维物体形状识别方法比较
二维物体形状识别方法比较 摘 要 针对模式识别中二维物体的形状识别问题,以二值图像中的物体形状为主要研究对象,依次从特征提取.分类器设计两个主要层面对形状识别方法进行了全面综述,并分析了国内外研究 ...
- MVTN:用于3D形状识别的多视图转换网络(ICCV2021)
论文标题:MVTN: Multi-View Transformation Network for 3D Shape Recognition 论文.项目地址:在公众号「3D视觉工坊」,后台回复「MVTN ...
- OpenCV 简单的人脸识别
OpenCV中自带已训练好的检测器,包括面部,眼睛,猫脸等,都保存在XML文件中,我们可以通过以下程序找到他们: import cv2 as cv print(cv.__file__) 找到的文件如下 ...
最新文章
- mysql cte 表不存在_使用CTE解决复杂查询的问题_MySQL
- ROS最正确的限速--------小包优先+带宽均分+简单队列限制上传速度
- python在文本添加超链接_Python将超链接文本打印到Spyder控制台(Python print hyperlinked text to Spyder Console)...
- 为什么每个理发店门口都有彩色的柱子?你不知道吧
- 【设计模式之美】<Reading Notes>继承与组合
- Android系统--Binder系统具体框架分析(一)补充
- Zabbix 微信报警Python版(带监控项波动图片)
- C语言经典例题(菜鸟教程100例)
- 手机卫星定位系统_真的可以通过手机号码,准确定位对方信息吗?
- 小米手机hbuilder开发者模式
- 一文看懂DSP的DMA传输(burst、transfer、wrap)
- oracle logged on,ORA-01012:not logged on的解决办法
- python dot_graphviz,dot,及dot图可视化
- 验证邮箱地址和手机号码
- MAC | svn: E175002: DAV request failed: 411 Content length required.
- 计算机控制运行内存,运行内存
- python中使用matplotlib.pyplot画函数图像
- p5.js 光速入门中文教程
- 【JS基础】立即执行函数表达式(自执行函数)
- android10官方刷机包下载,Android 11 喜讯!小米 10 率先尝鲜,官方刷机包发布下载...
热门文章
- Flutter App开发蓝牙协议
- html在图片上半透明磨砂,有没有办法在HTML内容上实现磨砂玻璃浮动div(类IO7)...
- CSS filter-仿磨砂玻璃效果
- 手动查杀skypee病毒(AutoIt3木马)
- 【华人学者风采】李凯 普林斯顿大学
- python实现键盘记录木马
- 山东计算机专业民办大学排名,2020年山东最好的民办大学排名
- 视频教程:Java七大外企经典面试套路之基础篇
- 在VMware vCenter中使用企业CA或第三方CA替换VMCA
- C++笔记8:C++提高编程2:STL---标准模板库