2012-05-24 4 views
4

Я пытаюсь реализовать встроенный API обнаружения лиц iOS 5. Я использую экземпляр UIImagePickerController, чтобы позволить пользователю сделать снимок, а затем я пытаюсь использовать CIDetector для обнаружения черт лица. К сожалению, featuresInImage всегда возвращает массив размером 0.CIDetector и UIImagePickerController

Вот код:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
{ 
UIImage* picture = [info objectForKey:UIImagePickerControllerOriginalImage]; 

NSNumber *orientation = [NSNumber numberWithInt: 
         [picture imageOrientation]]; 
NSDictionary *imageOptions = 
[NSDictionary dictionaryWithObject:orientation 
          forKey:CIDetectorImageOrientation]; 

CIImage *ciimage = [CIImage imageWithCGImage:[picture CGImage] 
            options:imageOptions]; 


NSDictionary *detectorOptions = 
[NSDictionary dictionaryWithObject:CIDetectorAccuracyLow 
          forKey:CIDetectorAccuracy]; 
CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace 
              context:nil 
              options:detectorOptions]; 

NSArray *features = [detector featuresInImage:ciimage]; 
NSLog(@"Feature size: %d", features.count); 
} 

Это всегда возвращает 0 функции. Однако, если я использую UIImage из файла, встроенного в приложение, распознавание лица отлично работает.

Я использую код из этого Pragmatic Bookshelf article.

Для чего это стоит, я думаю, что ошибка заключается в том, что я конвертирую UIImage из камеры в CIImage, но это может быть что угодно.

ответ

17

@tonyc Ваше решение работает только для конкретного случая, который является «UIImageOrientationRight». Проблема связана с различием ориентации в UIImage и CIDetectorImageOrientation. С прошивкой документы:

CIDetectorImageOrientation

Ключ, используемый для определения ориентации дисплея изображения, черты которого вы хотите, чтобы обнаружить. Этот ключ является объектом NSNumber с тем же значением, что и спецификация TIFF и EXIF; значения могут варьироваться от 1 до 8. Значение определяет, где находится начало координат (0,0) изображения. Если нет , значение по умолчанию равно 1, что означает начало изображения сверху, слева. Подробнее о происхождении изображения, заданном каждым значением, см. KCGImagePropertyOrientation.

Доступно в iOS 5.0 и новее.

Объявлено в CIDetector.h.

Так что проблема в настоящее время является переход между этими двумя ориентациями, вот что я сделал в моем коде, я проверил, и он работал на всех направлениях:

int exifOrientation; 
switch (self.image.imageOrientation) { 
    case UIImageOrientationUp: 
     exifOrientation = 1; 
     break; 
    case UIImageOrientationDown: 
     exifOrientation = 3; 
     break; 
    case UIImageOrientationLeft: 
     exifOrientation = 8; 
     break; 
    case UIImageOrientationRight: 
     exifOrientation = 6; 
     break; 
    case UIImageOrientationUpMirrored: 
     exifOrientation = 2; 
     break; 
    case UIImageOrientationDownMirrored: 
     exifOrientation = 4; 
     break; 
    case UIImageOrientationLeftMirrored: 
     exifOrientation = 5; 
     break; 
    case UIImageOrientationRightMirrored: 
     exifOrientation = 7; 
     break; 
    default: 
     break; 
} 

NSDictionary *detectorOptions = @{ CIDetectorAccuracy : CIDetectorAccuracyHigh }; // TODO: read doc for more tuneups 
CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeFace context:nil options:detectorOptions]; 

NSArray *features = [faceDetector featuresInImage:[CIImage imageWithCGImage:self.image.CGImage] 
              options:@{CIDetectorImageOrientation:[NSNumber numberWithInt:exifOrientation]}]; 
+0

+1 Отличный ответ. –

+0

что такое self.image.imageOrientation вы можете объяснить? –

2

Конечно, проведя день, изучая это и будучи в тупике, я нашел решение через час после публикации этого.

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

Оказывается, что мне нужно эти варианты:

NSDictionary *imageOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:6] 
                 forKey:CIDetectorImageOrientation]; 
NSArray *features = [detector featuresInImage:ciimage options:imageOptions]; 
0

У меня была аналогичная проблема - детектор лица работает в ориентации, которые не соответствуют свойству ориентации изображения. iOS face detector orientation and setting of CIImage orientation

быстро работа вокруг, что я нашел, чтобы помочь с этим, чтобы не учитывать ориентацию изображения все вместе и «придавить» изображение (так что нет никаких данных ориентации изображения)

Я использовал этот код:

http://blog.logichigh.com/2008/06/05/uiimage-fix/

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

0

Swift 3 Версия

var exifOrientation : Int 
switch (inputImage.imageOrientation) 
{ 
case UIImageOrientation.up: 
    exifOrientation = 1; 
case UIImageOrientation.down: 
    exifOrientation = 3; 
case UIImageOrientation.left: 
    exifOrientation = 8; 
case UIImageOrientation.right: 
    exifOrientation = 6; 
case UIImageOrientation.upMirrored: 
    exifOrientation = 2; 
case UIImageOrientation.downMirrored: 
    exifOrientation = 4; 
case UIImageOrientation.leftMirrored: 
    exifOrientation = 5; 
case UIImageOrientation.rightMirrored: 
    exifOrientation = 7; 
} 

let ciImage = CIImage(cgImage: inputImage.cgImage!) 
let options = [CIDetectorAccuracy: CIDetectorAccuracyHigh] 
let faceDetector = CIDetector(ofType: CIDetectorTypeFace, context: nil, options: options)! 
let faces = faceDetector.features(in: ciImage, options:["CIDetectorImageOrientation":exifOrientation])