我一直在努力将CIDetector(面部检测)结果转换为相对于显示图像的UIImageView的坐标,这样我就可以使用CGPath绘制坐标。
我已经查看了这里的所有问题以及我能找到的所有教程,其中大多数都使用了在UIImageView(example)中显示时未缩放的小图像。 我遇到的问题是使用在UIImageView中显示时使用aspectFit
缩放的大图像,并确定正确的比例+翻译值。
当测试不同尺寸/纵横比的图像时,我得到的结果不一致,所以我认为我的例程存在缺陷。我一直在努力解决这个问题,所以如果有人有一些提示或者可以X光检查我做错了什么,那将是一个很大的帮助。
我在做什么:
frameForImage
例程(在SO上找到)来获取UIImageView图像的比例和范围//我的确定变换值的例程
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;
}
答案 0 :(得分:4)
我完全理解你要做的事情,但是让我为你提供一种不同的方式来实现你想要的目标。
使用UIGraphicsBeginImageContextWithOptions(imageView.size,NO,0)提供的上下文,绘制背景颜色,然后绘制CGImage
CGContextDrawImage(context,CGRectMake(0,offset,imageView.size.width,rintf(image.size.height * scale)),[image CGImage]);
使用以下方式获取此新图片:
UIImage * image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 返回图片;
设置图片:imageView.image = image;
现在,您可以精确地映射回您的图像,因为您知道精确的缩放比例和偏移。
答案 1 :(得分: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)];
}