使用Accord.NET識別圖片中的人臉數量
最近在看《C#神經網絡編程》的時候,發現了一個使用C#檢測圖片中人臉的程序實例,就自己親手用Sunny.UI搭建了一個WinForm項目實踐了一遍,效果還可以,實例中檢測識別人臉的框架類庫用的是 Accord.NET Framework,也是基於C#語言編寫的。
1. 項目搭建
新建一個WinForm項目,引入界面類庫Sunny.UI,就是爲了界面能漂亮一些,不顯得土氣,之後Nuget安裝 Accord.Imaging,Accord.Vision,兩個依賴包。安裝完之後就可以寫程序了。界面樣式如下:
2. 界面概述
界面包括一個pictureBox控件,用於加載顯示待檢測的圖片,網絡圖片按鈕用於加載網絡圖片,本地圖片則用於加載本地的圖片,人臉識別檢測用於開始檢測動作的觸發,模式的combobox控件是用於對象檢測程序的搜索選項。範圍的combobox控件是選擇搜索識別的範圍:是從一個大的搜索窗口開始,逐步擴大到較小的搜索窗口。還是從較小的搜索窗口開始,逐步擴大到較大的搜索窗口。並行複選框checkBox是用來選擇是否用多線程併發來執行檢測程序。
3. 功能代碼
功能代碼挺簡單的,就是打開一個文件選擇對話框並選擇一個圖片文件,之後通過配置HaarObjectDetector的實例對象,來實現人臉識別。識別之後再通過RectanglesMarker 實例對象在原圖中標記出檢測的人臉,而後返回標記後的圖片。
public partial class MainForm : UIForm
{
Bitmap picture = Resources.faceOne;
HaarObjectDetector detector;
public MainForm()
{
InitializeComponent();
this.pictureBox_Images.Image = picture;
this.comboBox_mode.DataSource = Enum.GetValues(typeof(ObjectDetectorSearchMode));
this.comboBox_scaling.DataSource = Enum.GetValues(typeof(ObjectDetectorScalingMode));
comboBox_mode.SelectedItem = ObjectDetectorSearchMode.NoOverlap;
comboBox_scaling.SelectedItem = ObjectDetectorScalingMode.SmallerToGreater;
this.uiSymbolLabel_statue.Text = "準備就緒,請選擇合適的參數選項開始進行人臉檢測......";
HaarCascade cascade = new FaceHaarCascade();
detector = new HaarObjectDetector(cascade, 30);
}
/// <summary>
/// 讀取文件到字節流
/// </summary>
/// <param name="imagepath"></param>
/// <returns></returns>
public byte[] GetPictureData(string imagepath)
{
FileStream FileStream = new FileStream(imagepath, FileMode.Open);
byte[] byData = new byte[FileStream.Length];
FileStream.Read(byData, 0, byData.Length);
FileStream.Close();
return byData;
}
/// <summary>
/// 打開本地文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void uiButton_fileImg_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "圖片文件(*.jpg;*.jpeg)|*.jpg;*.jpg|所有文件|*.*";
ofd.ValidateNames = true;
ofd.CheckPathExists = true;
ofd.CheckFileExists = true;
if (ofd.ShowDialog() == DialogResult.OK)
{
string strFileName = ofd.FileName;
uiTextBox_urlfilePath.Text = strFileName;
using (MemoryStream mem = new MemoryStream(GetPictureData(strFileName)))
{
using (var image = Image.FromStream(mem))
{
this.pictureBox_Images.Image = this.picture = new Bitmap(image);
}
}
}
}
/// <summary>
/// 執行人臉檢測
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void uiButton_detect_Click(object sender, EventArgs e)
{
detector.SearchMode = (ObjectDetectorSearchMode)comboBox_mode.SelectedValue;
detector.ScalingMode = (ObjectDetectorScalingMode)comboBox_scaling.SelectedValue;
detector.ScalingFactor = 1.5f;
detector.UseParallelProcessing = this.uiCheckBox_parallel.Checked;
detector.Suppression = 2;
Stopwatch sw = Stopwatch.StartNew();
// 檢測人臉,返回檢測數量
Rectangle[] objects = detector.ProcessFrame(picture);
sw.Stop();
// 如果識別出了人臉,則標記原圖,並返回標記後的圖片。
if (objects.Length > 0)
{
RectanglesMarker marker = new RectanglesMarker(objects, Color.Red);
this.pictureBox_Images.Image = marker.Apply(picture);
}
this.uiSymbolLabel_statue.Text = string.Format("在 {0} s 內,已經完成 {1} 個人臉識別對象的檢測!", sw.Elapsed, objects.Length);
}
}
3. 算法概述
Accord.NET使用Viola-Jones對象檢測算法,該算法在2001年被提出,儘管它可以被訓練去發現各種各樣的目標事物,但在這個框架中,它主要的用途是檢測識別人臉,根據BSD許可證,該算法對學術和商業使用都是免費的。需要注意的是,有一些特定版本的Haar對象檢測框架,已經由維奧拉和瓊斯申請了專利,在商業使用時可能受到限制。
算法檢測模式說明
- Default 將掃描整個圖像。
- Single 只會檢索一個對象。
- NoOverlap 如果一個物體已經在一個區域內被檢測到,內部對象或重疊對象將不會被掃描兩次。
- Average 如果幾個物體位於彼此之間,就求它們的平均值。
一般來說模式選擇Average ,縮放範圍順序選擇GreaterToSmaller,檢測結果會比較準確。