2010-10-10 88 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