我一直在努力将 CIDetector(面部检测)结果转换为相对于显示图像的 UIImageView 的坐标,以便我可以使用 CGPaths 绘制坐标。
我已经查看了这里的所有问题以及我能找到的所有教程,其中大多数使用在 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);
// 错误结果示例:比例似乎不正确
// 下面的例程在 SO 上找到,用于确定使用“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;
}