背景 目前AI 處於風口浪尖,作為 公司的CTO,也作為自己的技術專研,開始了AI之旅,在朋友圈中也咨詢 一些大牛對於AI 機器學習框架的看法,目前自己的研究方向主要開源的 AI 庫,如:Emgu CV、TensorFlow、CNTK 等等,針對 四大平臺 百度AI、阿裡ET、騰訊AI、科大訊飛AI ...
背景
目前AI 處於風口浪尖,作為 公司的CTO,也作為自己的技術專研,開始了AI之旅,在朋友圈中也咨詢 一些大牛對於AI 機器學習框架的看法,目前自己的研究方向主要開源的 AI 庫,如:Emgu CV、TensorFlow、CNTK 等等,針對 四大平臺 百度AI、阿裡ET、騰訊AI、科大訊飛AI 做結合。
PS:筆者的主打語言是C#,目前項目主導系統都是基於Net 系列下開發而成的。主要負責公司軟體系統架構設計, 鑒於朋友圈中各位技術大牛無私分享,也是鑒於自己再專研時候遇到不少坑,希望把相關研究心得發出,為大家在coding 中減少 麻煩。稍後會把自己開源框架在博客中建立系列教程,插件化模式 自動服務 (都在實際項目中使用)。
選擇的理由:四大平臺目前 AI 團隊算是全世界最牛的一群人,而且資金背景雄厚(AI 很燒錢!),現在四大平臺 的AI有一些已經相對成熟,依靠於人家的技術,做自己的應用,應該是中小企業 在物聯網行業前進的一個方向吧。
四大平臺AI入口
1、百度AI https://ai.baidu.com/customer (百度AI 產品:阿波羅無人駕駛開源平臺 )
2、騰訊AI https://ai.qq.com/hr/youtu.shtml(騰訊AI 產品:騰訊覓影)
3、訊飛AI http://startups.xfyun.cn/(訊飛:語音)
4、阿裡雲ET https://et.aliyun.com/index(阿裡:城市大腦)
一、需求
1、目前我們需要通過攝像頭 精準的捕獲視頻監控中人臉(要求精度高)
2、批量捕獲人臉進行 人臉識別
3、在人臉矩形框中實時顯示人員相關信息
二、技術難點
1、百度人臉識別 只是需要通過Image 圖片通過開發介面發送,返回識別人物,所以前提還是要先做到人臉在視頻中動態捕捉。
2、視頻播放需要高效流暢播放,請求介面的效率是否影響視頻監控友好展示。
三、技術選型
1、為瞭解決 視頻中人臉動態捕捉,選用Emgu CV 是開源 框架 Open CV 的Net 版本,可以人臉精準抓取。
emgu CV 官網:http://www.emgu.com/
對於Emgu CV 的詳細信息,請百度。
2、百度人臉識別,介面完善,人臉識別精準度高,可以很好的做到人臉識別。
百度人臉識別介面文檔:http://ai.baidu.com/docs#/Face-Csharp-SDK/top
四、技術準備
1、到emgu cv 的官網下載 最新的emgu CV 版本,因為版本間差異較大,所以在百度搜索時候,會發現很多文章代碼是無法直接copy的。
2、安裝emgu cv 的最版本
請仔細查看 solution 文件夾,裡面有對應solution 文件,(在windowDeskTop文件夾裡面 )選擇Emgu.CV.sln打開,就可以看到Emgu.CV.Example(Emgu.CV 的Demo)。
3、我們需要將 FaceDetection(人臉精準查找Demo)和VideoSurveilance(視頻動態抓捕實現矩形框)兩個Demo 做結合
4、到百度開發者中心註冊成為開發者,並且獲取開發者。
5、下載百度AI 開發平臺 對應的SDK(已經封裝過,可以減少開發工作量),或者直接進行Api對接。
五、實現
先上實現效果,相關個人信息如頭像、還有姓名和電話都被我處理過了。
1、準備好攝像頭,連接沒問題就開始敲代碼了。
2、在百度人臉庫建立自己的人臉素材,這個要求要精準,比較適合就是員工的工牌相片,就是一寸或者兩寸的照片那種。
詳細方法 百度提供SDK 已經有了,就不多作介紹了。其中 自定義的 Uid(用戶id,用於唯一碼)、group (人才組)、userInfo(用戶信息,作為人臉識別返回信息顯示)比較關鍵。
sdk 下載地址:http://ai.baidu.com/sdk,下載完成將如圖中 dll 引用到自己的類庫中。
以下方法是我簡單改造過了。
我做了一個簡單的人臉庫添加 工具,可以進行簡單人臉庫操作
3、選擇VideoSurveilance 做改造,上代碼。
其中
void ProcessFrame(object sender, EventArgs e) 方法 是關鍵,裡面就是具體操作人臉識別具體應用。
將 FaceDetection 中的相關內容copy 到VideoSurveilance 項目中,其中 haarcascade_frontalface_default.xml 用於 人臉檢測,DetectFace.cs 是具體檢測人臉方法。
1 //---------------------------------------------------------------------------- 2 // Copyright (C) 2004-2017 by EMGU Corporation. All rights reserved. 3 //---------------------------------------------------------------------------- 4 5 using System; 6 using System.Collections.Generic; 7 using System.ComponentModel; 8 using System.Data; 9 using System.Drawing; 10 using System.Text; 11 using System.Windows.Forms; 12 13 using Emgu.CV; 14 using Emgu.CV.Cvb; 15 using Emgu.CV.UI; 16 using Emgu.CV.CvEnum; 17 using Emgu.CV.Structure; 18 using Emgu.CV.VideoSurveillance; 19 using FaceDetection; 20 using Emgu.CV.Cuda; 21 using AOP.Common; 22 using System.Drawing.Imaging; 23 using Baidu.Aip.API; 24 using System.Threading; 25 using BaiduAIAPI.Model; 26 27 namespace VideoSurveilance 28 { 29 public partial class VideoSurveilance : Form 30 { 31 32 private static VideoCapture _cameraCapture; 33 34 private static BackgroundSubtractor _fgDetector; 35 private static Emgu.CV.Cvb.CvBlobDetector _blobDetector; 36 private static Emgu.CV.Cvb.CvTracks _tracker; 37 38 private static Queue<ImageModel> FacIdentifyQueue = new Queue<ImageModel>(); 39 public Image faceImage; 40 Thread t1; 41 public VideoSurveilance() 42 { 43 InitializeComponent(); 44 Run(); 45 } 46 47 void Run() 48 { 49 try 50 { 51 _cameraCapture = new VideoCapture(); 52 } 53 catch (Exception e) 54 { 55 MessageBox.Show(e.Message); 56 return; 57 } 58 59 _fgDetector = new Emgu.CV.VideoSurveillance.BackgroundSubtractorMOG2(); 60 _blobDetector = new CvBlobDetector(); 61 _tracker = new CvTracks(); 62 63 Application.Idle += ProcessFrame; 64 } 65 66 void ProcessFrame(object sender, EventArgs e) 67 { 68 Mat frame = _cameraCapture.QueryFrame(); 69 Mat smoothedFrame = new Mat(); 70 CvInvoke.GaussianBlur(frame, smoothedFrame, new Size(3, 3), 1); //filter out noises 71 //frame._SmoothGaussian(3); 72 73 #region use the BG/FG detector to find the forground mask 74 Mat forgroundMask = new Mat(); 75 _fgDetector.Apply(smoothedFrame, forgroundMask); 76 #endregion 77 78 CvBlobs blobs = new CvBlobs(); 79 _blobDetector.Detect(forgroundMask.ToImage<Gray, byte>(), blobs); 80 blobs.FilterByArea(100, int.MaxValue); 81 82 float scale = (frame.Width + frame.Width) / 2.0f; 83 _tracker.Update(blobs, 0.01 * scale, 5, 5); 84 85 long detectionTime; 86 87 List<Rectangle> faces = new List<Rectangle>(); 88 List<Rectangle> eyes = new List<Rectangle>(); 89 90 IImage image = (IImage)frame;//這一步是重點 91 faceImage = frame.Bitmap; 92 DetectFace.Detect(image 93 , "haarcascade_frontalface_default.xml", "haarcascade_eye.xml", 94 faces, eyes, 95 out detectionTime); 96 97 #region 多人識別 98 Graphics g1 = Graphics.FromImage(frame.Bitmap); 99 List<FaceIdentifyModel> tempList = new List<FaceIdentifyModel>(); 100 foreach (Rectangle face in faces) 101 { 102 Image rectImage1 = ImageHelper.CaptureImage(frame.Bitmap, face);// 自己封裝的方法,通過大圖截取矩形框的人臉圖片,返回Image 對象 103 FaceIdentifyModel MoreIdentifyInfo = FaceAPI.FaceIdentify(rectImage1, tb_Group.Text.Trim(), 1, 1);
104 MoreIdentifyInfo.rect = face; 105 tempList.Add(MoreIdentifyInfo); 106 }
107 Color color_of_pen1 = Color.Gray; 108 color_of_pen1 = Color.Yellow; 109 Pen pen1 = new Pen(color_of_pen1, 2.0f); 110 111 Font font1 = new Font("微軟雅黑", 16, GraphicsUnit.Pixel); 112 SolidBrush drawBrush1 = new SolidBrush(Color.Yellow); 113 114 115 tb_Identify.Text = tempList.ToJson(); 116 foreach (var t in tempList) 117 { 118 g1.DrawRectangle(pen1, t.rect); 119 120 if (t.result != null) 121 { 122 g1.DrawString(t.result[0].user_info.Replace(",", "\r\n"), font1, drawBrush1, new Point(t.rect.X + 20, t.rect.Y - 20)); 123 } 124 125 } 126 #endregion 127 128 imageBox1.Image = frame; 129 imageBox2.Image = forgroundMask; 130 } 131 132 133 134 private void btn_Screenshot_Click(object sender, EventArgs e) 135 { 136 if (faceImage != null) 137 { 138 System.Drawing.Image ResourceImage = faceImage; 139 string fileDir = System.Environment.CurrentDirectory + "\\Snapshot\\"; 140 FileHelper.CreateDir(fileDir); 141 string filePath = fileDir + DateTime.Now.ToString("yyyyMMddHHmmss") + ".png"; 142 ResourceImage.Save(filePath); 143 MessageBox.Show("保存成功!" + filePath); 144 } 145 146 } 147 } 148 }
核心代碼介紹
獲取人臉矩形框,對應的xml 文件要放在根目錄下(winform就是 在bin文件夾中)
DetectFace.Detect(image , "haarcascade_frontalface_default.xml", "haarcascade_eye.xml", faces, eyes, out detectionTime);
faces 就是返回的 人臉檢測內容, foreach (Rectangle face in faces) 對它進行動態獲取人臉,在視頻中畫出來就可以了
// 調用百度人臉識別介面,該方法 SDK 已經有了,我做了一些簡單的封裝,就是把截取到的矩形頭像發送給百度去識別,這個識別是基於自己在百度建立的人臉庫
FaceIdentifyModel MoreIdentifyInfo = FaceAPI.FaceIdentify(rectImage1, tb_Group.Text.Trim(), 1, 1);//人臉識別 一個人的識別效果比較好
完成上述工作,人臉識別就完成了,測試過,只要人臉庫中的素材清晰,識別基本在99% 左右。