2013-01-12 4 views
0

나는 이것을 작성하는 것이 내 문제에 도움이되기를 바랍니다. 나는 얼굴을 포함하는 이미지를 가지고 있으며 가능한 한 많은 얼굴을 유지하면서 종횡비를 존중하면서 이러한 이미지를 되풀이하고 싶습니다.지정된 부분을 제거하지 않고 이미지 자르기를위한 알고리즘

이미지를 크고, 짧거나, 정사각형이거나, 최대 4 : 1 화면까지 임의의 직사각형으로 자르고 싶습니다. 가능한 한 많이, 나는 (이미지의 rect에 내부 직사각형으로) 내가 지정한 얼굴이나 피쳐를 자르고 싶지 않다. E.G. 나는 (0, 500, 300)의 이미지 직사각형과 (20, 40, 75, 75)의 특징 직사각형을 가지고 있고 (종횡비 존중) (0,0, 320,200), 모두 최소로 얼굴 사각형을 자릅니다.

나는 이미지의 더 큰면을 결정하고 동일한 비율을 기준으로 다른면을 스케일링하여 x 및 y를 스케일링 된 w/h - 타겟 w/h의 중심으로 설정하는 중앙 자르기를위한 작업 구현이 있습니다. .

sourceSize은 원본 이미지의 크기
(CGRect)crop:(CGSize)sourceSize toFitSize:(CGSize)fitSize withoutCroppingRect:(CGRect)featuresRect 

, fitSize 내가로 이미지를 자르 할 모양이며, featuresRect :

명확하게하기 위해, 서명은 OBJ (-C)에 다음과 같이 보일 것입니다 는 (0,0,sourceSize.width, sourceSize,height) 범위 내의 사각형입니다.

아마도이 기능 사각형을 중심으로 "가운데 자르기"로 수행해야합니까? 이게 무슨 뜻인지 내 머리를 싸려고.

+0

하면, 300분의 500 인해! = 200분의 300은 (0,0, 300,200)에 화상 직사각형 (0,0,500 300)을 잘라낼 수 없다. - "직사각형"이 목적지 직사각형에 맞지 않으면 어떻게 될까요? –

+0

@MartinR 좋은 지적, 나는 그걸 빨리 타이핑했다. 나는 알고리즘이 feature rectangle을 완전히 존중하지는 않지만 그것이 할 수있는 최선의 일을 할 필요가 있다고 가정합니다. 그게 문제의 일부입니다;) – akaru

+0

만약 당신이 당신이 그것을 성취하려는 노력 대신에 실제로 성취하려는 것을 우리에게 말하면, 우리는 뭔가 제안 할 수 있습니다. 지금 당신이 작성한 모든 것은 너무 모호하여 답이 무한 할 수도 있습니다. "직사각형"에 일반적으로면이 포함되어 있으면 직사각형의 중심이 [1/3 선] (http : // ko) 중 하나에있는 것이 유용 할 수 있습니다.wikipedia.org/wiki/Rule_of_thirds) 이미지에서 일반적으로 즐거운 결과를 얻을 수 있습니다. 또는 원하는 경우, [황금률 행] (http://en.wikipedia.org/wiki/Golden_ratio#Aesthetics) – user1118321

답변

0

이걸 가지고 가거나, 네가 원하는대로하거나 적어도 올바른 방향으로 너를 움직이는 것 같아. 출력 rect는 원본 이미지 rect와 동일한 종횡비를 유지합니다.

사용 예제 :

CGRect sizedRect = [self cropSize:self.inputView.image.size 
         toFitSize:self.outputView.bounds.size 
       withoutCroppingRect:self.regionOfInterest.frame]; 

CGImageRef cgImage = self.inputView.image.CGImage; 

CGImageRef cgCroppedImage = CGImageCreateWithImageInRect (
             cgImage, 
             sizedRect 
             ); 

self.outputView.image = [UIImage imageWithCGImage:cgCroppedImage]; 

당신이 특히 고려해야 할거야 문제가 있습니다 :
- 당신의 반환 RECT에서, fitSize보다 클 수 있습니다대로하지 않습니다 자르기 featuresRect이므로 자르기를 적용한 후 이미지를 비율 조정하거나 출력 이미지 뷰의 scaleToFit을 적절히 설정해야 할 수 있습니다.
- 어디에서 ROI 프레임 데이터를 가져 오나요? 원래의 소스 이미지 또는 소스 이미지가 포함 된 imageView와 관련이 있습니다. 후자의 경우 원본 이미지가 imageView와 1 : 1로 크기가 맞춰 지도록해야합니다. 자르기 rect가 imageView가 아니라 imageView에 적용됩니다.
- 출력 이미지 뷰가 입력 이미지 뷰보다 작습니다. 이것이 더 큰 경우 이것이 무엇인지 모르지만 비슷한 스케일링 문제가 발생할 수 있습니다.
- 0으로 나누기 오류 검사를 추가해야합니다. 종횡비를 유지하면서

-  (CGRect)cropSize:(CGSize)sourceSize 
      toFitSize:(CGSize)fitSize 
    withoutCroppingRect:(CGRect)featuresRect 
{ 
    CGRect result = CGRectZero; 
    BOOL fitSizeIsTaller; 
    CGFloat sourceRatio = sourceSize.width/sourceSize.height; 
    CGFloat fitRatio = fitSize.width /fitSize.height; 
    if (sourceRatio > fitRatio) 
      fitSizeIsTaller = YES; 
    else fitSizeIsTaller = NO; 

     //size sourceRect to fitSize 
    if (fitSizeIsTaller){ 
     result.size.width = fitSize.width; 
     result.size.height = result.size.width/sourceRatio; 
    } else { 
     result.size.height = fitSize.height; 
     result.size.width = result.size.height * sourceRatio; 
    } 
     //make sure it is at least as large as fitSize 
    if (result.size.height < featuresRect.size.height) { 
     result.size.height = featuresRect.size.height; 
     result.size.width = result.size.height * sourceRatio; 
    } 

    if (result.size.width < featuresRect.size.width) { 
     result.size.width = featuresRect.size.width; 
     result.size.height = result.size.width/sourceRatio; 
    } 

      //locate resultRect in center 
    result.origin.x = (sourceSize.width - result.size.width)/2; 
    result.origin.y = (sourceSize.height - result.size.height)/2; 

      //shift origin of result to make sure it includes ROI 

    if (featuresRect.origin.x < result.origin.x) //shift right? 
       result.origin.x = featuresRect.origin.x; 
    else 
     if ((featuresRect.origin.x + featuresRect.size.width) 
       > (result.origin.x + result.size.width)) //shift left? 
      result.origin.x = (featuresRect.origin.x + featuresRect.size.width) 
          - result.size.width; 

    if (featuresRect.origin.y < result.origin.y) //shift up? 
       result.origin.y = featuresRect.origin.y; 
    else 
     if ((featuresRect.origin.y + featuresRect.size.height) 
       > (result.origin.y + result.size.height)) //shift down? 
      result.origin.y = (featuresRect.origin.y+featuresRect.size.height) 
          - result.size.height; 
    return result; 
} 
+0

ROI는 실제 이미지와 관련이 있습니다. 지금은 그 지역을위한 얼굴 탐지 만 사용하십시오. 나는 이것을 체크 할 것이다 - 나는 적어도 그것이 올바른 방향으로 나를 가리킬 것이라 확신한다. – akaru

관련 문제