手绘图形识别方法(算法)
本文所讲的内容已经开源,你可以在 这里 找到源代码。
一些工具软件有手绘图形功能,手画一个三角形、平行四边形,虽然画的歪歪扭扭,但是工具内部能够自动转换为数字化的几何图形。
然而,这部分功能很少有开源代码,网上也找不到相关的算法说明,所以只能自己尝试实现。但是几个月来,一直没有一个完整的思路。
前几天,突然发现 OpenCV 的一个函数 approxPolyDP,它能将一个曲线,转换为一个多边形(近似拟合)。
其中的原理也很简单,就是计算所有点到起点、终点连线的距离,如果最大值超过一个设定值,就以最大值对应的点分割曲线,然后分别在两段曲线中递归上述算法;如果最大值不超过设定值,那么上述连线就是结果多边形的一部分。
有了上面这个算法工具,实现手绘图形识别的思路,就豁然开朗了。
关键思路
如果输入是一张图片,那么需要先二值化(cv2.threshold),然后寻找轮廓(cv2.findContours),得到一个曲线(离散点)。
如果是实时手绘(画笔),那么就是收集到一系列坐标点。
将上面的一系列坐标点,用 approxPolyDP 近似为一个多边形。
判断多边形首位是否相接,必须相接才能继续。
根据多边形的边数,可以确定作为结果的几何图形是三角形、四边形,五边形 .......,如果边数 >=8,一般就可以认为是圆形(椭圆)了。
算法细节
关于 approxPolyDP 的设定距离阈值,可以用曲线长度的 1% 作为经验值。不同比例值的实验的效果是:
1%:手绘时需要比较认真,手必须稳定,算法的抗抖动性不强
2%:比较适中,绘图时可以稍微随意些,但是绘制圆形要小心,不是太圆的话,可能处理后的多边形会少于 8 条边
3%:明明画的弯弯的也变成直边了
特殊几何图形识别
识别出一些特殊的图形,比如直角三角形,长方形等等,而不是普通的三角形、四边形。
识别这些特殊图形,主要依赖各条边的长度,各个顶角的度数。
特殊三角形
- 等边三角形
三条边相等,近似条件,边长两两之间的比例(短的:长的)都大于 0.9
- 等腰三角形
边长两两之间的比例,有一个超过 0.9
- 等腰直角三角形
边长两两之间的比例,有一个超过 0.9,且两边的夹角的 cos 值小于 0.15(大于 81°)
- 直接三角形
有一个顶角的 cos 值小于 0.15(81°)
特殊四边形
- 平行四边形
两条对边都平行,方向矢量的夹角 cos 小于 -0.95 (反方向小于 11°)
- 长方形
在平行四边形的基础上,四个顶角中 cos值最大的一个小于 0.15(大于 81°)
- 正方形
在长方形的基础上,一个相对边的长度和与另一个对边的长度和的比例大于 0.9
- 菱形
在平行四边形的基础上,两个相邻边的长度比例大于 0.9
- 梯形
有一个对边平行,方向矢量的夹角 cos 小于 -0.95 (反方向小于 11°)
- 直角梯形
在梯形的基础上,四个顶角中 cos 值最小的一个小于 0.1(大于 84°),且与另一个平行线的夹角的 cos 值也小于 0.1(大于 84°)
- 等腰梯形
在梯形的基础上,非平行的一对边的边长比例大于 0.9
特殊多边形
边数大于等于 5,小于8,正多边形。一般手绘只能绘制五条边,但是这里面有一个特殊的:那就是五角星。
判断是正多边形,可以用里面两个条件:
- 最小边长与最大边长的比例大于 0.7
- 最小夹角与最大的差小于 20°
另外,正多边形有不同 Span 的区别,比如五角星是正五边形(Span = 2)。怎么计算 Span 呢?
- 先计算中心点,即所有点的平均值
- 计算所有以中心点为顶点,中心点到两个相邻点为边的角的角度
- 角度的和是 360° 的多少倍,Span 就是多少
椭圆(圆形)
椭圆需要计算出中心点和长短轴的长度。用下面的方法(如下图):
- 取任意边作为投影轴(它的垂线作为另一个投影轴)
- 计算所有顶点在投影轴的位置,位置范围形成一个包围长方形
- 长方形的长短边长即椭圆的长短轴的长度
- 长方形的中心点就是椭圆的中心点
- 取所有边作为投影轴时,长短轴的长度比最大的
如果椭圆的长短轴的长度的比例大于 0.8,就作为圆处理,圆的半径是长短轴的长度的平均值。
手绘图形识别方法(算法)相关推荐
- 思考“手绘家谱”的算法
1.每个节点分别延伸其父 母 配偶 子女,将新延伸出的节点加入"待延伸"队列. 2.不断从队列中取出节点进行"步骤1"的操作. 每次延伸出的节点类型可以选择,比 ...
- 小程序地图覆盖手绘地图的解决方法
引言 手绘地图顾名思义就是手工绘制的地图,比普通的地图更有观赏性和生动性,通过把特定的地点绘制出来,兼具实用和纪念性,同时更加具有可看性.一般在旅游景点有很多这种纸质版手绘地图.比如这种: 问题 如 ...
- PS手绘!超萌儿童照片转手绘
模糊.钢笔.钢笔灵活就很简单. 简介:儿童照片转手绘的方法跟平时处理仿手绘的方法一样.大致过程:先简单的给人物磨皮,然后再处理五官及发丝. 为了突出人物肤色的水晶质感,高光部分的渲染非常重要,需要单独 ...
- 基于hsv的亮度调整算法_基于手绘工程图离线识别的预处理研究精品论文推荐
DOI: 10. 3969 / j. issn. 1009-9492. 2020. 11. 028 李春晓,田怀文,刘奇,等. 基于手绘工程图离线识别的预处理研究[J] . 机电工程技术,2020,4 ...
- 你也可以手绘二维码(二)纠错码字算法:数论基础及伽罗瓦域GF(2^8)
摘要:本文讲解二维码纠错码字生成使用到的数学数论基础知识,伽罗瓦域(Galois Field)GF(2^8),这是手绘二维码填格子理论基础,不想深究可以直接跳过.同时数论基础也是 Hash 算法,RS ...
- customplot设置单个点的颜色_[原创]单个超大型TB级imaris的ims文件的Surface手绘及Mask提速新方法...
本程序用于解决处理数百GB~TB级别单个超大型ims文件/或者一大群海量Tif切片contour surfce手绘时的若干问题.可在垃圾笔记本上运行(无需独显,无CPU特殊要求,只需内存4-8G即可, ...
- 单按钮启停电路实物图_手绘220V清洗机电路原理图和接线方法,单相电机常见故障排查...
图1.正在使用的高压清洗机 厂里有几台上海熊猫的220V清洗机,型号是DM90LL4,主要用于清洗空调机组的滤筒以及空调箱体内的灰尘,或者冲洗污水站压滤机和地面的污泥等,使用率还是比较高的.最近连续出 ...
- 零基础学手绘插画的方法
零基础学手绘插画的方法?插画要掌握的东西很多,因此可在练习过程中学习或试验不同的方法,当然这过程并不是漫无目的,而是每一次都有个主题,例如色彩的练习.氛围的尝试.构图的设计.留白的练习- 等等,甚至只 ...
- 如何教会爸妈用智能手机?方法比耐心重要,get这份手绘板说明书!
教爸妈用智能手机有多难,相信很多小伙伴都有体会.但这些东西对他们来说本来就是很陌生的,需要反复多遍的教,耐心很重要,但方法更重要. 在华为手机公众号上看到一个爸妈用机指南,里面全部是专门给爸妈介绍手机 ...
- Win10手绘板无压感故障解决方法
Win10手绘板无压感故障解决方法 参考文章: (1)Win10手绘板无压感故障解决方法 (2)https://www.cnblogs.com/huangzhewei/p/11053214.html ...
最新文章
- java lambda 变量_java8新特性-lambda(变量捕获)
- netlink怎么读_ovs源码阅读--netlink使用
- 转 Fragment 和 FragmentActivity的使用
- 05.multi_search_template
- appium java环境_Appium环境搭建(Windows版)
- HTTP协议 (三) 压缩
- wampserver橙色如何变成绿色_PLC视频教程:手机如何控制西门子变频器V20
- python中response对象的属性_Django 中的响应对象 Response
- mysql select不走索引_避免写出不走索引的SQL, MySQL
- Android Architecture Components 系列(五)Room
- GPS导航电文编码与校验
- 数据的存储和管理,主要有哪些好的方法?
- RTI_DDS使用参与者QoS属性编辑传输TCP
- iphone ipad 为孩子创建 apple id
- 计算机主机的光驱怎么打开,笔记本电脑光驱,教您笔记本光驱怎么打开
- php中implode什么意思,implode是什么意思中文翻译
- 笔记本也瑜枷,联想展示最新概念机
- 华为设备Loopback Detection配置命令
- 【踩坑记录】—— app运行闪退(Mac版)
- 函数的length代表什么