项目中遇到需要识别用户手绘几何图形的问题:使用鼠标/手势在屏幕画板中绘制单笔图形,识别之后给出相似图形的推荐。在此记录下实现的要点。
问题分析
手绘几何草图的识别是个老话题,许多书籍,论文,工程中都已经解决了此问题。在搜索了部分关于手绘几何图形的识别研究的论文后,我将问题拆解为以下三阶段:
- 数据平滑,以减少笔画抖动影响
- 角点检测与线元分类,角点是最重要的几何信息,准确定位角点是形状识别的前提。
- 形状识别,由于草图输入的随意性,很难做到任何情况下的精准识别。因此将方案设计为,假设用户较为规范地绘制形状,在此情况下以较高地准确率给出形状推荐。
数据平滑
方案很多,这里采用取均值的方式。即第 i 点的值由前后 k 点的均值决定。
角点检测
手绘几何形状的角点检测方式有许多,采用 k 余弦曲率法求数据点角度变化值的方式做。
对于离散数据,某点的曲率 = 角度变化值 / 弧长变化值。因为鼠标移动时采用等时采样,时间间隔也短,这里就简单假设弧长变化值不变,只求角度变化值即可。
对 i 点处的角度变化值,需要加入前后点计算。i-1 点,i 点,i+1 点,分别称为 a,b,c 三点, 将构成的 ab, bc 两个向量。仅需要求两向量夹角即为此点处的角度变化值。同时为了更准确,可以与前后 k 点结合计算 k 个夹角值,取最大者。
线元分类
两角点间的曲线称为线元,至少有两种类型:直线,二次曲线。
判断为直线: 此曲线首位两点间长度 / 此曲线的所有子线段的累计弧长,越接近 1 则越直。
判断为二次曲线: 采用最小二乘法做拟合。
这里就没有做曲线拟合,简单地识别下线元为直线和非直线。
图形识别
仅做了部分工作,尚未完成。 基本思路: 建立形状库,包含常见几何图形。 根据角点个数,线元类型,角点夹角三个维度进行形状推测
目标
用户随意绘制的图形,不管再好的算法也都无法准确识别,给出一下常见的和一些复杂的几何图形推荐;
用户认真绘制的简单几何图形:直线,圆,三角形,四边形等简单几何图形给出较好的识别率。
应该对同族几何形状,
- 即直线与箭头;
- 圆,椭圆,半圆;
- 等腰三角形,直角三角形;
- 长方形,正方形,平行四边形,梯形;
- 五边形;
- 六边形;
给出更加精确的推荐。
文档信息
- 本文作者:xu jinshan
- 本文链接:https://xujs0813.github.io/gitpage/2021/02/21/geometry-recognition.md/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)