У меня есть функция сопрограммы Kotlin InitializeCameraFrameCallback( ), который создает поток обратного вызова, испускающий объекты ByteBuffer при каждом получении кадра камеры.
Код: Выделить всё
CoroutineScope(Dispatchers.IO).launch {
initializeCameraFrameCallback(camera).buffer(2, BufferOverflow.DROP_OLDEST)
.collect {
if (SettingsScreen.ImageClassificationButton.isON) {
initiateImageClassificationProcess(it)
}
}
}
Код: Выделить всё
private fun initializeCameraFrameCallback(camera: UVCCamera): Flow = callbackFlow {
try {
camera.setFrameCallback(
{ frame ->
//Sending each frame to a usbVideoSourceListener to display the live feed on a View.
usbVideoSourceListener?.onNewFrame(
VideoSourceListener.FrameHolder.ByteBufferHolder(frame),
ImageFormat.RGBA,
CAMERA_FRAME_SIZE
)
//trySending a frame to our collector.
trySend(frame)
},
UVCCamera.PIXEL_FORMAT_RGBX
)
} catch (e:Exception) {}
awaitClose { channel.close() }
}
Код: Выделить всё
private fun convertByteBufferToImage(frameBuffer: ByteBuffer): Bitmap {
var frameBitmap = Bitmap.createBitmap(1024, 576, Bitmap.Config.ARGB_8888)
frameBuffer?.rewind()
frameBitmap.copyPixelsFromBuffer(frameBuffer)
........... Passes the frameBitmap to a tensorflow lite model.
}
Код: Выделить всё
crash_dump64 A #09 pc 000000000000dea8 /data/data/com.home.myapp/code_cache/.overlay/base.apk/classes5.dex (com.home.myapp.ImageClassification.convertByteBufferToImage+0)
crash_dump64 A #14 pc 000000000000df34 /data/data/com.home.myapp/code_cache/.overlay/base.apk/classes5.dex (com.home.myapp.ImageClassification.getFloodPredictions+0)
crash_dump64 A #19 pc 000000000000bbc8 /data/data/com.home.myapp/code_cache/.overlay/base.apk/classes5.dex (com.home.myapp.MainActivity.initiateImageClassificationProcess+0)
crash_dump64 A #24 pc 000000000000aed8 /data/data/com.home.myapp/code_cache/.overlay/base.apk/classes5.dex (com.home.myapp.MainActivity.access$initiateImageClassificationProcess+0)
crash_dump64 A #29 pc 0000000000009d64 /data/data/com.home.myapp/code_cache/.overlay/base.apk/classes5.dex (com.home.myapp.MainActivity$initiateFrameCallback$1$invokeSuspend$$inlined$collect$1.emit+0)
crash_dump64 A #34 pc 000000000176e6c0 /data/app/~~oHGntbsyp2gKiSlnNgiXjg==/com.home.myapp-n5oxScVgaYw3agwVG_eADg==/oat/arm64/base.vdex (kotlinx.coroutines.flow.FlowKt__ChannelsKt.emitAllImpl$FlowKt__ChannelsKt+0)
crash_dump64 A #39 pc 000000000176e674 /data/app/~~oHGntbsyp2gKiSlnNgiXjg==/com.home.myapp-n5oxScVgaYw3agwVG_eADg==/oat/arm64/base.vdex (kotlinx.coroutines.flow.FlowKt__ChannelsKt.access$emitAllImpl$FlowKt__ChannelsKt+0)
crash_dump64 A #44 pc 000000000176e624 /data/app/~~oHGntbsyp2gKiSlnNgiXjg==/com.home.myapp-n5oxScVgaYw3agwVG_eADg==/oat/arm64/base.vdex (kotlinx.coroutines.flow.FlowKt__ChannelsKt$emitAllImpl$1.invokeSuspend+0)
crash_dump64 A #54 pc 000000000178d7a0 /data/app/~~oHGntbsyp2gKiSlnNgiXjg==/com.home.myapp-n5oxScVgaYw3agwVG_eADg==/oat/arm64/base.vdex (kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely+0)
crash_dump64 A #59 pc 000000000178c484 /data/app/~~oHGntbsyp2gKiSlnNgiXjg==/com.home.myapp-n5oxScVgaYw3agwVG_eADg==/oat/arm64/base.vdex (kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask+0)
crash_dump64 A #64 pc 000000000178c59c /data/app/~~oHGntbsyp2gKiSlnNgiXjg==/com.home.myapp-n5oxScVgaYw3agwVG_eADg==/oat/arm64/base.vdex (kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker+0)
crash_dump64 A #69 pc 000000000178c584 /data/app/~~oHGntbsyp2gKiSlnNgiXjg==/com.home.myapp-n5oxScVgaYw3agwVG_eADg==/oat/arm64/base.vdex (kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run+0)
Другой метод, который я пробовал, - это брать 1 из 5 кадров из setFrameCallback(), т.е. сохраняя подсчет кадров, и когдаframeCount%5==0, отправьте кадр в метод инициализацииImageClassificationProcess().
При использовании этого метода сбоев не наблюдается.
Примечание: Функция setFrameCallback() создает около 10–12 кадров в секунду.
Подробнее здесь: https://stackoverflow.com/questions/784 ... faultdispa