Commit 3ef588b8 authored by Alexander Smorkalov's avatar Alexander Smorkalov

onCameraFrame callback signature changed. CvCameraFame interface added.

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.
parent f608df96
...@@ -6,7 +6,6 @@ import org.opencv.R; ...@@ -6,7 +6,6 @@ import org.opencv.R;
import org.opencv.android.Utils; import org.opencv.android.Utils;
import org.opencv.core.Mat; import org.opencv.core.Mat;
import org.opencv.core.Size; import org.opencv.core.Size;
import org.opencv.highgui.Highgui;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
...@@ -44,7 +43,6 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac ...@@ -44,7 +43,6 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
protected int mFrameHeight; protected int mFrameHeight;
protected int mMaxHeight; protected int mMaxHeight;
protected int mMaxWidth; protected int mMaxWidth;
protected int mPreviewFormat = Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA;
protected int mCameraIndex = -1; protected int mCameraIndex = -1;
protected boolean mEnabled; protected boolean mEnabled;
protected FpsMeter mFpsMeter = null; protected FpsMeter mFpsMeter = null;
...@@ -91,10 +89,15 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac ...@@ -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. * 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) * 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) { public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
Log.d(TAG, "call surfaceChanged event"); Log.d(TAG, "call surfaceChanged event");
synchronized(mSyncObject) { synchronized(mSyncObject) {
...@@ -183,11 +186,6 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac ...@@ -183,11 +186,6 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
mMaxHeight = maxHeight; mMaxHeight = maxHeight;
} }
public void SetCaptureFormat(int format)
{
mPreviewFormat = format;
}
/** /**
* Called when mSyncObject lock is held * Called when mSyncObject lock is held
*/ */
...@@ -276,13 +274,13 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac ...@@ -276,13 +274,13 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
* then displayed on the screen. * then displayed on the screen.
* @param frame - the current frame to be delivered * @param frame - the current frame to be delivered
*/ */
protected void deliverAndDrawFrame(Mat frame) { protected void deliverAndDrawFrame(CvCameraViewFrame frame) {
Mat modified; Mat modified;
if (mListener != null) { if (mListener != null) {
modified = mListener.onCameraFrame(frame); modified = mListener.onCameraFrame(frame);
} else { } else {
modified = frame; modified = frame.rgba();
} }
boolean bmpValid = true; boolean bmpValid = true;
......
...@@ -16,7 +16,6 @@ import android.view.SurfaceHolder; ...@@ -16,7 +16,6 @@ import android.view.SurfaceHolder;
import org.opencv.core.CvType; import org.opencv.core.CvType;
import org.opencv.core.Mat; import org.opencv.core.Mat;
import org.opencv.core.Size; import org.opencv.core.Size;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc; import org.opencv.imgproc.Imgproc;
/** /**
...@@ -33,7 +32,6 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb ...@@ -33,7 +32,6 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
private static final int MAGIC_TEXTURE_ID = 10; private static final int MAGIC_TEXTURE_ID = 10;
private static final String TAG = "JavaCameraView"; private static final String TAG = "JavaCameraView";
private Mat mBaseMat;
private byte mBuffer[]; private byte mBuffer[];
private Mat[] mFrameChain; private Mat[] mFrameChain;
private int mChainIdx = 0; private int mChainIdx = 0;
...@@ -41,7 +39,7 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb ...@@ -41,7 +39,7 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
private boolean mStopThread; private boolean mStopThread;
protected Camera mCamera; protected Camera mCamera;
protected JavaCameraFrame mCameraFrame;
private SurfaceTexture mSurfaceTexture; private SurfaceTexture mSurfaceTexture;
public static class JavaCameraSizeAccessor implements ListItemAccessor { public static class JavaCameraSizeAccessor implements ListItemAccessor {
...@@ -146,14 +144,14 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb ...@@ -146,14 +144,14 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
mCamera.addCallbackBuffer(mBuffer); mCamera.addCallbackBuffer(mBuffer);
mCamera.setPreviewCallbackWithBuffer(this); mCamera.setPreviewCallbackWithBuffer(this);
mBaseMat = new Mat(mFrameHeight + (mFrameHeight/2), mFrameWidth, CvType.CV_8UC1);
mFrameChain = new Mat[2]; mFrameChain = new Mat[2];
mFrameChain[0] = new Mat(); mFrameChain[0] = new Mat(mFrameHeight + (mFrameHeight/2), mFrameWidth, CvType.CV_8UC1);
mFrameChain[1] = new Mat(); mFrameChain[1] = new Mat(mFrameHeight + (mFrameHeight/2), mFrameWidth, CvType.CV_8UC1);
AllocateCache(); AllocateCache();
mCameraFrame = new JavaCameraFrame(mFrameChain[mChainIdx], mFrameWidth, mFrameHeight);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mSurfaceTexture = new SurfaceTexture(MAGIC_TEXTURE_ID); mSurfaceTexture = new SurfaceTexture(MAGIC_TEXTURE_ID);
getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
...@@ -183,12 +181,12 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb ...@@ -183,12 +181,12 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
mCamera.release(); mCamera.release();
} }
mCamera = null; mCamera = null;
if (mBaseMat != null)
mBaseMat.release();
if (mFrameChain != null) { if (mFrameChain != null) {
mFrameChain[0].release(); mFrameChain[0].release();
mFrameChain[1].release(); mFrameChain[1].release();
} }
if (mCameraFrame != null)
mCameraFrame.release();
} }
} }
...@@ -242,13 +240,45 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb ...@@ -242,13 +240,45 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
Log.i(TAG, "Frame size is " + frame.length); Log.i(TAG, "Frame size is " + frame.length);
synchronized (this) synchronized (this)
{ {
mBaseMat.put(0, 0, frame); mFrameChain[1 - mChainIdx].put(0, 0, frame);
this.notify(); this.notify();
} }
if (mCamera != null) if (mCamera != null)
mCamera.addCallbackBuffer(mBuffer); 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 { private class CameraWorker implements Runnable {
public void run() { public void run() {
...@@ -263,18 +293,8 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb ...@@ -263,18 +293,8 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
} }
if (!mStopThread) { 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()) if (!mFrameChain[mChainIdx].empty())
deliverAndDrawFrame(mFrameChain[mChainIdx]); deliverAndDrawFrame(mCameraFrame);
mChainIdx = 1 - mChainIdx; mChainIdx = 1 - mChainIdx;
} }
} while (!mStopThread); } while (!mStopThread);
......
...@@ -125,6 +125,31 @@ public class NativeCameraView extends CameraBridgeViewBase { ...@@ -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 class CameraWorker implements Runnable {
private Mat mRgba = new Mat(); private Mat mRgba = new Mat();
...@@ -137,22 +162,9 @@ public class NativeCameraView extends CameraBridgeViewBase { ...@@ -137,22 +162,9 @@ public class NativeCameraView extends CameraBridgeViewBase {
break; break;
} }
switch (mPreviewFormat) { deliverAndDrawFrame(new NativeCameraFrame(mCamera));
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!");
}
} while (!mStopThread); } while (!mStopThread);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment