最近在嘗試作一我的臉識別項目,在對比幾款主流人臉識別SDK後,採用了虹軟的Arcface SDK,由於它提供了免費版本,而且能夠離線使用,接入難度也比較低。項目中有一個需求就是顯示檢測到的人臉,可是如何從一張圖片中摳取合適大小的人臉呢?本文將從如下步驟來介紹如何實現:html
1. 如何得到人臉框
2. 如何根據人臉框裁剪
3. 如何進行結果圖旋轉
4. 應用場景舉例java
首先咱們來看一下虹軟Android ArcFace SDK用於人臉檢測的detectFaces函數以及人臉數據類FaceInfo:網絡
detectFaces函數:異步
參數 | 類型 | 說明 |
data | byte[] | 圖像數據的內存 |
width | int | 圖像的寬 |
height | int | 圖像的高 |
format | int | 圖像的格式 |
faceInfoList | List\<FaceInfo> | 人臉檢測結果列表 |
FaceInfo定義:函數
變量 | 類型 | 說明 |
rect | Rect | 人臉在圖像中的座標 |
orient | int | 人臉的朝向 |
faceId | int | 人臉id,用於標識人臉 |
人臉檢測函數介紹的文章有不少,這裏就很少作介紹了。FaceInfo中的rect就是咱們用來摳取人臉的重要參數,下圖就是根據它畫出的人臉框。post
以Android平臺爲例,Bitmap類提供了函數**createBitmap**(Bitmap source, int x, int y, int width, int height)spa
變量 | 類型 | 說明 |
source | Bitmap | 原始圖像 |
x | int | 人臉框左上角y座標 |
y | int | 人臉框左上角y座標 |
width | int | 新圖像的寬 |
height | int | 新圖像的高 |
使用這個函數就能夠摳取任意區域內圖像內容:3d
java //原圖 Bitmap source; //人臉框 Rect faceRect; //建立Bitmap Bitmap.createBitmap(source,faceRect.left,faceRect.top,faceRect.width(),faceRect.height();
FaceInfo中orient表明這我的臉在圖像中的朝向,當其不爲0°的時候,須要根據實際狀況進行旋轉。code
旋轉角度 | 類型 | 說明 |
ASF_OC_0 | int | 0° |
ASF_OC_90 | int | 逆時針90° |
ASF_OC_180 | int | 180° |
ASF_OC_270 | int | 順時針90° |
如下是旋轉代碼orm
java //原圖 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長度。示例代碼以下:
java //原圖 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可在虹軟人臉識別開放平臺下載