4

나는 CALayer에 그리기 위해 CIFaceFeature에서 반환 된 CGPoint 결과를 변환하는 방법을 알아 내려고하고 있습니다. 이전에는 물건을 더 쉽게 만들기 위해 이미지를 0으로 정규화했지만 가로 모드로 고정 된 장치로 촬영 한 이미지에는 문제가 발생합니다.CGFP 결과가 CIFaceFeature에서 반환 됨

나는이 작업을 잠시 동안 성공하지 못했고 작업에 대한 내 이해가 잘못되었거나 내 접근 방식이 올바르지 않거나 둘 다 맞는지 잘 모르겠습니다. 내가있는 CGPoint 회전하려고 아래의 코드에서 CIDetectorfeaturesInImage:options: 방법

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. 

image as displayed in UIImageView

에 대한 설명서에 따르면

original image from camera

: 여기에 내가 생각하는 것은 정확 UIImageView를 오버레이하는 CAShape 레이어를 통해 그릴 수 있습니다.

내가하고있는 것 (... 또는 내가하고있는 것 같아요 ...)은 왼쪽 눈 CGPoint를보기의 중심으로 90도 회전 한 다음 원래 위치로 되돌려 번역하는 것입니다. 이것은 정확하지 않지만 내가 어디로 잘못 가고 있는지 알지 못합니다. 내 방식이 잘못되었거나 구현하는 방식입니까? -

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

이 leftEyePosition가 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); 

입니다 : https://stackoverflow.com/a/14491293/840992, 나는 imageOrientation

방향

애플 /있는 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 

메시지가 오후 4시 9분

답변

0

에서 2/1/13에 skinnyTOD에 의해 편집 된 난 당신이 발견 얼굴을 뒤집어 야 어떻게 생각 이미지의 수평 중심 축에 대한 좌표

는이 변환에 시도 할 수 : 이것은 우리가 얼굴을 발견하기 전에 0으로 image.imageOrientation를 설정 한 경우에만 작동 변환

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

.

+0

아니요, 작동하지 않습니다. 좌표를 회전해야합니다 (저는 믿습니다). 나는 그 작업이 무엇인지를 보여주기 위해 몇 가지 이미지를 추가했다. –

+0

@skinnyTOD, 죄송합니다. 저는 잘못 생각했습니다.이 변형은 normalize (imageOrientation 0 방향 설정) 만하면 작동합니다. 나는 곧 업데이트를 게시 할 것이다. – foundry

6

정확한 문제를 찾아야합니다. Apple 샘플 "SquareCam"은 비디오 출력에서 ​​직접 작동하지만 여전히 UIImage의 결과가 필요합니다. 그래서 몇 가지 변환 방법으로 CIFaceFeature 클래스를 확장하여 UIImage와 UIImageView (또는 UIView의 CALayer)와 관련하여 정확한 포인트 위치와 범위를 가져 왔습니다. 전체 구현은 여기에 게시됩니다 : https://gist.github.com/laoyang/5747004. 직접 사용할 수 있습니다.여기에 위의 변환에 따라 분류 방법이있다

- (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 UIImageOrientationUpMirrored: 
      convertedPoint.x = imageWidth - originalPoint.x; 
      convertedPoint.y = imageHeight - originalPoint.y; 
      break; 
     case UIImageOrientationDownMirrored: 
      convertedPoint.x = originalPoint.x; 
      convertedPoint.y = originalPoint.y; 
      break; 
     case UIImageOrientationLeftMirrored: 
      convertedPoint.x = imageWidth - originalPoint.y; 
      convertedPoint.y = originalPoint.x; 
      break; 
     case UIImageOrientationRightMirrored: 
      convertedPoint.x = originalPoint.y; 
      convertedPoint.y = imageHeight - originalPoint.x; 
      break; 
     default: 
      break; 
    } 
    return convertedPoint; 
} 

을 그리고 :

// 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; 
다음

이 CIFaceFeature에서 포인트에 대한 가장 기본적인 변환하고, 반환 된 CGPoint는 이미지의 방향에 따라 변환된다

(UIImage 방향에서 얼굴 특징을 추출 할 때 올바른 EXIF ​​방향을 지정하는 것만 큼주의해야합니다.) 혼란 스럽네요 ... 여기 제가 한 것입니다 :

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 }; 
CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeFace context:nil options:detectorOptions]; 

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