From fae67e0b46194b9b074ac316fd23fb66d8334903 Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Fri, 15 Jul 2011 09:07:01 +0000 Subject: [PATCH] Refactored Android samples --- .../src/org/opencv/samples/s0/Sample0Base.java | 21 +- .../src/org/opencv/samples/s0/Sample0View.java | 149 +++----------- .../src/org/opencv/samples/s0/SampleViewBase.java | 119 ++++++++++++ .../src/org/opencv/samples/s1/Sample1View.java | 8 +- .../src/org/opencv/samples/s2/Sample2Native.java | 8 + .../src/org/opencv/samples/s2/Sample2View.java | 103 +--------- .../src/org/opencv/samples/s2/SampleViewBase.java | 119 ++++++++++++ .../src/org/opencv/samples/s4/Sample4Mixed.java | 43 +++-- .../src/org/opencv/samples/s4/Sample4View.java | 215 +++++++-------------- .../src/org/opencv/samples/s4/SampleViewBase.java | 119 ++++++++++++ 10 files changed, 514 insertions(+), 390 deletions(-) create mode 100644 samples/android/0-base/src/org/opencv/samples/s0/SampleViewBase.java create mode 100644 samples/android/2-native/src/org/opencv/samples/s2/SampleViewBase.java create mode 100644 samples/android/4-mixed/src/org/opencv/samples/s4/SampleViewBase.java diff --git a/samples/android/0-base/src/org/opencv/samples/s0/Sample0Base.java b/samples/android/0-base/src/org/opencv/samples/s0/Sample0Base.java index 7b20b8b..7aebe3e 100644 --- a/samples/android/0-base/src/org/opencv/samples/s0/Sample0Base.java +++ b/samples/android/0-base/src/org/opencv/samples/s0/Sample0Base.java @@ -8,31 +8,38 @@ import android.view.MenuItem; import android.view.Window; public class Sample0Base extends Activity { - private static final String TAG = "Sample0Base::Activity"; + private static final String TAG = "Sample::Activity"; - public static final int VIEW_MODE_RGBA = 0; - public static final int VIEW_MODE_GRAY = 1; + public static final int VIEW_MODE_RGBA = 0; + public static final int VIEW_MODE_GRAY = 1; - private MenuItem mItemPreviewRGBA; - private MenuItem mItemPreviewGray; + private MenuItem mItemPreviewRGBA; + private MenuItem mItemPreviewGray; - public int viewMode; + public static int viewMode = VIEW_MODE_RGBA; + + public Sample0Base() { + Log.i(TAG, "Instantiated new " + this.getClass()); + } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { + Log.i(TAG, "onCreate"); super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(new Sample0View(this)); - viewMode = VIEW_MODE_RGBA; } + @Override public boolean onCreateOptionsMenu(Menu menu) { + Log.i(TAG, "onCreateOptionsMenu"); mItemPreviewRGBA = menu.add("Preview RGBA"); mItemPreviewGray = menu.add("Preview GRAY"); return true; } + @Override public boolean onOptionsItemSelected(MenuItem item) { Log.i(TAG, "Menu Item selected " + item); if (item == mItemPreviewRGBA) diff --git a/samples/android/0-base/src/org/opencv/samples/s0/Sample0View.java b/samples/android/0-base/src/org/opencv/samples/s0/Sample0View.java index 410b7ae..165a61a 100644 --- a/samples/android/0-base/src/org/opencv/samples/s0/Sample0View.java +++ b/samples/android/0-base/src/org/opencv/samples/s0/Sample0View.java @@ -2,132 +2,45 @@ package org.opencv.samples.s0; import android.content.Context; import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.hardware.Camera; -import android.hardware.Camera.PreviewCallback; -import android.util.Log; -import android.view.SurfaceHolder; -import android.view.SurfaceView; - -import java.util.List; - -class Sample0View extends SurfaceView implements SurfaceHolder.Callback, Runnable { - private static final String TAG = "Sample0Base::View"; - - private Camera mCamera; - private SurfaceHolder mHolder; - private int mFrameWidth; - private int mFrameHeight; - private byte[] mFrame; - private boolean mThreadRun; +class Sample0View extends SampleViewBase { public Sample0View(Context context) { super(context); - mHolder = getHolder(); - mHolder.addCallback(this); - } - - public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) { - if ( mCamera != null) { - Camera.Parameters params = mCamera.getParameters(); - List sizes = params.getSupportedPreviewSizes(); - mFrameWidth = width; - mFrameHeight = height; - - //selecting optimal camera preview size - { - double minDiff = Double.MAX_VALUE; - for (Camera.Size size : sizes) { - if (Math.abs(size.height - height) < minDiff) { - mFrameWidth = size.width; - mFrameHeight = size.height; - minDiff = Math.abs(size.height - height); - } - } - } - params.setPreviewSize(mFrameWidth, mFrameHeight); - mCamera.setParameters(params); - mCamera.startPreview(); - } - } - - public void surfaceCreated(SurfaceHolder holder) { - mCamera = Camera.open(); - mCamera.setPreviewCallback( - new PreviewCallback() { - public void onPreviewFrame(byte[] data, Camera camera) { - synchronized(Sample0View.this) { - mFrame = data; - Sample0View.this.notify(); - } - } - } - ); - (new Thread(this)).start(); } - public void surfaceDestroyed(SurfaceHolder holder) { - mThreadRun = false; - if(mCamera != null) { - synchronized(Sample0View.this) { - mCamera.stopPreview(); - mCamera.setPreviewCallback(null); - mCamera.release(); - mCamera = null; - } - } - } + @Override + protected Bitmap processFrame(byte[] data) { + int frameSize = getFrameWidth() * getFrameHeight(); + int[] rgba = new int[frameSize]; - public void run() { - mThreadRun = true; - Log.i(TAG, "Starting thread"); - while(mThreadRun) { - byte[] data = null; - synchronized(this) { - try { - this.wait(); - data = mFrame; - } catch (InterruptedException e) { - e.printStackTrace(); - } + int view_mode = Sample0Base.viewMode; + if (view_mode == Sample0Base.VIEW_MODE_GRAY) { + for (int i = 0; i < frameSize; i++) { + int y = (0xff & ((int) data[i])); + rgba[i] = 0xff000000 + (y << 16) + (y << 8) + y; } - - int frameSize = mFrameWidth*mFrameHeight; - int[] rgba = new int[frameSize]; - - Sample0Base a = (Sample0Base)getContext(); - int view_mode = a.viewMode; - if(view_mode == Sample0Base.VIEW_MODE_GRAY) { - for(int i = 0; i < frameSize; i++) { - int y = (0xff & ((int)data[i])); - rgba[i] = 0xff000000 + (y << 16) + (y << 8) + y; + } else if (view_mode == Sample0Base.VIEW_MODE_RGBA) { + for (int i = 0; i < getFrameHeight(); i++) + for (int j = 0; j < getFrameWidth(); j++) { + int y = (0xff & ((int) data[i * getFrameWidth() + j])); + int u = (0xff & ((int) data[frameSize + (i >> 1) * getFrameWidth() + (j & ~1) + 0])); + int v = (0xff & ((int) data[frameSize + (i >> 1) * getFrameWidth() + (j & ~1) + 1])); + y = y < 16 ? 16 : y; + + int r = Math.round(1.164f * (y - 16) + 1.596f * (v - 128)); + int g = Math.round(1.164f * (y - 16) - 0.813f * (v - 128) - 0.391f * (u - 128)); + int b = Math.round(1.164f * (y - 16) + 2.018f * (u - 128)); + + r = r < 0 ? 0 : (r > 255 ? 255 : r); + g = g < 0 ? 0 : (g > 255 ? 255 : g); + b = b < 0 ? 0 : (b > 255 ? 255 : b); + + rgba[i * getFrameWidth() + j] = 0xff000000 + (b << 16) + (g << 8) + r; } - } else if (view_mode == Sample0Base.VIEW_MODE_RGBA) { - for(int i = 0; i < mFrameHeight; i++) - for(int j = 0; j < mFrameWidth; j++) { - int y = (0xff & ((int)data[i*mFrameWidth+j])); - int u = (0xff & ((int)data[frameSize + (i >> 1) * mFrameWidth + (j & ~1) + 0])); - int v = (0xff & ((int)data[frameSize + (i >> 1) * mFrameWidth + (j & ~1) + 1])); - if (y < 16) y = 16; - - int r = Math.round(1.164f * (y - 16) + 1.596f * (v - 128) ); - int g = Math.round(1.164f * (y - 16) - 0.813f * (v - 128) - 0.391f * (u - 128)); - int b = Math.round(1.164f * (y - 16) + 2.018f * (u - 128)); - - if (r < 0) r = 0; if (r > 255) r = 255; - if (g < 0) g = 0; if (g > 255) g = 255; - if (b < 0) b = 0; if (b > 255) b = 255; - - rgba[i*mFrameWidth+j] = 0xff000000 + (b << 16) + (g << 8) + r; - } - } - - Bitmap bmp = Bitmap.createBitmap(mFrameWidth, mFrameHeight, Bitmap.Config.ARGB_8888); - bmp.setPixels(rgba, 0/*offset*/, mFrameWidth /*stride*/, 0, 0, mFrameWidth, mFrameHeight); - - Canvas canvas = mHolder.lockCanvas(); - canvas.drawBitmap(bmp, (canvas.getWidth()-mFrameWidth)/2, (canvas.getHeight()-mFrameHeight)/2, null); - mHolder.unlockCanvasAndPost(canvas); } + + Bitmap bmp = Bitmap.createBitmap(getFrameWidth(), getFrameHeight(), Bitmap.Config.ARGB_8888); + bmp.setPixels(rgba, 0/* offset */, getFrameWidth() /* stride */, 0, 0, getFrameWidth(), getFrameHeight()); + return bmp; } } \ No newline at end of file diff --git a/samples/android/0-base/src/org/opencv/samples/s0/SampleViewBase.java b/samples/android/0-base/src/org/opencv/samples/s0/SampleViewBase.java new file mode 100644 index 0000000..8830e36 --- /dev/null +++ b/samples/android/0-base/src/org/opencv/samples/s0/SampleViewBase.java @@ -0,0 +1,119 @@ +package org.opencv.samples.s0; + +import java.util.List; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.hardware.Camera; +import android.hardware.Camera.PreviewCallback; +import android.util.Log; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + +public abstract class SampleViewBase extends SurfaceView implements SurfaceHolder.Callback, Runnable { + private static final String TAG = "Sample::SurfaceView"; + + private Camera mCamera; + private SurfaceHolder mHolder; + private int mFrameWidth; + private int mFrameHeight; + private byte[] mFrame; + private boolean mThreadRun; + + public SampleViewBase(Context context) { + super(context); + mHolder = getHolder(); + mHolder.addCallback(this); + Log.i(TAG, "Instantiated new " + this.getClass()); + } + + public int getFrameWidth() { + return mFrameWidth; + } + + public int getFrameHeight() { + return mFrameHeight; + } + + public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) { + Log.i(TAG, "surfaceCreated"); + if (mCamera != null) { + Camera.Parameters params = mCamera.getParameters(); + List sizes = params.getSupportedPreviewSizes(); + mFrameWidth = width; + mFrameHeight = height; + + // selecting optimal camera preview size + { + double minDiff = Double.MAX_VALUE; + for (Camera.Size size : sizes) { + if (Math.abs(size.height - height) < minDiff) { + mFrameWidth = size.width; + mFrameHeight = size.height; + minDiff = Math.abs(size.height - height); + } + } + } + + params.setPreviewSize(getFrameWidth(), getFrameHeight()); + mCamera.setParameters(params); + mCamera.startPreview(); + } + } + + public void surfaceCreated(SurfaceHolder holder) { + Log.i(TAG, "surfaceCreated"); + mCamera = Camera.open(); + mCamera.setPreviewCallback(new PreviewCallback() { + public void onPreviewFrame(byte[] data, Camera camera) { + synchronized (SampleViewBase.this) { + mFrame = data; + SampleViewBase.this.notify(); + } + } + }); + (new Thread(this)).start(); + } + + public void surfaceDestroyed(SurfaceHolder holder) { + Log.i(TAG, "surfaceDestroyed"); + mThreadRun = false; + if (mCamera != null) { + synchronized (this) { + mCamera.stopPreview(); + mCamera.setPreviewCallback(null); + mCamera.release(); + mCamera = null; + } + } + } + + protected abstract Bitmap processFrame(byte[] data); + + public void run() { + mThreadRun = true; + Log.i(TAG, "Starting processing thread"); + while (mThreadRun) { + Bitmap bmp = null; + + synchronized (this) { + try { + this.wait(); + bmp = processFrame(mFrame); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + if (bmp != null) { + Canvas canvas = mHolder.lockCanvas(); + if (canvas != null) { + canvas.drawBitmap(bmp, (canvas.getWidth() - getFrameWidth()) / 2, (canvas.getHeight() - getFrameHeight()) / 2, null); + mHolder.unlockCanvasAndPost(canvas); + } + bmp.recycle(); + } + } + } +} \ No newline at end of file diff --git a/samples/android/1-java/src/org/opencv/samples/s1/Sample1View.java b/samples/android/1-java/src/org/opencv/samples/s1/Sample1View.java index c74bbca..191aa6a 100644 --- a/samples/android/1-java/src/org/opencv/samples/s1/Sample1View.java +++ b/samples/android/1-java/src/org/opencv/samples/s1/Sample1View.java @@ -7,10 +7,10 @@ import android.graphics.Bitmap; import android.view.SurfaceHolder; class Sample1View extends SampleViewBase { - Mat mYuv; - Mat mRgba; - Mat mGraySubmat; - Mat mIntermediateMat; + private Mat mYuv; + private Mat mRgba; + private Mat mGraySubmat; + private Mat mIntermediateMat; public Sample1View(Context context) { super(context); diff --git a/samples/android/2-native/src/org/opencv/samples/s2/Sample2Native.java b/samples/android/2-native/src/org/opencv/samples/s2/Sample2Native.java index 9b11471..8e38916 100644 --- a/samples/android/2-native/src/org/opencv/samples/s2/Sample2Native.java +++ b/samples/android/2-native/src/org/opencv/samples/s2/Sample2Native.java @@ -2,12 +2,20 @@ package org.opencv.samples.s2; import android.app.Activity; import android.os.Bundle; +import android.util.Log; import android.view.Window; public class Sample2Native extends Activity { + private static final String TAG = "Sample::Activity"; + + public Sample2Native() { + Log.i(TAG, "Instantiated new " + this.getClass()); + } + /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { + Log.i(TAG, "onCreate"); super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(new Sample2View(this)); diff --git a/samples/android/2-native/src/org/opencv/samples/s2/Sample2View.java b/samples/android/2-native/src/org/opencv/samples/s2/Sample2View.java index f0cc521..8740c5c 100644 --- a/samples/android/2-native/src/org/opencv/samples/s2/Sample2View.java +++ b/samples/android/2-native/src/org/opencv/samples/s2/Sample2View.java @@ -2,108 +2,23 @@ package org.opencv.samples.s2; import android.content.Context; import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.hardware.Camera; -import android.hardware.Camera.PreviewCallback; -import android.util.Log; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import java.util.List; +class Sample2View extends SampleViewBase { -class Sample2View extends SurfaceView implements SurfaceHolder.Callback, Runnable { - private static final String TAG = "Sample2Native::View"; - - private Camera mCamera; - private SurfaceHolder mHolder; - private int mFrameWidth; - private int mFrameHeight; - private byte[] mFrame; - private boolean mThreadRun; - public Sample2View(Context context) { super(context); - mHolder = getHolder(); - mHolder.addCallback(this); } - public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) { - if ( mCamera != null) { - Camera.Parameters params = mCamera.getParameters(); - List sizes = params.getSupportedPreviewSizes(); - mFrameWidth = width; - mFrameHeight = height; - - //selecting optimal camera preview size - { - double minDiff = Double.MAX_VALUE; - for (Camera.Size size : sizes) { - if (Math.abs(size.height - height) < minDiff) { - mFrameWidth = size.width; - mFrameHeight = size.height; - minDiff = Math.abs(size.height - height); - } - } - } - params.setPreviewSize(mFrameWidth, mFrameHeight); - mCamera.setParameters(params); - mCamera.startPreview(); - } - } - - public void surfaceCreated(SurfaceHolder holder) { - mCamera = Camera.open(); - mCamera.setPreviewCallback( - new PreviewCallback() { - public void onPreviewFrame(byte[] data, Camera camera) { - synchronized(Sample2View.this) { - mFrame = data; - Sample2View.this.notify(); - } - } - } - ); - (new Thread(this)).start(); - } + @Override + protected Bitmap processFrame(byte[] data) { + int frameSize = getFrameWidth() * getFrameHeight(); + int[] rgba = new int[frameSize]; - public void surfaceDestroyed(SurfaceHolder holder) { - mThreadRun = false; - if(mCamera != null) { - synchronized(Sample2View.this) { - mCamera.stopPreview(); - mCamera.setPreviewCallback(null); - mCamera.release(); - mCamera = null; - } - } - } + FindFeatures(getFrameWidth(), getFrameHeight(), data, rgba); - public void run() { - mThreadRun = true; - Log.i(TAG, "Starting thread"); - while(mThreadRun) { - byte[] data = null; - synchronized(this) { - try { - this.wait(); - data = mFrame; - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - int frameSize = mFrameWidth*mFrameHeight; - int[] rgba = new int[frameSize]; - - FindFeatures(mFrameWidth, mFrameHeight, data, rgba); - - Bitmap bmp = Bitmap.createBitmap(mFrameWidth, mFrameHeight, Bitmap.Config.ARGB_8888); - bmp.setPixels(rgba, 0/*offset*/, mFrameWidth /*stride*/, 0, 0, mFrameWidth, mFrameHeight); - - Canvas canvas = mHolder.lockCanvas(); - canvas.drawBitmap(bmp, (canvas.getWidth()-mFrameWidth)/2, (canvas.getHeight()-mFrameHeight)/2, null); - mHolder.unlockCanvasAndPost(canvas); - } + Bitmap bmp = Bitmap.createBitmap(getFrameWidth(), getFrameHeight(), Bitmap.Config.ARGB_8888); + bmp.setPixels(rgba, 0/* offset */, getFrameWidth() /* stride */, 0, 0, getFrameWidth(), getFrameHeight()); + return bmp; } public native void FindFeatures(int width, int height, byte yuv[], int[] rgba); diff --git a/samples/android/2-native/src/org/opencv/samples/s2/SampleViewBase.java b/samples/android/2-native/src/org/opencv/samples/s2/SampleViewBase.java new file mode 100644 index 0000000..9a0daef --- /dev/null +++ b/samples/android/2-native/src/org/opencv/samples/s2/SampleViewBase.java @@ -0,0 +1,119 @@ +package org.opencv.samples.s2; + +import java.util.List; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.hardware.Camera; +import android.hardware.Camera.PreviewCallback; +import android.util.Log; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + +public abstract class SampleViewBase extends SurfaceView implements SurfaceHolder.Callback, Runnable { + private static final String TAG = "Sample::SurfaceView"; + + private Camera mCamera; + private SurfaceHolder mHolder; + private int mFrameWidth; + private int mFrameHeight; + private byte[] mFrame; + private boolean mThreadRun; + + public SampleViewBase(Context context) { + super(context); + mHolder = getHolder(); + mHolder.addCallback(this); + Log.i(TAG, "Instantiated new " + this.getClass()); + } + + public int getFrameWidth() { + return mFrameWidth; + } + + public int getFrameHeight() { + return mFrameHeight; + } + + public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) { + Log.i(TAG, "surfaceCreated"); + if (mCamera != null) { + Camera.Parameters params = mCamera.getParameters(); + List sizes = params.getSupportedPreviewSizes(); + mFrameWidth = width; + mFrameHeight = height; + + // selecting optimal camera preview size + { + double minDiff = Double.MAX_VALUE; + for (Camera.Size size : sizes) { + if (Math.abs(size.height - height) < minDiff) { + mFrameWidth = size.width; + mFrameHeight = size.height; + minDiff = Math.abs(size.height - height); + } + } + } + + params.setPreviewSize(getFrameWidth(), getFrameHeight()); + mCamera.setParameters(params); + mCamera.startPreview(); + } + } + + public void surfaceCreated(SurfaceHolder holder) { + Log.i(TAG, "surfaceCreated"); + mCamera = Camera.open(); + mCamera.setPreviewCallback(new PreviewCallback() { + public void onPreviewFrame(byte[] data, Camera camera) { + synchronized (SampleViewBase.this) { + mFrame = data; + SampleViewBase.this.notify(); + } + } + }); + (new Thread(this)).start(); + } + + public void surfaceDestroyed(SurfaceHolder holder) { + Log.i(TAG, "surfaceDestroyed"); + mThreadRun = false; + if (mCamera != null) { + synchronized (this) { + mCamera.stopPreview(); + mCamera.setPreviewCallback(null); + mCamera.release(); + mCamera = null; + } + } + } + + protected abstract Bitmap processFrame(byte[] data); + + public void run() { + mThreadRun = true; + Log.i(TAG, "Starting processing thread"); + while (mThreadRun) { + Bitmap bmp = null; + + synchronized (this) { + try { + this.wait(); + bmp = processFrame(mFrame); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + if (bmp != null) { + Canvas canvas = mHolder.lockCanvas(); + if (canvas != null) { + canvas.drawBitmap(bmp, (canvas.getWidth() - getFrameWidth()) / 2, (canvas.getHeight() - getFrameHeight()) / 2, null); + mHolder.unlockCanvasAndPost(canvas); + } + bmp.recycle(); + } + } + } +} \ No newline at end of file diff --git a/samples/android/4-mixed/src/org/opencv/samples/s4/Sample4Mixed.java b/samples/android/4-mixed/src/org/opencv/samples/s4/Sample4Mixed.java index fa34689..5a57e21 100644 --- a/samples/android/4-mixed/src/org/opencv/samples/s4/Sample4Mixed.java +++ b/samples/android/4-mixed/src/org/opencv/samples/s4/Sample4Mixed.java @@ -8,40 +8,45 @@ import android.view.MenuItem; import android.view.Window; public class Sample4Mixed extends Activity { - private static final String TAG = "Sample4Mixed::Activity"; + private static final String TAG = "Sample::Activity"; - public static final int VIEW_MODE_RGBA = 0; - public static final int VIEW_MODE_GRAY = 1; - public static final int VIEW_MODE_CANNY = 2; - public static final int VIEW_MODE_SOBEL = 3; - public static final int VIEW_MODE_BLUR = 4; - public static final int VIEW_MODE_FEATURES = 5; + public static final int VIEW_MODE_RGBA = 0; + public static final int VIEW_MODE_GRAY = 1; + public static final int VIEW_MODE_CANNY = 2; + public static final int VIEW_MODE_SOBEL = 3; + public static final int VIEW_MODE_BLUR = 4; + public static final int VIEW_MODE_FEATURES = 5; - private MenuItem mItemPreviewRGBA; - private MenuItem mItemPreviewGray; - private MenuItem mItemPreviewCanny; - private MenuItem mItemPreviewSobel; - private MenuItem mItemPreviewBlur; - private MenuItem mItemPreviewFeatures; + private MenuItem mItemPreviewRGBA; + private MenuItem mItemPreviewGray; + private MenuItem mItemPreviewCanny; + private MenuItem mItemPreviewSobel; + private MenuItem mItemPreviewBlur; + private MenuItem mItemPreviewFeatures; - public int viewMode; + public static int viewMode = VIEW_MODE_RGBA; + + public Sample4Mixed() { + Log.i(TAG, "Instantiated new " + this.getClass()); + } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + Log.i(TAG, "onCreate"); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(new Sample4View(this)); - viewMode = VIEW_MODE_RGBA; } public boolean onCreateOptionsMenu(Menu menu) { - mItemPreviewRGBA = menu.add("Preview RGBA"); - mItemPreviewGray = menu.add("Preview GRAY"); + Log.i(TAG, "onCreateOptionsMenu"); + mItemPreviewRGBA = menu.add("Preview RGBA"); + mItemPreviewGray = menu.add("Preview GRAY"); mItemPreviewCanny = menu.add("Canny"); mItemPreviewSobel = menu.add("Sobel"); - mItemPreviewBlur = menu.add("Blur"); - mItemPreviewFeatures = menu.add("Find features"); + mItemPreviewBlur = menu.add("Blur"); + mItemPreviewFeatures = menu.add("Find features"); return true; } diff --git a/samples/android/4-mixed/src/org/opencv/samples/s4/Sample4View.java b/samples/android/4-mixed/src/org/opencv/samples/s4/Sample4View.java index e64d0ef..6df2159 100644 --- a/samples/android/4-mixed/src/org/opencv/samples/s4/Sample4View.java +++ b/samples/android/4-mixed/src/org/opencv/samples/s4/Sample4View.java @@ -1,33 +1,12 @@ package org.opencv.samples.s4; +import org.opencv.*; + import android.content.Context; import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.hardware.Camera; -import android.hardware.Camera.PreviewCallback; -import android.util.Log; import android.view.SurfaceHolder; -import android.view.SurfaceView; - -import org.opencv.CvType; -import org.opencv.Mat; -import org.opencv.Size; -import org.opencv.core; -import org.opencv.imgproc; -import org.opencv.android; - -import java.util.List; - -class Sample4View extends SurfaceView implements SurfaceHolder.Callback, Runnable { - private static final String TAG = "Sample4Mixed::View"; - - private Camera mCamera; - private SurfaceHolder mHolder; - private int mFrameWidth; - private int mFrameHeight; - private byte[] mFrame; - private boolean mThreadRun; - + +class Sample4View extends SampleViewBase { private Mat mYuv; private Mat mRgba; private Mat mGraySubmat; @@ -35,145 +14,85 @@ class Sample4View extends SurfaceView implements SurfaceHolder.Callback, Runnabl public Sample4View(Context context) { super(context); - mHolder = getHolder(); - mHolder.addCallback(this); } + @Override public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) { - if ( mCamera != null) { - Camera.Parameters params = mCamera.getParameters(); - List sizes = params.getSupportedPreviewSizes(); - mFrameWidth = width; - mFrameHeight = height; - - //selecting optimal camera preview size - { - double minDiff = Double.MAX_VALUE; - for (Camera.Size size : sizes) { - if (Math.abs(size.height - height) < minDiff) { - mFrameWidth = size.width; - mFrameHeight = size.height; - minDiff = Math.abs(size.height - height); - } - } - } - params.setPreviewSize(mFrameWidth, mFrameHeight); - mCamera.setParameters(params); - mCamera.startPreview(); - - // initialize all required Mats before usage to minimize number of auxiliary jni calls - if(mYuv != null) mYuv.dispose(); - mYuv = new Mat(mFrameHeight+mFrameHeight/2, mFrameWidth, CvType.CV_8UC1); - - if(mRgba != null) mRgba.dispose(); - mRgba = new Mat(mFrameHeight, mFrameWidth, CvType.CV_8UC4); - - if(mGraySubmat != null) mGraySubmat.dispose(); - mGraySubmat = mYuv.submat(0, mFrameHeight, 0, mFrameWidth); - - if(mIntermediateMat != null) mIntermediateMat.dispose(); - mIntermediateMat = new Mat(mFrameHeight, mFrameWidth, CvType.CV_8UC1); + super.surfaceChanged(_holder, format, width, height); + + synchronized (this) { + // initialize Mats before usage + mYuv = new Mat(getFrameHeight() + getFrameHeight() / 2, getFrameWidth(), CvType.CV_8UC1); + mGraySubmat = mYuv.submat(0, getFrameHeight(), 0, getFrameWidth()); + + mRgba = new Mat(); + mIntermediateMat = new Mat(); } } - public void surfaceCreated(SurfaceHolder holder) { - mCamera = Camera.open(); - mCamera.setPreviewCallback( - new PreviewCallback() { - public void onPreviewFrame(byte[] data, Camera camera) { - synchronized(Sample4View.this) { - mFrame = data; - Sample4View.this.notify(); - } - } - } - ); - (new Thread(this)).start(); - } + @Override + protected Bitmap processFrame(byte[] data) { + mYuv.put(0, 0, data); - public void surfaceDestroyed(SurfaceHolder holder) { - mThreadRun = false; - if(mCamera != null) { - synchronized(Sample4View.this) { - mCamera.stopPreview(); - mCamera.setPreviewCallback(null); - mCamera.release(); - mCamera = null; - } + switch (Sample4Mixed.viewMode) { + case Sample4Mixed.VIEW_MODE_GRAY: + imgproc.cvtColor(mGraySubmat, mRgba, imgproc.CV_GRAY2RGBA, 4); + break; + case Sample4Mixed.VIEW_MODE_RGBA: + imgproc.cvtColor(mYuv, mRgba, imgproc.CV_YUV420i2RGB, 4); + break; + case Sample4Mixed.VIEW_MODE_CANNY: + imgproc.Canny(mGraySubmat, mIntermediateMat, 80, 100); + imgproc.cvtColor(mIntermediateMat, mRgba, imgproc.CV_GRAY2BGRA, 4); + break; + case Sample4Mixed.VIEW_MODE_SOBEL: + imgproc.Sobel(mGraySubmat, mIntermediateMat, CvType.CV_8U, 1, 1); + core.convertScaleAbs(mIntermediateMat, mIntermediateMat, 8); + imgproc.cvtColor(mIntermediateMat, mRgba, imgproc.CV_GRAY2BGRA, 4); + break; + case Sample4Mixed.VIEW_MODE_BLUR: + imgproc.cvtColor(mYuv, mRgba, imgproc.CV_YUV420i2RGB, 4); + imgproc.blur(mRgba, mRgba, new Size(15, 15)); + break; + case Sample4Mixed.VIEW_MODE_FEATURES: + imgproc.cvtColor(mYuv, mRgba, imgproc.CV_YUV420i2RGB, 4); + FindFeatures(mGraySubmat.getNativeObjAddr(), mRgba.getNativeObjAddr()); + break; } - - // Explicitly dispose Mats - if(mYuv != null) { - mYuv.dispose(); + + Bitmap bmp = Bitmap.createBitmap(getFrameWidth(), getFrameHeight(), Bitmap.Config.ARGB_8888); + + if (android.MatToBitmap(mRgba, bmp)) + return bmp; + + bmp.recycle(); + return null; + } + + @Override + public void run() { + super.run(); + + synchronized (this) { + // Explicitly deallocate Mats + if (mYuv != null) + mYuv.dispose(); + if (mRgba != null) + mRgba.dispose(); + if (mGraySubmat != null) + mGraySubmat.dispose(); + if (mIntermediateMat != null) + mIntermediateMat.dispose(); + mYuv = null; - } - if(mRgba != null) { - mRgba.dispose(); mRgba = null; - } - if(mGraySubmat != null) { - mGraySubmat.dispose(); mGraySubmat = null; - } - if(mIntermediateMat != null) { - mIntermediateMat.dispose(); mIntermediateMat = null; } } - public void run() { - mThreadRun = true; - Log.i(TAG, "Starting thread"); - while(mThreadRun) { - synchronized(this) { - try { - this.wait(); - mYuv.put(0, 0, mFrame); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - Sample4Mixed a = (Sample4Mixed)getContext(); - - switch(a.viewMode) - { - case Sample4Mixed.VIEW_MODE_GRAY: - imgproc.cvtColor(mGraySubmat, mRgba, imgproc.CV_GRAY2RGBA, 4); - break; - case Sample4Mixed.VIEW_MODE_RGBA: - imgproc.cvtColor(mYuv, mRgba, imgproc.CV_YUV420i2RGB, 4); - break; - case Sample4Mixed.VIEW_MODE_CANNY: - imgproc.Canny(mGraySubmat, mIntermediateMat, 80, 100); - imgproc.cvtColor(mIntermediateMat, mRgba, imgproc.CV_GRAY2BGRA, 4); - break; - case Sample4Mixed.VIEW_MODE_SOBEL: - imgproc.Sobel(mGraySubmat, mIntermediateMat, CvType.CV_8U, 1, 1); - core.convertScaleAbs(mIntermediateMat, mIntermediateMat, 8); - imgproc.cvtColor(mIntermediateMat, mRgba, imgproc.CV_GRAY2BGRA, 4); - break; - case Sample4Mixed.VIEW_MODE_BLUR: - imgproc.cvtColor(mYuv, mRgba, imgproc.CV_YUV420i2RGB, 4); - imgproc.blur(mRgba, mRgba, new Size(15, 15)); - break; - case Sample4Mixed.VIEW_MODE_FEATURES: - imgproc.cvtColor(mYuv, mRgba, imgproc.CV_YUV420i2RGB, 4); - FindFeatures(mGraySubmat.getNativeObjAddr(), mRgba.getNativeObjAddr()); - break; - } - - Bitmap bmp = Bitmap.createBitmap(mFrameWidth, mFrameHeight, Bitmap.Config.ARGB_8888); - android.MatToBitmap(mRgba, bmp); - - Canvas canvas = mHolder.lockCanvas(); - canvas.drawBitmap(bmp, (canvas.getWidth()-mFrameWidth)/2, (canvas.getHeight()-mFrameHeight)/2, null); - mHolder.unlockCanvasAndPost(canvas); - } - } - public native void FindFeatures(long matAddrGr, long matAddrRgba); - + static { System.loadLibrary("mixed_sample"); } diff --git a/samples/android/4-mixed/src/org/opencv/samples/s4/SampleViewBase.java b/samples/android/4-mixed/src/org/opencv/samples/s4/SampleViewBase.java new file mode 100644 index 0000000..13ac061 --- /dev/null +++ b/samples/android/4-mixed/src/org/opencv/samples/s4/SampleViewBase.java @@ -0,0 +1,119 @@ +package org.opencv.samples.s4; + +import java.util.List; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.hardware.Camera; +import android.hardware.Camera.PreviewCallback; +import android.util.Log; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + +public abstract class SampleViewBase extends SurfaceView implements SurfaceHolder.Callback, Runnable { + private static final String TAG = "Sample::SurfaceView"; + + private Camera mCamera; + private SurfaceHolder mHolder; + private int mFrameWidth; + private int mFrameHeight; + private byte[] mFrame; + private boolean mThreadRun; + + public SampleViewBase(Context context) { + super(context); + mHolder = getHolder(); + mHolder.addCallback(this); + Log.i(TAG, "Instantiated new " + this.getClass()); + } + + public int getFrameWidth() { + return mFrameWidth; + } + + public int getFrameHeight() { + return mFrameHeight; + } + + public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) { + Log.i(TAG, "surfaceCreated"); + if (mCamera != null) { + Camera.Parameters params = mCamera.getParameters(); + List sizes = params.getSupportedPreviewSizes(); + mFrameWidth = width; + mFrameHeight = height; + + // selecting optimal camera preview size + { + double minDiff = Double.MAX_VALUE; + for (Camera.Size size : sizes) { + if (Math.abs(size.height - height) < minDiff) { + mFrameWidth = size.width; + mFrameHeight = size.height; + minDiff = Math.abs(size.height - height); + } + } + } + + params.setPreviewSize(getFrameWidth(), getFrameHeight()); + mCamera.setParameters(params); + mCamera.startPreview(); + } + } + + public void surfaceCreated(SurfaceHolder holder) { + Log.i(TAG, "surfaceCreated"); + mCamera = Camera.open(); + mCamera.setPreviewCallback(new PreviewCallback() { + public void onPreviewFrame(byte[] data, Camera camera) { + synchronized (SampleViewBase.this) { + mFrame = data; + SampleViewBase.this.notify(); + } + } + }); + (new Thread(this)).start(); + } + + public void surfaceDestroyed(SurfaceHolder holder) { + Log.i(TAG, "surfaceDestroyed"); + mThreadRun = false; + if (mCamera != null) { + synchronized (this) { + mCamera.stopPreview(); + mCamera.setPreviewCallback(null); + mCamera.release(); + mCamera = null; + } + } + } + + protected abstract Bitmap processFrame(byte[] data); + + public void run() { + mThreadRun = true; + Log.i(TAG, "Starting processing thread"); + while (mThreadRun) { + Bitmap bmp = null; + + synchronized (this) { + try { + this.wait(); + bmp = processFrame(mFrame); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + if (bmp != null) { + Canvas canvas = mHolder.lockCanvas(); + if (canvas != null) { + canvas.drawBitmap(bmp, (canvas.getWidth() - getFrameWidth()) / 2, (canvas.getHeight() - getFrameHeight()) / 2, null); + mHolder.unlockCanvasAndPost(canvas); + } + bmp.recycle(); + } + } + } +} \ No newline at end of file -- 2.7.4