zoukankan      html  css  js  c++  java
  • C# 人脸姿态估计(HeadPoseEstimation)

    ##  先上结果

     红色的是用网上普遍的方法,参照是以旷视人脸检测的api。用六个关键点来评估误差太大,没啥用。

    ##  环境:

    说是C# 写的,实际都是调用opencv跟dlib的封装包。

    ## code:

    主要代码opencv的Cv2.SolvePnP

    输入为六个人脸关键点,图像宽和高,获取关键点还是最下面项目github看吧。

            public Angles GetAnglesAndPoints(Mat<Point2d> points, int width, int height)
            {
                var cameraMatrix = new Mat<double>(3, 3,
                   new double[] {
                        width, 0,     width / 2,
                        0,     width, height / 2,
                        0,     0,     1
                   });
    
                var dist = new Mat<double> { 0, 0, 0, 0, 0 };
                var rvec = new Mat<double>();
                var tvec = new Mat();
                var Model_points = new Mat<Point3f>
                 {
                            new Point3f(0.0f, 0.0f, 0.0f),             // Nose tip
                            new Point3f(0.0f, -330.0f, -65.0f),        // Chin
                            new Point3f(-225.0f, 170.0f, -135.0f),     // Left eye left corner
                            new Point3f(225.0f, 170.0f, -135.0f),      // Right eye right corne
                            new Point3f(-150.0f, -150.0f, -125.0f),    // Left Mouth corner
                            new Point3f(150.0f, -150.0f, -125.0f)      // Right mouth corner
                 };
                Cv2.SolvePnP(Model_points, points, cameraMatrix, dist, rvec, tvec, flags: SolvePnPFlags.Iterative);
    
                return GetEulerAngle(rvec);
            }

    旋转向量转化为欧拉角

           
            public Angles GetEulerAngle(Mat<double> rotation_vector)
            {
                var rotArray = rotation_vector.ToArray();
    
                Mat mat = new Mat(3, 1, MatType.CV_64FC1, rotArray);
                var theta = Cv2.Norm(mat, NormTypes.L2);
                var w = Math.Cos(theta / 2);
                var x = Math.Sin(theta / 2) * rotArray[0] / theta;
                var y = Math.Sin(theta / 2) * rotArray[1] / theta;
                var z = Math.Sin(theta / 2) * rotArray[2] / theta;
    
                var ysqr = y * y;
    
                // pitch (x-axis rotation)
                var t0 = 2.0 * (w * x + y * z);
                var t1 = 1.0 - 2.0 * (x * x + ysqr);
                var pitch = Math.Atan2(t0, t1);//反正切(给坐标轴,x,y)
    
                // yaw (y-axis rotation)
                var t2 = 2.0 * (w * y - z * x);
                if (t2 > 1.0) t2 = 1.0;
                if (t2 < -1.0) t2 = -1.0;
                var yaw = Math.Asin(t2); //反正弦函数
    
                // roll (z-axis rotation)
                var t3 = 2.0 * (w * z + x * y);
                var t4 = 1.0 - 2.0 * (ysqr + z * z);
                var roll = Math.Atan2(t3, t4);
    
                // 单位转换:将弧度转换为度
                var Y = (pitch / Math.PI) * 180;
                Y = Math.Sign(Y) * 180 - Y;
    
                var X = (yaw / Math.PI) * 180;
                var Z = (roll / Math.PI) * 180;
                Angles angles = new Angles() { Pitch = Y, Roll = Z, Yaw = X };
                return angles;
            }
    Angles就三个属性
        public class Angles
        {
            public double Roll { get; set; }
            public double Pitch { get; set; }
            public double Yaw { get; set; }
        } 

    效果图:(图源网络,侵删)

    ##  引用:

    C++实现       https://blog.csdn.net/u013512448/article/details/77804161

    python实现   https://blog.csdn.net/loveliuzz/article/details/102716290

    旷视api调用  https://www.faceplusplus.com.cn/face-detection/

    人脸识别    https://github.com/takuya-takeuchi/FaceRecognitionDotNet

    C# 实现        https://github.com/TrojanOlx/AI

               https://github.com/cheat13/FaceDetect

               https://github.com/Zhaofan-Su/FaceRig-Scripts(这个项目太旧,可以运行,但升级最新的opencv没成功)

     结尾:

    网上基于6个关键点评估方法并不靠谱,误差太大,完全没有实用价值。

    文章代码:https://github.com/zlyxm/HeadPoseSharp

    FaceRecognitionDotNet 最新版(1.3.0.2)已经支持关键点评估,比6个关键点强不知道多少,不过模型要自己训练就是,试下看。渣渣电脑训练了1天15个钟才45.43%....

  • 相关阅读:
    Excel文件上传,解析,下载(一 文件上传,使用MultipartFile来实现)
    从svn下载的Mavn项目,到本地后不识别(MyEcplise)
    Tomcat源代码阅读----服务器的启动(2)
    Tomcat源代码阅读----源代码部署(1)
    针对dhtmlX当中的treegrid在java类当中的封装实现的步骤(后台代码)
    Eclipse的maven插件最新地址
    oracle-创建JOB
    简单旋转特效的实现
    Spark SQL 小文件问题处理
    学好Spark/Kafka必须要掌握的Scala技术点(三)高阶函数、方法、柯里化、隐式转换
  • 原文地址:https://www.cnblogs.com/zlyxm/p/13544724.html
Copyright © 2011-2022 走看看