OpenCV app framework improved
FPS meter added; Camera switching posibility added; Attributes loading for layout filed implemented.
This commit is contained in:
parent
214629b220
commit
8266eab8b4
5
modules/java/android_lib/res/values/attrs.xml
Normal file
5
modules/java/android_lib/res/values/attrs.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<attr name="show_fps" format="boolean"/>
|
||||||
|
<attr name="camera_index" format="integer"/>
|
||||||
|
</resources>
|
@ -30,6 +30,11 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
|
|||||||
|
|
||||||
private static final int MAX_UNSPECIFIED = -1;
|
private static final int MAX_UNSPECIFIED = -1;
|
||||||
|
|
||||||
|
private static final int STOPPED = 0;
|
||||||
|
private static final int STARTED = 1;
|
||||||
|
|
||||||
|
private static final String TAG = "CameraBridge";
|
||||||
|
|
||||||
protected int mFrameWidth;
|
protected int mFrameWidth;
|
||||||
protected int mFrameHeight;
|
protected int mFrameHeight;
|
||||||
|
|
||||||
@ -37,11 +42,26 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
|
|||||||
protected int mMaxWidth;
|
protected int mMaxWidth;
|
||||||
|
|
||||||
protected int mPreviewFormat = Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA;
|
protected int mPreviewFormat = Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA;
|
||||||
|
protected int mCameraIndex = -1;
|
||||||
|
private boolean mEnabled;
|
||||||
|
|
||||||
private Bitmap mCacheBitmap;
|
private Bitmap mCacheBitmap;
|
||||||
|
protected FpsMeter mFpsMeter = null;
|
||||||
|
|
||||||
|
private CvCameraViewListener mListener;
|
||||||
|
private int mState = STOPPED;
|
||||||
|
|
||||||
|
private boolean mSurfaceExist;
|
||||||
|
|
||||||
|
private Object mSyncObject = new Object();
|
||||||
|
|
||||||
public CameraBridgeViewBase(Context context, AttributeSet attrs) {
|
public CameraBridgeViewBase(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
|
if (attrs.getAttributeBooleanValue(null, "show_fps", false))
|
||||||
|
enableFpsMeter();
|
||||||
|
|
||||||
|
mCameraIndex = attrs.getAttributeIntValue(null,"camera_index", -1);
|
||||||
|
|
||||||
getHolder().addCallback(this);
|
getHolder().addCallback(this);
|
||||||
mMaxWidth = MAX_UNSPECIFIED;
|
mMaxWidth = MAX_UNSPECIFIED;
|
||||||
mMaxHeight = MAX_UNSPECIFIED;
|
mMaxHeight = MAX_UNSPECIFIED;
|
||||||
@ -71,19 +91,6 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int STOPPED = 0;
|
|
||||||
private static final int STARTED = 1;
|
|
||||||
|
|
||||||
private static final String TAG = "CameraBridge";
|
|
||||||
|
|
||||||
private CvCameraViewListener mListener;
|
|
||||||
private int mState = STOPPED;
|
|
||||||
|
|
||||||
private boolean mEnabled;
|
|
||||||
private boolean mSurfaceExist;
|
|
||||||
|
|
||||||
private Object mSyncObject = new Object();
|
|
||||||
|
|
||||||
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) {
|
||||||
@ -135,6 +142,24 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method enables label with fps value on the screen
|
||||||
|
*/
|
||||||
|
public void enableFpsMeter() {
|
||||||
|
if (mFpsMeter == null) {
|
||||||
|
mFpsMeter = new FpsMeter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disableFpsMeter() {
|
||||||
|
mFpsMeter = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
|
|
||||||
public void setCvCameraViewListener(CvCameraViewListener listener) {
|
public void setCvCameraViewListener(CvCameraViewListener listener) {
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
}
|
}
|
||||||
@ -272,6 +297,10 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
|
|||||||
if (canvas != null) {
|
if (canvas != null) {
|
||||||
canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);
|
canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);
|
||||||
canvas.drawBitmap(mCacheBitmap, (canvas.getWidth() - mCacheBitmap.getWidth()) / 2, (canvas.getHeight() - mCacheBitmap.getHeight()) / 2, null);
|
canvas.drawBitmap(mCacheBitmap, (canvas.getWidth() - mCacheBitmap.getWidth()) / 2, (canvas.getHeight() - mCacheBitmap.getHeight()) / 2, null);
|
||||||
|
if (mFpsMeter != null) {
|
||||||
|
mFpsMeter.measure();
|
||||||
|
mFpsMeter.draw(canvas, 0, 0);
|
||||||
|
}
|
||||||
getHolder().unlockCanvasAndPost(canvas);
|
getHolder().unlockCanvasAndPost(canvas);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
57
modules/java/generator/src/java/android+FpsMeter.java
Normal file
57
modules/java/generator/src/java/android+FpsMeter.java
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package org.opencv.android;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
|
import org.opencv.core.Core;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class FpsMeter {
|
||||||
|
private static final String TAG = "OCVSample::FpsMeter";
|
||||||
|
int step;
|
||||||
|
int framesCouner;
|
||||||
|
double freq;
|
||||||
|
long prevFrameTime;
|
||||||
|
String strfps;
|
||||||
|
DecimalFormat twoPlaces = new DecimalFormat("0.00");
|
||||||
|
Paint paint;
|
||||||
|
boolean isInitialized = false;
|
||||||
|
|
||||||
|
public void init() {
|
||||||
|
step = 20;
|
||||||
|
framesCouner = 0;
|
||||||
|
freq = Core.getTickFrequency();
|
||||||
|
prevFrameTime = Core.getTickCount();
|
||||||
|
strfps = "";
|
||||||
|
|
||||||
|
paint = new Paint();
|
||||||
|
paint.setColor(Color.BLUE);
|
||||||
|
paint.setTextSize(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void measure() {
|
||||||
|
if (!isInitialized) {
|
||||||
|
init();
|
||||||
|
isInitialized = true;
|
||||||
|
} else {
|
||||||
|
framesCouner++;
|
||||||
|
if (framesCouner % step == 0) {
|
||||||
|
long time = Core.getTickCount();
|
||||||
|
double fps = step * freq / (time - prevFrameTime);
|
||||||
|
prevFrameTime = time;
|
||||||
|
DecimalFormat twoPlaces = new DecimalFormat("0.00");
|
||||||
|
strfps = twoPlaces.format(fps) + " FPS";
|
||||||
|
Log.i(TAG, strfps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Canvas canvas, float offsetx, float offsety) {
|
||||||
|
Log.d(TAG, strfps);
|
||||||
|
canvas.drawText(strfps, 20 + offsetx, 10 + 50 + offsety, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -40,6 +40,8 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
|
|||||||
private Thread mThread;
|
private Thread mThread;
|
||||||
private boolean mStopThread;
|
private boolean mStopThread;
|
||||||
|
|
||||||
|
protected Camera mCamera;
|
||||||
|
|
||||||
private SurfaceTexture mSurfaceTexture;
|
private SurfaceTexture mSurfaceTexture;
|
||||||
|
|
||||||
public static class JavaCameraSizeAccessor implements ListItemAccessor {
|
public static class JavaCameraSizeAccessor implements ListItemAccessor {
|
||||||
@ -55,8 +57,6 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Camera mCamera;
|
|
||||||
|
|
||||||
public JavaCameraView(Context context, AttributeSet attrs) {
|
public JavaCameraView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
Log.d(TAG, "Java camera view ctor");
|
Log.d(TAG, "Java camera view ctor");
|
||||||
@ -69,6 +69,7 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
|
|||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
mCamera = null;
|
mCamera = null;
|
||||||
|
|
||||||
|
if (mCameraIndex == -1) {
|
||||||
Log.d(TAG, "Trying to open camera with old open()");
|
Log.d(TAG, "Trying to open camera with old open()");
|
||||||
try {
|
try {
|
||||||
mCamera = Camera.open();
|
mCamera = Camera.open();
|
||||||
@ -90,6 +91,16 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
|
|||||||
if (connected) break;
|
if (connected) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
|
||||||
|
Log.d(TAG, "Trying to open camera with new open(" + Integer.valueOf(mCameraIndex) + ")");
|
||||||
|
try {
|
||||||
|
mCamera = Camera.open(mCameraIndex);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
Log.e(TAG, "Camera #" + mCameraIndex + "failed to open: " + e.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mCamera == null)
|
if (mCamera == null)
|
||||||
return false;
|
return false;
|
||||||
@ -217,6 +228,7 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
|
|||||||
releaseCamera();
|
releaseCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.FROYO)
|
||||||
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);
|
||||||
|
@ -19,7 +19,8 @@ public class NativeCameraView extends CameraBridgeViewBase {
|
|||||||
public static final String TAG = "NativeCameraView";
|
public static final String TAG = "NativeCameraView";
|
||||||
private boolean mStopThread;
|
private boolean mStopThread;
|
||||||
private Thread mThread;
|
private Thread mThread;
|
||||||
private VideoCapture mCamera;
|
|
||||||
|
protected VideoCapture mCamera;
|
||||||
|
|
||||||
public NativeCameraView(Context context, AttributeSet attrs) {
|
public NativeCameraView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
@ -77,12 +78,17 @@ public class NativeCameraView extends CameraBridgeViewBase {
|
|||||||
|
|
||||||
private boolean initializeCamera(int width, int height) {
|
private boolean initializeCamera(int width, int height) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
|
|
||||||
|
if (mCameraIndex == -1)
|
||||||
mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID);
|
mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID);
|
||||||
|
else
|
||||||
|
mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID + mCameraIndex);
|
||||||
|
|
||||||
if (mCamera == null)
|
if (mCamera == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//TODO: improve error handling
|
if (mCamera.isOpened() == false)
|
||||||
|
return false;
|
||||||
|
|
||||||
java.util.List<Size> sizes = mCamera.getSupportedPreviewSizes();
|
java.util.List<Size> sizes = mCamera.getSupportedPreviewSizes();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user