2D 形状识别算法 - 寻找指导 [关闭]

Posted

技术标签:

【中文标题】2D 形状识别算法 - 寻找指导 [关闭]【英文标题】:2D Shape recognition algorithm - looking for guidance [closed] 【发布时间】:2014-09-28 15:58:21 【问题描述】:

我需要能够验证用户是否正确绘制了形状,从简单的形状(如圆形、三角形)和更高级的形状(如字母 A)开始。

我需要能够实时计算正确性,例如,如果用户应该画一个圆但正在画一个矩形,我希望能够在绘制时检测到这一点。

形状识别有几种不同的方法,遗憾的是我没有经验或时间尝试所有方法,看看哪种方法有效。

对于这项特定任务,您会推荐哪种方法?

感谢您的帮助。

【问题讨论】:

您能添加一些示例数据吗? @nikie 不确定我理解你的意思,但如果你问我是否可以提供程序数据,那么可以。 相关问题***.com/questions/22876351/… 【参考方案1】:

我们可以将“识别”定义为检测元素中的特征/特征并将它们与我们经验中看到的已知元素的特征进行比较的能力。具有相似特征的对象可能是相似对象。特征的数量和复杂度越高,我们区分相似对象的能力就越大。

在形状的情况下,我们可以使用它们的几何属性,例如角度数、角度值、边数、边大小等。因此,为了完成您的任务,您应该使用图像处理算法从图纸中提取这些特征。

下面我提出了一个非常简单的方法,在实践中展示了这个概念。我们将使用角的数量来识别不同的形状。正如我所说:“特征的数量和复杂性越高,我们区分相似对象的能力就越大”。由于我们只使用一个特征,即角的数量,我们可以区分几种不同的形状。将不区分具有相同角数的形状。因此,为了改进方法,您可能会添加新功能。


更新:

为了实时完成这项任务,您可以实时提取特征。如果要绘制的对象是三角形,并且用户正在绘制任何其他图形的第四条边,则您知道他或她不是在绘制三角形。关于正确程度,您可以计算所需对象的特征向量与绘制的特征向量之间的距离。


输入:

算法

    缩小输入图像,因为可以在较低分辨率下检测到所需的特征。 分割每个要独立处理的对象。 对于每个对象,提取其特征,在本例中,仅提取角的数量。 使用特征对物体形状进行分类。

软件:

下面介绍的软件是用 Java 开发的,使用 Marvin Image Processing Framework。但是,您可以使用任何编程语言和工具。

import static marvin.MarvinPluginCollection.floodfillSegmentation;
import static marvin.MarvinPluginCollection.moravec;
import static marvin.MarvinPluginCollection.scale;

public class ShapesExample 

    public ShapesExample()
        // Scale down the image since the desired features can be extracted
        // in a lower resolution.
        MarvinImage image = MarvinImageIO.loadImage("./res/shapes.png");
        scale(image.clone(), image, 269);

        // segment each object
        MarvinSegment[] objs = floodfillSegmentation(image);
        MarvinSegment seg;

        // For each object...
        // Skip position 0 which is just the background
        for(int i=1; i<objs.length; i++)
            seg = objs[i];
            MarvinImage imgSeg = image.subimage(seg.x1-5, seg.y1-5, seg.width+10, seg.height+10);
            MarvinAttributes output = new MarvinAttributes();
            output = moravec(imgSeg, null, 18, 1000000);
            System.out.println("figure "+(i-1)+":" + getShapeName(getNumberOfCorners(output)));
        
    

    public String getShapeName(int corners)
        switch(corners)
            case 3: return "Triangle";
            case 4: return "Rectangle";
            case 5: return "Pentagon";
        
        return null;
    

    private static int getNumberOfCorners(MarvinAttributes attr)
        int[][] cornernessMap = (int[][]) attr.get("cornernessMap");
        int corners=0;
        List<Point> points = new ArrayList<Point>();
        for(int x=0; x<cornernessMap.length; x++)
            for(int y=0; y<cornernessMap[0].length; y++)
                // Is it a corner?
                if(cornernessMap[x][y] > 0)
                    // This part of the algorithm avoid inexistent corners
                    // detected almost in the same position due to noise.
                    Point newPoint = new Point(x,y);
                    if(points.size() == 0)
                        points.add(newPoint); corners++;
                    else 
                        boolean valid=true;
                        for(Point p:points)
                            if(newPoint.distance(p) < 10)
                                valid=false;
                            
                        
                        if(valid)
                            points.add(newPoint); corners++;
                        
                    
                
            
        
        return corners;
    

    public static void main(String[] args) 
        new ShapesExample();
    

软件输出:

figure 0:Rectangle
figure 1:Triangle
figure 2:Pentagon

【讨论】:

我有一个基于您的代码的问题。可以看这里吗:***.com/questions/52549493/…?【参考方案2】:

您有两个输入 - 初始图像和用户输入 - 您正在寻找布尔结果。

理想情况下,您会将所有输入数据转换为可比较的格式。相反,您也可以参数化这两种类型的输入并使用supervised machine learning 算法(最近邻会想到封闭形状)。

诀窍在于找到正确的参数。如果您的输入是平面图像文件,则这可能是二进制转换。如果用户输入是滑动动作或笔划,我确信有办法将其捕获并映射为二进制,但如果使用最接近原始输入的数据,该算法可能会更稳健。

【讨论】:

【参考方案3】:

另一种方法是,您可以使用与您比较它的点距离最小的每个点的平均值来使用数学来解决这个问题, 首先,您必须使用形状库中的形状调整形状大小,然后:

      function shortestDistanceSum( subject, test_subject ) 

         var sum = 0;

         operate( subject, function( shape )

            var smallest_distance = 9999;

            operate( test_subject, function( test_shape )
                var distance = dist( shape.x, shape.y, test_shape.x, test_shape.y );

                smallest_distance = Math.min( smallest_distance, distance );
            );

            sum += smallest_distance;

        );

            var average = sum/subject.length;

            return average;
       

       function operate( array, callback ) 
          $.each(array, function()
              callback( this );
          );
       

       function dist( x, y, x1, y1 ) 
            return Math.sqrt( Math.pow( x1 - x, 2) + Math.pow( y1 - y, 2) );
        

        var square_shape = Array; // collection of vertices in a square shape
        var triangle_shape = Array; // collection of vertices in a triangle
        var unknown_shape = Array; // collection of vertices in the shape your'e comparing from

        square_sum = shortestDistanceSum( square_shape, unknown_shape );
        triangle_sum = shortestDistanceSum( triangle_shape, unknown_shape );

其中最小的和是最接近的形状。

【讨论】:

是否有可能通过这样的方法获得同构?例如,将钻石识别为正方形? 不,这取决于顶点和初始位置,圆形比正方形更可能匹配菱形,除非您先将菱形倾斜成直角以匹配正方形

以上是关于2D 形状识别算法 - 寻找指导 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

识别曲线直线部分的算法[关闭]

R中的人脸识别[关闭]

人们识别图像是靠形状,那AI是怎么识别图像的?

开源音频模式识别(指纹)[关闭]

AI图像识别:人类看的是形状,算法看的是纹理

Canvas 的形状识别转化为功能