iT邦幫忙

2021 iThome 鐵人賽

DAY 29
0
AI & Data

AI Facial Expression Recognition: Data, Model, Application系列 第 29

[Day 29] Android Studio 七日隕石開發:影像辨識功能實作!

前言

有了App介面和tflite model with metadata之後,
App的核心功能!靈魂!終於要被我實現了!


影像辨識程式碼實作

  1. 載入深度學習模型
// Loading my custom model
val model = Effb0FerMeta.newInstance(this)
  1. 轉bitmap成TensorImage
    (延伸閱讀 : bitmap是甚麼?)
// Creates inputs for reference.
val tensorImage = TensorImage.fromBitmap(bitmap)
  1. 應用模型於image上進行辨識
// Runs model inference and gets result.
val outputs = model.process(tensorImage)
    .probabilityAsCategoryList.apply {
        sortByDescending { it.score } // 排序,由高到低
    }
  1. 將辨識結果與可信度存成List
val result = arrayListOf<String>()
for (output in outputs) {
    val label = output.label
    val score: Int = (output.score * 100).roundToInt()
    result.add("表情是 $label 的可能性為 $score %")
}
  1. 將結果顯示於 ListView
val listView = findViewById<ListView>(R.id.listView)
listView.adapter = ArrayAdapter(this,
    android.R.layout.simple_list_item_1,
    result
)
  1. 用try-catch避免錯誤情況發生造成程式閃退
try{
    // ...
}catch(...){
    // ...
}

將以上程式碼寫成function: recognizeImage()

private fun recognizeImage(bitmap: Bitmap) {
        try {
            // Loads my custom model
            val model = Effb0FerMeta.newInstance(this)

            // Creates inputs for reference.
            val tensorImage = TensorImage.fromBitmap(bitmap)

            // Runs model inference and gets result.
            val outputs = model.process(tensorImage)
                .probabilityAsCategoryList.apply {
                    sortByDescending { it.score } // 排序,由高到低
                }

            //取得辨識結果與可信度
            val result = arrayListOf<String>()
            for (output in outputs) {
                val label = output.label
                val score = (output.score * 100).roundToInt()
                result.add("表情是 $label 的可能性為 $score %")
            }

            //將結果顯示於 ListView
            val listView = findViewById<ListView>(R.id.listView)
            listView.adapter = ArrayAdapter(this,
                android.R.layout.simple_list_item_1,
                result
            )
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

onActivityResult()

這個程式碼區塊是我拖更很久的部分,
現在我補上來了。
基本上就是:

  1. 判斷image來自相機(0)還是相簿(1)
  2. 將image放到imageView元件上顯示
  3. 呼叫recognizeImage()進行辨識&顯示辨識結果的List
    override fun onActivityResult(requestCode: Int,
                                  resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == 0 && resultCode == RESULT_OK) {
            val image = data?.extras?.get("data") ?: return //取得資料
            val bitmap = image as Bitmap 
            val imageView = findViewById<ImageView>(R.id.imageView)
            imageView.setImageBitmap(bitmap) //使用 Bitmap 設定圖像
            imageView.rotation = 90f
            recognizeImage(bitmap) 

        }
        if (requestCode == 1 && resultCode == RESULT_OK) {
            val uri = data!!.data
            val imageView = findViewById<ImageView>(R.id.imageView)
            imageView.setImageURI(uri)
            val drawable = imageView.drawable as BitmapDrawable 
            val bitmap = drawable.bitmap
            recognizeImage(bitmap) 
        }
    }

結語

只要合併前幾天的文章內容,
應該已經有些帥氣/漂亮的觀眾們應該已經完成App了。
這裡有完整的code,不嫌棄的話給個star吧 :D
明天就是最後一天了,
內容應該是成果發表和感言吧XD
/images/emoticon/emoticon25.gif


上一篇
[Day 28] Android Studio 七日隕石開發:把 tflite 模型放進 app
下一篇
[Day 30] 人臉表情辨識App成果發表與完賽感想
系列文
AI Facial Expression Recognition: Data, Model, Application30

尚未有邦友留言

立即登入留言