CGPaths を使用して座標を描画できるように、CIDetector (顔検出) の結果を、画像を表示する UIImageView に対する座標に変換するのに苦労しています。
ここですべての質問と見つけたすべてのチュートリアルを見てきましたが、それらのほとんどは、UIImageView (例) に表示されるときにスケーリングされない小さな画像を使用しています。私が抱えている問題はaspectFit
、UIImageView に表示されるときに使用してスケーリングされる大きな画像を使用し、正しいスケール + 変換値を決定することです。
異なるサイズ/アスペクト比の画像でテストすると一貫性のない結果が得られるので、私のルーチンに欠陥があると思います. 私はしばらくこれに苦労していたので、誰かがいくつかのヒントを持っているか、私が間違っていることをX線で見ることができれば、それは大きな助けになるでしょう.
私がやっていること:
- 顔座標を取得する
- 以下のルーチンを使用して
frameForImage
(ここ SO にあります)、UIImageView 画像のスケールと境界を取得します。 - スケール + 平行移動の変換を作成
- CIDetector の結果に変換を適用する
// 変換値を決定するルーチン
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 の結果:
mouthPosition = CGPointApplyAffineTransform(mouthPosition, transform);
// 悪い結果の例: スケールが正しくないようです
// 'aspectFit` を使用して UIImageView でスケーリングされた画像の境界を決定するための SO の以下のルーチン
-(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;
}