Re: [OpenCV4Android] get problem when using Mat() constructor

3,299 views
Skip to first unread message

Nafi Ur Rashid

unread,
Jul 11, 2012, 2:31:18 AM7/11/12
to android...@googlegroups.com
Where are you running the .apk? If you are running in the emulator, try to change

APP_ABI := armeabi-v7a

line in Application.mk to 

APP_ABI := armeabi

Amidofu Lue

unread,
Jul 11, 2012, 4:24:53 PM7/11/12
to android...@googlegroups.com
I run on HTC EVO 3D. I tried what you said and it doesn't work. Thank you.

Nafi於 2012年7月11日星期三UTC+8下午2時31分18秒寫道:

Andrey Pavlenko

unread,
Jul 17, 2012, 4:43:58 AM7/17/12
to android...@googlegroups.com
Did you inspected logcat?

Amidofu Lue

unread,
Jul 17, 2012, 1:42:42 PM7/17/12
to android...@googlegroups.com
yes, it just showed the same error (unstatisfied link error).
Thank you.

Andrey Pavlenko於 2012年7月17日星期二UTC+8下午4時43分58秒寫道:
Did you inspected logcat?

Andrey Pavlenko

unread,
Jul 18, 2012, 11:09:34 AM7/18/12
to android...@googlegroups.com
can you share the logcat quote from the app start?
or maybe you'll share your activity code to check if the OpenCV lib init code is correct...

Amidofu Lue

unread,
Jul 18, 2012, 4:38:30 PM7/18/12
to android...@googlegroups.com

Log:
07-18 13:30:52.610: I/dalvikvm-heap(7746): Grow heap (frag case) to 6.240MB for 614416-byte allocation
07-18 13:30:52.681: W/dalvikvm(7746): No implementation found for native Lorg/opencv/core/Mat;.n_Mat (III)J
07-18 13:30:52.681: W/dalvikvm(7746): threadid=1: thread exiting with uncaught exception (group=0x4001d648)
07-18 13:30:52.681: E/AndroidRuntime(7746): FATAL EXCEPTION: main
07-18 13:30:52.681: E/AndroidRuntime(7746): java.lang.UnsatisfiedLinkError: n_Mat
07-18 13:30:52.681: E/AndroidRuntime(7746):     at org.opencv.core.Mat.n_Mat(Native Method)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at org.opencv.core.Mat.<init>(Mat.java:211)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at amidofu.MyOpenCVTest.MyOpenCVTest.MyPreviewCallback.setupMat(MyPreviewCallback.java:47)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at amidofu.MyOpenCVTest.MyOpenCVTest.MyOpenCVTestActivity.setupCamera(MyOpenCVTestActivity.java:93)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at amidofu.MyOpenCVTest.MyOpenCVTest.MyOpenCVTestActivity.onCreate(MyOpenCVTestActivity.java:44)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1072)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1794)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1851)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at android.app.ActivityThread.access$1500(ActivityThread.java:132)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1038)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at android.os.Looper.loop(Looper.java:150)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at android.app.ActivityThread.main(ActivityThread.java:4293)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at java.lang.reflect.Method.invokeNative(Native Method)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at java.lang.reflect.Method.invoke(Method.java:507)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)
07-18 13:30:52.681: E/AndroidRuntime(7746):     at dalvik.system.NativeStart.main(Native Method)
07-18 13:30:52.761: W/dalvikvm(7746): No implementation found for native Lorg/opencv/core/Mat;.n_delete (J)V
07-18 13:30:52.761: I/dalvikvm(7746): Uncaught exception thrown by finalizer (will be discarded):
07-18 13:30:52.761: I/dalvikvm(7746): Ljava/lang/UnsatisfiedLinkError;: n_delete
07-18 13:30:52.761: I/dalvikvm(7746):     at org.opencv.core.Mat.n_delete(Native Method)
07-18 13:30:52.761: I/dalvikvm(7746):     at org.opencv.core.Mat.finalize(Mat.java:1966)
07-18 13:30:52.761: I/dalvikvm(7746):     at dalvik.system.NativeStart.run(Native Method)
07-18 13:30:55.914: I/Process(7746): Sending signal. PID: 7746 SIG: 9

------------------------------------------------------------------------------------------------------------------------------------------------------
Main Activity:
package amidofu.MyOpenCVTest.MyOpenCVTest;

import java.io.IOException;
import java.util.List;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;


import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MyOpenCVTestActivity extends Activity {
    /** Called when the activity is first created. */
    Camera mCamera;
    SurfaceView CamSurfaceView;
    MyPreviewCallback previewCallback;
    byte [] mBuffer;
    byte [] mFrame;
    SurfaceHolder mHolder;
    boolean setupCamLock;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        CamSurfaceView=(SurfaceView)findViewById(R.id.CamSurfaceView);
       
       

        if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack))
        {
            Log.e("Load OpenCV", "Cannot connect to OpenCV Manager");
        }

        Log.d("On Create", "OpenCV loaded");
        setupCamera();
    }

   
    public void setupCamera()
    {
       
        mCamera=Camera.open();
        synchronized (MyOpenCVTestActivity.this) {

              if (mCamera != null) { 
                  Log.d("setupCamera", "camera opened");
                 Camera.Parameters params = mCamera.getParameters();
                 List<Camera.Size> sizes = params.getSupportedPreviewSizes();
                   
                 int width=0;
                 int height=0;
                   
                 int mFrameWidth = width;
                 int mFrameHeight = height;

                 // selecting optimal camera preview size
                 {
                      int  minDiff = Integer.MAX_VALUE;
                      for (Camera.Size size : sizes) {
                          if (Math.abs(size.height - height) < minDiff) {
                             mFrameWidth = size.width;
                             mFrameHeight = size.height;
                             minDiff = Math.abs(size.height - height);
                          }
                      }
                 }
                   
                 params.setPreviewSize(mFrameWidth, mFrameHeight);
                   
                 List<String> FocusModes = params.getSupportedFocusModes();
                 if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
                 {
                     params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
                 }           
                   
                 mCamera.setParameters(params);
                   
                 previewCallback=new MyPreviewCallback();
                    mCamera.setPreviewCallback(previewCallback);
                 //CamSurfaceView=new SurfaceView(OSGActivity.this);
                    mHolder=CamSurfaceView.getHolder();
                    previewCallback.setSurfaceHolder(mHolder);
                    previewCallback.setupPreviewBitmap(mFrameHeight, mFrameWidth);
                    previewCallback.setupMat();
                 Log.d("setupCamera", "previewCallback Ok");
                 try {
                     mCamera.setPreviewDisplay(mHolder);
                  }catch (IOException e) {
                         // TODO Auto-generated catch block
                         e.printStackTrace();
                  }
                   
                  /* Now allocate the buffer */
                 params = mCamera.getParameters();
                 int size = params.getPreviewSize().width * params.getPreviewSize().height;
                 size  = size * ImageFormat.getBitsPerPixel(params.getPreviewFormat()) / 8;
                 mBuffer = new byte[size];
                 /* The buffer where the current frame will be copied */
                 mFrame = new byte [size];
                 mCamera.addCallbackBuffer(mBuffer);
                 previewCallback.setFrameSize(size);
                  mCamera.startPreview();
                  Log.d("setupCamera", "start preview");
                }
            }
    }
   
   
    private BaseLoaderCallback  mOpenCVCallBack = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS:
                {
                    Log.i("Load OpenCV", "OpenCV loaded successfully");
                } break;
                default:
                {
                    super.onManagerConnected(status);
                } break;
            }
        }
    };
}

------------------------------------------------------------------------------------------------------------
MyPreviewCallback

package amidofu.MyOpenCVTest.MyOpenCVTest;
import nativeFunctions.NativeLib;

import org.opencv.android.Utils;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.util.Log;
import android.view.SurfaceHolder;
public class MyPreviewCallback implements PreviewCallback{

    SurfaceHolder mHolder;
    int mHeight;
    int mWidth;
    Bitmap mBitmap;
    int [] mRGBA;
    int frameSize;
    long time=0;
   
    private Mat mYuv;
    private Mat mRgba;
    private Mat mGraySubmat;
   
   
    public void setSurfaceHolder(SurfaceHolder holder)
    {
        mHolder=holder;
    }
    public void setupPreviewBitmap(int height, int width)
    {
        mHeight=height;
        mWidth=width;
        mBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
        mRGBA = new int[mWidth * mHeight];
    }
    public void setFrameSize(int fs)
    {
        frameSize=fs;
    }
    public void setupMat()
    {
        mYuv = new Mat(mHeight + mHeight / 2, mWidth, CvType.CV_8UC1);
        mGraySubmat = mYuv.submat(0, mHeight, 0, mWidth);

        mRgba = new Mat();
    }
    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        ///////native part
        mYuv.put(0, 0, data);
        Imgproc.cvtColor(mYuv, mRgba, Imgproc.COLOR_YUV420sp2RGB, 4);
        NativeLib.FindFeatures(mGraySubmat.getNativeObjAddr(), mRgba.getNativeObjAddr());
       
       
       

        try {
            Utils.matToBitmap(mRgba, mBitmap);
        } catch(Exception e) {
            Log.e("org.opencv.samples.puzzle15", "Utils.matToBitmap() throws an exception: " + e.getMessage());
            mBitmap.recycle();
            //mBitmap = null;
            mBitmap= Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
        }
       
    }

   
   
}

Thank you.
Andrey Pavlenko於 2012年7月18日星期三UTC-7上午8時09分34秒寫道:

Alexander Smorkalov

unread,
Jul 19, 2012, 1:31:29 AM7/19/12
to android...@googlegroups.com
Hello, Amidofu Lue!

OpenCV Manager like other Android API uses asynchronous event handling model. So, OpenCV library is not ready for use before
onManagerConnected event with LoaderCallbackInterface.SUCCESS status.
You cannot use any OpenCV related staff, even OpenCV dependent object constructors before initialization. First of all you need to move your camera initialization code to OnManagerConnected method. Then you need to move View initialization here, due to View depends on OpenCV too. You must get something like this:


    private BaseLoaderCallback  mOpenCVCallBack = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS:
                {
                    Log.i("Load OpenCV", "OpenCV loaded successfully");
                    setContentView(R.layout.main);
                    amSurfaceView=(SurfaceView)findViewById(R.id.CamSurfaceView);
                    setupCamera();
                } break;
                default:
                {
                    super.onManagerConnected(status);
                } break;
            }
        }
    };


Reply all
Reply to author
Forward
0 new messages