2010-10-10 87 views
7

如何检测两幅图像之间的差异,创建不同区域的蒙版以处理两幅图像共有的区域(例如高斯模糊)?根据两幅图像(iPhone)之间的差异创建一个蒙版

sketch

编辑:我目前使用此代码来获取像素的RGBA值:

+ (NSArray*)getRGBAsFromImage:(UIImage*)image atX:(int)xx andY:(int)yy count:(int)count 
{ 
    NSMutableArray *result = [NSMutableArray arrayWithCapacity:count]; 

    // First get the image into your data buffer 
    CGImageRef imageRef = [image CGImage]; 
    NSUInteger width = CGImageGetWidth(imageRef); 
    NSUInteger height = CGImageGetHeight(imageRef); 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    unsigned char *rawData = malloc(height * width * 4); 
    NSUInteger bytesPerPixel = 4; 
    NSUInteger bytesPerRow = bytesPerPixel * width; 
    NSUInteger bitsPerComponent = 8; 
    CGContextRef context = CGBitmapContextCreate(rawData, width, height, 
        bitsPerComponent, bytesPerRow, colorSpace, 
        kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 
    CGColorSpaceRelease(colorSpace); 

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); 
    CGContextRelease(context); 

    // Now your rawData contains the image data in the RGBA8888 pixel format. 
    int byteIndex = (bytesPerRow * yy) + xx * bytesPerPixel; 
    for (int ii = 0 ; ii < count ; ++ii) 
    { 
     CGFloat red = (rawData[byteIndex]  * 1.0)/255.0; 
     CGFloat green = (rawData[byteIndex + 1] * 1.0)/255.0; 
     CGFloat blue = (rawData[byteIndex + 2] * 1.0)/255.0; 
     CGFloat alpha = (rawData[byteIndex + 3] * 1.0)/255.0; 
     byteIndex += 4; 

     UIColor *acolor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; 
     [result addObject:acolor]; 
    } 

    free(rawData); 

    return result; 
} 

的问题是,将图像从iPhone的相机拍摄,使他们并不完全一样。我需要创建几个像素的区域并提取该区域的一般颜色(也许通过将RGBA值相加并除以像素数量)。我怎么能做到这一点,然后把它翻译成CGMask?

我知道这是一个复杂的问题,所以任何帮助表示赞赏。

谢谢。

回答

6

我认为最简单的方法是使用差异混合模式。以下代码基于CKImageAdditions中使用的代码。

+ (UIImage *) differenceOfImage:(UIImage *)top withImage:(UIImage *)bottom { 
    CGImageRef topRef = [top CGImage]; 
    CGImageRef bottomRef = [bottom CGImage]; 

    // Dimensions 
    CGRect bottomFrame = CGRectMake(0, 0, CGImageGetWidth(bottomRef), CGImageGetHeight(bottomRef)); 
    CGRect topFrame = CGRectMake(0, 0, CGImageGetWidth(topRef), CGImageGetHeight(topRef)); 
    CGRect renderFrame = CGRectIntegral(CGRectUnion(bottomFrame, topFrame)); 

    // Create context 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    if(colorSpace == NULL) { 
     printf("Error allocating color space.\n"); 
     return NULL; 
    } 

    CGContextRef context = CGBitmapContextCreate(NULL, 
               renderFrame.size.width, 
               renderFrame.size.height, 
               8, 
               renderFrame.size.width * 4, 
               colorSpace, 
               kCGImageAlphaPremultipliedLast); 
    CGColorSpaceRelease(colorSpace); 

    if(context == NULL) { 
     printf("Context not created!\n"); 
     return NULL; 
    } 

    // Draw images 
    CGContextSetBlendMode(context, kCGBlendModeNormal); 
    CGContextDrawImage(context, CGRectOffset(bottomFrame, -renderFrame.origin.x, -renderFrame.origin.y), bottomRef); 
    CGContextSetBlendMode(context, kCGBlendModeDifference); 
    CGContextDrawImage(context, CGRectOffset(topFrame, -renderFrame.origin.x, -renderFrame.origin.y), topRef); 

    // Create image from context 
    CGImageRef imageRef = CGBitmapContextCreateImage(context); 
    UIImage * image = [UIImage imageWithCGImage:imageRef]; 
    CGImageRelease(imageRef); 

    CGContextRelease(context); 

    return image; 
} 
+1

你好科里,代码是非常有用的,它设法产生在任何一张照片都不存在的元素。但是,它似乎也产生了黑色背景,而不是透明背景。有没有办法去除黑色背景? – wahkiz 2013-02-20 08:23:42

0

难道你不能只是从图像中减去像素值,并处理差异i 0的像素?

+0

@ Ross,谢谢你的回答。我的问题是,我不知道如何创建RGBA值不同的像素的蒙版。 – 2010-10-12 11:44:30

0

通过像素,将下图中不同的图像复制到新图像(不透明)。

完全模糊上面一个,然后显示上面的一个。

+0

如何将像素复制到新图像上? – 2010-10-13 20:52:42

0

在某个半径内的另一个图像中没有合适的相似像素的每个像素都可以被视为掩膜的一部分。它很慢,(尽管没有太多的东西会更快),但它工作起来相当简单。

2

像素从一张iPhone照片变为下一张,主体改变,iPhone移动和随机噪音有三个原因。我假设对于这个问题,你最感兴趣的是主题的变化,并且你想要处理掉其他两个变化的影响。我还假定该应用程序旨在让用户保持合理的iPhone,所以iPhone的移动变化不如主题变化。

为了减少随机噪声的影响,只需稍微模糊图像即可。一个简单的平均模糊,其中结果图像中的每个像素是最近邻居的原始像素的平均值,应该足以消除光线充足的iPhone图像中的任何噪点。

要解决iPhone移动问题,您可以在每个图像上运行特征检测算法(在维基百科上查找特征检测以便开始使用)。然后计算对齐变化最小的检测到的特征所需的变换。

将变换应用于模糊图像,并找出图像之间的差异。具有足够差异的任何像素将成为您的面具。然后,您可以处理遮罩以消除任何变化像素的岛屿。例如,一个主题可能穿着一件纯色衬衫。主题可能会从一个图像移动到另一个图像,但纯色衬衫的面积可能会重叠,导致中间有一个孔洞的面罩。

换句话说,这是一个重要且困难的图像处理问题。你不会在stackoverflow.com上找到答案。你会在数字图像处理教科书中找到答案。

+0

感谢您的回答伯纳先生。我知道这是一个复杂的问题,并感谢您的提示。为了解决这个问题,我肯定会做一些图像处理研究。 – 2010-10-19 15:21:53