Resultados de transformación de CGPoint devueltos desde CIFaceFeature

Estoy tratando de averiguar cómo transformar los resultados de CGPoint devueltos de CIFaceFeature para dibujar con ellos en un CALayer . Anteriormente, había normalizado mi image para tener una rotation de 0 para facilitar las cosas, pero eso causa problemas a las imágenes tomadas con el dispositivo en modo horizontal.

He estado trabajando en esto por un time sin éxito y no estoy seguro de si mi comprensión de la tarea es incorrecta o si mi enfoque es incorrecto o ambos. Esto es lo que creo que es correcto:

imagen original de la cámara

Según la documentation de CIDetector featuresInImage:options: method

 A dictionary that specifies the orientation of the image. The detection is adjusted to account for the image orientation but the coordinates in the returned feature objects are based on those of the image. 

imagen como se muestra en UIImageView

En el siguiente código estoy intentando rotar un CGPoint para dibujarlo a través de una capa CAShape que se superpone a un UIImageView.

Lo que estoy haciendo (… o creo que estoy haciendo …) está traduciendo el ojo izquierdo CGPoint al centro de la vista, girando 90 grados, y luego traduciendo el punto a donde estaba. Esto no es correcto, pero no sé a dónde me voy mal. ¿Es incorrecto mi enfoque o la manera en que lo estoy implementando?

 #define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI) 

– leftEyePosition es un CGPoint

 CGAffineTransform transRot = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(90)); float x = self.center.x; float y = self.center.y; CGAffineTransform tCenter = CGAffineTransformMakeTranslation(-x, -y); CGAffineTransform tOffset = CGAffineTransformMakeTranslation(x, y); leftEyePosition = CGPointApplyAffineTransform(leftEyePosition, tCenter); leftEyePosition = CGPointApplyAffineTransform(leftEyePosition, transRot); leftEyePosition = CGPointApplyAffineTransform(leftEyePosition, tOffset); 

De esta publicación: https://stackoverflow.com/a/14491293/840992 , necesito hacer rotaciones basadas en imageOrientation

Orientación

Apple / UIImage.imageOrientation Jpeg / File kCGImagePropertyOrientation

 UIImageOrientationUp = 0 = Landscape left = 1 UIImageOrientationDown = 1 = Landscape right = 3 UIImageOrientationLeft = 2 = Portrait down = 8 UIImageOrientationRight = 3 = Portrait up = 6 

El post fue editado por skinnyTOD el 01/02/13 a las 4:09 PM

    Necesito averiguar el mismo problema. La muestra de Apple "SquareCam" opera directamente en una salida de video, pero necesito los resultados del UIImage todavía. Así que extendí la class CIFaceFeature con algunos methods de conversión para get las ubicaciones y los límites del punto correctos con respecto al UIImage y su UIImageView (o el CALayer de una UIView). La implementación completa se publica aquí: https://gist.github.com/laoyang/5747004 . Puede usar directamente.

    Aquí está la conversión más básica para un punto de CIFaceFeature, el CGPoint devuelto se convierte en function de la orientación de la image:

     - (CGPoint) pointForImage:(UIImage*) image fromPoint:(CGPoint) originalPoint { CGFloat imageWidth = image.size.width; CGFloat imageHeight = image.size.height; CGPoint convertedPoint; switch (image.imageOrientation) { case UIImageOrientationUp: convertedPoint.x = originalPoint.x; convertedPoint.y = imageHeight - originalPoint.y; break; case UIImageOrientationDown: convertedPoint.x = imageWidth - originalPoint.x; convertedPoint.y = originalPoint.y; break; case UIImageOrientationLeft: convertedPoint.x = imageWidth - originalPoint.y; convertedPoint.y = imageHeight - originalPoint.x; break; case UIImageOrientationRight: convertedPoint.x = originalPoint.y; convertedPoint.y = originalPoint.x; break; case UIImageOrientationUpMirronetworking: convertedPoint.x = imageWidth - originalPoint.x; convertedPoint.y = imageHeight - originalPoint.y; break; case UIImageOrientationDownMirronetworking: convertedPoint.x = originalPoint.x; convertedPoint.y = originalPoint.y; break; case UIImageOrientationLeftMirronetworking: convertedPoint.x = imageWidth - originalPoint.y; convertedPoint.y = originalPoint.x; break; case UIImageOrientationRightMirronetworking: convertedPoint.x = originalPoint.y; convertedPoint.y = imageHeight - originalPoint.x; break; default: break; } return convertedPoint; } 

    Y aquí están los methods de categoría basados ​​en la conversión anterior:

     // Get converted features with respect to the imageOrientation property - (CGPoint) leftEyePositionForImage:(UIImage *)image; - (CGPoint) rightEyePositionForImage:(UIImage *)image; - (CGPoint) mouthPositionForImage:(UIImage *)image; - (CGRect) boundsForImage:(UIImage *)image; // Get normalized features (0-1) with respect to the imageOrientation property - (CGPoint) normalizedLeftEyePositionForImage:(UIImage *)image; - (CGPoint) normalizedRightEyePositionForImage:(UIImage *)image; - (CGPoint) normalizedMouthPositionForImage:(UIImage *)image; - (CGRect) normalizedBoundsForImage:(UIImage *)image; // Get feature location inside of a given UIView size with respect to the imageOrientation property - (CGPoint) leftEyePositionForImage:(UIImage *)image inView:(CGSize)viewSize; - (CGPoint) rightEyePositionForImage:(UIImage *)image inView:(CGSize)viewSize; - (CGPoint) mouthPositionForImage:(UIImage *)image inView:(CGSize)viewSize; - (CGRect) boundsForImage:(UIImage *)image inView:(CGSize)viewSize; 

    (Otra cosa que debe tener en count es especificar la orientación EXIF ​​correcta al extraer las características de la cara de la orientación UIImage. Bastante confuso … esto es lo que hice:

     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 UIImageOrientationUpMirronetworking: exifOrientation = 2; break; case UIImageOrientationDownMirronetworking: exifOrientation = 4; break; case UIImageOrientationLeftMirronetworking: exifOrientation = 5; break; case UIImageOrientationRightMirronetworking: exifOrientation = 7; break; default: break; } NSDictionary *detectorOptions = @{ CIDetectorAccuracy : CIDetectorAccuracyHigh }; CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeFace context:nil options:detectorOptions]; NSArray *features = [faceDetector featuresInImage:[CIImage imageWithCGImage:self.image.CGImage] options:@{CIDetectorImageOrientation:[NSNumber numberWithInt:exifOrientation]}]; 

    )

    Creo que lo que necesita para voltear las coorderadas de las caras encontradas sobre el eje central horizontal de la image

    ¿Puedes probar con esta transformación?

     CGAffineTransform transform = CGAffineTransformIdentity; transform = CGAffineTransformTranslate(transform, 0.0f, image.size.height); transform = CGAffineTransformScale(transform, 1.0f, -1.0f); [path applyTransform:transform]; 

    Esta transformación funciona solo si establecemos image.imageOrientation en 0 antes de encontrar caras.