画像認識に関するSOの投稿がいくつかあります。これはおそらくあなたが望むものに最も近いものであり、Tom Gullenの答えは非常に包括的です. この質問に対する redmoskito の回答もご覧ください。
これらの投稿のいずれにも言及されていない、私が見たかなり基本的な方法の1つは、次のとおりです。
(私はこれを信用することはできません - 他の誰かがこれが元の SO 投稿を見つけることができる場合は、私に知らせてください!)
- 比較したい画像を小さいサイズ (例: 4x4 px) に縮小します。
- ユーザーの手描き画像を同じサイズに縮小する
- ピクセルを反復処理し、それらの (RGB などの) データを縮小された参照イメージ ピクセルと比較します。
- ((ここに比較しきい値を挿入)) 個々のピクセルが元の画像のピクセルと「十分に類似」している場合 - 一致しています。
閉じた比較画像のセットがあり、それらの画像の 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 を使用) - そのためのチュートリアルがいくつかあります (例: ここ)。