Community
cancel
Showing results for 
Search instead for 
Did you mean: 
yhu_y_
Beginner
58 Views

Accuracy of face recognition

Hello.

 

I am making a face recognition module in C # using the RealSense.

But the problem has occurred.

It is because the will to recognize the wrong face.

I would like to correct the wrong face recognition to improve the program.

In this case, should I put what to care?

 

Hardware: Intel®RealSense™ Developer Kit featuring SR300

SDK Version: 2016 R1

Driver Build Number: 3.1.25.2599

 

Is there some property should be set in order to RealSense to collect face recognition?

 

 

I'm thinking the thing is IsRegistered().[Line 213]
This function often misrecognize(false positive) person who has already registered in database(.bin).
The source code is as below.
Does anyone advice me what is wrong or something to add to improve the quality of face recognition??

** I tried to register several face sample to database(.bin) but the situation is almost the same.
** I also tried to change SetDepthConfidenceThreshold[Line 102] from 0 to 15 but also remains unchanged.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RegFace {

    public partial class MainForm : Form {

        PXCMSession _session;
        PXCMSenseManager _senseManager;
        PXCMFaceData _faceData;

        private bool _isStop = false;

        public MainForm() {
            InitializeComponent();
            TextBoxMsg.Text = "Please put in the center of the frame your face";
        }

        private void MainForm_Load(object sender, EventArgs e) {
        }

        private void MainForm_Shown(object sender, EventArgs e) {

            const int DETECTION_MAXFACES = 3;
            const int COLOR_WIDTH = 640;
            const int COLOR_HEIGHT = 480;
            const float COLOR_FPS = 30f;

            try {

                _session = PXCMSession.CreateInstance();

                _senseManager = _session.CreateSenseManager();
                if (_senseManager == null) {
                    throw new Exception("CreateSenseManager");
                }
                _senseManager.EnableStream(PXCMCapture.StreamType.STREAM_TYPE_COLOR, COLOR_WIDTH, COLOR_HEIGHT, COLOR_FPS);
                _senseManager.EnableStream(PXCMCapture.StreamType.STREAM_TYPE_DEPTH, COLOR_WIDTH, COLOR_HEIGHT, COLOR_FPS);
                _senseManager.EnableStream(PXCMCapture.StreamType.STREAM_TYPE_IR, COLOR_WIDTH, COLOR_HEIGHT, COLOR_FPS);

                pxcmStatus enablingModuleStatus = _senseManager.EnableFace();
                if (enablingModuleStatus != pxcmStatus.PXCM_STATUS_NO_ERROR) {
                    throw new Exception("EnableFace");
                }

                PXCMFaceModule faceModule = _senseManager.QueryFace();
                if (faceModule == null) {
                    throw new Exception("QueryFace");
                }

                PXCMFaceConfiguration faceConfiguration = faceModule.CreateActiveConfiguration();
                if (faceConfiguration == null) {
                    throw new Exception("CreateActiveConfiguration");
                }

                faceConfiguration.SetTrackingMode(PXCMFaceConfiguration.TrackingModeType.FACE_MODE_COLOR_PLUS_DEPTH);
                faceConfiguration.pose.isEnabled = true;
                faceConfiguration.landmarks.isEnabled = true;
                faceConfiguration.strategy = PXCMFaceConfiguration.TrackingStrategyType.STRATEGY_CLOSEST_TO_FARTHEST;
                faceConfiguration.detection.maxTrackedFaces = DETECTION_MAXFACES;

                PXCMFaceConfiguration.RecognitionConfiguration recognitionConfiguration = faceConfiguration.QueryRecognition();
                if (recognitionConfiguration == null) {
                    throw new Exception("QueryRecognition");
                }
                recognitionConfiguration.Enable();

                byte[] recogFaceData = null;

                string fName = string.Empty;
                if (Directory.GetFiles(Directory.GetCurrentDirectory(), "*.bin").Count() > 0) {
                    fName = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.bin")[0];
                    recogFaceData = File.ReadAllBytes(fName);
                }
                if (recogFaceData != null) {
                    recognitionConfiguration.SetDatabaseBuffer(recogFaceData);
                }

                if (faceConfiguration.ApplyChanges() < pxcmStatus.PXCM_STATUS_NO_ERROR) {
                    throw new Exception("ApplyChanges");
                }

                if (_senseManager.Init() < pxcmStatus.PXCM_STATUS_NO_ERROR) {
                    throw new Exception("Init");
                }

                PXCMCapture.Device device = _senseManager.QueryCaptureManager().QueryDevice();
                if (device == null) {
                    throw new Exception("QueryDevice");
                }
                device.SetMirrorMode(PXCMCapture.Device.MirrorMode.MIRROR_MODE_HORIZONTAL);

                PXCMCapture.DeviceInfo deviceInfo;
                device.QueryDeviceInfo(out deviceInfo);
                if (deviceInfo.model == PXCMCapture.DeviceModel.DEVICE_MODEL_SR300) {
                    device.SetDepthConfidenceThreshold(3);
                    // 0: Skeleton
                    // 1: Raw
                    // 2: Raw + Gradients filter
                    // 3: Very close range
                    // 4: Close range               between 350mm to 550mm
                    // 5: Mid-range [Default]       between 550mm to 850mm
                    // 6: Far range                 between 850mm to 1000mm
                    // 7: Very far range
                    device.SetIVCAMFilterOption(4);
                    device.SetIVCAMMotionRangeTradeOff(50);
                    // IVCAM_ACCURACY_FINEST        Use 11 coded patterns at 50fps.
                    // IVCAM_ACCURACY_MEDIAN        Use 10 coded patterns at 55 fps. This is the default.
                    // IVCAM_ACCURACY_COARSE        Use 9 coded patterns at 60 fps.
                    device.SetIVCAMAccuracy(PXCMCapture.Device.IVCAMAccuracy.IVCAM_ACCURACY_FINEST);
                    device.SetIVCAMLaserPower(16);
                }

                _faceData = faceModule.CreateOutput();
                if (_faceData == null) {
                    throw new Exception("CreateOutput");
                }

                LabelInit.Visible = false;

                Action recog = async () => {
                    long frameCount = 0;
                    while (true) {
                        var res = await Task.Run(() => GeneratePictureAndRecognition(_senseManager, _faceData, ref frameCount));
                        if (res == null) {
                            TextBoxMsg.Text = "frame skip";
                            continue;
                        }
                        PictureBoxCamera.Image = res.Item1;
                        TextBoxMsg.Text = res.Item3;
                        TextBoxLandmarks.Text = res.Item4.ToString();
                        TextBoxHeadPos.Text = string.Format("x:{0:0.00}, y:{1:0.00}, z:{2:0.00}", res.Item5.headCenter.x, res.Item5.headCenter.y, res.Item5.headCenter.z);
                        TextBoxHeadAngle.Text = string.Format("yaw:{0:0.00}, pitch:{1:0.00}, roll:{2:0.00}", res.Item6.yaw, res.Item6.pitch, res.Item6.roll);
                        if (_isStop) {
                            FinalizeAuth(false);
                            //break;
                        }
                        if (res.Item2) {
                            FinalizeAuth(true);
                            //break;
                        }
                        frameCount++;
                    }
                };
                recog();

            } catch {
                MessageBox.Show(this, "An error has occurred", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private Tuple<Bitmap, bool, string, int, PXCMFaceData.HeadPosition, PXCMFaceData.PoseEulerAngles> GeneratePictureAndRecognition(PXCMSenseManager senseManager, PXCMFaceData faceData, ref long frameCount) {

            const long FRAME_COUNT = 500000;
            const float LINE_WIDTH = 3.0f;
            const float RECT_ROUND = 20.0f;

            Bitmap bmp = null;
            int landmarksNum = 0;
            PXCMFaceData.HeadPosition headPos = new PXCMFaceData.HeadPosition();
            PXCMFaceData.PoseEulerAngles poseAngle = new PXCMFaceData.PoseEulerAngles();

            string msg = string.Empty;

            if (senseManager.AcquireFrame(true) < pxcmStatus.PXCM_STATUS_NO_ERROR) {
                return null;
            }

            PXCMCapture.Sample sample = senseManager.QuerySample();
            bmp = GeneratePicture(sample.color);

            if (faceData != null) {
                faceData.Update();
            }

            int numberOfFaces = faceData.QueryNumberOfDetectedFaces();

            bool isRecog = false;

            for (int i = 0; i < numberOfFaces; i++) {

                PXCMFaceData.LandmarkPoint[] lands = null;

                PXCMFaceData.Face faceObject = faceData.QueryFaceByIndex(i);
                if (faceObject == null) {
                    continue;
                }

                PXCMRectI32 faceRect;
                faceObject.QueryDetection().QueryBoundingRect(out faceRect);

                if (i == 0) {

                    PXCMFaceData.LandmarksData land = faceObject.QueryLandmarks();
                    if (land != null) {
                        landmarksNum = land.QueryNumPoints();
                        PXCMFaceData.PoseData pose = faceObject.QueryPose();
                        land.QueryPoints(out lands);
                        pose.QueryHeadPosition(out headPos);
                        pose.QueryPoseAngles(out poseAngle);
                    }

                    if (frameCount < FRAME_COUNT) {
                        PXCMFaceData.RecognitionData recognitionData = faceObject.QueryRecognition();
                        int id = recognitionData.QueryUserID();
                        if (numberOfFaces == 1) {
                            isRecog = recognitionData.IsRegistered();
                        }
                    }
                }

                Color c = Color.Yellow;
                if (i == 0) {
                    c = Color.Red;
                    if (isRecog) {
                        c = Color.Blue;
                    }
                }

                using (Graphics g = Graphics.FromImage(bmp))
                using (Pen p = new Pen(c, LINE_WIDTH)) {
                    DrawCenter(g, bmp.Width, bmp.Height);
                    DrawRoundRectPath(g, p, faceRect.x, faceRect.y, faceRect.w, faceRect.h, RECT_ROUND);
                    DrawLandPoint(g, lands);
                }
            }

            sample.color.Dispose();
            senseManager.ReleaseFrame();

            if (frameCount < FRAME_COUNT) {
                if (numberOfFaces == 0) {
                    msg = "Please put in the center of the frame your face";
                } else if (numberOfFaces == 1) {
                    if (isRecog) {
                        msg = "Recognize";
                    } else {
                        if (headPos.headCenter.z > 350) {
                            msg = "Closer to the camera";
                        } else if (headPos.headCenter.z < 300) {
                            msg = "Away from the camera";
                        } else {
                            msg = "Please be had as it is attitude";
                        }
                    }
                } else {
                    msg = "It has detected more than one person";
                }
            } else {
                msg = "Failure";
            }

            return new Tuple<Bitmap, bool, string, int, PXCMFaceData.HeadPosition, PXCMFaceData.PoseEulerAngles>(bmp, isRecog, msg, landmarksNum, headPos, poseAngle);
        }

        private async void MainForm_FormClosing(object sender, FormClosingEventArgs e) {
            _isStop = true;
            await Task.Delay(500);
            if (_senseManager != null) {
                _senseManager.Dispose();
                _senseManager = null;
            }
            if (_session != null) {
                _session.Dispose();
                _session = null;
            }
        }

        private async void ButtonClose_Click(object sender, EventArgs e) {
            _isStop = true;
            await Task.Delay(500);
            TextBoxMsg.Text = "End";
        }

        private Bitmap GeneratePicture(PXCMImage image) {
            PXCMImage.PixelFormat pf = PXCMImage.PixelFormat.PIXEL_FORMAT_RGB32;
            Bitmap bmp = null;
            PXCMImage.ImageData data;
            pxcmStatus sts = image.AcquireAccess(PXCMImage.Access.ACCESS_READ, pf, out data);
            if (sts >= pxcmStatus.PXCM_STATUS_NO_ERROR) {
                bmp = new Bitmap(data.ToBitmap(0, image.info.width, image.info.height));
                image.ReleaseAccess(data);
            }
            return bmp;
        }

        private static void DrawCenter(Graphics g, float width, float height) {
            using (Pen p = new Pen(Color.White, 1f))
            using (GraphicsPath gp = new GraphicsPath()) {
                gp.AddLine(width / 2, 0, width / 2, height);
                gp.CloseFigure();
                gp.AddLine(0, height / 2, width, height / 2);
                gp.CloseFigure();
                g.DrawPath(p, gp);
            }
        }

        private static void DrawRoundRectPath(Graphics g, Pen p, float x, float y, float width, float height, float radius) {
            using (GraphicsPath gp = new GraphicsPath()) {
                gp.AddLine(x + radius, y, x + width - (radius * 2), y);
                gp.AddArc(x + width - (radius * 2), y, radius * 2, radius * 2, 270, 90);
                gp.AddLine(x + width, y + radius, x + width, y + height - (radius * 2));
                gp.AddArc(x + width - (radius * 2), y + height - (radius * 2), radius * 2, radius * 2, 0, 90);
                gp.AddLine(x + width - (radius * 2), y + height, x + radius, y + height);
                gp.AddArc(x, y + height - (radius * 2), radius * 2, radius * 2, 90, 90);
                gp.AddLine(x, y + height - (radius * 2), x, y + radius);
                gp.AddArc(x, y, radius * 2, radius * 2, 180, 90);
                gp.CloseFigure();
                g.DrawPath(p, gp);
            }
        }

        private static void DrawLandPoint(Graphics g, PXCMFaceData.LandmarkPoint[] lands) {
            if (lands == null) {
                return;
            }
            using (Pen p = new Pen(Color.White, 2f))
            using (GraphicsPath gp = new GraphicsPath()) {
                foreach (var item in lands) {
                    gp.AddEllipse(item.image.x, item.image.y, 3f, 3f);
                    g.DrawPath(p, gp);
                }
            }
        }

        private void FinalizeAuth(bool isAuth) {

        }

        private void ButtonOutputDatabase_Click(object sender, EventArgs e) {
            if (_faceData.QueryNumberOfDetectedFaces() == 1) {
                PXCMFaceData.RecognitionData recognitionData = _faceData.QueryFaceByIndex(0).QueryRecognition();
                recognitionData.RegisterUser();
                PXCMFaceData.RecognitionModuleData rmd = _faceData.QueryRecognitionModule();
                int nbytes = rmd.QueryDatabaseSize();
                byte[] buffer = new byte[nbytes];
                rmd.QueryDatabaseBuffer(buffer);
                if (Directory.GetFiles(Directory.GetCurrentDirectory(), "*.bin").Count() > 0) {
                    File.Delete(Directory.GetFiles(Directory.GetCurrentDirectory(), "*.bin")[0]);
                }
                string fName = "test" + ".bin";
                File.WriteAllBytes(fName, buffer);
                MessageBox.Show("Make file");
            } else {
                MessageBox.Show("It has detected more than one person");
            }
        }
    }
}

 

0 Kudos
2 Replies
Thanh_L_
Beginner
58 Views

Hello, I'm a developer at Samsung. I have a same question with @yhu y, I'm using R200 for facial recognition but I feel that the accurracy is small. We cannot using bad algorithms for our products. Any answer from Intel engineer ? 

samontab
Valued Contributor II
58 Views

You can always write you own facial recognition system, tailored for your needs.

And, I would assume a huge company like Samsung should have plenty of things like that built in house. I'm surprised to hear they rely on 3rd party libraries at that level.

Reply