Android tutorial updated. HelloWorld sample ported on new framework.

pull/136/head
mikle 13 years ago committed by Alexander Smorkalov
parent 6484732509
commit 7ef378b230
  1. 239
      doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.rst

@ -270,214 +270,107 @@ It will be capable of accessing camera output, processing it and displaying the
#. Set name, target, package and minSDKVersion accordingly. #. Set name, target, package and minSDKVersion accordingly.
#. Create a new class (*File -> New -> Class*). Name it for example: *HelloOpenCVView*. #. Add the following permissions to the AndroidManifest.xml file:
.. image:: images/dev_OCV_new_class.png
:alt: Add a new class.
:align: center
* It should extend *SurfaceView* class.
* It also should implement *SurfaceHolder.Callback*, *Runnable*.
#. Edit *HelloOpenCVView* class.
* Add an *import* line for *android.content.context*.
* Modify autogenerated stubs: *HelloOpenCVView*, *surfaceCreated*, *surfaceDestroyed* and *surfaceChanged*.
.. code-block:: java .. code-block:: xml
:linenos: :linenos:
package com.hello.opencv.test; </application>
import android.content.Context; <uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
public class HelloOpenCVView extends SurfaceView implements Callback, Runnable { #. Reference OpenCV library within your project properties.
public HelloOpenCVView(Context context) { .. image:: images/dev_OCV_reference.png
super(context); :alt: Reference OpenCV library.
getHolder().addCallback(this); :align: center
}
public void surfaceCreated(SurfaceHolder holder) { #. Create new view layout for your application, lets name it hello_opencv.xml, and add the following to it:
(new Thread(this)).start();
}
public void surfaceDestroyed(SurfaceHolder holder) { .. code-block:: xml
cameraRelease(); :linenos:
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
cameraSetup(width, height); xmlns:tools="http://schemas.android.com/tools"
} android:layout_width="match_parent"
android:layout_height="match_parent" >
<org.opencv.android.JavaCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"
android:id="@+id/java_surface_view" />
//... </LinearLayout>
* Add *cameraOpen*, *cameraRelease* and *cameraSetup* voids as shown below. #. Remove default auto generated layout, if exists.
* Also, don't forget to add the public void *run()* as follows: #. Create a new *Activity* (*New -> Other -> Android -> Android Activity*) and name it, for example: *HelloOpenCVActivity*. Add *CvCameraViewListener* interface to *implementes* section of *HelloOpenCVActivity* class. Add the following code to activity implementation:
.. code-block:: java .. code-block:: java
:linenos: :linenos:
public void run() { public class Sample1Java extends Activity implements CvCameraViewListener {
// TODO: loop { getFrame(), processFrame(), drawFrame() }
}
public boolean cameraOpen() { private CameraBridgeViewBase mOpenCvCameraView;
return false; //TODO: open camera
}
private void cameraRelease() { private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
// TODO release camera @Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS: {
Log.i(TAG, "OpenCV loaded successfully");
mOpenCvCameraView.enableView();
} break;
default:
super.onManagerConnected(status);
} }
private void cameraSetup(int width, int height) {
// TODO setup camera
} }
};
#. Create a new *Activity* (*New -> Other -> Android -> Android Activity*) and name it, for example: *HelloOpenCVActivity*. For this activity define *onCreate*, *onResume* and *onPause* voids. /** Called when the activity is first created. */
@Override
.. code-block:: java public void onCreate(Bundle savedInstanceState) {
:linenos: Log.i(TAG, "called onCreate");
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mView = new HelloOpenCVView(this); requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView (mView); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.hello_opencv);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.java_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
} }
protected void onPause() { @Override
public void onPause()
{
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
super.onPause(); super.onPause();
mView.cameraRelease();
} }
protected void onResume() { @Override
public void onResume()
{
super.onResume(); super.onResume();
if( !mView.cameraOpen() ) { OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
// MessageBox and exit app
AlertDialog ad = new AlertDialog.Builder(this).create();
ad.setCancelable(false); // This blocks the "BACK" button
ad.setMessage("Fatal error: can't open camera!");
ad.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
});
ad.show();
}
}
#. Add the following permissions to the AndroidManifest.xml file:
.. code-block:: xml
:linenos:
</application>
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
#. Reference OpenCV library within your project properties.
.. image:: images/dev_OCV_reference.png
:alt: Reference OpenCV library.
:align: center
#. We now need some code to handle the camera. Update the *HelloOpenCVView* class as follows:
.. code-block:: java
:linenos:
private VideoCapture mCamera;
public boolean cameraOpen() {
synchronized (this) {
cameraRelease();
mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID);
if (!mCamera.isOpened()) {
mCamera.release();
mCamera = null;
Log.e("HelloOpenCVView", "Failed to open native camera");
return false;
}
}
return true;
} }
public void cameraRelease() { public void onDestroy() {
synchronized(this) { super.onDestroy();
if (mCamera != null) { if (mOpenCvCameraView != null)
mCamera.release(); mOpenCvCameraView.disableView();
mCamera = null;
}
}
}
private void cameraSetup(int width, int height) {
synchronized (this) {
if (mCamera != null && mCamera.isOpened()) {
List<Size> sizes = mCamera.getSupportedPreviewSizes();
int mFrameWidth = width;
int mFrameHeight = height;
{ // selecting optimal camera preview size
double minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - height) < minDiff) {
mFrameWidth = (int) size.width;
mFrameHeight = (int) size.height;
minDiff = Math.abs(size.height - height);
}
}
}
mCamera.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, mFrameWidth);
mCamera.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, mFrameHeight);
}
}
} }
#. The last step would be to update the *run()* void in *HelloOpenCVView* class as follows: public void onCameraViewStarted(int width, int height) {
.. code-block:: java
:linenos:
public void run() {
while (true) {
Bitmap bmp = null;
synchronized (this) {
if (mCamera == null)
break;
if (!mCamera.grab())
break;
bmp = processFrame(mCamera);
} }
if (bmp != null) {
Canvas canvas = getHolder().lockCanvas();
if (canvas != null) {
canvas.drawBitmap(bmp, (canvas.getWidth() - bmp.getWidth()) / 2,
(canvas.getHeight() - bmp.getHeight()) / 2, null);
getHolder().unlockCanvasAndPost(canvas);
} public void onCameraViewStopped() {
bmp.recycle();
}
}
} }
protected Bitmap processFrame(VideoCapture capture) { public Mat onCameraFrame(Mat inputFrame) {
Mat mRgba = new Mat(); return inputFrame;
capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
//process mRgba
Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
try {
Utils.matToBitmap(mRgba, bmp);
} catch(Exception e) {
Log.e("processFrame", "Utils.matToBitmap() throws an exception: " + e.getMessage());
bmp.recycle();
bmp = null;
} }
return bmp;
} }

Loading…
Cancel
Save