最近在嘗試做一個人臉識別項目,在對比幾款主流人臉識別SDK后,采用了虹軟的Arcface SDK,因為它提供了免費版本,并且可以離線使用,接入難度也比較低。項目中有一個需求就是顯示檢測到的人臉,但是如何從一張圖片中摳取合適大小的人臉呢?本文將從以下步驟來介紹如何實現:
1. 如何獲得人臉框
2. 如何根據人臉框裁剪
3. 如何進行結果圖旋轉
4. 應用場景舉例
首先我們來看一下虹軟Android ArcFace SDK用于人臉檢測的detectFaces函數以及人臉數據類FaceInfo:
detectFaces函數:
| 參數 | 類型 | 說明 |
|---|---|---|
| data | byte[] | 圖像數據的內存 |
| width | int | 圖像的寬 |
| height | int | 圖像的高 |
| format | int | 圖像的格式 |
| faceInfoList | List
| 人臉檢測結果列表 |
FaceInfo定義:
| 參數 | 類型 | 說明 |
|---|---|---|
| rect | Rect | 人臉在圖像中的坐標 |
| orient | int | 人臉的朝向 |
| faceId | int | 人臉id,用于標識人臉 |
人臉檢測函數介紹的文章有很多,這里就不多做介紹了。FaceInfo中的rect就是我們用來摳取人臉的重要參數,下圖就是根據它畫出的人臉框。
以Android平臺為例,Bitmap類提供了函數 createBitmap(Bitmap source, int x, int y, int width, int height)
| 參數 | 類型 | 說明 |
|---|---|---|
| source | Bitmap | 原始圖像 |
| x | int | 人臉框左上角y坐標 |
| y | int | 人臉框左上角y坐標 |
| width | int | 新圖像的寬 |
| height | int | 新圖像的高 |
使用這個函數就可以摳取任意區域內圖像內容:
//原圖
Bitmap source;
//人臉框
Rect faceRect;
//創建Bitmap
Bitmap.createBitmap(source,faceRect.left,faceRect.top,faceRect.width(),faceRect.height();
FaceInfo中orient代表這個人臉在圖像中的朝向,當其不為0°的時候,需要根據實際情況進行旋轉。
| 旋轉角度 | 類型 | 說明 |
|---|---|---|
| ASF_OC_0 | int | 0° |
| ASF_OC_90 | int | 逆時針90° |
| ASF_OC_180 | int | 180° |
| ASF_OC_270 | int | 順時針90° |
以下是旋轉代碼
//原圖
Bitmap source;
//人臉框
Rect faceRect;
//創建Bitmap,假設需要順時針旋轉90°
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap.createBitmap(source, faceRect.left, faceRect.top, faceRect.width(),
faceRect.height(), matrix, true);
例如門禁場景下,需要顯示人臉(摳圖)或者上傳人臉圖片到服務端。如果上傳完整的圖像,則會占用大量的存儲空間以及網絡資源,所以上傳摳取的人臉圖片是比較合適的,但是根據檢測所得的人臉框摳取的人臉是不完整的,所以需要對人臉框做一些后期處理,最簡單的方案就是寬高分別向外擴大其1/2長度。示例代碼如下:
//原圖
Bitmap source;
//人臉框
Rect faceRect;
//調整人臉框
Rect newRect = new Rect(faceRect);
//確保人臉框在圖像內
if (newRect.left < 0) {
newRect.left = 0;
}
if (newRect.top < 0) {
newRect.top = 0;
}
if (newRect.right > source.getWidth()) {
newRect.right =
source.getWidth();
}
if (newRect.bottom > source.getHeight()) {
newRect.bottom =
source.getHeight();
}
//
int offsetX = Math.min(Math.min(faceRect.width()/2,newRect.left),
source.getWidth() - newRect.right);
int offsetY = Math.min(Math.min(faceRect.height()/2,newRect.top),
source.getHeight() - newRect.bottom);
newRect.inset(-offsetX, -offsetY);
//創建Bitmap,假設需要順時針旋轉90°
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap.createBitmap(source, newRect.left, newRect.top, newRect.width(),
newRect.height(), matrix, true);
虹軟人臉識別Android Demo中提供了很多人臉識別相關功能,如:畫人臉框適配的方案;異步人臉特征提??;異步人臉特征比對等等,有需要可以在下面鏈接下載:
Android Demo可在
虹軟人臉識別開放平臺下載
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。