---------------------
Performs initial step of meanshift segmentation of an image.
-.. ocv:function: void pyrMeanShiftFiltering( InputArray src, OutputArray dst, double sp, double sr, int maxLevel=1, TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5,1) )
+.. ocv:function:: void pyrMeanShiftFiltering( InputArray src, OutputArray dst, double sp, double sr, int maxLevel=1, TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5,1) )
.. ocv:pyfunction:: cv2.pyrMeanShiftFiltering(src, sp, sr[, dst[, maxLevel[, termcrit]]]) -> dst
\r
}\r
\r
-setManualFunctions=set(['minMaxLoc'])\r
+setManualFunctions=set(['minMaxLoc', 'getTextSize'])\r
\r
class ConstInfo(object):\r
def __init__(self, cname, name, val):\r
return minMaxLoc(src, null);\r
}\r
private static native double[] n_minMaxLocManual(long src_nativeObj, long mask_nativeObj);\r
-\r
+ \r
+ //javadoc:getTextSize(text, fontFace, fontScale, thickness, baseLine)\r
+ public static Size getTextSize(String text, int fontFace, double fontScale, int thickness, int[] baseLine) {\r
+ assert(baseLine == null || baseLine.length == 1);\r
+ Size retVal = new Size(n_getTextSize(text, fontFace, fontScale, thickness, baseLine));\r
+ return retVal;\r
+ }\r
+ private static native double[] n_getTextSize(String text, int fontFace, double fontScale, int thickness, int[] baseLine);\r
\r
""" )\r
\r
LOGD("core::n_1minMaxLoc() catched unknown exception (...)");\r
#endif // DEBUG\r
jclass je = env->FindClass("java/lang/Exception");\r
- env->ThrowNew(je, "Unknown exception in JNI code {$module::$fname()}");\r
+ env->ThrowNew(je, "Unknown exception in JNI code {core::minMaxLoc()}");\r
+ return NULL;\r
+ }\r
+}\r
+\r
+JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_n_1getTextSize\r
+ (JNIEnv* env, jclass cls, jstring text, jint fontFace, jdouble fontScale, jint thickness, jintArray baseLine)\r
+{\r
+ try {\r
+#ifdef DEBUG\r
+ LOGD("core::n_1getTextSize()");\r
+#endif // DEBUG\r
+\r
+ jdoubleArray result;\r
+ result = env->NewDoubleArray(2);\r
+ if (result == NULL) {\r
+ return NULL; /* out of memory error thrown */\r
+ }\r
+ \r
+ const char* utf_text = env->GetStringUTFChars(text, 0);\r
+ std::string n_text( utf_text ? utf_text : "" );\r
+ env->ReleaseStringUTFChars(text, utf_text);\r
+ \r
+ int _baseLine;\r
+ int* pbaseLine = 0;\r
+ \r
+ if (baseLine != NULL)\r
+ pbaseLine = &_baseLine;\r
+ \r
+ cv::Size rsize = cv::getTextSize(n_text, (int)fontFace, (double)fontScale, (int)thickness, pbaseLine);\r
+\r
+ jdouble fill[2];\r
+ fill[0]=rsize.width;\r
+ fill[1]=rsize.height;\r
+\r
+ env->SetDoubleArrayRegion(result, 0, 2, fill);\r
+ \r
+ if (baseLine != NULL)\r
+ env->SetIntArrayRegion(baseLine, 0, 1, pbaseLine);\r
+\r
+ return result;\r
+\r
+ } catch(cv::Exception e) {\r
+#ifdef DEBUG\r
+ LOGD("core::n_1getTextSize() catched cv::Exception: %s", e.what());\r
+#endif // DEBUG\r
+ jclass je = env->FindClass("org/opencv/CvException");\r
+ if(!je) je = env->FindClass("java/lang/Exception");\r
+ env->ThrowNew(je, e.what());\r
+ return NULL;\r
+ } catch (...) {\r
+#ifdef DEBUG\r
+ LOGD("core::n_1getTextSize() catched unknown exception (...)");\r
+#endif // DEBUG\r
+ jclass je = env->FindClass("java/lang/Exception");\r
+ env->ThrowNew(je, "Unknown exception in JNI code {core::getTextSize()}");\r
return NULL;\r
}\r
}\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry kind="src" path="src"/>\r
+ <classpathentry kind="src" path="gen"/>\r
+ <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>\r
+ <classpathentry kind="src" path="OpenCV-2.3.1_src"/>\r
+ <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>15-puzzle</name>\r
+ <comment></comment>\r
+ <projects>\r
+ </projects>\r
+ <buildSpec>\r
+ <buildCommand>\r
+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ <buildCommand>\r
+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ <buildCommand>\r
+ <name>org.eclipse.jdt.core.javabuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ <buildCommand>\r
+ <name>com.android.ide.eclipse.adt.ApkBuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ </buildSpec>\r
+ <natures>\r
+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature>\r
+ <nature>org.eclipse.jdt.core.javanature</nature>\r
+ </natures>\r
+ <linkedResources>\r
+ <link>\r
+ <name>OpenCV-2.3.1_src</name>\r
+ <type>2</type>\r
+ <locationURI>_android_OpenCV_2_3_1_df28900a/src</locationURI>\r
+ </link>\r
+ </linkedResources>\r
+</projectDescription>\r
--- /dev/null
+#Wed Jun 29 04:36:40 MSD 2011\r
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5\r
+org.eclipse.jdt.core.compiler.compliance=1.5\r
+org.eclipse.jdt.core.compiler.source=1.5\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.opencv.samples.puzzle15"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <application android:icon="@drawable/icon" android:label="@string/app_name">
+ <activity android:name=".puzzle15Activity"
+ android:label="@string/app_name"
+ android:screenOrientation="landscape"
+ android:configChanges="keyboardHidden|orientation">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+ <uses-sdk android:minSdkVersion="8" />
+
+ <uses-permission android:name="android.permission.CAMERA"/>
+ <uses-feature android:name="android.hardware.camera" />
+ <uses-feature android:name="android.hardware.camera.autofocus" />
+</manifest>
\ No newline at end of file
--- /dev/null
+android.library.reference.1=../../../android/build
+# Project target.
+target=android-8
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">15-puzzle</string>
+</resources>
--- /dev/null
+package org.opencv.samples.puzzle15;
+
+import java.util.List;
+
+import org.opencv.*;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+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 SurfaceHolder mHolder;
+ private VideoCapture mCamera;
+
+ public SampleViewBase(Context context) {
+ super(context);
+ mHolder = getHolder();
+ mHolder.addCallback(this);
+ Log.i(TAG, "Instantiated new " + this.getClass());
+ }
+
+ public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {
+ Log.i(TAG, "surfaceCreated");
+ synchronized (this) {
+ if (mCamera != null && mCamera.isOpened()) {
+ Log.i(TAG, "before mCamera.getSupportedPreviewSizes()");
+ List<Size> sizes = mCamera.getSupportedPreviewSizes();
+ Log.i(TAG, "after 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);
+ }
+ }
+ }
+
+ public void surfaceCreated(SurfaceHolder holder) {
+ Log.i(TAG, "surfaceCreated");
+ mCamera = new VideoCapture(highgui.CV_CAP_ANDROID);
+ if (mCamera.isOpened()) {
+ (new Thread(this)).start();
+ } else {
+ mCamera.release();
+ mCamera = null;
+ Log.e(TAG, "Failed to open native camera");
+ }
+ }
+
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ Log.i(TAG, "surfaceDestroyed");
+ if (mCamera != null) {
+ synchronized (this) {
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+ }
+
+ protected abstract Bitmap processFrame(VideoCapture capture);
+
+ public void run() {
+ Log.i(TAG, "Starting processing thread");
+ while (true) {
+ Bitmap bmp = null;
+
+ synchronized (this) {
+ if (mCamera == null)
+ break;
+
+ if (!mCamera.grab()) {
+ Log.e(TAG, "mCamera.grab() failed");
+ break;
+ }
+
+ bmp = processFrame(mCamera);
+ }
+
+ if (bmp != null) {
+ Canvas canvas = mHolder.lockCanvas();
+ if (canvas != null) {
+ canvas.drawBitmap(bmp, (canvas.getWidth() - bmp.getWidth()) / 2, (canvas.getHeight() - bmp.getHeight()) / 2, null);
+ mHolder.unlockCanvasAndPost(canvas);
+ }
+ bmp.recycle();
+ }
+ }
+
+ Log.i(TAG, "Finishing processing thread");
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.opencv.samples.puzzle15;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.Window;
+
+public class puzzle15Activity extends Activity {
+ private static final String TAG = "Sample::Activity";
+
+ private MenuItem mItemNewGame;
+ private MenuItem mItemToggleNumbers;
+ private puzzle15View mView;
+
+ public puzzle15Activity() {
+ 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);
+ mView = new puzzle15View(this);
+ setContentView(mView);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ Log.i(TAG, "onCreateOptionsMenu");
+ mItemNewGame = menu.add("Start new game");
+ mItemToggleNumbers = menu.add("Show/hide tile numbers");
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ Log.i(TAG, "Menu Item selected " + item);
+ if (item == mItemNewGame) {
+ synchronized (mView) {
+ mView.startNewGame();
+ }
+ } else if (item == mItemToggleNumbers)
+ mView.tolggleTileNumbers();
+ return true;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.opencv.samples.puzzle15;\r
+\r
+import org.opencv.*;\r
+\r
+import android.content.Context;\r
+import android.graphics.Bitmap;\r
+import android.view.MotionEvent;\r
+import android.view.SurfaceHolder;\r
+import android.view.View;\r
+import android.view.View.OnTouchListener;\r
+\r
+public class puzzle15View extends SampleViewBase implements OnTouchListener {\r
+ private Mat mRgba;\r
+ private Mat mRgba15;\r
+ private Mat[] mCells;\r
+ private Mat[] mCells15;\r
+ private int[] mIndexses;\r
+ private int[] mTextWidths;\r
+ private int[] mTextHeights;\r
+ private boolean mShowTileNumbers = true;\r
+\r
+ int gridSize = 4;\r
+ int gridArea = gridSize * gridSize;\r
+ int gridEmptyIdx = gridArea - 1;\r
+\r
+ public puzzle15View(Context context) {\r
+ super(context);\r
+ setOnTouchListener(this);\r
+\r
+ mTextWidths = new int[gridArea];\r
+ mTextHeights = new int[gridArea];\r
+ for (int i = 0; i < gridArea; i++) {\r
+ Size s = core.getTextSize(Integer.toString(i + 1), 3/* CV_FONT_HERSHEY_COMPLEX */, 1, 2, null);\r
+ mTextHeights[i] = (int) s.height;\r
+ mTextWidths[i] = (int) s.width;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {\r
+ super.surfaceChanged(_holder, format, width, height);\r
+ synchronized (this) {\r
+ // initialize Mat before usage\r
+ mRgba = new Mat();\r
+ }\r
+ }\r
+\r
+ public static void shuffle(int[] array) {\r
+ for (int i = array.length; i > 1; i--) {\r
+ int temp = array[i - 1];\r
+ int randIx = (int) (Math.random() * i);\r
+ array[i - 1] = array[randIx];\r
+ array[randIx] = temp;\r
+ }\r
+ }\r
+\r
+ public boolean isPuzzleSolvable() {\r
+ if (gridSize != 4)\r
+ return true;\r
+\r
+ int sum = 0;\r
+ for (int i = 0; i < gridArea; i++) {\r
+ if (mIndexses[i] == gridEmptyIdx)\r
+ sum += (i / gridSize) + 1;\r
+ else {\r
+ int smaller = 0;\r
+ for (int j = i + 1; j < gridArea; j++) {\r
+ if (mIndexses[j] < mIndexses[i])\r
+ smaller++;\r
+ }\r
+ sum += smaller;\r
+ }\r
+ }\r
+\r
+ return sum % 2 == 0;\r
+ }\r
+\r
+ private void createPuzzle(int cols, int rows) {\r
+ mCells = new Mat[gridArea];\r
+ mCells15 = new Mat[gridArea];\r
+\r
+ mRgba15 = new Mat(rows, cols, mRgba.type());\r
+ mIndexses = new int[gridArea];\r
+\r
+ for (int i = 0; i < gridSize; i++) {\r
+ for (int j = 0; j < gridSize; j++) {\r
+ int k = i * gridSize + j;\r
+ mIndexses[k] = k;\r
+ mCells[k] = mRgba.submat(i * rows / gridSize, (i + 1) * rows / gridSize, j * cols / gridSize, (j + 1) * cols / gridSize);\r
+ mCells15[k] = mRgba15.submat(i * rows / gridSize, (i + 1) * rows / gridSize, j * cols / gridSize, (j + 1) * cols / gridSize);\r
+ }\r
+ }\r
+\r
+ startNewGame();\r
+ }\r
+\r
+ public void startNewGame() {\r
+ do {\r
+ shuffle(mIndexses);\r
+ } while (!isPuzzleSolvable());\r
+ }\r
+\r
+ public void tolggleTileNumbers() {\r
+ mShowTileNumbers = !mShowTileNumbers;\r
+ }\r
+\r
+ @Override\r
+ protected Bitmap processFrame(VideoCapture capture) {\r
+ capture.retrieve(mRgba, highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);\r
+ int cols = mRgba.cols();\r
+ int rows = mRgba.rows();\r
+\r
+ if (mCells == null)\r
+ createPuzzle(cols, rows);\r
+\r
+ // copy shuffled tiles\r
+ for (int i = 0; i < gridArea; i++) {\r
+ int idx = mIndexses[i];\r
+ if (idx == gridEmptyIdx)\r
+ mCells15[i].setTo(new Scalar(0x33, 0x33, 0x33, 0xFF));\r
+ else {\r
+ mCells[idx].copyTo(mCells15[i]);\r
+ if (mShowTileNumbers) {\r
+ core.putText(mCells15[i], Integer.toString(1 + idx), new Point((cols / gridSize - mTextWidths[idx]) / 2,\r
+ (rows / gridSize + mTextHeights[idx]) / 2), 3/* CV_FONT_HERSHEY_COMPLEX */, 1, new Scalar(255, 0, 0, 255), 2);\r
+ }\r
+ }\r
+ }\r
+\r
+ drawGrid(cols, rows);\r
+\r
+ Bitmap bmp = Bitmap.createBitmap(cols, rows, Bitmap.Config.ARGB_8888);\r
+ if (android.MatToBitmap(mRgba15, bmp))\r
+ return bmp;\r
+\r
+ bmp.recycle();\r
+ return null;\r
+ }\r
+\r
+ private void drawGrid(int cols, int rows) {\r
+ for (int i = 1; i < gridSize; i++) {\r
+ core.line(mRgba15, new Point(0, i * rows / gridSize), new Point(cols, i * rows / gridSize), new Scalar(0, 255, 0, 255), 3);\r
+ core.line(mRgba15, new Point(i * cols / gridSize, 0), new Point(i * cols / gridSize, rows), new Scalar(0, 255, 0, 255), 3);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void run() {\r
+ super.run();\r
+\r
+ synchronized (this) {\r
+ // Explicitly deallocate Mats\r
+ if (mCells != null) {\r
+ for (Mat m : mCells)\r
+ m.dispose();\r
+ }\r
+ if (mCells15 != null) {\r
+ for (Mat m : mCells15)\r
+ m.dispose();\r
+ }\r
+ if (mRgba != null)\r
+ mRgba.dispose();\r
+ if (mRgba15 != null)\r
+ mRgba15.dispose();\r
+\r
+ mRgba = null;\r
+ mRgba15 = null;\r
+ mCells = null;\r
+ mCells15 = null;\r
+ mIndexses = null;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public boolean onTouch(View v, MotionEvent event) {\r
+ int cols = mRgba.cols();\r
+ int rows = mRgba.rows();\r
+ float xoffset = (getWidth() - cols) / 2;\r
+ float yoffset = (getHeight() - rows) / 2;\r
+\r
+ float x = event.getX() - xoffset;\r
+ float y = event.getY() - yoffset;\r
+\r
+ int row = (int) Math.floor(y * gridSize / rows);\r
+ int col = (int) Math.floor(x * gridSize / cols);\r
+\r
+ if (row < 0 || row >= gridSize || col < 0 || col >= gridSize)\r
+ return false;\r
+\r
+ int idx = row * gridSize + col;\r
+ int idxtoswap = -1;\r
+\r
+ // left\r
+ if (idxtoswap < 0 && col > 0)\r
+ if (mIndexses[idx - 1] == gridEmptyIdx)\r
+ idxtoswap = idx - 1;\r
+ // right\r
+ if (idxtoswap < 0 && col < gridSize - 1)\r
+ if (mIndexses[idx + 1] == gridEmptyIdx)\r
+ idxtoswap = idx + 1;\r
+ // top\r
+ if (idxtoswap < 0 && row > 0)\r
+ if (mIndexses[idx - gridSize] == gridEmptyIdx)\r
+ idxtoswap = idx - gridSize;\r
+ // bottom\r
+ if (idxtoswap < 0 && row < gridSize - 1)\r
+ if (mIndexses[idx + gridSize] == gridEmptyIdx)\r
+ idxtoswap = idx + gridSize;\r
+\r
+ // swap\r
+ if (idxtoswap >= 0) {\r
+ synchronized (this) {\r
+ int touched = mIndexses[idx];\r
+ mIndexses[idx] = mIndexses[idxtoswap];\r
+ mIndexses[idxtoswap] = touched;\r
+ }\r
+ }\r
+\r
+ return false;// don't need subsequent touch events\r
+ }\r
+}\r
private SurfaceHolder mHolder;
private VideoCapture mCamera;
- private boolean mThreadRun;
public SampleViewBase(Context context) {
super(context);
public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {
Log.i(TAG, "surfaceCreated");
- if (mCamera != null && mCamera.isOpened()) {
- Log.i(TAG, "before mCamera.getSupportedPreviewSizes()");
- List<Size> sizes = mCamera.getSupportedPreviewSizes();
- Log.i(TAG, "after 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);
+ synchronized (this) {
+ if (mCamera != null && mCamera.isOpened()) {
+ Log.i(TAG, "before mCamera.getSupportedPreviewSizes()");
+ List<Size> sizes = mCamera.getSupportedPreviewSizes();
+ Log.i(TAG, "after 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);
+ mCamera.set(highgui.CV_CAP_PROP_FRAME_WIDTH, mFrameWidth);
+ mCamera.set(highgui.CV_CAP_PROP_FRAME_HEIGHT, mFrameHeight);
+ }
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.i(TAG, "surfaceDestroyed");
- mThreadRun = false;
if (mCamera != null) {
synchronized (this) {
mCamera.release();
protected abstract Bitmap processFrame(VideoCapture capture);
public void run() {
- mThreadRun = true;
Log.i(TAG, "Starting processing thread");
- while (mThreadRun) {
+ while (true) {
Bitmap bmp = null;
- if (!mCamera.grab()) {
- Log.e(TAG, "mCamera.grab() failed");
- break;
- }
-
synchronized (this) {
+ if (mCamera == null)
+ break;
+
+ if (!mCamera.grab()) {
+ Log.e(TAG, "mCamera.grab() failed");
+ break;
+ }
+
bmp = processFrame(mCamera);
}
bmp.recycle();
}
}
+
+ Log.i(TAG, "Finishing processing thread");
}
}
\ No newline at end of file