使用Accord.NET識別圖片中的人臉數量

使用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,檢測結果會比較準確。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章