Как включить tflite-yolov4 в приложение для Android? (Kotlin)
Спасибо, что посмотрели этот пост. Я новичок в разработке для Android. Если какая-либо информация отсутствует для проверки, пожалуйста, сообщите мне.
Я пытаюсь включить yolov4.tflite в свое приложение.
Для подтверждения результатов обнаружения я создаю класс AnalyzeActivity. В классе AnalyzeActivity я написал код для запуска Viedeo в VieoView и отображения изображения результата обнаружения под ним.
Когда я запускал код, отображалась следующая информация, и ничего не было обнаружено.
Я/Хореограф: Пропущено 30 кадров! Приложение может выполнять слишком много работы в своем основном потоке.
W/Parcel: Ожидание переплета, но его нет!
У меня есть два вопроса.
- Я неправильно делю потоки? Как мне уменьшить работу в основном потоке?
- У меня неправильный способ использования модели YoloV4?
Ниже приведен код и структура репозитория.
【код】
class AnalyzeActivity : AppCompatActivity() {
companion object{
const val TAG:String = "AnalyzeActivity"
}
private var pointsArray = mutableListOf<Point>()
private var frameArray = mutableMapOf<Int,MutableList<Point>>()
//Yolov4用パラメータ
//viewModel作成
private val viewModel by viewModels<YoloV4MainViewModel>{getViewModelFactory()}
//binding作成
private lateinit var binding: ActivityAnalyzeBinding
@RequiresApi(Build.VERSION_CODES.P)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityAnalyzeBinding.inflate(layoutInflater)
setContentView(binding.root)
OpenCVLoader.initDebug()
//Views
val intent = getIntent()
val videoName = intent.getStringExtra("videoName")
val videoView = findViewById<VideoView>(R.id.videoView)
val imgView = findViewById<ImageView>(R.id.imageView)
val context = applicationContext
//set Video to videoView
val fileDir = context.getExternalFilesDir(null)
val uri = Uri.parse(fileDir.toString() + "/$videoName")
videoView.setVideoURI(uri)
videoView.start();
val retriever = MediaMetadataRetriever()
// var bitmap = MediaMetadataRetriever.BitmapParams()
retriever.setDataSource(context, uri)
//Yolov4
val sourceBitmap = assets.open("kite.jpg").use{
inputStream->
BitmapFactory.decodeStream(inputStream)
}
viewModel.setUpBitmaps(assets)
imgView.setImageBitmap(sourceBitmap)
try{
viewModel.setUpDetector(assets)
Log.d(TAG,"YoloV4 Detector Set Up Done")
}catch(e: IOException){
Log.e(YoloV4MainActivity.TAG,"Exception initializing detector!")
Log.e(YoloV4MainActivity.TAG,e.stackTraceToString())
Toast.makeText(
baseContext,"Detector could not be initialized", Toast.LENGTH_LONG
).show()
finish()
}
viewModel.setUpDetectionProcessor(
imgView,
findViewById(R.id.tracking_overlay),
resources.displayMetrics
)
thread{
viewModel.processImage()
}
}
【структура репо】
1 ответ
Если ваш основной поток выполняет слишком много задач, вы можете использовать потоки для выполнения операций. Либо используйте сопрограммы, либо класс Executor. реализация класса исполнителя ниже:
public static void getAllDataPagination(final Context context, final ImageDataControllerCallback imageDataControllerCallback) {
final ExecutorService executor = Executors.newSingleThreadExecutor();
final Handler handler = new Handler(Looper.getMainLooper());
executor.execute(new Runnable() {
@Override
public void run() {
final List<FolderDataDisplay> imageDataList = DatabaseClient.getInstance(context).getAppDatabase().imageDataDao().getAllDataPagination(from, to);
handler.post(new Runnable() {
@Override
public void run() {
if (imageDataControllerCallback != null) {
imageDataControllerCallback.onImageDataPaginatedFetched(imageDataList);
}
/*executor.shutdown();
System.runFinalization();*/
}
});
}
});
}
Интерфейс будет выглядеть примерно так:
public interface ImageDataControllerCallback {
void onImageDataFetched(List<ImageData> data);
}