本文所讲的内容已经开源,你可以在 这里 找到源代码。


一些工具软件有手绘图形功能,手画一个三角形、平行四边形,虽然画的歪歪扭扭,但是工具内部能够自动转换为数字化的几何图形。

然而,这部分功能很少有开源代码,网上也找不到相关的算法说明,所以只能自己尝试实现。但是几个月来,一直没有一个完整的思路。

前几天,突然发现 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. 思考“手绘家谱”的算法

    1.每个节点分别延伸其父 母 配偶 子女,将新延伸出的节点加入"待延伸"队列. 2.不断从队列中取出节点进行"步骤1"的操作. 每次延伸出的节点类型可以选择,比 ...

  2. 小程序地图覆盖手绘地图的解决方法

     引言 手绘地图顾名思义就是手工绘制的地图,比普通的地图更有观赏性和生动性,通过把特定的地点绘制出来,兼具实用和纪念性,同时更加具有可看性.一般在旅游景点有很多这种纸质版手绘地图.比如这种: 问题 如 ...

  3. PS手绘!超萌儿童照片转手绘

    模糊.钢笔.钢笔灵活就很简单. 简介:儿童照片转手绘的方法跟平时处理仿手绘的方法一样.大致过程:先简单的给人物磨皮,然后再处理五官及发丝. 为了突出人物肤色的水晶质感,高光部分的渲染非常重要,需要单独 ...

  4. 基于hsv的亮度调整算法_基于手绘工程图离线识别的预处理研究精品论文推荐

    DOI: 10. 3969 / j. issn. 1009-9492. 2020. 11. 028 李春晓,田怀文,刘奇,等. 基于手绘工程图离线识别的预处理研究[J] . 机电工程技术,2020,4 ...

  5. 你也可以手绘二维码(二)纠错码字算法:数论基础及伽罗瓦域GF(2^8)

    摘要:本文讲解二维码纠错码字生成使用到的数学数论基础知识,伽罗瓦域(Galois Field)GF(2^8),这是手绘二维码填格子理论基础,不想深究可以直接跳过.同时数论基础也是 Hash 算法,RS ...

  6. customplot设置单个点的颜色_[原创]单个超大型TB级imaris的ims文件的Surface手绘及Mask提速新方法...

    本程序用于解决处理数百GB~TB级别单个超大型ims文件/或者一大群海量Tif切片contour surfce手绘时的若干问题.可在垃圾笔记本上运行(无需独显,无CPU特殊要求,只需内存4-8G即可, ...

  7. 单按钮启停电路实物图_手绘220V清洗机电路原理图和接线方法,单相电机常见故障排查...

    图1.正在使用的高压清洗机 厂里有几台上海熊猫的220V清洗机,型号是DM90LL4,主要用于清洗空调机组的滤筒以及空调箱体内的灰尘,或者冲洗污水站压滤机和地面的污泥等,使用率还是比较高的.最近连续出 ...

  8. 零基础学手绘插画的方法

    零基础学手绘插画的方法?插画要掌握的东西很多,因此可在练习过程中学习或试验不同的方法,当然这过程并不是漫无目的,而是每一次都有个主题,例如色彩的练习.氛围的尝试.构图的设计.留白的练习- 等等,甚至只 ...

  9. 如何教会爸妈用智能手机?方法比耐心重要,get这份手绘板说明书!

    教爸妈用智能手机有多难,相信很多小伙伴都有体会.但这些东西对他们来说本来就是很陌生的,需要反复多遍的教,耐心很重要,但方法更重要. 在华为手机公众号上看到一个爸妈用机指南,里面全部是专门给爸妈介绍手机 ...

  10. Win10手绘板无压感故障解决方法

    Win10手绘板无压感故障解决方法 参考文章: (1)Win10手绘板无压感故障解决方法 (2)https://www.cnblogs.com/huangzhewei/p/11053214.html ...

最新文章

  1. java lambda 变量_java8新特性-lambda(变量捕获)
  2. netlink怎么读_ovs源码阅读--netlink使用
  3. 转 Fragment 和 FragmentActivity的使用
  4. 05.multi_search_template
  5. appium java环境_Appium环境搭建(Windows版)
  6. HTTP协议 (三) 压缩
  7. wampserver橙色如何变成绿色_PLC视频教程:手机如何控制西门子变频器V20
  8. python中response对象的属性_Django 中的响应对象 Response
  9. mysql select不走索引_避免写出不走索引的SQL, MySQL
  10. Android Architecture Components 系列(五)Room
  11. GPS导航电文编码与校验
  12. 数据的存储和管理,主要有哪些好的方法?
  13. RTI_DDS使用参与者QoS属性编辑传输TCP
  14. iphone ipad 为孩子创建 apple id
  15. 计算机主机的光驱怎么打开,笔记本电脑光驱,教您笔记本光驱怎么打开
  16. php中implode什么意思,implode是什么意思中文翻译
  17. 笔记本也瑜枷,联想展示最新概念机
  18. 华为设备Loopback Detection配置命令
  19. 【踩坑记录】—— app运行闪退(Mac版)
  20. 函数的length代表什么

热门文章

  1. validation参数检验 - 注解介绍
  2. mysql 2000_sql server 2000 下载
  3. 【MATLAB】高维矩阵求和
  4. 【openGL基础系列】之画一个正方体玩玩吧
  5. word毕业论文页眉设置自动添加章节标题并左右对齐
  6. this指向问题(箭头函数)
  7. 免费开放,GSTO-沪深A股L2行情数据API接口,开发接口文档
  8. mysql asc_mysql – 在字符串列上使用asc和desc的索引
  9. 54_集合类库(上)
  10. 如何用C语言编辑一个万年历,如何用C语言编写一个万年历系统?