OpenCV Mat становится пустым в Android HandlerThread - PullRequest
0 голосов
/ 26 апреля 2019

Я пытаюсь обработать изображения с задней камеры смартфона с помощью OpenCV. Необработанные изображения должны быть показаны в JavaCamera2View, обработанные должны быть показаны в отдельном ImageView. Поэтому я беру каждый кадр внутри функции обратного вызова onCameraFrame для CvCameraViewListener2.

//CameraFragment.kt
private var listener = object : CvCameraViewListener2 {

    override fun onCameraViewStarted(width: Int, height: Int) {
        mRgba = Mat(height, width, CvType.CV_8UC4)
    }

    override fun onCameraViewStopped() {
        mRgba.release()
    }

    override fun onCameraFrame(inputFrame: CameraBridgeViewBase.CvCameraViewFrame): Mat {
        mRgba = inputFrame.rgba()

        processor.processMat(mRgba)
        return mRgba
    }

}

Без «processor.processMat (mRgba)» предварительный просмотр показывается со скоростью около 20 кадров в секунду. Как только я пытаюсь обработать изображения, мое приложение вылетает, сообщая мне Msgstr "NullPointerException: попытка чтения из нулевого массива". Я обнаружил, что каким-то образом мой Mat получает недействительный статус, как только я покидаю Главный поток.

// Processor.kt
class Processor : HandlerThread(TAG, THREAD_PRIORITY_BACKGROUND) {

init{
    start()
}

private lateinit var handler: Handler

override fun onLooperPrepared() {
    super.onLooperPrepared()

    handler = Handler(looper)
}

fun processMat(originalImage: Mat) {
    //originalImage still above has correct size & data addr
    handler.post {
    // as soon as i try to use it in here
    // size is 0*0 and data addr is 0x0 
    }
}

companion object {
    val TAG: String = ProcessingPipeline::class.java.simpleName
}

}

Уже пытался отправить Мэту обработчику сообщения, но оказался в том же беспорядке.

Кто-нибудь знает решение? Спасибо

1 Ответ

0 голосов
/ 26 апреля 2019

Проблема в вашем коде в том, что вы пытаетесь использовать один и тот же объект фрейма mRgba для обоих конвейеров рендеринга. Как только вы возвращаете mRgba из функции onFrame, она обрабатывается и память освобождается, чтобы она могла содержать новый входящий кадр. Поэтому вам необходимо клонировать фрейм, прежде чем передать его потоку вашего процессора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...