2

今日は、描かれた画像を認識する最良の方法についてアドバイスを求めています。たとえば、中国語/日本語のキーボードを使用している場合、その特殊な記号を指で描くと、それが認識され、正しい記号がテキスト領域に配置されます。どうすればこのようなことができますか?cocos2d の使用を考えていましたが、Core Image は役に立ちますか?

もう 1 つ質問したいことがあります。たとえば、画面にフォグ テクスチャがロードされていて、指をスワイプしてウィンドウを掃除する必要があるとします。どうすればそれができますか?良い例として、ゲーム Where's my Water はこのようなものを使用します。指をスワイプして地面を取り除き、水のためのスペースを作る必要があります。

私はそれが明確に聞こえることを願っています、そして私はどんな答えにも感謝します:)

4

1 に答える 1

2

画像認識に関するSOの投稿がいくつかあります。これはおそらくあなたが望むものに最も近いものであり、Tom Gullenの答えは非常に包括的です. この質問に対する redmoskito の回答もご覧ください。

これらの投稿のいずれにも言及されていない、私が見たかなり基本的な方法の1つは、次のとおりです。

(私はこれを信用することはできません - 他の誰かがこれが元の SO 投稿を見つけることができる場合は、私に知らせてください!)

  1. 比較したい画像を小さいサイズ (例: 4x4 px) に縮小します。
  2. ユーザーの手描き画像を同じサイズに縮小する
  3. ピクセルを反復処理し、それらの (RGB などの) データを縮小された参照イメージ ピクセルと比較します。
  4. ((ここに比較しきい値を挿入)) 個々のピクセルが元の画像のピクセルと「十分に類似」している場合 - 一致しています。

閉じた比較画像のセットがあり、それらの画像の 1 つが描画されることがわかっている場合、これはかなりうまく機能します (各画像には一意の 4x4 ピクセルの「指紋」があるという考えです)。

その全体的な有効性は、「類似ピクセル」を定義するもの (類似した RGB 値、最近傍類似性など) を決定するために使用するアルゴリズムに基づいており、当然、縮小された画像が大きいほど、プロセスはより正確になります。私はこの一般的な手順を使用して、基本的な形状と文字を認識するのに十分な成功を収めました。ただし、この製品品質を実現するには、かなり優れた (そして徹底的にテストされた) ロジック アルゴリズムが必要です。

2番目の質問については、指でなぞった霧を取り除く方法を意味していると思います(実際の生活のように)。これを達成する 1 つの方法は、指がどこにあるかを検出し、フォグ イメージのマスクとして機能する「アルファ チャネルを描画」することです。または、画像に直接描画して、関連するピクセルのアルファ値を 0 に設定することもできます。

これらはほんの一部のアイデアであり、画像の比較と操作の領域は膨大です。しかし、これがさらなる探索の出発点になることを願っています。

編集:

Apple は、ピクセル データを抽出するための 2 つの優れた (iOS 互換の) 関数を提供しています。それらを関数でラップする場合:

+ (NSMutableData *)pixelDataFromImage:(UIImage *)image {

    NSMutableData *pixelData = (__bridge_transfer NSMutableData *)
    CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));
    return pixelData;
    // Return data is of the form [RGBA RGBA RGBA ....]
    //                             ^^^^ ^^^^ ^^^^
    //               Byte Index:   0123 4567 89..
    //                             ^    ^    ^
    //             Pixel Number:   px1  px2  px3
}

したがって、上記の 4 つの手順に基づいて (最小限の) アルゴリズムに結び付けるには、次のようにします。

//...
NSMutableData *imagePixelData = [self pixelDataFromImage:image];
NSMutableData *referencePixelData = [self pixelDataFromImage:reference];
// Both image and reference are UIImages

if ([imagePixelData length] != [referencePixelData length]) {
    return 0.0f; // Can't compare, different number of pixels
}

Byte *imagePixelBytes = [imagePixelData mutableBytes];
Byte *referencePixelBytes = [referencePixelData mutableBytes];

int totalDifference = 0;
float averageDifference = 0;
int bytesCompared = 0;

for (int i = 0; i < [imagePixelData length]; i++) {

    if ((i+1) % 4 == 0) { // Compare only alpha values in this example
                          // (compares images ignoring colour)

        int difference = (int)fabs(imagePixelBytes[i] - referencePixelBytes[i]];
        totalDifference += difference;
        bytesCompared += 1;
    }
}

averageDifference = totalDifference/bytesCompared;
float similarity = 1.0f - (averageDifference/255);
return similarity;
// 1.0 => Exact match
// Now you need to determine a threshold for "how similar means 'the same'".

前述したように、これは最小限にすぎませんが、上記で概説した手順を実装する 1 つの方法です。確かに、2 つのコア グラフィックス関数を使用すると作業がはるかに簡単になります。データを取得したら、2 つのバイト配列を比較するだけです。最初に画像を縮小する必要があることに注意してください (Core Graphics を使用) - そのためのチュートリアルがいくつかあります (例: ここ)。

于 2012-11-02T02:04:39.123 に答える