科大讯飞摄像头人眼关键点检测Demo关键点位置不准确的问题

官方Demo的效果是这样的:


IMG_0012.PNG

虽然基本上还算准确,但是对精度要求比较高的使用场景来说还是差一点。

查阅代码

FaceStreamDetectorViewController.m
//Line 91
self.captureManager.previewLayer.videoGravity=AVLayerVideoGravityResizeAspectFill;

摄像头预览图像的缩放方式为:AVLayerVideoGravityResizeAspectFill

查阅文档

AVLayerVideoGravityResize
Specifies that the video should be stretched to fill the layer’s bounds.
AVLayerVideoGravityResizeAspect
Specifies that the player should preserve the video’s aspect ratio and fit the video within the layer’s bounds.
AVLayerVideoGravityResizeAspectFill
Specifies that the player should preserve the video’s aspect ratio and fill the layer’s bounds.

Demo中绘制关键点的逻辑分析如下:

1. 摄像头捕获到的图像数据回调:
-(void)onOutputFaceImage:(IFlyFaceImage*)faceImg;
2. 然后会调用下面这个方法对检测到的坐标信息按照preview的大小进行缩放:
-(void)praseTrackResult:(NSString*)result OrignImage:(IFlyFaceImage*)faceImg
3.其中对关键点进行缩放的方法如下
-(NSMutableArray*)praseAlign:(NSDictionary* )landmarkDic OrignImage:(IFlyFaceImage*)faceImg
4. 具体执行缩放的代码

CGPoint pScale(CGPoint p ,CGFloat wScale, CGFloat hScale){
    p.x*=wScale;
    p.y*=hScale;
    return p;
}
// scale coordinates so they fit in the preview box, which may be scaled
CGFloat widthScaleBy = self.previewLayer.frame.size.width / faceImg.height;
CGFloat heightScaleBy = self.previewLayer.frame.size.height / faceImg.width;
//省略中间计算屏幕旋转的部分以及其他运算过程
p=pScale(p, widthScaleBy, heightScaleBy);

结论:绘制关键点的缩放方式对应的摄像头preview的缩放方式应该是
AVLayerVideoGravityResize,而官方Demo中给的是AVLayerVideoGravityResizeAspectFill,如此导致了绘制的关键点偏差。

最终效果如下图

IMG_0013.PNG

你可能感兴趣的:(科大讯飞摄像头人眼关键点检测Demo关键点位置不准确的问题)