17

円、三角形などの単純な形状から、文字 A などのより高度な形状まで、ユーザーが形状を正しく描画したことを確認する機能が必要です。

正確さをリアルタイムで計算できる必要があります。たとえば、ユーザーが円を描くはずなのに四角形を描いている場合、描画中にそれを検出できるようにしたいと考えています。

形状認識にはいくつかの異なるアプローチがありますが、残念ながら、それらすべてを試して何が機能するかを確認する経験や時間はありません。

この特定のタスクにどのアプローチをお勧めしますか?

あなたの助けに感謝します。

4

3 に答える 3

9

「認識」を、要素の特徴/特性を検出し、それらを私たちの経験で見られる既知の要素の特徴と比較する能力として定義する場合があります。類似した特徴を持つオブジェクトは、おそらく類似したオブジェクトです。特徴の量と複雑さが高ければ高いほど、同様のオブジェクトを識別する能力が大きくなります。

形状の場合、角度の数、角度の値、辺の数、辺のサイズなどの幾何学的プロパティを使用できます。したがって、タスクを達成するには、画像処理アルゴリズムを使用して、図面からそのような特徴を抽出する必要があります。

以下に、この概念を実際に示す非常に単純なアプローチを示します。角の数を使ってさまざまな形を認識します。私が言ったように、「機能の量と複雑さが高ければ高いほど、類似したオブジェクトを識別する能力は大きくなります」。角の数という 1 つの特徴のみを使用しているため、いくつかの異なる種類の形状を区別できます。角の数が同じ形状は判別しません。したがって、アプローチを改善するために、新しい機能を追加することがあります。


アップデート:

このタスクをリアルタイムで実行するために、特徴をリアルタイムで抽出できます。描画するオブジェクトが三角形で、ユーザーが他の図形の 4 番目の辺を描画している場合、ユーザーは三角形を描画していないことがわかります。正確さのレベルについては、目的のオブジェクトの特徴ベクトルと描画されたオブジェクトの間の距離を計算できます。


入力:

ここに画像の説明を入力

アルゴリズム

  1. 目的の特徴を低解像度で検出できるため、入力画像を縮小します。
  2. 各オブジェクトをセグメント化して、個別に処理します。
  3. 各オブジェクトについて、その特徴を抽出します。この場合はコーナーの数だけです。
  4. 特徴を使用して、オブジェクトの形状を分類します。

ソフトウェア:

以下に示すソフトウェアは、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
于 2014-08-09T22:47:43.003 に答える
1

もう1つの方法は、この問題で数学を使用して、比較するポイントからの距離が最も小さい各ポイントの平均を使用することです。最初に、形状のライブラリにある形状のサイズを変更する必要があります。

      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 );

最小の合計が最も近い形状です。

于 2015-06-14T14:51:50.860 に答える
0

初期画像とユーザー入力の 2 つの入力があり、ブール値の結果を探しています。

理想的には、すべての入力データを同等の形式に変換します。代わりに、両方のタイプの入力をパラメーター化し、教師あり機械学習アルゴリズムを使用することもできます (閉じた形状の場合、最近隣人が思い浮かびます)。

トリックは、適切なパラメーターを見つけることです。入力がフラット イメージ ファイルの場合、これはバイナリ変換である可能性があります。ユーザー入力がスワイプ モーションまたはペン ストロークである場合、これをキャプチャしてバイナリとしてマップする方法があると確信していますが、元の入力に最も近いデータを使用した場合、アルゴリズムはおそらくより堅牢になります。

于 2014-08-15T08:34:29.810 に答える