1. 程式人生 > >C#開發學習人工智慧的第一步

C#開發學習人工智慧的第一步

前言

作為一個軟體開發者,我們除了要學會複製,黏貼,還要學會呼叫API和優秀的開源類庫。

也許,有人說C#做不了人工智慧,如果你相信了,那隻能說明你的思想還是狹隘的。

做不了人工智慧的不是C#這種語言,而是你,我這種普通的程式設計師。

做人工智慧需要一定的學歷背景,一定的數學基礎和公司專項的資源供給;而這種機緣小之又小,你我既然是普通的程式設計師,就必然與此無緣。

但在人工智慧如日中天的當下,接觸深度學習是必然會發生的事情,所以我們要做的就是,學會呼叫相關的類庫。

現在,讓我們邁出C#學習人工智慧的第一步,通過呼叫Affdex來鎖定圖片中人物的面部,然後將其截取出來。

準備工作

首先,我們需要先訪問官網下載Affdex的Sdk。

在官網找中找到下載Affdex的Sdk的地方也是個挺困難的事。。。所以下載連結如下:

下載Affdex_Sdk網址

進入網頁後,向下拉動滾動條,找到到下圖所示位置,點選Download進行下載。

下載完成後得到Sdk,如下圖:

下面,我們雙擊進行安裝,不過安裝SDK有一些限制,需要預先安裝NET Framework4.0和C++ 2015。如果電腦裡已經安裝了,就不必擔心了;如果安裝的是C++2015-2017這型別的,則需要解除安裝了,重新安裝C++2015的版本,否則Affdex的SDK將安裝失敗。

安裝完成後,我們去安裝目錄找到Affdex.dll,affdex-native.dll,tensorflow.dll三個檔案,如下圖:

我們先將它們複製出來,等待使用。

簡單的介紹一下,這三個類庫中,Affdex.dll是可以被C#專案直接引用的,而另外兩個檔案是Affdex.dll的依賴檔案;也就是說,affdex-native.dll,tensorflow.dll需要在生成時,輸出到執行目錄下。

有經驗的朋友想必已經發現了,這裡有個類庫名叫tensorflow.dll,tensorflow是什麼啊?稍微百度一下大家就會了解了,它是專門來做深度學習的。

也就是說Affdex是支援深度學習的。

----------------------------------------------------------------------------------------------------

現在我們來學習Affdex的使用。

首先我們新建一個WPF專案,然後引用Affdex.dll。

然後將專案的執行平臺設定為64位,因為,這樣處理圖片的速度能快一點,如下圖:

在Affdex中我們可以發現四個探頭—VideoDetector,PhotoDetector,FrameDetector,CameraDetector。

在這裡我們要處理的是圖片,所以我們選擇PhotoDetector,下面我們建立一個PhotoWindow.Xaml頁面來使用PhotoDetector處理圖片。

程式碼實現

首先,我們定義一個PhotoDetector的屬性,用於處理圖片。

然後我們在建構函式中對他進行例項化,程式碼如下:

private Affdex.PhotoDetector Detector { get; set; }
public PhotoWindow()
{
    InitializeComponent(); 
    uint maxNumFaces = 1;//最多識別圖片中幾張臉
    Detector = new Affdex.PhotoDetector(maxNumFaces, Affdex.FaceDetectorMode.SMALL_FACES);            
    Detector.setImageListener(this); 
    Detector.setProcessStatusListener(this);
    Detector.start();
}

在上述程式碼中可以看到,除了初始化PhotoDetector,我們還做了一個圖片監聽設定setImageListener,那麼圖片監聽是幹什麼的呢?

很簡單,圖片被PhotoDetector處理完,我們需要知道圖片處理結果呀,而這個圖片監聽正是是用來返回圖片處理結果的。

可以看到圖片監聽設定的入參是this,也就是說,需要把圖片的處理結果返回給當前頁面。

如果就這樣寫是會編譯報錯的,會提示setImageListener的入參錯誤。

我們檢視setImageListener的入參,發現它的入參是一個ImageListener介面,即,setImageListener的入參是一個要實現了ImageListener介面的類。

到這裡,我們就都明白了,現在我們讓當前PhotoWindow.xaml窗體繼承介面ImageListener,並實現介面ImageListener內的方法。

public partial class PhotoWindow : Window, Affdex.ImageListener
===========================================================================
public void onImageCapture(Affdex.Frame frame)
{
} 
public void onImageResults(Dictionary<int, Face> faces, Affdex.Frame frame)
{
}

如上述程式碼所示,在我們實現的介面onImageResults裡有兩個引數:faces、frame。

其中faces是最重要的,這裡包含Affdex分析圖片的結果。

----------------------------------------------------------------------------------------------------

現在,Affdex的配置程式碼已經寫完了,我們可以把圖片讀取出來呼叫Affdex處理了。

public PhotoWindow()
{
    InitializeComponent(); 
    uint maxNumFaces = 1;//最多識別圖片中幾張臉
    Detector = new Affdex.PhotoDetector(maxNumFaces, Affdex.FaceDetectorMode.SMALL_FACES);   
    Detector.setImageListener(this); 
    Detector.start(); 
    
    byte[] bytes = FileHelper.FileToBytes(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "timg.jpg"));
    BitmapSource bitmapSource = ImageHelper.BytesToBitmapImage(bytes); 
    var w = bitmapSource.Width;
    var h = bitmapSource.Height;
    var stride = bitmapSource.Format.BitsPerPixel * (int)w / 8; //計算Stride  
    byte[] byteList = new byte[(int)h * stride];
    bitmapSource.CopyPixels(byteList, stride, 0);   
    Affdex.Frame frame = new Affdex.Frame((int)w, (int)h, byteList, Affdex.Frame.COLOR_FORMAT.BGRA);  
    Detector.process(frame);
}  

如上述程式碼所示,我們在啟動了Detector後,讀取了一個人物圖片,然後把人物圖片的畫素陣列解析出來,生成一個Frame;這個Frame是Affdex的類,用於儲存影象資料資訊。

最後,我們把生成的Frame物件,扔給Detecotor的Process方法處理。

Detecotor處理完成後,會觸發onImageResults方法。

在onImageResults方法裡,入參faces包含了處理結果。

現在我們使用faces裡的內容,來定點陣圖片中人物面部的位置。

public void onImageResults(Dictionary<int, Face> faces, Affdex.Frame frame)
{
    Face face = null;
    if (faces != null && faces.Values != null && faces.Values.Count() > 0)
    {
        face = faces.Values.First();//因為我們的Detector只識別了一個臉,所以這裡最多隻有一個數據
    }
    int top = (int)face.FeaturePoints.Min(r => r.X);
    int left = (int)face.FeaturePoints.Min(r => r.Y);
    int bottom = (int)face.FeaturePoints.Max(r => r.X);
    int right = (int)face.FeaturePoints.Max(r => r.Y);
    ImageHelper.cutPicture(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "timg.jpg"),
     left, top, right , bottom - top);
}

如上述程式碼所示,我們在onImageResults裡做了【最簡單】人物面部座標定位,並進行了剪下。 

處理結果如下圖所示:

結語

事實上,上面介紹的只是Affdex最基礎呼叫,而且,這裡並沒有使用到深度學習的內容,只是簡單的掃描和分析。

想要使用深度學習的內容還需要進一步學習該開源控制元件,不過,萬事開頭難,我們現在已經邁出了第一步。

----------------------------------------------------------------------------------------------------

到此C#開發學習人工智慧的第一步就完成了。

程式碼已經傳到Github上了,歡迎大家下載。

Github地址:https://github.com/kiba518/WpfAffdex

----------------------------------------------------------------------------------------------------

注:此文章為原創,任何形式的轉載都請聯絡作者獲得授權並註明出處!
若您覺得這篇文章還不錯,請點選下方的【推薦】,非常感謝!

https://www.cnblogs.com/kiba/p/11416919.html

&n