Доступ в реальном времени к изображениям с камеры iPhone - PullRequest
1 голос
/ 18 февраля 2011

Я пытаюсь прочитать (среднее) RGB-значение центральных пикселей камеры iPhone.Это должно почти произойти в реальном времени.Поэтому я открываю UIImagePickerController, использую таймер, чтобы делать снимки каждые x секунд.Обработка изображения выполняется в отдельном потоке, чтобы он не блокировал приложение при вычислении значения RGB.Я попробовал несколько способов получить доступ к значениям RGB / pixel снятого изображения, но у всех есть проблема в том, что они слишком медленные и приводят к задержке обзора камеры.Я попробовал следующее:

- (UIColor *)getAverageColorOfImage:(UIImage*)image {
int pixelCount = kDetectorSize * kDetectorSize;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * kDetectorSize;
NSUInteger bitsPerComponent = 8;
unsigned char *rawData = malloc(pixelCount * bytesPerPixel);
CGContextRef context = CGBitmapContextCreate(rawData, kDetectorSize, kDetectorSize, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextSetInterpolationQuality(context, kCGInterpolationNone);

NSLog(@"Drawing image");
CGContextDrawImage(context, CGRectMake(0, 0, kDetectorSize, kDetectorSize), [image CGImage]);
NSLog(@"Image drawn");

CGContextRelease(context);

// rawData contains the image data in the RGBA8888 pixel format. Alpha values are ignored
int byteIndex = 0;
CGFloat red = 0.0;
CGFloat green = 0.0;
CGFloat blue = 0.0;

for (int i = 0 ; i <  pixelCount; ++i) {
    red   += rawData[byteIndex];
    green += rawData[byteIndex + 1];
    blue  += rawData[byteIndex + 2];
    byteIndex += bytesPerPixel;
}

free(rawData);

return [UIColor colorWithRed:red/pixelCount/255.0 green:green/pixelCount/255.0 blue:blue/pixelCount/255.0 alpha:1.0];
}

kDetectorSize установлен в 6 так, что обработанное изображение имеет размер 6x6 пикселей.Один из параметров изображения также был обрезан до 6x6 пикселей ранее.Медленная часть - это CGContextDrawImage, который занимает около 500-600 мс на моем iPhone 4. Я попробовал несколько альтернатив для этой строки:

UIGraphicsPushContext(context); 
[image drawAtPoint:CGPointMake(0.0, 0.0)];
UIGraphicsPopContext();

или

UIGraphicsPushContext(context); 
[image drawInRect:CGRectMake(0.0, 0.0, kDetectorSize, kDetectorSize)];
UIGraphicsPopContext();

Оба подхода медленнее, чемодин выше.Размер изображения не оказывает существенного влияния (я бы сказал, что это не имеет никакого влияния).Кто-нибудь знает более быстрый способ доступа к значению RGB?

Также было бы хорошо, если бы поток не вызывал задержку обзора камеры.Я так называю свою тему:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
    [NSThread detachNewThreadSelector:@selector(pickColorFromImage:) toTarget:self withObject:image]; 
}

- (void)pickColorFromImage:(UIImage *)image {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];   
    [NSThread setThreadPriority:0.0];

    [...cropping the image...]
UIColor *averageColor = [self getAverageColorOfImage:croppedImage];

    [self performSelectorOnMainThread:@selector(applyPickedColor:) withObject:averageColor waitUntilDone:NO];  

    [pool release];
}

Спасибо за вашу помощь!

1 Ответ

4 голосов
/ 18 февраля 2011

Вы подходите к этому неправильно - Apple предлагает класс, который делает именно то, что вы хотите, не возиться с таймерами и UIImagePickers. AVCaptureSession и связанные классы предоставляют вам доступ в реальном времени к необработанным пиксельным данным с камеры.

Для получения дополнительной информации см. Документацию:

http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVCaptureSession_Class/Reference/Reference.html%23//apple_ref/doc/uid/TP40009521

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