#. Set name, target, package and minSDKVersion accordingly.
-#. Create a new class (*File -> New -> Class*). Name it for example: *HelloOpenCVView*.
-
- .. 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
- :linenos:
-
- package com.hello.opencv.test;
-
- import android.content.Context;
-
- public class HelloOpenCVView extends SurfaceView implements Callback, Runnable {
-
- public HelloOpenCVView(Context context) {
- super(context);
- getHolder().addCallback(this);
- }
-
- public void surfaceCreated(SurfaceHolder holder) {
- (new Thread(this)).start();
- }
-
- public void surfaceDestroyed(SurfaceHolder holder) {
- cameraRelease();
- }
-
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- cameraSetup(width, height);
- }
-
- //...
-
- * Add *cameraOpen*, *cameraRelease* and *cameraSetup* voids as shown below.
-
- * Also, don't forget to add the public void *run()* as follows:
-
- .. code-block:: java
- :linenos:
-
- public void run() {
- // TODO: loop { getFrame(), processFrame(), drawFrame() }
- }
-
- public boolean cameraOpen() {
- return false; //TODO: open camera
- }
-
- private void cameraRelease() {
- // TODO release camera
- }
-
- 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.
-
- .. code-block:: java
- :linenos:
-
- public void onCreate (Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mView = new HelloOpenCVView(this);
- setContentView (mView);
- }
-
- protected void onPause() {
- super.onPause();
- mView.cameraRelease();
- }
-
- protected void onResume() {
- super.onResume();
- if( !mView.cameraOpen() ) {
- // 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
:alt: Reference OpenCV library.
:align: center
-#. We now need some code to handle the camera. Update the *HelloOpenCVView* class as follows:
+#. Create new view layout for your application, lets name it hello_opencv.xml, and add the following to it:
- .. code-block:: java
- :linenos:
+ .. code-block:: xml
+ :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;
- }
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
- public void cameraRelease() {
- synchronized(this) {
- if (mCamera != null) {
- mCamera.release();
- mCamera = null;
- }
- }
- }
+ <org.opencv.android.JavaCameraView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:visibility="gone"
+ android:id="@+id/java_surface_view" />
- 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);
- }
- }
- }
+ </LinearLayout>
+
+#. Remove default auto generated layout, if exists.
-#. The last step would be to update the *run()* void in *HelloOpenCVView* class 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
: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);
-
- }
- bmp.recycle();
- }
- }
- }
+ public class Sample1Java extends Activity implements CvCameraViewListener {
+
+ private CameraBridgeViewBase mOpenCvCameraView;
+
+ private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
+ @Override
+ public void onManagerConnected(int status) {
+ switch (status) {
+ case LoaderCallbackInterface.SUCCESS: {
+ Log.i(TAG, "OpenCV loaded successfully");
+ mOpenCvCameraView.enableView();
+ } break;
+ default:
+ super.onManagerConnected(status);
+ }
+ }
+ };
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ Log.i(TAG, "called onCreate");
+ super.onCreate(savedInstanceState);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ 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 Bitmap processFrame(VideoCapture capture) {
- Mat mRgba = new Mat();
- 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;
- }
+ @Override
+ public void onPause()
+ {
+ if (mOpenCvCameraView != null)
+ mOpenCvCameraView.disableView();
+ super.onPause();
+ }
+
+ @Override
+ public void onResume()
+ {
+ super.onResume();
+ OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
+ }
+
+ public void onDestroy() {
+ super.onDestroy();
+ if (mOpenCvCameraView != null)
+ mOpenCvCameraView.disableView();
+ }
+
+ public void onCameraViewStarted(int width, int height) {
+ }
+
+ public void onCameraViewStopped() {
+ }
+
+ public Mat onCameraFrame(Mat inputFrame) {
+ return inputFrame;
+ }
+ }