それで、私は新しいGoogleのCamera API-CameraX
を探求したいと思いました。私がやりたいのは、カメラフィードから毎秒画像を取得し、それを機械学習の目的でビットマップを受け入れる関数に渡すことです。
Camera X
Image Analyzerのドキュメントを読みました。
画像分析のユースケースは、画像処理、コンピュータービジョン、または機械学習の推論を実行するためのCPUアクセス可能な画像をアプリに提供します。アプリケーションは、各フレームで実行されるアナライザーメソッドを実装します。
..これは基本的に私が必要とするものです。そこで、この画像アナライザーを次のように実装しました。
imageAnalysis.setAnalyzer { image: ImageProxy, _: Int ->
viewModel.onAnalyzeImage(image)
}
私が得るものはimage: ImageProxy
です。これをImageProxy
からBitmap
に転送するにはどうすればよいですか?
私はこのようにそれを解決しようとしました:
fun decodeBitmap(image: ImageProxy): Bitmap? {
val buffer = image.planes[0].buffer
val bytes = ByteArray(buffer.capacity()).also { buffer.get(it) }
return BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
}
しかし、それはnull
を返します-decodeByteArray
が有効な(?)ビットマップバイトを受信しないためです。何か案は?
より簡単な解決策があります。変換せずにBitmap
からTextureView
を取得できます。詳細は documentation をご覧ください。
imageAnalysis.setAnalyzer { image: ImageProxy, _: Int ->
val bitmap = textureView.bitmap
}
@ mike-aの回答に触発されました
private fun ImageProxy.toMat(): Mat {
val graySourceMatrix = Mat(height, width, CvType.CV_8UC1)
val yBuffer = planes[0].buffer
val ySize = yBuffer.remaining()
val yPlane = ByteArray(ySize)
yBuffer[yPlane, 0, ySize]
graySourceMatrix.put(0, 0, yPlane)
return graySourceMatrix
}
OpenCVを使用するつもりであれば、これにより直接グレイマトリックスランドに移動でき、色はもう関係ありません。
すべてのフレームでこれを行っている場合、パフォーマンスのためにMat
の初期化を外部に移動できます。