bytedeco/javacv

JavaCV in Kotlin - Memory Allocation/Management?

Open

#1975 aperta il 22 gen 2023

Vedi su GitHub
 (7 commenti) (0 reazioni) (0 assegnatari)Java (1583 fork)batch import
enhancementhelp wanted

Metriche repository

Star
 (6985 star)
Metriche merge PR
 (Nessuna PR mergiata in 30 g)

Descrizione

I'm building an app in Kotlin that heavily depends on image processing through saliency.

My code looks like this:

package com.example.testingsaliency5

import android.graphics.Bitmap
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.graphics.drawable.toBitmap
import com.example.testingsaliency5.databinding.ActivityMainBinding
import org.bytedeco.javacv.AndroidFrameConverter
import org.bytedeco.javacv.OpenCVFrameConverter.ToMat
import org.bytedeco.opencv.opencv_core.Mat
import org.bytedeco.opencv.opencv_saliency.StaticSaliencyFineGrained


class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        binding.imageView.setImageDrawable(this.resources.getDrawable(R.drawable.lancer))
        binding.button.setOnClickListener { binding.imageView.setImageBitmap(saliencyBitmap(binding.imageView.drawable.toBitmap())) }
        setContentView(view)
    }

    fun saliencyBitmap(bitmap : Bitmap) : Bitmap {

        val converterToBitmap = AndroidFrameConverter()
        val converterToMat = ToMat()

        val frame = converterToBitmap.convert(bitmap)
        val saliencyMap = Mat()
        val byteMap = Mat()
        val sal = StaticSaliencyFineGrained()
        sal.computeSaliency(converterToMat.convert(frame), saliencyMap)
        sal.computeBinaryMap(saliencyMap, byteMap)

        return converterToBitmap.convert(converterToMat.convert(byteMap))
    }
}

But when ran, after I press the button, I get this error on line return converterToBitmap.convert(converterToMat.convert(byteMap)):

I/estingsaliency5: Starting a blocking GC Alloc
I/estingsaliency5: Starting a blocking GC Alloc
I/estingsaliency5: Alloc young concurrent copying GC freed 190867(12MB) AllocSpace objects, 0(0B) LOS objects, 86% free, 3863KB/27MB, paused 29us,12us total 22.231ms
I/estingsaliency5: WaitForGcToComplete blocked NativeAlloc on Alloc for 22.376ms
I/estingsaliency5: Forcing collection of SoftReferences for 254MB allocation
I/estingsaliency5: Starting a blocking GC Alloc
I/estingsaliency5: Alloc concurrent copying GC freed 1873(61KB) AllocSpace objects, 0(0B) LOS objects, 86% free, 3817KB/27MB, paused 20us,13us total 9.242ms
W/estingsaliency5: Throwing OutOfMemoryError "Failed to allocate a 266501312 byte allocation with 25165824 free bytes and 252MB until OOM, target footprint 29075352, growth limit 268435456" (VmSize 16893380 kB)
I/estingsaliency5: Starting a blocking GC Alloc
I/estingsaliency5: Starting a blocking GC Alloc
I/estingsaliency5: Forcing collection of SoftReferences for 254MB allocation
I/estingsaliency5: Starting a blocking GC Alloc
I/estingsaliency5: Alloc concurrent copying GC freed 1774(71KB) AllocSpace objects, 0(0B) LOS objects, 86% free, 3746KB/27MB, paused 17us,14us total 8.149ms
W/estingsaliency5: Throwing OutOfMemoryError "Failed to allocate a 266501312 byte allocation with 25165824 free bytes and 252MB until OOM, target footprint 29002392, growth limit 268435456" (VmSize 16893380 kB)
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.testingsaliency5, PID: 4452
    java.lang.OutOfMemoryError: Failed to allocate a 266501312 byte allocation with 25165824 free bytes and 252MB until OOM, target footprint 29002392, growth limit 268435456
        at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:54)
        at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:49)
        at java.nio.ByteBuffer.allocate(ByteBuffer.java:284)
        at org.bytedeco.javacv.AndroidFrameConverter.gray2rgba(AndroidFrameConverter.java:131)
        at org.bytedeco.javacv.AndroidFrameConverter.convert(AndroidFrameConverter.java:201)
        at com.example.testingsaliency5.MainActivity.saliencyBitmap(MainActivity.kt:38)
        at com.example.testingsaliency5.MainActivity.onCreate$lambda$0(MainActivity.kt:22)
        at com.example.testingsaliency5.MainActivity.$r8$lambda$71u2Lpx-hlCZ4uuH3x2VT4aZAZY(Unknown Source:0)
        at com.example.testingsaliency5.MainActivity$$ExternalSyntheticLambda0.onClick(Unknown Source:2)
        at android.view.View.performClick(View.java:7506)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1219)
        at android.view.View.performClickInternal(View.java:7483)
        at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
        at android.view.View$PerformClick.run(View.java:29341)
        at android.os.Handler.handleCallback(Handler.java:942)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7872)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
I/Process: Sending signal. PID: 4452 SIG: 9

The quesiton is, do I need to manage memory in some way, when working with JavaCV on Android?

Guida contributor