Сравнение буфера AVFoundation с сохраненным изображением - PullRequest
3 голосов
/ 16 января 2011

Я давний читатель, впервые пишу о StackOverflow, и должен сказать, что это был отличный источник знаний для меня.

Я пытаюсь познакомиться с фреймворком AVFoundation.

Что я хочу сделать, это сохранить то, что видит камера , а затем обнаружить, когда что-то изменится .

Вот часть, где я сохраняю изображение в UIImage:

if (shouldSetBackgroundImage) {
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    // Create a bitmap graphics context with the sample buffer data
    CGContextRef context = CGBitmapContextCreate(rowBase, bufferWidth,
        bufferHeight, 8, bytesPerRow,
        colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 
    // Create a Quartz image from the pixel data in the bitmap graphics context
    CGImageRef quartzImage = CGBitmapContextCreateImage(context); 

    // Free up the context and color space
    CGContextRelease(context); 
    CGColorSpaceRelease(colorSpace);

    // Create an image object from the Quartz image
    UIImage * image = [UIImage imageWithCGImage:quartzImage];
    [self setBackgroundImage:image];
    NSLog(@"reference image actually set");

    // Release the Quartz image
    CGImageRelease(quartzImage);

    //Signal that the image has been saved
    shouldSetBackgroundImage = NO;

}

и вот часть, где я проверяю, есть ли какие-либо изменения в изображении, видимом камерой:

else {

    CGImageRef cgImage = [backgroundImage CGImage];
    CGDataProviderRef provider = CGImageGetDataProvider(cgImage);
    CFDataRef bitmapData = CGDataProviderCopyData(provider);
    char* data = CFDataGetBytePtr(bitmapData);

    if (data != NULL)
    {
        int64_t numDiffer = 0, pixelCount = 0;
        NSMutableArray * pointsMutable = [NSMutableArray array];

        for( int row = 0; row < bufferHeight; row += 8 ) {
            for( int column = 0; column < bufferWidth; column += 8 ) {

                //we get one pixel from each source (buffer and saved image)
                unsigned char *pixel = rowBase + (row * bytesPerRow) + (column * BYTES_PER_PIXEL);
                unsigned char *referencePixel = data + (row * bytesPerRow) + (column * BYTES_PER_PIXEL);

                pixelCount++;

                if ( !match(pixel, referencePixel, matchThreshold) ) {
                    numDiffer++;
                    [pointsMutable addObject:[NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH - (column/ (float) bufferHeight)* SCREEN_WIDTH - 4.0, (row/ (float) bufferWidth)* SCREEN_HEIGHT- 4.0)]];
                }
            }
        }
        numberOfPixelsThatDiffer = numDiffer;
        points = [pointsMutable copy];
    }

По какой-то причине это не работает, это означает, что iPhone обнаруживает, что почти все отличается от сохраненного изображения, хотя я установил очень низкий порог обнаружения в функции сопоставления ...

Ты хоть представляешь, что я делаю неправильно?

Ответы [ 2 ]

1 голос
/ 16 января 2011

Существует три возможности, по которым я могу предположить, почему вы можете видеть, что почти каждый пиксель различен: преобразования цветового пространства, неправильное отображение местоположения пикселей или ваша пороговая величина слишком чувствительна для фактического движения камеры iPhone. Первые два маловероятны, поэтому я думаю, что это может быть третьим, но их стоит проверить.

Возможно, происходит некоторая коррекция цвета, когда вы помещаете свои пиксели в UIImage, а затем извлекаете их позже. Вы можете попытаться просто сохранить их в исходном состоянии из буфера, а затем использовать этот исходный буфер в качестве точки сравнения, а не данные поддержки UIImage.

Кроме того, убедитесь, что ваша арифметика строки / столбца работает для фактических положений пикселей в обоих изображениях. Возможно, сгенерируйте разностное изображение с абсолютной разницей, вычитая два изображения, а затем используйте простую черно-белую разделенную область в качестве тестового изображения для камеры.

Наиболее вероятным случаем является то, что общее изображение сдвигается более чем на один пиксель просто под воздействием руки человека, держащей его. Эти сдвиги целого кадра могут привести к тому, что почти каждый пиксель будет отличаться при простом сравнении. Возможно, вам придется настроить пороговое значение или выполнить более интеллектуальную оценку движения, как это используется в процедурах сжатия видео.

Наконец, когда дело доходит до операции сравнения, я рекомендую взглянуть на шейдеры OpenGL ES 2.0 для выполнения этого. Вы должны увидеть значительное ускорение (14-28X в моих тестах) по сравнению с этим попиксельным сравнением процессора. В этой статье , в которой есть этот пример приложения для iPhone , который отслеживает цветные объекты в режиме реального времени с помощью шейдеров GLSL, я показываю, как выполнять настройку порогового значения на основе цвета с помощью графического процессора

1 голос
/ 16 января 2011

Человеческие глаза сильно отличаются от камеры (даже очень дорогой) тем, что мы не воспринимаем минимальные изменения света или небольшие изменения движения.Камеры ДЕЛАЮТ, они очень чувствительные, но совсем не умные!

При вашем текущем подходе (кажется, вы сравниваете каждый пиксель): что произойдет, если кадр сместится только на 1 пиксель вправо ?!Вы можете правильно изобразить результат вашего алгоритма, верно?Люди не воспримут ничего или почти ничего.

Существует также проблема с затвором камеры: это означает, что в каждом кадре может не быть одинакового количества света.Следовательно, метод попиксельного сравнения слишком подвержен ошибкам.

Вы хотите по крайней мере предварительно обработать свое изображение и извлечь некоторые основные функции.Может быть, края, углы и т. Д. OpenCV прост для этого, но я не уверен, что такая обработка будет быстрой в iPhone.(Это зависит от размера вашего изображения)

В качестве альтернативы вы можете попробовать наивный алгоритм сопоставления шаблонов с размером шаблона, который будет немного короче, чем размер вашего отверстия.

Обработка изображений является вычислительно дорогой, поэтому не ожидайте, что она будет быстрой с первого раза, особенно на мобильном устройстве, и даже больше, если у вас нет опыта в обработке изображений / Computer Vision.

Надеюсь, это поможет;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...