iphone - 识别绘制图像的最佳方法

标签 iphone objective-c xcode image-processing cocos2d-iphone

今天我正在寻求有关识别绘制图像的最佳方法的建议。例如,如果您使用中文/日文键盘,您可以用手指绘制特殊符号,它将被识别并将正确的符号放置在文本区域中。我怎样才能做这样的事情?我正在考虑使用 cocos2d,Core Image 可以提供帮助吗?

我还想问另一个问题:假设您的屏幕加载了雾纹理,并且您必须滑动手指来清洁 window 。如何做呢?举一个很好的例子,《Where's my Water》游戏使用了类似的内容,你必须滑动手指来移除一些地面并为水腾出空间。

我希望听起来很清楚,如果有任何答案,我将不胜感激:)

最佳答案

有一些关于图像识别的帖子。 This one 可能是与您想要的最接近的匹配,Tom Gullen 的答案非常全面。您可能还想查看 redmoskito 对 this question 的回答。

我见过的一个相当基本的方法,但在这两篇文章中都没有提到,如下:

(我不能将此归功于 - 如果其他人可以找到此帖子的来源,请告诉我!)

  1. 将要比较的图像缩小到较小尺寸(例如 4x4 像素)
  2. 将用户的手绘图像缩小到相同尺寸
  3. 迭代像素并将其数据(例如 RGB)与缩小的引用图像像素进行比较。
  4. ((在此处插入比较阈值))如果各个像素与原始图像的像素“足够相似” - 则表示匹配。

如果您有一组封闭的比较图像,并且您知道其中一个图像将是所绘制的图像(其想法是每个图像将具有唯一的 4x4px“指纹”),则此方法可以很好地工作。

它的整体有效性取决于您用来确定“相似像素”定义的算法(例如相似的 RGB 值、最近邻相似度等),当然,缩小的图像越大,过程就越精确将。我已经使用这个一般过程来识别基本形状和字符,并取得了相当成功。不过,您需要一个非常好的(并且经过彻底测试的)逻辑算法来保证这种生产质量。

至于你的第二个问题,我假设你的意思是如何去除你用手指划过的雾(就像现实生活中发生的那样)。实现此目的的一种方法是检测手指所在位置并“绘制 Alpha channel ”,然后将其用作雾图像的 mask 。或者,您可以直接绘制到图像并将相关像素的 Alpha 值设置为 0。

这些只是一些想法,图像比较和操作的领域是巨大的。但希望这能为进一步探索提供一个起点。

编辑:

Apple 提供了两个很好的(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'".

正如我所说,这只是最小的,但它是实现上述过程的一种方法。当然,两个 Core Graphics 函数使生活变得更加轻松,一旦获得数据,您只需比较两个字节数组即可。请注意,您仍然需要首先缩小图像(使用 Core Graphics) - 有一些相关教程 ( e.g. here )。

关于iphone - 识别绘制图像的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13186959/

相关文章:

iphone - iOS 应用程序缺少屏幕截图

php - EasyAPNS 无法连接到数据库

ios - 错误 : User interaction disabled in lower parts of UIScrollView

iphone - iOS 无法在扩展类中找到方法

ios - 从另一个文件快速访问变量

swift - 保存 Bool/tableView 复选标记 - 第三次幸运

iPhone屏幕分辨率在未来硬件中的变化

iphone - 启用滑动图像的能力

ios - 带导航栏的 MKMapView 内容插入

ios - "UserNotificationsUI"在构建 UIKit for Mac 错误时不可用