0

I'm new to Renderscript and my app crashes every time at this line:

inAllocation.copyFromUnchecked(copyOfRange(nv21ByteArray, 0, size-1));

What I want to do is to convert the YUV-image that I get from the camera (nv21ByteArray), to a black and white image (So I just need the Y-values). This is the java code:

package org.rwca.anthe.robocup15;

import android.support.v8.renderscript.Allocation;
import android.support.v8.renderscript.Element;
import android.support.v8.renderscript.RenderScript;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v8.renderscript.Type;
import android.widget.ImageView;
import android.widget.Toast;

import org.jetbrains.annotations.NotNull;

import io.fotoapparat.Fotoapparat;
import io.fotoapparat.error.CameraErrorListener;
import io.fotoapparat.exception.camera.CameraException;
import io.fotoapparat.parameter.ScaleType;
import io.fotoapparat.preview.Frame;
import io.fotoapparat.preview.FrameProcessor;
import io.fotoapparat.view.CameraView;

import static io.fotoapparat.log.LoggersKt.fileLogger;
import static io.fotoapparat.log.LoggersKt.logcat;
import static io.fotoapparat.log.LoggersKt.loggers;
import static io.fotoapparat.selector.LensPositionSelectorsKt.back;
import static java.util.Arrays.copyOfRange;

public class MainActivity extends AppCompatActivity {

    private CameraView cameraView;
    private ImageView imageView;
    private Fotoapparat fotoapparat;

    public byte[] nv21ByteArray;
    public int size = 960 * 1280;
    public int thresholdValue;

    public RenderScript rs;
    public Allocation inAllocation, outAllocation;
    public ScriptC_imageProc mScript;

    @NonNull
    private Fotoapparat createFotoapparat() {
        return Fotoapparat
                .with(this)
                .into(cameraView)
                .previewScaleType(ScaleType.CenterCrop)
                .lensPosition(back())
                .frameProcessor(new SampleFrameProcessor())
                .logger(loggers(
                        logcat(),
                        fileLogger(this)
                ))
                .cameraErrorCallback(new CameraErrorListener() {
                    @Override
                    public void onError(CameraException e) {
                        Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();;
                    }
                })
                .build();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        cameraView = findViewById(R.id.cameraView);
        imageView = findViewById(R.id.imageView);
        fotoapparat = createFotoapparat();

        rs = RenderScript.create(this);
        mScript = new ScriptC_imageProc(rs);
        Type t = Type.createX(rs, Element.U8(rs), size);
        inAllocation = Allocation.createSized(rs, Element.U8(rs), size);
        outAllocation = Allocation.createTyped(rs, t);
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onStart() {
        super.onStart();
        fotoapparat.start();
    }

    @Override
    protected void onStop() {
        super.onStop();
        fotoapparat.stop();
    }

    private class SampleFrameProcessor implements FrameProcessor {
        @Override
        public void process(@NotNull Frame frame) {

            nv21ByteArray = frame.getImage();

            inAllocation.copyFromUnchecked(copyOfRange(nv21ByteArray, 0, size-1));

            mScript.set_thresholdValue(thresholdValue);
            mScript.forEach_root(inAllocation, outAllocation);



            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                }
            });
        }
    }
}

And this is my renderscript file:

#pragma version(1)
#pragma rs java_package_name(org.rwca.anthe.robocup15)

#include "rs_core.rsh"
#include "rs_time.rsh"

int thresholdValue;

uchar __attribute__((kernel)) root(uchar in, uint32_t x) {
    //rsDebug("Called root", rsUptimeMillis());
}

What am I doing wrong?

Thank you in advance, Anton

Anton
  • 137
  • 2
  • 14
  • Why you used `uchar` as first parameter in root method, but passed `Allocation` to it ? – Corey Dec 27 '18 at 05:19
  • Another question, what does `frame.getImage()` do ? – Corey Dec 27 '18 at 05:25
  • First question: because I thought it works like that, but maybe I didn’t understand something? What should it be then if I want to pass a 1 dimensional byte array? Second question: it returns a byte array of the image in YUV NV21 format, so the first 960*1280 elements are the Y-values of the image (with elements 1-960 being the first row, elements 961-1920 being the 2nd row, ...). What I want is making it a bitmap and applying a threshold to it. – Anton Dec 27 '18 at 10:07
  • What's the error message when app crashes at this line `inAllocation.copyFromUnchecked(copyOfRange(nv21ByteArray, 0, size-1));` ? – Corey Dec 28 '18 at 01:01

0 Answers0