diff --git a/samples/android/1-java/.project b/samples/android/1-java/.project index 957043183c..365825ad52 100644 --- a/samples/android/1-java/.project +++ b/samples/android/1-java/.project @@ -1,6 +1,6 @@ - Sample 1 Java + Sample 1 Java API diff --git a/samples/android/2-native/.classpath b/samples/android/2-native/.classpath new file mode 100644 index 0000000000..609aa00ebc --- /dev/null +++ b/samples/android/2-native/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/samples/android/2-native/.project b/samples/android/2-native/.project new file mode 100644 index 0000000000..fcf32d8e84 --- /dev/null +++ b/samples/android/2-native/.project @@ -0,0 +1,33 @@ + + + Sample 2 Native API + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/samples/android/2-native/.settings/org.eclipse.jdt.core.prefs b/samples/android/2-native/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..d995784334 --- /dev/null +++ b/samples/android/2-native/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +#Wed Jun 29 04:36:40 MSD 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/samples/android/2-native/AndroidManifest.xml b/samples/android/2-native/AndroidManifest.xml new file mode 100644 index 0000000000..0b5e6cfdbc --- /dev/null +++ b/samples/android/2-native/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/android/2-native/default.properties b/samples/android/2-native/default.properties new file mode 100644 index 0000000000..e2e8061f26 --- /dev/null +++ b/samples/android/2-native/default.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-8 diff --git a/samples/android/2-native/jni/Android.mk b/samples/android/2-native/jni/Android.mk new file mode 100644 index 0000000000..9c6114e028 --- /dev/null +++ b/samples/android/2-native/jni/Android.mk @@ -0,0 +1,16 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +OPENCV_MK_BUILD_PATH:=../../../../android/build/OpenCV.mk +ifeq ("$(wildcard $(OPENCV_MK_BUILD_PATH))","") + include $(TOOLCHAIN_PREBUILT_ROOT)/user/share/OpenCV/OpenCV.mk +else + include $(OPENCV_MK_BUILD_PATH) +endif + +LOCAL_MODULE := native_sample +LOCAL_SRC_FILES := jni_part.cpp +LOCAL_LDLIBS += -llog -ldl + +include $(BUILD_SHARED_LIBRARY) diff --git a/samples/android/2-native/jni/Application.mk b/samples/android/2-native/jni/Application.mk new file mode 100644 index 0000000000..c7de9c761b --- /dev/null +++ b/samples/android/2-native/jni/Application.mk @@ -0,0 +1,3 @@ +APP_STL := gnustl_static +APP_CPPFLAGS := -frtti -fexceptions +APP_ABI := armeabi-v7a diff --git a/samples/android/2-native/jni/jni_part.cpp b/samples/android/2-native/jni/jni_part.cpp new file mode 100644 index 0000000000..eee1adeb8c --- /dev/null +++ b/samples/android/2-native/jni/jni_part.cpp @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include + +using namespace std; +using namespace cv; + +extern "C" { +JNIEXPORT void JNICALL Java_org_opencv_samples_s2_Sample2View_FindFeatures(JNIEnv* env, jobject thiz, jint width, jint height, jbyteArray yuv, jintArray rgba) +{ + jbyte* _yuv = env->GetByteArrayElements(yuv, 0); + jint* _rgba = env->GetIntArrayElements(rgba, 0); + + Mat myuv(height + height/2, width, CV_8UC1, (unsigned char *)_yuv); + Mat mrgba(height, width, CV_8UC4, (unsigned char *)_rgba); + Mat mgray(height, width, CV_8UC1, (unsigned char *)_yuv); + + cvtColor(myuv, mrgba, CV_YUV420i2BGR, 4); + + vector v; + + FastFeatureDetector detector(50); + detector.detect(mgray, v); + for( size_t i = 0; i < v.size(); i++ ) + circle(mrgba, Point(v[i].pt.x, v[i].pt.y), 10, Scalar(0,0,255,255)); + + env->ReleaseIntArrayElements(rgba, _rgba, 0); + env->ReleaseByteArrayElements(yuv, _yuv, 0); +} + +} diff --git a/samples/android/2-native/res/drawable/icon.png b/samples/android/2-native/res/drawable/icon.png new file mode 100644 index 0000000000..4e828bafd8 Binary files /dev/null and b/samples/android/2-native/res/drawable/icon.png differ diff --git a/samples/android/2-native/res/values/strings.xml b/samples/android/2-native/res/values/strings.xml new file mode 100644 index 0000000000..9f3a6779ac --- /dev/null +++ b/samples/android/2-native/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Sample 2: Native API + 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 new file mode 100644 index 0000000000..9b114715c2 --- /dev/null +++ b/samples/android/2-native/src/org/opencv/samples/s2/Sample2Native.java @@ -0,0 +1,15 @@ +package org.opencv.samples.s2; + +import android.app.Activity; +import android.os.Bundle; +import android.view.Window; + +public class Sample2Native extends Activity { + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + 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 new file mode 100644 index 0000000000..f0cc52183e --- /dev/null +++ b/samples/android/2-native/src/org/opencv/samples/s2/Sample2View.java @@ -0,0 +1,114 @@ +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 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(); + } + + public void surfaceDestroyed(SurfaceHolder holder) { + mThreadRun = false; + if(mCamera != null) { + synchronized(Sample2View.this) { + mCamera.stopPreview(); + mCamera.setPreviewCallback(null); + mCamera.release(); + mCamera = null; + } + } + } + + 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); + } + } + + public native void FindFeatures(int width, int height, byte yuv[], int[] rgba); + + static { + System.loadLibrary("native_sample"); + } +}