C# 攝像頭實時_4線程人臉識別demo

效率有點低,你們看看哪裏開能夠節省時間? 源代碼:https://github.com/catzhou2002/ArcFaceDemo 整個項目使用虹軟技術完成開發git

說實話,爲了提升識別效率,我也是竭盡所能,幹了很多自認爲的優化,若有興趣聽我說說。github

第一部分 單線程時候的各類折騰數組

1、折騰LPASVLOFFSCREEN 話說這個LPASVLOFFSCREEN的結果文檔裏面沒有說明,或者是我沒找到。 我也不知道從哪裏複製來的,主要折騰的是ppu8Plane[0]地址,通常操做是微信

一、鎖定圖片內存 二、ppu8Plane[0]分配製定長度的內存 三、把圖片內存中的字節複製到一個臨時數組 四、而後用Marshal.Copy複製到指定的地址 五、解鎖圖片內存 我改爲: 一、鎖定圖片內存 二、ppu8Plane[0]指向圖片地址 三、等不須要LPASVLOFFSCREEN時(人臉檢測、獲取特徵值、性別判斷、年齡估算等結束後)解鎖圖片內存多線程

就晚一點解鎖,省了好多事情,耗時由4毫秒沒成2微妙。當時就發了個帖:C# Bitmap轉ASVLOFFSCREEN的最佳方式?編輯器

後來以爲這名字實在記不住,也不C#,改爲了ImageData,整個轉換過程以下:ide

var bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            var imageData = new ImageData
            {
                PixelArrayFormat = 513,//Rgb24,
                Width = bitmap.Width,
                Height = bitmap.Height,
                Pitch = new int[4] { bmpData.Stride, 0, 0, 0 },
                ppu8Plane = new IntPtr[4] { bmpData.Scan0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero }
            };

            bitmap.UnlockBits(bmpData);

其實若是是視頻圖片的話,圖片的寬度和高度都是固定的,想了想,沒折騰。測試

2、單線程時將獲取到的FaceModel直接作人臉比對的參數優化

ExtractFeature(_FaceMatchEngine, ref imageData, ref faceFeatureInput, out var <font color="#ff8c00">faceModel</font>);
FacePairMatch(_FaceMatchEngine, ref fm, ref <font color="#ff8c00">faceModel</font>, out float score);

通常操做是faceModel裏面的字節複製到臨時字節數組,而後建立新的FaceModel,分配內存,在將臨時字節數組複製到FaceModel。this

3、人臉庫直接用FaceModel

/// <summary>
    /// 人臉庫
    /// </summary>
    public class FaceLib
    {
        public List<Item> Items { get; set; } = new List<Item>();
        public class Item
        {
            /// <summary>
            /// 用於排序
            /// </summary>
            public long OrderId { get; set; }
            /// <summary>
            /// 文件名做爲ID
            /// </summary>
            public string ID { get; set; }
            /// <summary>
            /// 人臉模型
            /// </summary>
<font color="#ff8c00">            public FaceModel FaceModel { get; set; }</font>  
        }
    }

4、比對結果>0.5就算成功 5、人臉庫增長OrderId 識別成功後再次比對就很快,應該是首發命中。

6、將人臉比對和結果顯示分開 一開始沒想太多,將人臉比對和結果顯示放在新視頻幀事件裏面,流程是:

新視頻幀(30幀/秒) 獲取檢測和識別的結果(人臉框和ID) 顯示檢測和識別的結果 結果視頻卡頓,獲取人臉特徵的200毫秒成爲瓶頸,改爲:

人臉比對

Task.Factory.StartNew(() =>
            {
                Task.Delay(1000).Wait();
                while (!_CancellationTokenSource.IsCancellationRequested)
                {
                    #region 200毫秒左右
                    MatchFrame(); 
                    #endregion
                }
            }, _CancellationTokenSource.Token);

結果顯示

private void VideoPlayer_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawRectangle(Pens.White, _FaceResult.Rectangle);
            e.Graphics.DrawString(_FaceResult.ID , this.Font, Brushes.White, _FaceResult.Rectangle.Left, _FaceResult.Rectangle.Top - 20);
        }

測試了一下,效果還能夠,就在博客園發表了 C# 虹軟SDK視頻人臉識別和註冊 ,還順手弄了個打賞二維碼。 發表完以爲這麼辛苦寫出來的文章,必須到首頁去亮個相,9天后終於學會發表到博客園首頁了,因而刪除了打賞二維碼,去首頁亮了個相。 話說首頁和非首頁效果着實不同,截圖爲證: 在這裏插入圖片描述 第二部分 多線程的折騰

1、肯定4線程爲最佳 各類測試後得出的結論,也不知道對不對,也不知道爲何,哎。 因網友的要求,同步到了github

2、刪除了單線程 有了更快的,就不要慢的了。

3、n張臉如何分配給4個線程獲取特徵值? 動了很多腦筋,Interlocked.Increment是關鍵。 最終有改了下面的內容

若是隻有一張臉(竊覺得一張臉的機率比較高),也用Task,影響效率,增長了 if (detectResult.FaceCount == 1) Intptr之間複製字節用CopyMemory比較快 兩三張臉的時候開4個線程很差,改爲 new Task[TaskNum < detectResult.FaceCount ? TaskNum : detectResult.FaceCount] 4、識別結果(集)的折騰

弄了個結果集,按最大人臉數設了個List( Items = new List();) 增長了FaceFeatureInput FFI,省的每次都去建立 並將人臉方向設成1(Orient = 1)(由於是視頻圖片,其餘方向的人臉,呵呵),人臉檢測後都不要去獲取人臉方向的值 增長並初始化了FaceModel(FaceModel FaceModel = new FaceModel() { Size = 22020, PFeature = Marshal.AllocCoTaskMem(22020) };),獲取到的特徵字節直接複製過來即可 5、保存特徵值到人臉庫的時候同時保存頭像 由於虹軟說了,sdk升級的時候,特徵值也有可能變化。那咱先把頭像保存起來,到時候從新生成一下。 主要的操做是把矩形放大一點(Inflate((int)(r.Width * 0.5), (int)(r.Height * 0.5))),咱保存的頭像怎麼着得是我的頭吧。

(想來條分割線,竟然只有華麗的分割線,算了。順便吐槽一下,這個論壇的編輯器實在是讓人無語_)

各類折騰後,黔驢技窮了,10,000人臉的庫得出10張不認識的臉的結論,須要10秒鐘。固然,換好一點的電腦能夠提升效率,如個人臺式機(i5-7500),輸入圖片只有1張臉的時候,遍歷

1萬張人臉僅需390毫秒 5萬張人臉也就1525毫秒 10萬張人臉說我內存不夠,多是個人程序是32位的緣故,換成64位的sdk估計3秒鐘也能搞定(太麻煩,不折騰了) 結論是:虹軟中型sdk用於考勤、小區門禁、寫字樓門禁等場所徹底沒問題。

下一步我打算(其實已經差很少完成,我公司的項目——酒店自助機)改爲單臉多線程識別,增長如下功能:

40次檢測人臉數爲0,則確認爲沒人,識別頻率下降 是否換人了? 同一我的三、4次識別不出ID後,確認爲陌生人,不在遍歷 刷身份證獲取照片人臉比對後存入人臉庫 另外想跟企業微信結合開發開發門禁、CRM什麼的,有興趣的朋友一塊兒交流交流?

相關文章
相關標籤/搜索