onCameraFrame callback signature changed. CvCameraFame interface added.
authorAlexander Smorkalov <alexander.smorkalov@itseez.com>
Thu, 31 Jan 2013 12:13:12 +0000 (16:13 +0400)
committerAlexander Smorkalov <alexander.smorkalov@itseez.com>
Mon, 4 Feb 2013 13:43:45 +0000 (17:43 +0400)
New interface allows to get one RGBA or Gray frame from camera or both in the same time;
New interface fixes data rase in samples also.

modules/java/generator/src/java/android+CameraBridgeViewBase.java
modules/java/generator/src/java/android+JavaCameraView.java
modules/java/generator/src/java/android+NativeCameraView.java

index 06288c9..44b97e7 100644 (file)
@@ -6,7 +6,6 @@ import org.opencv.R;
 import org.opencv.android.Utils;
 import org.opencv.core.Mat;
 import org.opencv.core.Size;
-import org.opencv.highgui.Highgui;
 
 import android.app.Activity;
 import android.app.AlertDialog;
@@ -44,7 +43,6 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
     protected int mFrameHeight;
     protected int mMaxHeight;
     protected int mMaxWidth;
-    protected int mPreviewFormat = Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA;
     protected int mCameraIndex = -1;
     protected boolean mEnabled;
     protected FpsMeter mFpsMeter = null;
@@ -91,10 +89,15 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
          * The returned values - is a modified frame which needs to be displayed on the screen.
          * TODO: pass the parameters specifying the format of the frame (BPP, YUV or RGB and etc)
          */
-        public Mat onCameraFrame(Mat inputFrame);
+        public Mat onCameraFrame(CvCameraViewFrame inputFrame);
 
     }
 
+    public interface CvCameraViewFrame {
+        public abstract Mat rgba();
+        public abstract Mat gray();
+    };
+
     public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
         Log.d(TAG, "call surfaceChanged event");
         synchronized(mSyncObject) {
@@ -183,11 +186,6 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
         mMaxHeight = maxHeight;
     }
 
-    public void SetCaptureFormat(int format)
-    {
-        mPreviewFormat = format;
-    }
-
     /**
      * Called when mSyncObject lock is held
      */
@@ -276,13 +274,13 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
      * then displayed on the screen.
      * @param frame - the current frame to be delivered
      */
-    protected void deliverAndDrawFrame(Mat frame) {
+    protected void deliverAndDrawFrame(CvCameraViewFrame frame) {
         Mat modified;
 
         if (mListener != null) {
             modified = mListener.onCameraFrame(frame);
         } else {
-            modified = frame;
+            modified = frame.rgba();
         }
 
         boolean bmpValid = true;
index c3d8f56..508a650 100644 (file)
@@ -16,7 +16,6 @@ import android.view.SurfaceHolder;
 import org.opencv.core.CvType;
 import org.opencv.core.Mat;
 import org.opencv.core.Size;
-import org.opencv.highgui.Highgui;
 import org.opencv.imgproc.Imgproc;
 
 /**
@@ -33,7 +32,6 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
     private static final int MAGIC_TEXTURE_ID = 10;
     private static final String TAG = "JavaCameraView";
 
-    private Mat mBaseMat;
     private byte mBuffer[];
     private Mat[] mFrameChain;
     private int mChainIdx = 0;
@@ -41,7 +39,7 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
     private boolean mStopThread;
 
     protected Camera mCamera;
-
+    protected JavaCameraFrame mCameraFrame;
     private SurfaceTexture mSurfaceTexture;
 
     public static class JavaCameraSizeAccessor implements ListItemAccessor {
@@ -146,14 +144,14 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
                     mCamera.addCallbackBuffer(mBuffer);
                     mCamera.setPreviewCallbackWithBuffer(this);
 
-                    mBaseMat = new Mat(mFrameHeight + (mFrameHeight/2), mFrameWidth, CvType.CV_8UC1);
-
                     mFrameChain = new Mat[2];
-                    mFrameChain[0] = new Mat();
-                    mFrameChain[1] = new Mat();
+                    mFrameChain[0] = new Mat(mFrameHeight + (mFrameHeight/2), mFrameWidth, CvType.CV_8UC1);
+                    mFrameChain[1] = new Mat(mFrameHeight + (mFrameHeight/2), mFrameWidth, CvType.CV_8UC1);
 
                     AllocateCache();
 
+                    mCameraFrame = new JavaCameraFrame(mFrameChain[mChainIdx], mFrameWidth, mFrameHeight);
+
                     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                         mSurfaceTexture = new SurfaceTexture(MAGIC_TEXTURE_ID);
                         getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
@@ -183,12 +181,12 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
                 mCamera.release();
             }
             mCamera = null;
-            if (mBaseMat != null)
-                mBaseMat.release();
             if (mFrameChain != null) {
                 mFrameChain[0].release();
                 mFrameChain[1].release();
             }
+            if (mCameraFrame != null)
+                mCameraFrame.release();
         }
     }
 
@@ -242,13 +240,45 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
         Log.i(TAG, "Frame size  is " + frame.length);
         synchronized (this)
         {
-            mBaseMat.put(0, 0, frame);
+            mFrameChain[1 - mChainIdx].put(0, 0, frame);
             this.notify();
         }
         if (mCamera != null)
             mCamera.addCallbackBuffer(mBuffer);
     }
 
+    private class JavaCameraFrame implements CvCameraViewFrame
+    {
+        public Mat gray() {
+            return mYuvFrameData.submat(0, mHeight, 0, mWidth);
+        }
+
+        public Mat rgba() {
+            Imgproc.cvtColor(mYuvFrameData, mRgba, Imgproc.COLOR_YUV2BGR_NV12, 4);
+            return mRgba;
+        }
+
+        public JavaCameraFrame(Mat Yuv420sp, int width, int height) {
+            super();
+            mWidth = width;
+            mHeight = height;
+            mYuvFrameData = Yuv420sp;
+            mRgba = new Mat(mHeight, mWidth, CvType.CV_8UC4);
+        }
+
+        public void release() {
+            mRgba.release();
+        }
+
+        private JavaCameraFrame(CvCameraViewFrame obj) {
+        }
+
+        private Mat mYuvFrameData;
+        private Mat mRgba;
+        private int mWidth;
+        private int mHeight;
+    };
+
     private class CameraWorker implements Runnable {
 
         public void run() {
@@ -263,18 +293,8 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
                 }
 
                 if (!mStopThread) {
-                    switch (mPreviewFormat) {
-                        case Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA:
-                            Imgproc.cvtColor(mBaseMat, mFrameChain[mChainIdx], Imgproc.COLOR_YUV2RGBA_NV21, 4);
-                        break;
-                        case Highgui.CV_CAP_ANDROID_GREY_FRAME:
-                            mFrameChain[mChainIdx] = mBaseMat.submat(0, mFrameHeight, 0, mFrameWidth);
-                        break;
-                        default:
-                            Log.e(TAG, "Invalid frame format! Only RGBA and Gray Scale are supported!");
-                    };
                     if (!mFrameChain[mChainIdx].empty())
-                        deliverAndDrawFrame(mFrameChain[mChainIdx]);
+                        deliverAndDrawFrame(mCameraFrame);
                     mChainIdx = 1 - mChainIdx;
                 }
             } while (!mStopThread);
index dad3cb9..7e55d9b 100644 (file)
@@ -125,6 +125,31 @@ public class NativeCameraView extends CameraBridgeViewBase {
         }
     }
 
+    private class NativeCameraFrame implements CvCameraViewFrame {
+
+        @Override
+        public Mat rgba() {
+            mCamera.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
+            return mRgba;
+        }
+
+        @Override
+        public Mat gray() {
+            mCamera.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME);
+            return mGray;
+        }
+
+        public NativeCameraFrame(VideoCapture capture) {
+            mCapture = capture;
+            mGray = new Mat();
+            mRgba = new Mat();
+        }
+
+        private VideoCapture mCapture;
+        private Mat mRgba;
+        private Mat mGray;
+    };
+
     private class CameraWorker implements Runnable {
 
         private Mat mRgba = new Mat();
@@ -137,22 +162,9 @@ public class NativeCameraView extends CameraBridgeViewBase {
                     break;
                 }
 
-                switch (mPreviewFormat) {
-                    case Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA:
-                    {
-                        mCamera.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
-                        deliverAndDrawFrame(mRgba);
-                    } break;
-                    case Highgui.CV_CAP_ANDROID_GREY_FRAME:
-                        mCamera.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME);
-                        deliverAndDrawFrame(mGray);
-                        break;
-                    default:
-                        Log.e(TAG, "Invalid frame format! Only RGBA and Gray Scale are supported!");
-                }
+                deliverAndDrawFrame(new NativeCameraFrame(mCamera));
 
             } while (!mStopThread);
-
         }
     }