二维形状识别算法-寻找指导
image-processing
image-recognition
5
0

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

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

形状识别有几种不同的方法,但不幸的是,我没有经验或时间尝试所有这些方法,也不知道有什么用。

您会为该特定任务推荐哪种方法?

感谢您的帮助。

参考资料:
Stack Overflow
收藏
评论
共 1 个回答
高赞 时间 活跃

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

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

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


UPDATE:

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


输入:

在此处输入图片说明

算法

  1. 按比例缩小输入图像,因为可能无法以较低的分辨率检测到所需的功能。
  2. 分割每个要独立处理的对象。
  3. 对于每个对象,提取其特征,在这种情况下,仅提取拐角数。
  4. 使用特征对对象形状进行分类。

软体:

下面介绍的软件是使用Java开发的,并使用Marvin图像处理框架 。但是,您可以使用任何编程语言和工具。

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
收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号