C# OpenCvSharp DNN Gaze Estimation

目录

介绍

效果

模型信息

项目

代码

frmMain.cs

GazeEstimation.cs

下载


C# OpenCvSharp DNN Gaze Estimation

介绍

训练源码地址:https://github.com/deepinsight/insightface/tree/master/reconstruction/gaze

效果

模型信息

Inputs
-------------------------
name:input
tensor:Float[1, 3, 160, 160]
---------------------------------------------------------------

Outputs
-------------------------
name:output
tensor:Float[1, 962, 3]
---------------------------------------------------------------

项目

代码

frmMain.cs

using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace OpenCvSharp_Yolov8_Demo
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string image_path = "";
        string startupPath;
        Mat image;
        Mat result_image;

        YOLOv8_face face_detector = new YOLOv8_face("model/yolov8n-face.onnx", 0.45f, 0.5f);
        GazeEstimation gaze_predictor=new GazeEstimation("model/generalizing_gaze_estimation_with_weak_supervision_from_synthetic_views_1x3x160x160.onnx");

        private void Form1_Load(object sender, EventArgs e)
        {

            image_path = "img_test/1.jpg";
            pictureBox1.Image = new Bitmap(image_path);
            image = new Mat(image_path);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() != DialogResult.OK) return;
            pictureBox1.Image = null;
            image_path = ofd.FileName;
            pictureBox1.Image = new Bitmap(image_path);
            textBox1.Text = "";
            pictureBox2.Image = null;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (image_path == "")
            {
                return;
            }
            textBox1.Text = "";
            pictureBox2.Image = null;
            button2.Enabled = false;
            Application.DoEvents();

            image = new Mat(image_path);
            List<Face> ltFace = face_detector.Detect(new Mat(image_path));

            if (ltFace.Count > 0)
            {
                result_image = image.Clone();
                //face_detector.DrawPred(ltFace, result_image);
                String info = "";
                foreach (Face item in ltFace)
                {
                    gaze_predictor.Detect(image, item);
                    result_image = gaze_predictor.DrawOn(result_image, item,out info);
                }
                pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());
                textBox1.Text = info;
            }
            else
            {
                textBox1.Text = "无信息";
            }

            button2.Enabled = true;
        }

    }
}
 

using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;namespace OpenCvSharp_Yolov8_Demo
{public partial class frmMain : Form{public frmMain(){InitializeComponent();}string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";string image_path = "";string startupPath;Mat image;Mat result_image;YOLOv8_face face_detector = new YOLOv8_face("model/yolov8n-face.onnx", 0.45f, 0.5f);GazeEstimation gaze_predictor=new GazeEstimation("model/generalizing_gaze_estimation_with_weak_supervision_from_synthetic_views_1x3x160x160.onnx");private void Form1_Load(object sender, EventArgs e){image_path = "img_test/1.jpg";pictureBox1.Image = new Bitmap(image_path);image = new Mat(image_path);}private void button1_Click(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.Filter = fileFilter;if (ofd.ShowDialog() != DialogResult.OK) return;pictureBox1.Image = null;image_path = ofd.FileName;pictureBox1.Image = new Bitmap(image_path);textBox1.Text = "";pictureBox2.Image = null;}private void button2_Click(object sender, EventArgs e){if (image_path == ""){return;}textBox1.Text = "";pictureBox2.Image = null;button2.Enabled = false;Application.DoEvents();image = new Mat(image_path);List<Face> ltFace = face_detector.Detect(new Mat(image_path));if (ltFace.Count > 0){result_image = image.Clone();//face_detector.DrawPred(ltFace, result_image);String info = "";foreach (Face item in ltFace){gaze_predictor.Detect(image, item);result_image = gaze_predictor.DrawOn(result_image, item,out info);}pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());textBox1.Text = info;}else{textBox1.Text = "无信息";}button2.Enabled = true;}}
}

GazeEstimation.cs

 unsafe public class GazeEstimation
    {

        float[] mean = new float[] { 0.5f, 0.5f, 0.5f };
        float[] std = new float[] { 0.5f, 0.5f, 0.5f };
        int[] iris_idx_481 = new int[] { 248, 252, 224, 228, 232, 236, 240, 244 };
        int num_eye = 481;
        int input_size = 160;
        float[] eye_kps;
        Net net;

        public GazeEstimation(string modelpath)
        {
            net = CvDnn.ReadNetFromOnnx(modelpath);
            eye_kps = new float[num_eye * 2 * 3];
        }

        public void Detect(Mat img, Face box)
        {

            Point kps_right_eye = box.kpt[1];
            Point kps_left_eye = box.kpt[0];
            float[] center = new float[] { (kps_right_eye.X + kps_left_eye.X) * 0.5f, (kps_right_eye.Y + kps_left_eye.Y) * 0.5f };
            float _size = (float)(Math.Max(box.rect.Width / 1.5f, Math.Abs(kps_right_eye.X - kps_left_eye.X)) * 1.5f);

            float _scale = input_size / _size;
            //transform
            float cx = center[0] * _scale;
            float cy = center[1] * _scale;

            float[] data = new float[] { _scale, 0, (float)(-cx + input_size * 0.5), 0, _scale, (float)(-cy + input_size * 0.5) };
            Mat M = new Mat(2, 3, MatType.CV_32F, data);

            Mat cropped = new Mat();
            Cv2.WarpAffine(img, cropped, M, new Size(input_size, input_size));

            Mat rgbimg = new Mat();
            Cv2.CvtColor(cropped, rgbimg, ColorConversionCodes.BGR2RGB);

            Mat normalized_mat = Normalize(rgbimg);

            Mat blob = CvDnn.BlobFromImage(normalized_mat);

            net.SetInput(blob);

            Mat[] outs = new Mat[3] { new Mat(), new Mat(), new Mat() };
            string[] outBlobNames = net.GetUnconnectedOutLayersNames().ToArray();

            net.Forward(outs, outBlobNames);

            float* opred = (float*)outs[0].Data;//outs[0]的形状是(1,962,3)
            Mat IM = new Mat();
            Cv2.InvertAffineTransform(M, IM);
            //trans_points
            float scale = (float)Math.Sqrt(IM.At<float>(0, 0) * IM.At<float>(0, 0) + IM.At<float>(0, 1) * IM.At<float>(0, 1));
            int row = outs[0].Size(1);
            int col = outs[0].Size(2);

            for (int i = 0; i < row; i++)
            {
                eye_kps[i * 3] = IM.At<float>(0, 0) * opred[i * 3] + IM.At<float>(0, 1) * opred[i * 3 + 1] + IM.At<float>(0, 2);
                eye_kps[i * 3 + 1] = IM.At<float>(1, 0) * opred[i * 3] + IM.At<float>(1, 1) * opred[i * 3 + 1] + IM.At<float>(1, 2);
                eye_kps[i * 3 + 2] = opred[i * 3 + 2] * scale;
            }

        }

        public Mat DrawOn(Mat srcimg, Face box, out string info)
        {
            StringBuilder sb = new StringBuilder();

            float rescale = 300.0f / box.rect.Width;
            Mat eimg = new Mat();
            Cv2.Resize(srcimg, eimg, new Size(), rescale, rescale);
            //draw_item
            int row = num_eye * 2;
            for (int i = 0; i < row; i++)
            {
                float tmp = eye_kps[i * 3];
                eye_kps[i * 3] = eye_kps[i * 3 + 1] * rescale;
                eye_kps[i * 3 + 1] = tmp * rescale;
                eye_kps[i * 3 + 2] *= rescale;
            }
            //angles_and_vec_from_eye
            int slice = num_eye * 3;
            float[] theta_x_y_vec_l = new float[5];

            float[] eye_kps_l = new float[481 * 3];
            float[] eye_kps_r = new float[481 * 3];

            Array.Copy(eye_kps, 0, eye_kps_l, 0, 481 * 3);
            Array.Copy(eye_kps, 481 * 3, eye_kps_r, 0, 481 * 3);

            angles_and_vec_from_eye(eye_kps_l, iris_idx_481, theta_x_y_vec_l);
            float[] theta_x_y_vec_r = new float[5];

            angles_and_vec_from_eye(eye_kps_r, iris_idx_481, theta_x_y_vec_r);

            float[] gaze_pred = new float[] { (float)((theta_x_y_vec_l[0] + theta_x_y_vec_r[0]) * 0.5), (float)((theta_x_y_vec_l[1] + theta_x_y_vec_r[1]) * 0.5) };

            float diag = (float)Math.Sqrt((float)eimg.Rows * eimg.Cols);

            float[] eye_pos_left = new float[] { 0, 0 };
            float[] eye_pos_right = new float[] { 0, 0 };
            for (int i = 0; i < 8; i++)
            {
                int ind = iris_idx_481[i];
                eye_pos_left[0] += eye_kps[ind * 3];
                eye_pos_left[1] += eye_kps[ind * 3 + 1];
                eye_pos_right[0] += eye_kps[slice + ind * 3];
                eye_pos_right[1] += eye_kps[slice + ind * 3 + 1];
            }
            eye_pos_left[0] /= 8;
            eye_pos_left[1] /= 8;
            eye_pos_right[0] /= 8;
            eye_pos_right[1] /= 8;

            float dx = (float)(0.4 * diag * Math.Sin(theta_x_y_vec_l[1]));
            float dy = (float)(0.4 * diag * Math.Sin(theta_x_y_vec_l[0]));
            Point eye_left_a = new Point(eye_pos_left[1], eye_pos_left[0]);  左眼的箭头线的起始点坐标
            Point eye_left_b = new Point(eye_pos_left[1] + dx, eye_pos_left[0] + dy);   左右的箭头线的终点坐标

            Cv2.ArrowedLine(eimg, eye_left_a, eye_left_b, new Scalar(0, 0, 255), 5, LineTypes.AntiAlias, 0, 0.18);
            float yaw_deg_l = (float)(theta_x_y_vec_l[1] * (180 / Math.PI));
            float pitch_deg_l = (float)(-theta_x_y_vec_l[0] * (180 / Math.PI));

            dx = (float)(0.4 * diag * Math.Sin(theta_x_y_vec_r[1]));
            dy = (float)(0.4 * diag * Math.Sin(theta_x_y_vec_r[0]));

            Point eye_right_a = new Point(eye_pos_right[1], eye_pos_right[0]);  右眼的箭头线的起始点坐标
            Point eye_right_b = new Point(eye_pos_right[1] + dx, eye_pos_right[0] + dy);  右眼的箭头线的终点坐标
            Cv2.ArrowedLine(eimg, eye_right_a, eye_right_b, new Scalar(0, 0, 255), 5, LineTypes.AntiAlias, 0, 0.18);

            float yaw_deg_r = (float)(theta_x_y_vec_r[1] * (180 / Math.PI));
            float pitch_deg_r = (float)(-theta_x_y_vec_r[0] * (180 / Math.PI));

            Cv2.Resize(eimg, eimg, new Size(srcimg.Cols, srcimg.Rows));
            //draw Yaw, Pitch
            string label = String.Format("L-Yaw : {0:f2}", yaw_deg_l);
            sb.AppendLine(label);
            Cv2.PutText(eimg, label, new Point(eimg.Cols - 200, 30), HersheyFonts.HersheySimplex, 0.7, new Scalar(0, 255, 0), 2);

            label = String.Format("L-Pitch :{0:f2}", pitch_deg_l);
            sb.AppendLine(label);
            Cv2.PutText(eimg, label, new Point(eimg.Cols - 200, 60), HersheyFonts.HersheySimplex, 0.7, new Scalar(0, 255, 0), 2);

            label = String.Format("R-Yaw : {0:f2}", yaw_deg_r);
            sb.AppendLine(label);
            Cv2.PutText(eimg, label, new Point(eimg.Cols - 200, 90), HersheyFonts.HersheySimplex, 0.7, new Scalar(0, 255, 0), 2);

            label = String.Format("R-Pitch : {0:f2}", pitch_deg_r);
            sb.AppendLine(label);
            Cv2.PutText(eimg, label, new Point(eimg.Cols - 200, 120), HersheyFonts.HersheySimplex, 0.7, new Scalar(0, 255, 0), 2);

            info = sb.ToString();

            return eimg;

        }

        public Mat Normalize(Mat src)
        {
            Mat[] bgr = src.Split();
            for (int i = 0; i < bgr.Length; ++i)
            {
                bgr[i].ConvertTo(bgr[i], MatType.CV_32FC1, 1.0 / (255.0 * std[i]), (0.0 - mean[i]) / std[i]);
            }

            Cv2.Merge(bgr, src);

            foreach (Mat channel in bgr)
            {
                channel.Dispose();
            }

            return src;
        }

        /// <summary>
        /// 输入参数eye的形状是(481,3)
        /// 输入参数iris_lms_idx的长度shi
        /// 输出theta_x_y_vec的长度是5, 分别是theta_x, theta_y, vec[0], vec[1], vec[2]
        /// </summary>
        void angles_and_vec_from_eye(float[] eye, int[] iris_lms_idx, float[] theta_x_y_vec)
        {

            float[] mean = new float[] { 0, 0, 0 };
            for (int i = 0; i < 32; i++)
            {
                mean[0] += eye[i * 3];
                mean[1] += eye[i * 3 + 1];
                mean[2] += eye[i * 3 + 2];
            }
            mean[0] /= 32;
            mean[1] /= 32;
            mean[2] /= 32;

            float[] p_iris = new float[8 * 3];
            for (int i = 0; i < 8; i++)
            {
                int ind = iris_lms_idx[i];
                p_iris[i * 3] = eye[ind * 3] - mean[0];
                p_iris[i * 3 + 1] = eye[ind * 3 + 1] - mean[1];
                p_iris[i * 3 + 2] = eye[ind * 3 + 2] - mean[2];
            }

            float[] mean_p_iris = new float[] { 0, 0, 0 };
            for (int i = 0; i < 8; i++)
            {
                mean_p_iris[0] += p_iris[i * 3];
                mean_p_iris[1] += p_iris[i * 3 + 1];
                mean_p_iris[2] += p_iris[i * 3 + 2];
            }
            mean_p_iris[0] /= 8;
            mean_p_iris[1] /= 8;
            mean_p_iris[2] /= 8;

            float l2norm_p_iris = (float)Math.Sqrt(mean_p_iris[0] * mean_p_iris[0] + mean_p_iris[1] * mean_p_iris[1] + mean_p_iris[2] * mean_p_iris[2]);
            theta_x_y_vec[2] = mean_p_iris[0] / l2norm_p_iris;  ///vec[0]
            theta_x_y_vec[3] = mean_p_iris[1] / l2norm_p_iris;  ///vec[1]
            theta_x_y_vec[4] = mean_p_iris[2] / l2norm_p_iris;  ///vec[2]

            //angles_from_vec
            float x = -theta_x_y_vec[4];
            float y = theta_x_y_vec[3];
            float z = -theta_x_y_vec[2];
            float theta = (float)Math.Atan2(y, x);
            float phi = (float)(Math.Atan2(Math.Sqrt(x * x + y * y), z) - Math.PI * 0.5);
            theta_x_y_vec[0] = phi;
            theta_x_y_vec[1] = theta;
        }

    }

 unsafe public class GazeEstimation{float[] mean = new float[] { 0.5f, 0.5f, 0.5f };float[] std = new float[] { 0.5f, 0.5f, 0.5f };int[] iris_idx_481 = new int[] { 248, 252, 224, 228, 232, 236, 240, 244 };int num_eye = 481;int input_size = 160;float[] eye_kps;Net net;public GazeEstimation(string modelpath){net = CvDnn.ReadNetFromOnnx(modelpath);eye_kps = new float[num_eye * 2 * 3];}public void Detect(Mat img, Face box){Point kps_right_eye = box.kpt[1];Point kps_left_eye = box.kpt[0];float[] center = new float[] { (kps_right_eye.X + kps_left_eye.X) * 0.5f, (kps_right_eye.Y + kps_left_eye.Y) * 0.5f };float _size = (float)(Math.Max(box.rect.Width / 1.5f, Math.Abs(kps_right_eye.X - kps_left_eye.X)) * 1.5f);float _scale = input_size / _size;//transformfloat cx = center[0] * _scale;float cy = center[1] * _scale;float[] data = new float[] { _scale, 0, (float)(-cx + input_size * 0.5), 0, _scale, (float)(-cy + input_size * 0.5) };Mat M = new Mat(2, 3, MatType.CV_32F, data);Mat cropped = new Mat();Cv2.WarpAffine(img, cropped, M, new Size(input_size, input_size));Mat rgbimg = new Mat();Cv2.CvtColor(cropped, rgbimg, ColorConversionCodes.BGR2RGB);Mat normalized_mat = Normalize(rgbimg);Mat blob = CvDnn.BlobFromImage(normalized_mat);net.SetInput(blob);Mat[] outs = new Mat[3] { new Mat(), new Mat(), new Mat() };string[] outBlobNames = net.GetUnconnectedOutLayersNames().ToArray();net.Forward(outs, outBlobNames);float* opred = (float*)outs[0].Data;//outs[0]的形状是(1,962,3)Mat IM = new Mat();Cv2.InvertAffineTransform(M, IM);//trans_pointsfloat scale = (float)Math.Sqrt(IM.At<float>(0, 0) * IM.At<float>(0, 0) + IM.At<float>(0, 1) * IM.At<float>(0, 1));int row = outs[0].Size(1);int col = outs[0].Size(2);for (int i = 0; i < row; i++){eye_kps[i * 3] = IM.At<float>(0, 0) * opred[i * 3] + IM.At<float>(0, 1) * opred[i * 3 + 1] + IM.At<float>(0, 2);eye_kps[i * 3 + 1] = IM.At<float>(1, 0) * opred[i * 3] + IM.At<float>(1, 1) * opred[i * 3 + 1] + IM.At<float>(1, 2);eye_kps[i * 3 + 2] = opred[i * 3 + 2] * scale;}}public Mat DrawOn(Mat srcimg, Face box, out string info){StringBuilder sb = new StringBuilder();float rescale = 300.0f / box.rect.Width;Mat eimg = new Mat();Cv2.Resize(srcimg, eimg, new Size(), rescale, rescale);//draw_itemint row = num_eye * 2;for (int i = 0; i < row; i++){float tmp = eye_kps[i * 3];eye_kps[i * 3] = eye_kps[i * 3 + 1] * rescale;eye_kps[i * 3 + 1] = tmp * rescale;eye_kps[i * 3 + 2] *= rescale;}//angles_and_vec_from_eyeint slice = num_eye * 3;float[] theta_x_y_vec_l = new float[5];float[] eye_kps_l = new float[481 * 3];float[] eye_kps_r = new float[481 * 3];Array.Copy(eye_kps, 0, eye_kps_l, 0, 481 * 3);Array.Copy(eye_kps, 481 * 3, eye_kps_r, 0, 481 * 3);angles_and_vec_from_eye(eye_kps_l, iris_idx_481, theta_x_y_vec_l);float[] theta_x_y_vec_r = new float[5];angles_and_vec_from_eye(eye_kps_r, iris_idx_481, theta_x_y_vec_r);float[] gaze_pred = new float[] { (float)((theta_x_y_vec_l[0] + theta_x_y_vec_r[0]) * 0.5), (float)((theta_x_y_vec_l[1] + theta_x_y_vec_r[1]) * 0.5) };float diag = (float)Math.Sqrt((float)eimg.Rows * eimg.Cols);float[] eye_pos_left = new float[] { 0, 0 };float[] eye_pos_right = new float[] { 0, 0 };for (int i = 0; i < 8; i++){int ind = iris_idx_481[i];eye_pos_left[0] += eye_kps[ind * 3];eye_pos_left[1] += eye_kps[ind * 3 + 1];eye_pos_right[0] += eye_kps[slice + ind * 3];eye_pos_right[1] += eye_kps[slice + ind * 3 + 1];}eye_pos_left[0] /= 8;eye_pos_left[1] /= 8;eye_pos_right[0] /= 8;eye_pos_right[1] /= 8;float dx = (float)(0.4 * diag * Math.Sin(theta_x_y_vec_l[1]));float dy = (float)(0.4 * diag * Math.Sin(theta_x_y_vec_l[0]));Point eye_left_a = new Point(eye_pos_left[1], eye_pos_left[0]);  左眼的箭头线的起始点坐标Point eye_left_b = new Point(eye_pos_left[1] + dx, eye_pos_left[0] + dy);   左右的箭头线的终点坐标Cv2.ArrowedLine(eimg, eye_left_a, eye_left_b, new Scalar(0, 0, 255), 5, LineTypes.AntiAlias, 0, 0.18);float yaw_deg_l = (float)(theta_x_y_vec_l[1] * (180 / Math.PI));float pitch_deg_l = (float)(-theta_x_y_vec_l[0] * (180 / Math.PI));dx = (float)(0.4 * diag * Math.Sin(theta_x_y_vec_r[1]));dy = (float)(0.4 * diag * Math.Sin(theta_x_y_vec_r[0]));Point eye_right_a = new Point(eye_pos_right[1], eye_pos_right[0]);  右眼的箭头线的起始点坐标Point eye_right_b = new Point(eye_pos_right[1] + dx, eye_pos_right[0] + dy);  右眼的箭头线的终点坐标Cv2.ArrowedLine(eimg, eye_right_a, eye_right_b, new Scalar(0, 0, 255), 5, LineTypes.AntiAlias, 0, 0.18);float yaw_deg_r = (float)(theta_x_y_vec_r[1] * (180 / Math.PI));float pitch_deg_r = (float)(-theta_x_y_vec_r[0] * (180 / Math.PI));Cv2.Resize(eimg, eimg, new Size(srcimg.Cols, srcimg.Rows));//draw Yaw, Pitchstring label = String.Format("L-Yaw : {0:f2}", yaw_deg_l);sb.AppendLine(label);Cv2.PutText(eimg, label, new Point(eimg.Cols - 200, 30), HersheyFonts.HersheySimplex, 0.7, new Scalar(0, 255, 0), 2);label = String.Format("L-Pitch :{0:f2}", pitch_deg_l);sb.AppendLine(label);Cv2.PutText(eimg, label, new Point(eimg.Cols - 200, 60), HersheyFonts.HersheySimplex, 0.7, new Scalar(0, 255, 0), 2);label = String.Format("R-Yaw : {0:f2}", yaw_deg_r);sb.AppendLine(label);Cv2.PutText(eimg, label, new Point(eimg.Cols - 200, 90), HersheyFonts.HersheySimplex, 0.7, new Scalar(0, 255, 0), 2);label = String.Format("R-Pitch : {0:f2}", pitch_deg_r);sb.AppendLine(label);Cv2.PutText(eimg, label, new Point(eimg.Cols - 200, 120), HersheyFonts.HersheySimplex, 0.7, new Scalar(0, 255, 0), 2);info = sb.ToString();return eimg;}public Mat Normalize(Mat src){Mat[] bgr = src.Split();for (int i = 0; i < bgr.Length; ++i){bgr[i].ConvertTo(bgr[i], MatType.CV_32FC1, 1.0 / (255.0 * std[i]), (0.0 - mean[i]) / std[i]);}Cv2.Merge(bgr, src);foreach (Mat channel in bgr){channel.Dispose();}return src;}/// <summary>/// 输入参数eye的形状是(481,3)/// 输入参数iris_lms_idx的长度shi/// 输出theta_x_y_vec的长度是5, 分别是theta_x, theta_y, vec[0], vec[1], vec[2]/// </summary>void angles_and_vec_from_eye(float[] eye, int[] iris_lms_idx, float[] theta_x_y_vec){float[] mean = new float[] { 0, 0, 0 };for (int i = 0; i < 32; i++){mean[0] += eye[i * 3];mean[1] += eye[i * 3 + 1];mean[2] += eye[i * 3 + 2];}mean[0] /= 32;mean[1] /= 32;mean[2] /= 32;float[] p_iris = new float[8 * 3];for (int i = 0; i < 8; i++){int ind = iris_lms_idx[i];p_iris[i * 3] = eye[ind * 3] - mean[0];p_iris[i * 3 + 1] = eye[ind * 3 + 1] - mean[1];p_iris[i * 3 + 2] = eye[ind * 3 + 2] - mean[2];}float[] mean_p_iris = new float[] { 0, 0, 0 };for (int i = 0; i < 8; i++){mean_p_iris[0] += p_iris[i * 3];mean_p_iris[1] += p_iris[i * 3 + 1];mean_p_iris[2] += p_iris[i * 3 + 2];}mean_p_iris[0] /= 8;mean_p_iris[1] /= 8;mean_p_iris[2] /= 8;float l2norm_p_iris = (float)Math.Sqrt(mean_p_iris[0] * mean_p_iris[0] + mean_p_iris[1] * mean_p_iris[1] + mean_p_iris[2] * mean_p_iris[2]);theta_x_y_vec[2] = mean_p_iris[0] / l2norm_p_iris;  ///vec[0]theta_x_y_vec[3] = mean_p_iris[1] / l2norm_p_iris;  ///vec[1]theta_x_y_vec[4] = mean_p_iris[2] / l2norm_p_iris;  ///vec[2]//angles_from_vecfloat x = -theta_x_y_vec[4];float y = theta_x_y_vec[3];float z = -theta_x_y_vec[2];float theta = (float)Math.Atan2(y, x);float phi = (float)(Math.Atan2(Math.Sqrt(x * x + y * y), z) - Math.PI * 0.5);theta_x_y_vec[0] = phi;theta_x_y_vec[1] = theta;}}

下载

源码下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/598664.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java重修第一天—学习数组

1. 认识数组 建议1.5倍速学习&#xff0c;并且关闭弹幕。 数组的定义&#xff1a;数组是一个容器&#xff0c;用来存储一批同种类型的数据。 下述图&#xff1a;是生成数字数组和字符串数组。 为什么有了变量还需要定义数组呢&#xff1f;为了解决在某些场景下&#xff0c;变…

ZigBee协议栈 -- 协议栈版本与IAR版本适配说明(Zstack2.5.1a + IAR10.30.1)

文章目录 协议栈安装工程适配 在讲到ZigBee协议栈的文章中所用的协议栈版本是Zstack2.5.1a&#xff0c;对于Zstack2.5.1a运行在IAR8.10中是可以完全适配进行编译开发的&#xff0c;现在较新版本的IAR都是10的版本以上了&#xff0c;有部分开发者习惯使用最新版本来获得更好的开…

正则表达式的语法

如果要想灵活的运用正则表达式&#xff0c;必须了解其中各种元素字符的功能&#xff0c;元字符从功能上大致分为&#xff1a; 限定符 选择匹配符 分组组合和反向引用符 特殊字符 字符匹配符 定位符 我们先说一下元字符的转义号 元字符(Metacharacter)-转义号 \\ \\ 符号…

关于系统设计的一些思考

0.前言 当我们站在系统设计的起点&#xff0c;面对一个新的需求&#xff0c;我们该如何开始呢&#xff1f;这是许多处于系统分析与设计领域的新手常常思考的问题。有些人可能会误以为&#xff0c;只要掌握了诸如面向对象、统一建模语言、设计模式、微服务、Serverless、Servic…

《操作系统导论》笔记

操作系统三个关键&#xff1a;虚拟化( virtualization) 并发(concurrency) 持久性&#xff08;persistence&#xff09; 1 CPU虚拟化 1.1 进程 虚拟化CPU&#xff1a;许多任务共享物理CPU&#xff0c;让它们看起来像是同时运行。 时分共享&#xff1a;运行一个进程一段时间…

前端常用的几种算法的特征、复杂度、分类及用法示例演示

算法&#xff08;Algorithm&#xff09;可以理解为有基本运算及规定的运算顺序所构成的完整的解题步骤&#xff0c;或者看成按照要求设计好的有限的确切的计算序列&#xff0c;并且这样的步骤和序列可以解决一类问题。算法代表着用系统的方法描述解决问题的策略机制&#xff0c…

嵌入式Linux之MX6ULL裸机开发学习笔记(IMX启动方式-启动设备的选择)

一,硬件启动方式选择 1.启动方式的选择 6ull支持多种启动方式。 比如可以从 SD/EMMC、 NAND Flash、 QSPI Flash等启动。 6ull是怎么支持多种外置flash启动程序的。 1.启动方式选择&#xff1a; BOOT_MODE0 and BOOT_MODE1&#xff0c;这两个是两个IO来控制的&#xff0c;…

C#上位机与欧姆龙PLC的通信09----开发专用的通讯工具软件(Winform版)

1、介绍 上节文章已经完成了通讯库的开发&#xff0c;可以看到库还是蛮厉害的&#xff0c;在项目中就可以直接拿来应用&#xff0c;这节要做的就是做一个工具软件&#xff0c;形成自己专业的通讯工具&#xff0c;也是对通讯库的直接利用&#xff0c;本节要写的工具软件是一个w…

【HBase】——优化

1 RowKey设计 重要&#xff1a;一条数据的唯一标识就是 rowkey&#xff0c;那么这条数据存储于哪个分区&#xff0c;取决于 rowkey 处于 哪个一个预分区的区间内&#xff0c;设计 rowkey的主要目的 &#xff0c;就是让数据均匀的分布于所有的 region 中&#xff0c;在一定程度…

如何查找iPhone中所有的应用程序

​ ​ Apple 的 App Store 共有约 200 万个适用于 iPhone 和 iPad 的应用程序。如果您像我们一样&#xff0c;您的 iOS 或 iPadOS 设备上可能有数十个应用程序&#xff0c;但没有机会将它们全部整理好。您很容易忘记主屏幕上应用程序图标的位置。 幸运的是&#xff0c;iPhone…

2024年软件测试行业如何发展呢?测试人该怎么办?

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、表面"衰落…

亚马逊店铺遇到账号申诉模版分享

1.表达诚意&#xff0c;先认错再说&#xff1a;我知道&#xff0c;最近我们在Amazon.com上作为卖家的表现已经低于亚马逊和我们自己的质量标准。 2.清楚分明的格式&#xff1a;我们库存管理的混乱导致了延迟发货&#xff0c;更糟糕的是&#xff0c;物品无法使用。当延迟发货和…

杰发科技AC7801——IO模拟IIC注意事项

7801的参考手册没有说清楚 7840说明了用开漏 使用办法

【力扣每日一题】1944队列中可以看到的人数

目录 题目来源 题目描述 示例 提示&#xff1a; 思路分析 总结 代码实现 java实现 c实现 得分情况 java c p.s.吐槽一点无足轻重的事情 题目来源 力扣1944队列中可以看到的人数 题目描述 有 n 个人排成一个队列&#xff0c;从左到右 编号为 0 到 n - 1 。给你以…

jupyter更改默认路径到其它的目录或者到其它的盘 比如D盘

1.打开终端 输入jupyter notebook --generate-config 如下 2.在C:\Users\mb5958\.jupyter路径下 3.用记事本打开它&#xff0c;搜索directory 4.在你想要的路径下新建一个文件夹&#xff0c;如‘D:\jupyterFile’&#xff0c;然后将路径名放在c.NotebookApp.notebook_dir"…

appium自动化问题总结

1、DeprecationWarning: find_element_by_name is deprecated. Please use find_element(byBy.NAME, valuename) instead self.driver.find_element_by_name appium软件查看不到新建session的工具时候&#xff0c;可以下载2020年版本的appim&#xff0c;然后安装下面地址操作配…

leaflet呼吸闪烁效果

leaflet呼吸闪烁效果 1.功能背景 这个效果一把用于点击选中&#xff0c;报警提升效果。 2.功能开发 2.1 marker 这个效果还是很好实现&#xff0c;主要通过计时器设置透明度的组合实现。 function setTargetSelect(e){var i 1var int setInterval(() > {if(!e._map…

从vue小白到高手,从一个内容管理网站开始实战开发第三天,使用Element UI构建页面-登录(一)

上次我们介绍了如何安装Element UI库,这次我们使用Element UI中的组件开始开发我们的页面。 开发之前要先在项目中建立好几个目录,方便我们下面的开发。 一、在项目中创建页面管理目录 1、pages目录(文件夹) 首先在src文件夹下创建一个名为pages的文件夹,该文件夹用来统…

KeyError: ‘mistral‘解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

打开软件游戏提示缺少msvcp140.dll的解决方法,修复缺少140dll文件的方法

一、msvcp140.dll是什么文件&#xff1f; msvcp140.dll是Microsoft Visual C 2015 Redistributable Package的一部分&#xff0c;它是运行许多Windows应用程序所必需的动态链接库文件之一。它包含了许多C类库&#xff0c;这些类库为开发人员提供了丰富的功能和工具&#xff0c…