编程知识 cdmana.com

Android人臉識別app——基於Face,Android進階

<provider

android:name=“android.support.v4.content.FileProvider”

android:authorities=“com.chaochaowu.facedetect.provider”

android:exported=“false”

android:grantUriPermissions=“true”>

<meta-data

android:name=“android.support.FILE_PROVIDER_PATHS”

android:resource=“@xml/file_paths” />

</provider>

拍照之後從文件中讀取照片,我們可以得到一個 BitMap 對象。這裏就有一個很大的坑,如果手機是三星的話,照片從文件裏讀出來,最後得到的照片會被旋轉 90°!!!,這個賊坑啊,調了我好久,以為是自己手機的故障,後來網上查了一下,也請教了一下前輩,原來三星的手機都有這個問題,所以說我們要對文件中取出來的照片進行一下處理。

/**

  • 讀取圖片的旋轉的角度

  • @param path 圖片絕對路徑

  • @return 圖片的旋轉角度

*/

public static int getBitmapDegree(String path) {

int degree = 0;

try {

// 從指定路徑下讀取圖片,並獲取其EXIF信息

ExifInterface exifInterface = new ExifInterface(path);

// 獲取圖片的旋轉信息

int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,

ExifInterface.ORIENTATION_NORMAL);

switch (orientation) {

case ExifInterface.ORIENTATION_ROTATE_90:

degree = 90;

break;

case ExifInterface.ORIENTATION_ROTATE_180:

degree = 180;

break;

case ExifInterface.ORIENTATION_ROTATE_270:

degree = 270;

break;

default:

degree = 0;

break;

}

} catch (IOException e) {

e.printStackTrace();

}

return degree;

}

/**

  • 將圖片按照某個角度進行旋轉

  • @param bm 需要旋轉的圖片

  • @param degree 旋轉角度

  • @return 旋轉後的圖片

*/

public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {

Bitmap returnBm = null;

// 根據旋轉角度,生成旋轉矩陣

Matrix matrix = new Matrix();

matrix.postRotate(degree);

try {

// 將原始圖片按照旋轉矩陣進行旋轉,並得到新的圖片

returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);

} catch (OutOfMemoryError | Exception e) {

e.printStackTrace();

}

if (returnBm == null) {

returnBm = bm;

}

if (bm != returnBm) {

bm.recycle();

}

return returnBm;

}

封裝了兩個方法,依次調用可以解决三星手機照片的問題。兩個方法主要的工作就是,得到取出來的照片被旋轉的角度,然後再將角度旋轉回去,就可以得到原來的照片。因為並不是所有的手機在獲取照片時,照片都會被旋轉,所以得先判斷一下照片有沒有被旋轉,再决定是否需要將它旋轉調整。

行,這樣最後就獲得到了正確的 BitMap 照片,可以進行下一步了。

傳照片獲取數據

傳照片獲取數據,主要是運用了 Retrofit 和 RxJava 的封裝。請求的參數可以參考 Face++ 的官方文檔。

/**

  • retrofit 面部識別請求的網絡服務

  • @author chaochaowu

*/

public interface FaceppService {

/**

  • @param apikey

  • @param apiSecret

  • @param imageBase64

  • @param returnLandmark

  • @param returnAttributes

  • @return

*/

@POST(“facepp/v3/detect”)

@FormUrlEncoded

Observable<FaceppBean> getFaceInfo(@Field(“api_key”) String apikey,

@Field(“api_secret”) String apiSecret,

@Field(“image_base64”) String imageBase64,

@Field(“return_landmark”) int returnLandmark,

@Field(“return_attributes”) String returnAttributes);

}

照片需要進行 base64 轉碼後上傳至服務器,封裝了一個照片base64轉碼方法。

public static String base64(Bitmap bitmap){

ByteArrayOutputStream baos = new ByteArrayOutputStream();

bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

byte[] bytes = baos.toByteArray();

return Base64.encodeToString(bytes, Base64.DEFAULT);

}

處理完成之後就可以進行網絡請求獲取數據。

@Override

public void getDetectResultFromServer(final Bitmap photo) {

String s = Utils.base64(photo);

faceppService.getFaceInfo(BuildConfig.API_KEY, BuildConfig.API_SECRET, s, 1, “gender,age,smiling,emotion,beauty”)

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new Observer<FaceppBean>() {

@Override

public void onSubscribe(Disposable d) {

mView.showProgress();

}

@Override

public void onNext(FaceppBean faceppBean) {

handleDetectResult(photo,faceppBean);

}

@Override

public void onError(Throwable e) {

mView.hideProgress();

}

@Override

public void onComplete() {

mView.hideProgress();

}

});

}

Face++ 服務器會對我們上傳的照片進行處理,分析照片中的人臉信息,並以 json 形式返回,返回的數據將被放入我們定義的bean類中。

/**

  • 面部識別結果的bean

  • @author chaochaowu

*/

public class FaceppBean {

/**

  • image_id : Dd2xUw9S/7yjr0oDHHSL/Q==

  • request_id : 1470472868,dacf2ff1-ea45-4842-9c07-6e8418cea78b

  • time_used : 752

  • faces : [{“landmark”:{“mouth_upper_lip_left_contour2”:{“y”:185,“x”:146},“contour_chin”:{“y”:231,“x”:137},“right_eye_pupil”:{“y”:146,“x”:205},“mouth_upper_lip_bottom”:{“y”:195,“x”:159}},“attributes”:{“gender”:{“value”:“Female”},“age”:{“value”:21},“glass”:{“value”:“None”},“headpose”:{“yaw_angle”:-26.625063,“pitch_angle”:12.921974,“roll_angle”:22.814377},“smile”:{“threshold”:30.1,“value”:2.566890001296997}},“face_rectangle”:{“width”:140,“top”:89,“left”:104,“height”:141},“face_token”:“ed319e807e039ae669a4d1af0922a0c8”}]

*/

最後

文章不易,如果大家喜歡這篇文章,或者對你有幫助希望大家多多點贊轉發關注哦。文章會持續更新的。絕對幹貨!!!

由於文章篇幅問題 查看詳細文章以及獲取學習筆記鏈接: GitHub

  • Android進階學習全套手册
    關於實戰,我想每一個做開發的都有話要說,對於小白而言,缺乏實戰經驗是通病,那麼除了在實際工作過程當中,我們如何去更了解實戰方面的內容呢?實際上,我們很有必要去看一些實戰相關的電子書。目前,我手頭上整理到的電子書還算比較全面,HTTP、自定義view、c++、MVP、Android源碼設計模式、Android開發藝術探索、Java並發編程的藝術、Android基於Glide的二次封裝、Android內存優化——常見內存泄露及優化方案、.Java編程思想 (第4版)等高級技術都囊括其中。

Android人臉識別app——基於Face,Android進階_程序員

  • Android高級架構師進階知識體系圖
    關於視頻這塊,我也是自己搜集了一些,都按照Android學習路線做了一個分類。按照Android學習路線一共有八個模塊,其中視頻都有對應,就是為了幫助大家系統的學習。接下來看一下導圖和對應系統視頻吧!!!
    Android人臉識別app——基於Face,Android進階_Android_02

  • Android對標阿裏P7學習視頻

Android人臉識別app——基於Face,Android進階_Android_03

  • BATJ大廠Android高頻面試題
    這個題庫內容是比較多的,除了一些流行的熱門技術面試題,如Kotlin,數據庫,Java虛擬機面試題,數組,Framework ,混合跨平臺開發,等
    Android人臉識別app——基於Face,Android進階_移動開發_04

版权声明
本文为[mb61c1dbbb44788]所创,转载请带上原文链接,感谢
https://cdmana.com/2022/01/202201150218513172.html

Scroll to Top