7 Stimmen

Erstellen Sie eine Maske aus dem Unterschied zwischen zwei Bildern (iPhone)

Wie kann ich den Unterschied zwischen 2 Bildern erkennen, indem ich eine Maske des Bereichs erstelle, der sich unterscheidet, um den Bereich zu verarbeiten, der beiden Bildern gemeinsam ist (zum Beispiel Gaußscher Weichzeichner)?

sketch

BEARBEITEN: Ich verwende derzeit diesen Code, um den RGBA-Wert von Pixeln zu erhalten:

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

    // Zuerst das Bild in den Datenpuffer bekommen
    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);

    // Jetzt enthält rawData die Bilddaten im RGBA8888-Pixelformat.
    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;
}

Das Problem ist, die Bilder werden von der Kamera des iPhones erfasst, daher sind sie nicht genau in derselben Position. Ich muss Bereiche von ein paar Pixeln erstellen und die allgemeine Farbe des Bereichs extrahieren (vielleicht durch Addition der RGBA-Werte und Division durch die Anzahl der Pixel?). Wie könnte ich das tun und es dann in eine CGMask übersetzen?

Ich weiß, dass dies eine komplexe Frage ist, also wäre jede Hilfe willkommen.

Danke.

6voto

Cory Kilger Punkte 12974

Ich denke, der einfachste Weg, dies zu tun, wäre die Verwendung eines Differenz-Blend-Modus. Der folgende Code basiert auf dem Code, den ich in CKImageAdditions verwende.

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

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

    // Kontext erstellen
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    if(colorSpace == NULL) {
        printf("Fehler beim Zuweisen des Farbraums.\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("Kontext nicht erstellt!\n");
        return NULL;
    }

    // Bilder zeichnen
    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);

    // Bild aus Kontext erstellen
    CGImageRef imageRef = CGBitmapContextCreateImage(context);
    UIImage * image = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);

    CGContextRelease(context);

    return image;
}

2voto

Mr. Berna Punkte 10303

Es gibt drei Gründe, warum sich Pixels von einem iPhone-Foto zum nächsten ändern: Das Motiv hat sich geändert, das iPhone hat sich bewegt und zufälliges Rauschen. Ich gehe davon aus, dass du bei dieser Frage hauptsächlich an den Motivwechsel interessiert bist und die Effekte der anderen beiden Veränderungen herausfiltern möchtest. Ich nehme auch an, dass die App beabsichtigt, dass der Benutzer das iPhone möglichst ruhig hält, daher sind Veränderungen der iPhone-Bewegungen weniger signifikant als Motivveränderungen.

Um die Effekte des zufälligen Rauschens zu reduzieren, verwische einfach das Bild ein wenig. Ein einfacher Durchschnittsunschärfe, bei dem jeder Pixel im resultierenden Bild ein Durchschnitt des Originalpixels mit seinen nächsten Nachbarn ist, sollte ausreichen, um eventuelles Rauschen in einem vernünftig beleuchteten iPhone-Bild zu glätten.

Um auf die iPhone-Bewegung einzugehen, kannst du einen Merkmalsdetektionsalgorithmus auf jedes Bild anwenden (suche nach Merkmalsdetektion auf Wikipedia, um anzufangen). Berechne dann die Transformationen, die nötig sind, um die am wenigsten veränderten erkannten Merkmale auszurichten.

Wende diese Transformationen auf die verwischten Bilder an und finde den Unterschied zwischen den Bildern. Jene Pixels mit einem ausreichenden Unterschied werden deine Maske. Du kannst dann die Maske bearbeiten, um eventuelle Gruppen von veränderten Pixels zu eliminieren. Zum Beispiel kann ein Motiv einfarbiges Hemd tragen. Das Motiv kann sich von einem Bild zum nächsten bewegen, aber der Bereich des einfarbigen Hemdes kann überlappen und eine Maske mit einem Loch in der Mitte erzeugen.

Anders ausgedrückt, dies ist ein bedeutendes und schwieriges Bildverarbeitungsproblem. Du wirst die Antwort nicht in einem stackoverflow.com-Beitrag finden. Du wirst die Antwort in einem Lehrbuch zur digitalen Bildverarbeitung finden.

0voto

Ross Punkte 2002

Kannst du nicht einfach Pixelwerte von den Bildern abziehen und Pixel verarbeiten, bei denen der Unterschied 0 ist?

0voto

TaslemGuy Punkte 584

Jeder Pixel, der innerhalb eines bestimmten Radius keinen geeignete ähnlichen Pixel im anderen Bild hat, kann als Teil der Maske betrachtet werden. Es ist langsam, (obwohl nicht viel schneller sein würde), aber es funktioniert ziemlich einfach.

-1voto

Thyraz Punkte 79

Gehen Sie durch die Pixel, kopieren Sie diejenigen, die im unteren Bild anders sind, in ein neues (nicht undurchsichtiges).

Verwischen Sie das obere ganz, dann zeigen Sie das Neue darüber.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X