OpenCV app framework improved

FPS meter added;
Camera switching posibility added;
Attributes loading for layout filed implemented.
This commit is contained in:
Alexander Smorkalov 2012-11-22 15:56:55 +04:00
parent 214629b220
commit 8266eab8b4
5 changed files with 144 additions and 35 deletions

View 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>

View File

@ -30,6 +30,11 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
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 mFrameHeight;
@ -37,11 +42,26 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
protected int mMaxWidth;
protected int mPreviewFormat = Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA;
protected int mCameraIndex = -1;
private boolean mEnabled;
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) {
super(context, attrs);
if (attrs.getAttributeBooleanValue(null, "show_fps", false))
enableFpsMeter();
mCameraIndex = attrs.getAttributeIntValue(null,"camera_index", -1);
getHolder().addCallback(this);
mMaxWidth = 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) {
Log.d(TAG, "call surfaceChanged event");
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) {
mListener = listener;
}
@ -272,6 +297,10 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
if (canvas != null) {
canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);
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);
}
}

View 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);
}
}

View File

@ -40,6 +40,8 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
private Thread mThread;
private boolean mStopThread;
protected Camera mCamera;
private SurfaceTexture mSurfaceTexture;
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) {
super(context, attrs);
Log.d(TAG, "Java camera view ctor");
@ -69,25 +69,36 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
synchronized (this) {
mCamera = null;
Log.d(TAG, "Trying to open camera with old open()");
try {
mCamera = Camera.open();
}
catch (Exception e){
Log.e(TAG, "Camera is not available (in use or does not exist): " + e.getLocalizedMessage());
}
if (mCameraIndex == -1) {
Log.d(TAG, "Trying to open camera with old open()");
try {
mCamera = Camera.open();
}
catch (Exception e){
Log.e(TAG, "Camera is not available (in use or does not exist): " + e.getLocalizedMessage());
}
if(mCamera == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
boolean connected = false;
for (int camIdx = 0; camIdx < Camera.getNumberOfCameras(); ++camIdx) {
Log.d(TAG, "Trying to open camera with new open(" + Integer.valueOf(camIdx) + ")");
try {
mCamera = Camera.open(camIdx);
connected = true;
} catch (RuntimeException e) {
Log.e(TAG, "Camera #" + camIdx + "failed to open: " + e.getLocalizedMessage());
if(mCamera == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
boolean connected = false;
for (int camIdx = 0; camIdx < Camera.getNumberOfCameras(); ++camIdx) {
Log.d(TAG, "Trying to open camera with new open(" + Integer.valueOf(camIdx) + ")");
try {
mCamera = Camera.open(camIdx);
connected = true;
} catch (RuntimeException e) {
Log.e(TAG, "Camera #" + camIdx + "failed to open: " + e.getLocalizedMessage());
}
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 (connected) break;
}
}
@ -217,6 +228,7 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
releaseCamera();
}
@TargetApi(Build.VERSION_CODES.FROYO)
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, "Frame size is " + frame.length);

View File

@ -19,7 +19,8 @@ public class NativeCameraView extends CameraBridgeViewBase {
public static final String TAG = "NativeCameraView";
private boolean mStopThread;
private Thread mThread;
private VideoCapture mCamera;
protected VideoCapture mCamera;
public NativeCameraView(Context context, AttributeSet attrs) {
super(context, attrs);
@ -77,12 +78,17 @@ public class NativeCameraView extends CameraBridgeViewBase {
private boolean initializeCamera(int width, int height) {
synchronized (this) {
mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID);
if (mCameraIndex == -1)
mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID);
else
mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID + mCameraIndex);
if (mCamera == null)
return false;
//TODO: improve error handling
if (mCamera.isOpened() == false)
return false;
java.util.List<Size> sizes = mCamera.getSupportedPreviewSizes();