2012-08-30 3 views
2

저는 CGPaths를 사용하여 좌표를 그릴 수 있도록 이미지를 표시하는 UIImageView에 상대적인 좌표로 CIDetector (얼굴 감지) 결과를 변환하는 데 어려움을 겪고 있습니다.CIDetector (얼굴 감지) 결과를 UIImageView 좌표로 변환

여기에서 모든 질문과 내가 찾을 수있는 모든 자습서를 살펴 보았으며 대부분 UIImageView (example)에 표시 될 때 크기가 조정되지 않은 작은 이미지를 사용합니다. 내가 겪고있는 문제는 UIImageView에 표시 될 때 aspectFit을 사용하여 크기가 조정 된 큰 이미지를 사용하고 올바른 크기와 변환 값을 결정할 때 발생합니다.

다른 크기/종횡비의 이미지로 테스트 할 때 일관성없는 결과가 발생하므로 내 일상에 결함이있는 것 같습니다. 나는 잠시 동안이 문제로 고생하고 있었으므로 누군가가 팁을 가지고 있거나 내가 뭘 잘못하고 있는지 엑스레이 할 수 있다면 큰 도움이 될 것입니다.

내가 뭐하는 거지 :

  • 얼굴이
  • 규모 변환을 만드는있는 UIImageView 이미지의 규모와 범위를 얻기 위해 (SO에 여기) 아래 frameForImage 루틴을 사용하여 좌표를 얻을 + 번역
  • 는 CIDetector 결과 드에 대한

// 내 일상에 변환을 적용 나쁜 결과

 mouthPosition = CGPointApplyAffineTransform(mouthPosition, transform); 

// 예 : 변환 termining 값

NSDictionary* data = [self frameForImage:self.imageView.image inImageViewAspectFit:self.imageView]; 

CGRect scaledImageBounds = CGRectFromString([data objectForKey:@"bounds"]); 
float scale = [[data objectForKey:@"scale"] floatValue]; 

CGAffineTransform transform = CGAffineTransformMakeScale(scale, -scale); 

transform = CGAffineTransformTranslate(transform, 
      scaledImageBounds.origin.x/scale, 
      -(scaledImageBounds.origin.y/scale + scaledImageBounds.size.height/scale)); 

CIDetector 결과를 사용하여 전환 규모는 SO에 대한에 여기

enter image description here

// 루틴 아래 잘못된 것 같습니다 'aspectFit`을 사용하여 UIImageView에서 크기가 조정 된 이미지 바운드를 결정합니다.

-(NSDictionary*)frameForImage:(UIImage*)image inImageViewAspectFit:(UIImageView*)myImageView 
{ 
    float imageRatio = image.size.width/image.size.height; 
    float viewRatio = myImageView.frame.size.width/myImageView.frame.size.height; 

    float scale; 
    CGRect boundingRect; 
    if(imageRatio < viewRatio) 
    { 
     scale = myImageView.frame.size.height/image.size.height; 
     float width = scale * image.size.width; 
     float topLeftX = (myImageView.frame.size.width - width) * 0.5; 
     boundingRect = CGRectMake(topLeftX, 0, width, myImageView.frame.size.height); 
    } 
    else 
    { 
     scale = myImageView.frame.size.width/image.size.width; 
     float height = scale * image.size.height; 
     float topLeftY = (myImageView.frame.size.height - height) * 0.5; 
     boundingRect = CGRectMake(0, topLeftY, myImageView.frame.size.width, height); 
    } 

    NSDictionary * data = [NSDictionary dictionaryWithObjectsAndKeys: 
          [NSNumber numberWithFloat:scale], @"scale", 
          NSStringFromCGRect(boundingRect), @"bounds", 
          nil]; 

    return data; 
} 

답변

4

나는 당신이하려는 것을 완전히 이해하지만, 원하는 것을 얻기 위해 다른 방법을 제공하겠습니다.

  • 당신은 이미지로 나눈 이미지 뷰 폭 인 '규모'요소를 결정 크기의 이미지 위에
  • 당신이 이미지 뷰
  • 의 크기를 알고 자신의 CGImage
  • 이미지를 요청해야 폭
  • 다중이 가치와 이미지 높이가, 다음 이미지 뷰에서 "빈"높이를 얻으려면, imageViewHeight에서 결과를 빼기, 얻을 라운드 2이 'fillHeight'
  • 나누기 'fillHeight'를 호출 할 수 있습니다 '의 fset '값은 아래에서 사용됩니다.
  • UIGraphicsBeginImageContextWithOptions (imageView.CGImage (CGImage (0, offset, imageView.size.width, rintf (image.size.height * scale)), CGImage (CGImage, CGImage, size, NO, 0)를 사용하여 CGI 이미지를 그릴 수 있습니다. , [image CGImage]);

  • 하여 새로운 화상을 얻을 :

    있는 UIImage * = UIGraphicsGetImageFromCurrentImageContext 화상(); UIGraphicsEndImageContext(); 반환 이미지;

  • 이미지 설정 : imageView.image = image;

정확한 배율 및 오프셋을 알면 정확하게 이미지에 다시 매핑 할 수 있습니다.

+0

- 그것은 작동 감사 이봐! 그것은 "그것의 주위에 드라이브"유형 생각이다! 번역 문제를 해결할 수 있었지만 이미 너무 많은 시간을 보냈습니다. –

+0

안녕하세요 @ 데이비드, 당신이 도울 수 있기를 바랍니다, 위의 장면 채우기로 작업하는 데 어려움을 겪고 있습니다. 시간 내 주셔서 감사합니다, 내 최근 질문입니다. http://stackoverflow.com/questions/36099735/how-to-use-cidetector-and-cifacefeature-with-large-images-and-different-aspect-r –

+0

@ TalZion을 사용하면 뷰를 채우기 위해 뷰티의 배율과 오프셋을 정확히 계산하고 적용 할 수 있습니다. 숨을 깊이들이 쉬고 종이 한장에 그려 낸 다음 알아냅니다. 그냥 수학. –

0

귀하가 찾고 계신 간단한 답변 일 수도 있습니다. x 좌표와 y 좌표가 뒤바뀐 경우 직접 거울을 칠할 수 있습니다. 아래의 조각 메신저에서 내 반환 기능을 통해 반복하고, y 좌표를 반전 할 필요, 그것은 전면 카메라의 경우 X 좌표 :

for (CIFaceFeature *f in features) { 
     float newy = -f.bounds.origin.y + self.frame.size.height - f.bounds.size.height; 

     float newx = f.bounds.origin.x; 
     if(isMirrored) { 
      newx = -f.bounds.origin.x + self.frame.size.width - f.bounds.size.width; 
     } 
     [[soups objectAtIndex:rnd] drawInRect:CGRectMake(newx, newy, f.bounds.size.width, f.bounds.size.height)]; 
    }