Commit 8393fd0c authored by Alexander Smorkalov's avatar Alexander Smorkalov Committed by Andrey Kamaev

Auto focus added;

Old Android support added;
Android 4.1.x fixes added;
Thead sync added;
Camera errors handling added.
parent f8bcff8f
...@@ -27,94 +27,94 @@ import org.opencv.imgproc.Imgproc; ...@@ -27,94 +27,94 @@ import org.opencv.imgproc.Imgproc;
*/ */
public class OpenCvJavaCameraView extends OpenCvCameraBridgeViewBase implements PreviewCallback { public class OpenCvJavaCameraView extends OpenCvCameraBridgeViewBase implements PreviewCallback {
private static final int MAGIC_TEXTURE_ID = 10; private static final int MAGIC_TEXTURE_ID = 10;
private static final String TAG = "OpenCvJavaCameraView"; private static final String TAG = "OpenCvJavaCameraView";
private Mat mBaseMat; private Mat mBaseMat;
public static class JavaCameraSizeAccessor implements ListItemAccessor { public static class JavaCameraSizeAccessor implements ListItemAccessor {
@Override @Override
public int getWidth(Object obj) { public int getWidth(Object obj) {
Camera.Size size = (Camera.Size) obj; Camera.Size size = (Camera.Size) obj;
return size.width; return size.width;
} }
@Override
public int getHeight(Object obj) {
Camera.Size size = (Camera.Size) obj;
return size.height;
}
@Override
public int getHeight(Object obj) {
Camera.Size size = (Camera.Size) obj;
return size.height;
} }
}
private Camera mCamera; private Camera mCamera;
public OpenCvJavaCameraView(Context context, AttributeSet attrs) { public OpenCvJavaCameraView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
} }
@Override @Override
protected void connectCamera(int width, int height) { protected void connectCamera(int width, int height) {
mCamera = Camera.open(0); mCamera = Camera.open(0);
List<android.hardware.Camera.Size> sizes = mCamera.getParameters().getSupportedPreviewSizes(); List<android.hardware.Camera.Size> sizes = mCamera.getParameters().getSupportedPreviewSizes();
/* Select the size that fits surface considering maximum size allowed */ /* Select the size that fits surface considering maximum size allowed */
FrameSize frameSize = calculateCameraFrameSize(sizes, new JavaCameraSizeAccessor(), width, height); FrameSize frameSize = calculateCameraFrameSize(sizes, new JavaCameraSizeAccessor(), width, height);
/* Now set camera parameters */ /* Now set camera parameters */
try { try {
Camera.Parameters params = mCamera.getParameters(); Camera.Parameters params = mCamera.getParameters();
List<Integer> formats = params.getSupportedPictureFormats(); List<Integer> formats = params.getSupportedPictureFormats();
params.setPreviewFormat(ImageFormat.NV21); params.setPreviewFormat(ImageFormat.NV21);
params.setPreviewSize(frameSize.width, frameSize.height); params.setPreviewSize(frameSize.width, frameSize.height);
mCamera.setPreviewCallback(this); mCamera.setPreviewCallback(this);
mCamera.setParameters(params); mCamera.setParameters(params);
//mCamera.setPreviewTexture(new SurfaceTexture(MAGIC_TEXTURE_ID)); //mCamera.setPreviewTexture(new SurfaceTexture(MAGIC_TEXTURE_ID));
SurfaceTexture tex = new SurfaceTexture(MAGIC_TEXTURE_ID); SurfaceTexture tex = new SurfaceTexture(MAGIC_TEXTURE_ID);
mCamera.setPreviewTexture(tex); mCamera.setPreviewTexture(tex);
mFrameWidth = frameSize.width; mFrameWidth = frameSize.width;
mFrameHeight = frameSize.height; mFrameHeight = frameSize.height;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
mBaseMat = new Mat(mFrameHeight + (mFrameHeight/2), mFrameWidth, CvType.CV_8UC1); mBaseMat = new Mat(mFrameHeight + (mFrameHeight/2), mFrameWidth, CvType.CV_8UC1);
/* Finally we are ready to start the preview */ /* Finally we are ready to start the preview */
mCamera.startPreview(); mCamera.startPreview();
} }
@Override @Override
protected void disconnectCamera() { protected void disconnectCamera() {
mCamera.setPreviewCallback(null); mCamera.setPreviewCallback(null);
mCamera.stopPreview(); mCamera.stopPreview();
mCamera.release(); mCamera.release();
} }
@Override @Override
public void onPreviewFrame(byte[] frame, Camera arg1) { public void onPreviewFrame(byte[] frame, Camera arg1) {
Log.i(TAG, "Preview Frame received. Need to create MAT and deliver it to clients"); Log.i(TAG, "Preview Frame received. Need to create MAT and deliver it to clients");
Log.i(TAG, "Frame size is " + frame.length); Log.i(TAG, "Frame size is " + frame.length);
mBaseMat.put(0, 0, frame); mBaseMat.put(0, 0, frame);
Mat frameMat = new Mat(); Mat frameMat = new Mat();
Imgproc.cvtColor(mBaseMat, frameMat, Imgproc.COLOR_YUV2RGBA_NV21, 4); Imgproc.cvtColor(mBaseMat, frameMat, Imgproc.COLOR_YUV2RGBA_NV21, 4);
deliverAndDrawFrame(frameMat); deliverAndDrawFrame(frameMat);
frameMat.release(); frameMat.release();
} }
} }
...@@ -19,68 +19,68 @@ import android.util.Log; ...@@ -19,68 +19,68 @@ import android.util.Log;
*/ */
public class OpenCvNativeCameraView extends OpenCvCameraBridgeViewBase { public class OpenCvNativeCameraView extends OpenCvCameraBridgeViewBase {
public static final String TAG = "OpenCvNativeCameraView"; public static final String TAG = "OpenCvNativeCameraView";
private boolean mStopThread; private boolean mStopThread;
private Thread mThread; private Thread mThread;
private VideoCapture mCamera; private VideoCapture mCamera;
public OpenCvNativeCameraView(Context context, AttributeSet attrs) { public OpenCvNativeCameraView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
}
@Override
protected void connectCamera(int width, int height) {
/* 1. We need to instantiate camera
* 2. We need to start thread which will be getting frames
*/
/* First step - initialize camera connection */
initializeCamera(getWidth(), getHeight());
/* now we can start update thread */
mThread = new Thread(new CameraWorker(getWidth(), getHeight()));
mThread.start();
}
@Override
protected void disconnectCamera() {
/* 1. We need to stop thread which updating the frames
* 2. Stop camera and release it
*/
try {
mStopThread = true;
mThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
mThread = null;
mStopThread = false;
} }
/* Now release camera */
releaseCamera();
@Override }
protected void connectCamera(int width, int height) {
/* 1. We need to instantiate camera public static class OpenCvSizeAccessor implements ListItemAccessor {
* 2. We need to start thread which will be getting frames
*/
/* First step - initialize camera connection */
initializeCamera(getWidth(), getHeight());
/* now we can start update thread */ @Override
mThread = new Thread(new CameraWorker(getWidth(), getHeight())); public int getWidth(Object obj) {
mThread.start(); Size size = (Size)obj;
return (int)size.width;
} }
@Override @Override
protected void disconnectCamera() { public int getHeight(Object obj) {
/* 1. We need to stop thread which updating the frames Size size = (Size)obj;
* 2. Stop camera and release it return (int)size.height;
*/
try {
mStopThread = true;
mThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
mThread = null;
mStopThread = false;
}
/* Now release camera */
releaseCamera();
} }
public static class OpenCvSizeAccessor implements ListItemAccessor { }
@Override
public int getWidth(Object obj) {
Size size = (Size)obj;
return (int)size.width;
}
@Override
public int getHeight(Object obj) {
Size size = (Size)obj;
return (int)size.height;
}
} private void initializeCamera(int width, int height) {
private void initializeCamera(int width, int height) {
mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID); mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID);
//TODO: improve error handling //TODO: improve error handling
...@@ -101,42 +101,42 @@ public class OpenCvNativeCameraView extends OpenCvCameraBridgeViewBase { ...@@ -101,42 +101,42 @@ public class OpenCvNativeCameraView extends OpenCvCameraBridgeViewBase {
mFrameHeight = (int)frameHeight; mFrameHeight = (int)frameHeight;
Log.i(TAG, "Selected camera frame size = (" + mFrameWidth + ", " + mFrameHeight + ")"); Log.i(TAG, "Selected camera frame size = (" + mFrameWidth + ", " + mFrameHeight + ")");
} }
private void releaseCamera() { private void releaseCamera() {
if (mCamera != null) { if (mCamera != null) {
mCamera.release(); mCamera.release();
}
} }
}
private class CameraWorker implements Runnable { private class CameraWorker implements Runnable {
private Mat mRgba = new Mat(); private Mat mRgba = new Mat();
private int mWidth; private int mWidth;
private int mHeight; private int mHeight;
CameraWorker(int w, int h) { CameraWorker(int w, int h) {
mWidth = w; mWidth = w;
mHeight = h; mHeight = h;
} }
@Override @Override
public void run() { public void run() {
Mat modified; Mat modified;
do { do {
if (!mCamera.grab()) { if (!mCamera.grab()) {
Log.e(TAG, "Camera frame grab failed"); Log.e(TAG, "Camera frame grab failed");
break; break;
} }
mCamera.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA); mCamera.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
deliverAndDrawFrame(mRgba); deliverAndDrawFrame(mRgba);
} 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