baiduAIFaceIdentify項目是C#語言,集成百度AI的SDK利用AForge開發的實時人臉識別的小demo,里邊包含了人臉檢測識別,人臉注冊,人臉登錄等功能
人臉實時檢測識別功能
思路是利用AForge打開攝像頭,通過攝像頭獲取到的圖像顯示在winform窗體中AForge的控件中,利用AForge控件中的NewFrame事件獲取要顯示的每一幀的圖像,獲取圖像傳輸到百度AI平台進行人臉檢測,並且將檢測結果反饋到界面顯示的圖像中。在這個過程中有兩個問題,獲取圖像上傳到百度AI平台進行分析需要時間,這個時間跟網絡有關,所以需要單獨一個線程進行人臉識別,第二個問題,百度人臉識別接口開發者一秒內只能掉用2次接口,所以需要控制不是每一幀的圖像都要上傳。所以基於以上思路
首先頁面初始化的時候獲取視頻設備、啟動一個單獨線程控制1秒內人臉檢測的次數:
private void Form1_Load(object sender, EventArgs e) { /// 獲取電腦已經安裝的視頻設備 videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice); if (videoDevices!=null && videoDevices.Count>0) { foreach (FilterInfo device in videoDevices) { comboBox1.Items.Add(device.Name); } comboBox1.SelectedIndex = 0; } videoSourcePlayer1.NewFrame += VideoSourcePlayer1_NewFrame; // 開發者在百度AI平台人臉識別接口只能1秒中調用2次,所以需要做 定時開始檢測,每個一秒檢測2次 ThreadPool.QueueUserWorkItem(new WaitCallback(p => { while (true) { IsStart = true; Thread.Sleep(500); } })); }
其次,在NewFrame的回調方法中,根據IsStart判斷是否要開始人臉識別,並且另外啟動一個線程進行人臉識別操作,判斷如果已經有識別過的結構,根據返回的人臉的位置,在當前的一幀圖像中繪制方框指示出識別出的人臉位置
private void VideoSourcePlayer1_NewFrame(object sender, ref Bitmap image) { try { if (IsStart) { IsStart = false; // 在線程池中另起一個線程進行人臉檢測,這樣不會造成界面視頻卡頓現象 ThreadPool.QueueUserWorkItem(new WaitCallback(this.Detect), image.Clone()); } if (location != null) { try { // 繪制方框套住人臉 Graphics g = Graphics.FromImage(image); g.DrawLine(new Pen(Color.Black), new System.Drawing.Point(location.left, location.top), new System.Drawing.Point(location.left + location.width, location.top)); g.DrawLine(new Pen(Color.Black), new System.Drawing.Point(location.left, location.top), new System.Drawing.Point(location.left, location.top + location.height)); g.DrawLine(new Pen(Color.Black), new System.Drawing.Point(location.left, location.top + location.height), new System.Drawing.Point(location.left + location.width, location.top + location.height)); g.DrawLine(new Pen(Color.Black), new System.Drawing.Point(location.left + location.width, location.top), new System.Drawing.Point(location.left + location.width, location.top + location.height)); g.Dispose(); } catch (Exception ex) { ClassLoger.Error("VideoSourcePlayer1_NewFrame", ex); } } } catch (Exception ex) { ClassLoger.Error("VideoSourcePlayer1_NewFrame1", ex); } }
人臉注冊。
在一些類似刷臉簽到、刷臉登錄的應用場景中,根據人臉獲取人物信息,前提就是人臉注冊,人臉注冊就是獲取當前攝像頭的一幀圖像,調用百度AI的人臉注冊接口進行注冊
// 用戶ID string uid = "1"; // 用戶資料,長度限制256B string userInfo = textBox6.Text.Trim(); // 用戶組ID string groupId = textBox5.Text.Trim(); if (comboBox1.Items.Count <= 0) { MessageBox.Show("請插入視頻設備"); return; } try { if (videoSourcePlayer1.IsRunning) { BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( videoSourcePlayer1.GetCurrentVideoFrame().GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); var img = BitmapSource2Byte(bitmapSource); var options = new Dictionary<string, object>{ {"action_type", "replace"} }; var result = client.UserAdd(uid, userInfo, groupId, img, options); if (result.ToString().Contains("error_code")) { MessageBox.Show("注冊失敗:" + result.ToString()); } else { MessageBox.Show("注冊成功"); } } } catch (Exception ex) { MessageBox.Show("攝像頭異常:" + ex.Message); }
人臉登錄
人臉登錄和人臉注冊的方式一樣,只不過調用的是百度AI的人臉登錄接口
// 用戶ID string uid = "1"; // 用戶資料,長度限制256B string userInfo = textBox6.Text.Trim(); // 用戶組ID string groupId = textBox5.Text.Trim(); if (comboBox1.Items.Count <= 0) { MessageBox.Show("請插入視頻設備"); return; } try { if (videoSourcePlayer1.IsRunning) { BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( videoSourcePlayer1.GetCurrentVideoFrame().GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); var img = BitmapSource2Byte(bitmapSource); // 如果有可選參數 //var options = new Dictionary<string, object>{ // {"ext_fields", "faceliveness"}, // {"user_top_num", 3} //}; var result = client.Identify(groupId, img); FaceIdentifyInfo info = JsonHelper.DeserializeObject<FaceIdentifyInfo>(result.ToString()); if (info!=null && info.result!=null && info.result.Length>0) { textBox7.Text = info.result[0].user_info; } } } catch (Exception ex) { MessageBox.Show("攝像頭異常:" + ex.Message); }
源碼地址:https://github.com/liemei/baiduAIFaceIdentify