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%....

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM