diff --git a/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionActivity.java b/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionActivity.java index ecb053301d3ad1bcc93239b479b4c9cb7c5334a2..a47eb466b819dc4fc3b48a6eceea442e1aede911 100644 --- a/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionActivity.java +++ b/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionActivity.java @@ -9,7 +9,7 @@ import android.view.Window; public class ColorBlobDetectionActivity extends Activity { - private static final String TAG = "Example/CollorBlobDetection"; + private static final String TAG = "Example/ColorBlobDetection"; private ColorBlobDetectionView mView; public ColorBlobDetectionActivity() diff --git a/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionView.java b/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionView.java index d9ed3ad7dfc7ae5a475b318cea0b3c211c3ca5dc..d167cbc9f759bb1d52b37150b0b8b2abf5623e2a 100644 --- a/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionView.java +++ b/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetectionView.java @@ -1,17 +1,14 @@ package org.opencv.samples.colorblobdetect; -import java.util.ArrayList; -import java.util.Iterator; import java.util.List; - import org.opencv.android.Utils; import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.core.MatOfPoint; -import org.opencv.core.Point; import org.opencv.core.Rect; import org.opencv.core.Scalar; +import org.opencv.core.Size; import org.opencv.highgui.Highgui; import org.opencv.highgui.VideoCapture; import org.opencv.imgproc.Imgproc; @@ -29,24 +26,16 @@ public class ColorBlobDetectionView extends SampleCvViewBase implements OnTouchL private Mat mRgba; private boolean mIsColorSelected = false; - private Scalar mSelectedColorRgba = new Scalar(255); - private Scalar mSelectedColorHsv = new Scalar(255); - - // Lower and Upper bounds for range checking in HSV color space - private Scalar mLowerBound = new Scalar(0); - private Scalar mUpperBound = new Scalar(0); - + private Scalar mBlobColorRgba = new Scalar(255); + private Scalar mBlobColorHsv = new Scalar(255); + private ColorBlobDetector mDetector = new ColorBlobDetector(); private Mat mSpectrum = new Mat(); - private int mSpectrumScale = 4; - - // Color radius for range checking in HSV color space - private static final Scalar COLOR_RADIUS = new Scalar(25,50,50,0); - - // Minimum contour area in percent for contours filtering - private static final double MIN_CONTOUR_AREA = 0.1; + private static Size SPECTRUM_SIZE = new Size(200, 32); // Logcat tag - private static final String TAG = "Example/CollorBlobDetection"; + private static final String TAG = "Example/ColorBlobDetection"; + + private static final Scalar CONTOUR_COLOR = new Scalar(255,0,0,255); public ColorBlobDetectionView(Context context) @@ -85,63 +74,30 @@ public class ColorBlobDetectionView extends SampleCvViewBase implements OnTouchL touchedRect.x = (x>4) ? x-4 : 0; touchedRect.y = (y>4) ? y-4 : 0; - touchedRect.width = (x+4= COLOR_RADIUS.val[0]) ? mSelectedColorHsv.val[0]-COLOR_RADIUS.val[0] : 0; - double maxH = (mSelectedColorHsv.val[0]+COLOR_RADIUS.val[0] <= 255) ? mSelectedColorHsv.val[0]+COLOR_RADIUS.val[0] : 255; - - mLowerBound.val[0] = minH; - mUpperBound.val[0] = maxH; + Log.i(TAG, "Touched rgba color: (" + mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] + + ", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3] + ")"); - mLowerBound.val[1] = mSelectedColorHsv.val[1] - COLOR_RADIUS.val[1]; - mUpperBound.val[1] = mSelectedColorHsv.val[1] + COLOR_RADIUS.val[1]; + mDetector.setHsvColor(mBlobColorHsv); - mLowerBound.val[2] = mSelectedColorHsv.val[2] - COLOR_RADIUS.val[2]; - mUpperBound.val[2] = mSelectedColorHsv.val[2] + COLOR_RADIUS.val[2]; - - Log.d(TAG, "Bounds: " + mLowerBound + "x" + mUpperBound); - - Mat spectrumHsv = new Mat(32, (int)(maxH-minH)*mSpectrumScale, CvType.CV_8UC3); - - for (int i = 0; i < 32; i++) - { - for (int k = 0; k < mSpectrumScale; k++) - { - for (int j = 0; j < maxH-minH; j++) - { - byte[] tmp = {(byte)(minH+j), (byte)255, (byte)255}; - spectrumHsv.put(i, j*mSpectrumScale + k, tmp); - } - } - } - - Imgproc.cvtColor(spectrumHsv, mSpectrum, Imgproc.COLOR_HSV2RGB_FULL, 4); + Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE); mIsColorSelected = true; @@ -155,61 +111,17 @@ public class ColorBlobDetectionView extends SampleCvViewBase implements OnTouchL Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888); if (mIsColorSelected) - { - Mat PyrDownMat = new Mat(); - - Imgproc.pyrDown(mRgba, PyrDownMat); - Imgproc.pyrDown(PyrDownMat, PyrDownMat); - - Mat hsvMat = new Mat(); - Imgproc.cvtColor(PyrDownMat, hsvMat, Imgproc.COLOR_RGB2HSV_FULL); - - Mat rangedHsvMat = new Mat(); - Core.inRange(hsvMat, mLowerBound, mUpperBound, rangedHsvMat); - - Mat dilatedMat = new Mat(); - Imgproc.dilate(rangedHsvMat, dilatedMat, new Mat()); - - List contours = new ArrayList(); - Mat hierarchy = new Mat(); - - Imgproc.findContours(dilatedMat, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); + { + mDetector.process(mRgba); + List contours = mDetector.getContours(); + Log.e(TAG, "Contours count: " + contours.size()); + Imgproc.drawContours(mRgba, contours, -1, CONTOUR_COLOR); - // Find max contour area - double maxArea = 0; - Iterator it = contours.iterator(); - while (it.hasNext()) - { - MatOfPoint wrapper = it.next(); - double area = Imgproc.contourArea(wrapper); - if (area > maxArea) - maxArea = area; - } + Mat colorLabel = mRgba.submat(2, 34, 2, 34); + colorLabel.setTo(mBlobColorRgba); - // Filter contours by area and resize to fit the original image size - List filteredContours = new ArrayList(); - it = contours.iterator(); - while (it.hasNext()) - { - MatOfPoint wrapper = it.next(); - if (Imgproc.contourArea(wrapper) > MIN_CONTOUR_AREA*maxArea); - Point[] contour = wrapper.toArray(); - for (int i = 0; i < contour.length; i++) - { - // Original image was pyrDown twice - contour[i].x *= 4; - contour[i].y *= 4; - } - filteredContours.add(new MatOfPoint(contour)); - } - - Imgproc.drawContours(mRgba, filteredContours, -1, new Scalar(255,0,0,255)); - - Mat testColorMat = mRgba.submat(2, 34, 2, 34); - testColorMat.setTo(mSelectedColorRgba); - - Mat testSpectrumMat = mRgba.submat(2, 34, 38, 38 + mSpectrum.cols()); - mSpectrum.copyTo(testSpectrumMat); + Mat spectrumLabel = mRgba.submat(2, 2 + mSpectrum.rows(), 38, 38 + mSpectrum.cols()); + mSpectrum.copyTo(spectrumLabel); } try { @@ -223,6 +135,15 @@ public class ColorBlobDetectionView extends SampleCvViewBase implements OnTouchL return bmp; } + private Scalar converScalarHsv2Rgba(Scalar hsvColor) + { + Mat pointMatRgba = new Mat(); + Mat pointMatHsv = new Mat(1, 1, CvType.CV_8UC3, hsvColor); + Imgproc.cvtColor(pointMatHsv, pointMatRgba, Imgproc.COLOR_HSV2RGB_FULL, 4); + + return new Scalar(pointMatRgba.get(0, 0)); + } + @Override public void run() { super.run(); diff --git a/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetector.java b/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetector.java new file mode 100644 index 0000000000000000000000000000000000000000..19eeb3b204b39e097852e65ad0ab7a65082bc5d0 --- /dev/null +++ b/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetector.java @@ -0,0 +1,119 @@ +package org.opencv.samples.colorblobdetect; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.opencv.core.Core; +import org.opencv.core.CvType; +import org.opencv.core.Mat; +import org.opencv.core.MatOfPoint; +import org.opencv.core.Scalar; +import org.opencv.imgproc.Imgproc; + +public class ColorBlobDetector +{ + public void setColorRadius(Scalar radius) + { + mColorRadius = radius; + } + + public void setHsvColor(Scalar hsvColor) + { + double minH = (hsvColor.val[0] >= mColorRadius.val[0]) ? hsvColor.val[0]-mColorRadius.val[0] : 0; + double maxH = (hsvColor.val[0]+mColorRadius.val[0] <= 255) ? hsvColor.val[0]+mColorRadius.val[0] : 255; + + mLowerBound.val[0] = minH; + mUpperBound.val[0] = maxH; + + mLowerBound.val[1] = hsvColor.val[1] - mColorRadius.val[1]; + mUpperBound.val[1] = hsvColor.val[1] + mColorRadius.val[1]; + + mLowerBound.val[2] = hsvColor.val[2] - mColorRadius.val[2]; + mUpperBound.val[2] = hsvColor.val[2] + mColorRadius.val[2]; + + mLowerBound.val[3] = 0; + mUpperBound.val[3] = 255; + + Mat spectrumHsv = new Mat(1, (int)(maxH-minH), CvType.CV_8UC3); + + for (int j = 0; j < maxH-minH; j++) + { + byte[] tmp = {(byte)(minH+j), (byte)255, (byte)255}; + spectrumHsv.put(0, j, tmp); + } + + Imgproc.cvtColor(spectrumHsv, mSpectrum, Imgproc.COLOR_HSV2RGB_FULL, 4); + + } + + public Mat getSpectrum() + { + return mSpectrum; + } + + public void setMinContourArea(double area) + { + mMinContourArea = area; + } + + public void process(Mat rgbaImage) + { + Mat pyrDownMat = new Mat(); + + Imgproc.pyrDown(rgbaImage, pyrDownMat); + Imgproc.pyrDown(pyrDownMat, pyrDownMat); + + Mat hsvMat = new Mat(); + Imgproc.cvtColor(pyrDownMat, hsvMat, Imgproc.COLOR_RGB2HSV_FULL); + + Mat Mask = new Mat(); + Core.inRange(hsvMat, mLowerBound, mUpperBound, Mask); + Mat dilatedMask = new Mat(); + Imgproc.dilate(Mask, dilatedMask, new Mat()); + + List contours = new ArrayList(); + Mat hierarchy = new Mat(); + + Imgproc.findContours(dilatedMask, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); + + // Find max contour area + double maxArea = 0; + Iterator each = contours.iterator(); + while (each.hasNext()) + { + MatOfPoint wrapper = each.next(); + double area = Imgproc.contourArea(wrapper); + if (area > maxArea) + maxArea = area; + } + + // Filter contours by area and resize to fit the original image size + mContours.clear(); + each = contours.iterator(); + while (each.hasNext()) + { + MatOfPoint contour = each.next(); + if (Imgproc.contourArea(contour) > mMinContourArea*maxArea) + { + Core.multiply(contour, new Scalar(4,4), contour); + mContours.add(contour); + } + } + } + + public List getContours() + { + return mContours; + } + + // Lower and Upper bounds for range checking in HSV color space + private Scalar mLowerBound = new Scalar(0); + private Scalar mUpperBound = new Scalar(0); + // Minimum contour area in percent for contours filtering + private static double mMinContourArea = 0.1; + // Color radius for range checking in HSV color space + private Scalar mColorRadius = new Scalar(25,50,50,0); + private Mat mSpectrum = new Mat(); + private List mContours = new ArrayList();; +} diff --git a/samples/android/face-detection/jni/Android.mk b/samples/android/face-detection/jni/Android.mk index 8881e828aa5526680edc81fe5f7cdb05ef59dbca..9271198bfc8a3425cb0886581ab6a3068aa176c2 100644 --- a/samples/android/face-detection/jni/Android.mk +++ b/samples/android/face-detection/jni/Android.mk @@ -12,10 +12,10 @@ else include $(OPENCV_MK_PATH) endif -LOCAL_SRC_FILES := DetectionBaseTracker.cpp -LOCAL_C_INCLUDES := $(LOCAL_PATH) +LOCAL_SRC_FILES := DetectionBasedTracker_jni.cpp +LOCAL_C_INCLUDES := $(LOCAL_PATH) LOCAL_LDLIBS += -llog -ldl -LOCAL_MODULE := detection_base_tacker +LOCAL_MODULE := detection_based_tacker include $(BUILD_SHARED_LIBRARY) \ No newline at end of file diff --git a/samples/android/face-detection/jni/DetectionBaseTracker.h b/samples/android/face-detection/jni/DetectionBaseTracker.h deleted file mode 100644 index d6015f93f4aaaf997f581b07ab10703ddffb50a9..0000000000000000000000000000000000000000 --- a/samples/android/face-detection/jni/DetectionBaseTracker.h +++ /dev/null @@ -1,61 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include -/* Header for class org_opencv_samples_fd_DetectionBaseTracker */ - -#ifndef _Included_org_opencv_samples_fd_DetectionBaseTracker -#define _Included_org_opencv_samples_fd_DetectionBaseTracker -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: org_opencv_samples_fd_DetectionBaseTracker - * Method: nativeCreateObject - * Signature: (Ljava/lang/String;F)J - */ -JNIEXPORT jlong JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeCreateObject - (JNIEnv *, jclass, jstring, jint); - -/* - * Class: org_opencv_samples_fd_DetectionBaseTracker - * Method: nativeDestroyObject - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeDestroyObject - (JNIEnv *, jclass, jlong); - -/* - * Class: org_opencv_samples_fd_DetectionBaseTracker - * Method: nativeStart - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeStart - (JNIEnv *, jclass, jlong); - -/* - * Class: org_opencv_samples_fd_DetectionBaseTracker - * Method: nativeStop - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeStop - (JNIEnv *, jclass, jlong); - - /* - * Class: org_opencv_samples_fd_DetectionBaseTracker - * Method: nativeSetFaceSize - * Signature: (JI)V - */ - JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeSetFaceSize - (JNIEnv *, jclass, jlong, jint); - -/* - * Class: org_opencv_samples_fd_DetectionBaseTracker - * Method: nativeDetect - * Signature: (JJJ)V - */ -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeDetect - (JNIEnv *, jclass, jlong, jlong, jlong); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/samples/android/face-detection/jni/DetectionBaseTracker.cpp b/samples/android/face-detection/jni/DetectionBasedTracker_jni.cpp similarity index 63% rename from samples/android/face-detection/jni/DetectionBaseTracker.cpp rename to samples/android/face-detection/jni/DetectionBasedTracker_jni.cpp index 527d180d3d3954dd5db55762671d5ae7b66aa0b2..b03961e382d1d1812d3f2c90a2b023f4f16118a3 100644 --- a/samples/android/face-detection/jni/DetectionBaseTracker.cpp +++ b/samples/android/face-detection/jni/DetectionBasedTracker_jni.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include #include @@ -13,14 +13,12 @@ using namespace std; using namespace cv; -vector RectFaces; - inline void vector_Rect_to_Mat(vector& v_rect, Mat& mat) { mat = Mat(v_rect, true); } -JNIEXPORT jlong JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeCreateObject +JNIEXPORT jlong JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject (JNIEnv * jenv, jclass jobj, jstring jFileName, jint faceSize) { const char* jnamestr = jenv->GetStringUTFChars(jFileName, NULL); @@ -42,11 +40,18 @@ JNIEXPORT jlong JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeCr je = jenv->FindClass("java/lang/Exception"); jenv->ThrowNew(je, e.what()); } + catch (...) + { + LOGD("nativeCreateObject catched unknown exception"); + jclass je = jenv->FindClass("java/lang/Exception"); + jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}"); + return 0; + } return result; } -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeDestroyObject +JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDestroyObject (JNIEnv * jenv, jclass jobj, jlong thiz) { try @@ -62,9 +67,15 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeDes je = jenv->FindClass("java/lang/Exception"); jenv->ThrowNew(je, e.what()); } + catch (...) + { + LOGD("nativeDestroyObject catched unknown exception"); + jclass je = jenv->FindClass("java/lang/Exception"); + jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}"); + } } -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeStart +JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStart (JNIEnv * jenv, jclass jobj, jlong thiz) { try @@ -79,10 +90,15 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeSta je = jenv->FindClass("java/lang/Exception"); jenv->ThrowNew(je, e.what()); } - + catch (...) + { + LOGD("nativeStart catched unknown exception"); + jclass je = jenv->FindClass("java/lang/Exception"); + jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}"); + } } -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeStop +JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStop (JNIEnv * jenv, jclass jobj, jlong thiz) { try @@ -97,9 +113,15 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeSto je = jenv->FindClass("java/lang/Exception"); jenv->ThrowNew(je, e.what()); } + catch (...) + { + LOGD("nativeStop catched unknown exception"); + jclass je = jenv->FindClass("java/lang/Exception"); + jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}"); + } } -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeSetFaceSize +JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize (JNIEnv * jenv, jclass jobj, jlong thiz, jint faceSize) { try @@ -120,15 +142,22 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeSet if(!je) je = jenv->FindClass("java/lang/Exception"); jenv->ThrowNew(je, e.what()); - } + } + catch (...) + { + LOGD("nativeSetFaceSize catched unknown exception"); + jclass je = jenv->FindClass("java/lang/Exception"); + jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}"); + } } -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeDetect +JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect (JNIEnv * jenv, jclass jobj, jlong thiz, jlong imageGray, jlong faces) { try { + vector RectFaces; ((DetectionBasedTracker*)thiz)->process(*((Mat*)imageGray)); ((DetectionBasedTracker*)thiz)->getObjects(RectFaces); vector_Rect_to_Mat(RectFaces, *((Mat*)faces)); @@ -137,8 +166,14 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBaseTracker_nativeDet { LOGD("nativeCreateObject catched cv::Exception: %s", e.what()); jclass je = jenv->FindClass("org/opencv/core/CvException"); - if(!je) + if(!je) je = jenv->FindClass("java/lang/Exception"); jenv->ThrowNew(je, e.what()); } + catch (...) + { + LOGD("nativeDetect catched unknown exception"); + jclass je = jenv->FindClass("java/lang/Exception"); + jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}"); + } } \ No newline at end of file diff --git a/samples/android/face-detection/jni/DetectionBasedTracker_jni.h b/samples/android/face-detection/jni/DetectionBasedTracker_jni.h new file mode 100644 index 0000000000000000000000000000000000000000..1ac5758be8223a7738b79520f106cc3d60ab633b --- /dev/null +++ b/samples/android/face-detection/jni/DetectionBasedTracker_jni.h @@ -0,0 +1,61 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_opencv_samples_fd_DetectionBasedTracker */ + +#ifndef _Included_org_opencv_samples_fd_DetectionBasedTracker +#define _Included_org_opencv_samples_fd_DetectionBasedTracker +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_opencv_samples_fd_DetectionBasedTracker + * Method: nativeCreateObject + * Signature: (Ljava/lang/String;F)J + */ +JNIEXPORT jlong JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject + (JNIEnv *, jclass, jstring, jint); + +/* + * Class: org_opencv_samples_fd_DetectionBasedTracker + * Method: nativeDestroyObject + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDestroyObject + (JNIEnv *, jclass, jlong); + +/* + * Class: org_opencv_samples_fd_DetectionBasedTracker + * Method: nativeStart + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStart + (JNIEnv *, jclass, jlong); + +/* + * Class: org_opencv_samples_fd_DetectionBasedTracker + * Method: nativeStop + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStop + (JNIEnv *, jclass, jlong); + + /* + * Class: org_opencv_samples_fd_DetectionBasedTracker + * Method: nativeSetFaceSize + * Signature: (JI)V + */ + JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_opencv_samples_fd_DetectionBasedTracker + * Method: nativeDetect + * Signature: (JJJ)V + */ +JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect + (JNIEnv *, jclass, jlong, jlong, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/samples/android/face-detection/src/org/opencv/samples/fd/DetectionBaseTracker.java b/samples/android/face-detection/src/org/opencv/samples/fd/DetectionBaseTracker.java deleted file mode 100644 index 7f776f6d40877de675371ddd2c0324ee8a239f27..0000000000000000000000000000000000000000 --- a/samples/android/face-detection/src/org/opencv/samples/fd/DetectionBaseTracker.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.opencv.samples.fd; - -import org.opencv.core.Mat; -import org.opencv.core.MatOfRect; - -public class DetectionBaseTracker -{ - public DetectionBaseTracker(String filename, int faceSize) - { - mNativeObj = nativeCreateObject(filename, faceSize); - } - - public void start() - { - nativeStart(mNativeObj); - } - - public void stop() - { - nativeStop(mNativeObj); - } - - public void setMinFaceSize(int faceSize) - { - nativeSetFaceSize(mNativeObj, faceSize); - } - - public void detect(Mat imageGray, MatOfRect faces) - { - nativeDetect(mNativeObj, imageGray.getNativeObjAddr(), faces.getNativeObjAddr()); - } - - public void release() - { - nativeDestroyObject(mNativeObj); - mNativeObj = 0; - } - - protected long mNativeObj = 0; - - protected static native long nativeCreateObject(String filename, int faceSize); - protected static native void nativeDestroyObject(long thiz); - protected static native void nativeStart(long thiz); - protected static native void nativeStop(long thiz); - protected static native void nativeSetFaceSize(long thiz, int faceSize); - protected static native void nativeDetect(long thiz, long inputImage, long resultMat); - - static - { - System.loadLibrary("detection_base_tacker"); - } -} diff --git a/samples/android/face-detection/src/org/opencv/samples/fd/DetectionBasedTracker.java b/samples/android/face-detection/src/org/opencv/samples/fd/DetectionBasedTracker.java new file mode 100644 index 0000000000000000000000000000000000000000..04350ca7067e9e70a6b8bbc3dfd908417a86941a --- /dev/null +++ b/samples/android/face-detection/src/org/opencv/samples/fd/DetectionBasedTracker.java @@ -0,0 +1,52 @@ +package org.opencv.samples.fd; + +import org.opencv.core.Mat; +import org.opencv.core.MatOfRect; + +public class DetectionBasedTracker +{ + public DetectionBasedTracker(String cascadeName, int minFaceSize) + { + mNativeObj = nativeCreateObject(cascadeName, minFaceSize); + } + + public void start() + { + nativeStart(mNativeObj); + } + + public void stop() + { + nativeStop(mNativeObj); + } + + public void setMinFaceSize(int size) + { + nativeSetFaceSize(mNativeObj, size); + } + + public void detect(Mat imageGray, MatOfRect faces) + { + nativeDetect(mNativeObj, imageGray.getNativeObjAddr(), faces.getNativeObjAddr()); + } + + public void release() + { + nativeDestroyObject(mNativeObj); + mNativeObj = 0; + } + + private long mNativeObj = 0; + + private static native long nativeCreateObject(String cascadeName, int minFaceSize); + private static native void nativeDestroyObject(long thiz); + private static native void nativeStart(long thiz); + private static native void nativeStop(long thiz); + private static native void nativeSetFaceSize(long thiz, int size); + private static native void nativeDetect(long thiz, long inputImage, long faces); + + static + { + System.loadLibrary("detection_based_tacker"); + } +} diff --git a/samples/android/face-detection/src/org/opencv/samples/fd/FdActivity.java b/samples/android/face-detection/src/org/opencv/samples/fd/FdActivity.java index 59265e7c567351d18acac4fbc014b918e538f4ee..efe5daa98113d13795083011f9136fc856dfd9d3 100644 --- a/samples/android/face-detection/src/org/opencv/samples/fd/FdActivity.java +++ b/samples/android/face-detection/src/org/opencv/samples/fd/FdActivity.java @@ -26,8 +26,8 @@ public class FdActivity extends Activity { public FdActivity() { Log.i(TAG, "Instantiated new " + this.getClass()); mDetectorName = new String[2]; - mDetectorName[0] = "Cascade"; - mDetectorName[1] = "DBT"; + mDetectorName[FdView.JAVA_DETECTOR] = "Java"; + mDetectorName[FdView.NATIVE_DETECTOR] = "Native (tracking)"; } @Override @@ -62,7 +62,8 @@ public class FdActivity extends Activity { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); mView = new FdView(this); - mView.setDtetectorType(mDetectorType); + mView.setDetectorType(mDetectorType); + mView.setMinFaceSize(0.2f); setContentView(mView); } @@ -93,7 +94,7 @@ public class FdActivity extends Activity { { mDetectorType = (mDetectorType + 1) % mDetectorName.length; item.setTitle(mDetectorName[mDetectorType]); - mView.setDtetectorType(mDetectorType); + mView.setDetectorType(mDetectorType); } return true; } diff --git a/samples/android/face-detection/src/org/opencv/samples/fd/FdView.java b/samples/android/face-detection/src/org/opencv/samples/fd/FdView.java index e424a99c667be430f91e17b47f86e828eb0bf8dd..cfc55747a403252a79eb3c12be8cfd3d0e8e627c 100644 --- a/samples/android/face-detection/src/org/opencv/samples/fd/FdView.java +++ b/samples/android/face-detection/src/org/opencv/samples/fd/FdView.java @@ -22,45 +22,44 @@ import android.util.Log; import android.view.SurfaceHolder; class FdView extends SampleCvViewBase { - private static final String TAG = "Sample::FdView"; - private Mat mRgba; - private Mat mGray; - private File mCascadeFile; - private CascadeClassifier mCascade; - private DetectionBaseTracker mTracker; - - public final int CASCADE_DETECTOR = 0; - public final int DBT_DETECTOR = 1; + private static final String TAG = "Sample::FdView"; + private Mat mRgba; + private Mat mGray; + private File mCascadeFile; + private CascadeClassifier mJavaDetector; + private DetectionBasedTracker mNativeDetector; + + private static final Scalar FACE_RECT_COLOR = new Scalar(0, 255, 0, 255); - private int mDetectorType = CASCADE_DETECTOR; + public static final int JAVA_DETECTOR = 0; + public static final int NATIVE_DETECTOR = 1; + + private int mDetectorType = JAVA_DETECTOR; - public static int mFaceSize = 200; + private float mRelativeFaceSize = 0; + private int mAbsoluteFaceSize = 0; public void setMinFaceSize(float faceSize) { - int height = mGray.rows(); - if (Math.round(height * faceSize) > 0); - { - mFaceSize = Math.round(height * faceSize); - } - mTracker.setMinFaceSize(mFaceSize); + mRelativeFaceSize = faceSize; + mAbsoluteFaceSize = 0; } - public void setDtetectorType(int type) + public void setDetectorType(int type) { if (mDetectorType != type) { mDetectorType = type; - if (type == DBT_DETECTOR) + if (type == NATIVE_DETECTOR) { - Log.i(TAG, "Detection Base Tracker enabled"); - mTracker.start(); + Log.i(TAG, "Detection Based Tracker enabled"); + mNativeDetector.start(); } else { - Log.i(TAG, "Cascade detectior enabled"); - mTracker.stop(); + Log.i(TAG, "Cascade detector enabled"); + mNativeDetector.stop(); } } } @@ -82,14 +81,14 @@ class FdView extends SampleCvViewBase { is.close(); os.close(); - mCascade = new CascadeClassifier(mCascadeFile.getAbsolutePath()); - if (mCascade.empty()) { + mJavaDetector = new CascadeClassifier(mCascadeFile.getAbsolutePath()); + if (mJavaDetector.empty()) { Log.e(TAG, "Failed to load cascade classifier"); - mCascade = null; + mJavaDetector = null; } else Log.i(TAG, "Loaded cascade classifier from " + mCascadeFile.getAbsolutePath()); - mTracker = new DetectionBaseTracker(mCascadeFile.getAbsolutePath(), 0); + mNativeDetector = new DetectionBasedTracker(mCascadeFile.getAbsolutePath(), 0); cascadeDir.delete(); @@ -115,37 +114,49 @@ class FdView extends SampleCvViewBase { capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA); capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME); + if (mAbsoluteFaceSize == 0) + { + int height = mGray.rows(); + if (Math.round(height * mRelativeFaceSize) > 0); + { + mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize); + } + mNativeDetector.setMinFaceSize(mAbsoluteFaceSize); + } + MatOfRect faces = new MatOfRect(); - if (mDetectorType == CASCADE_DETECTOR) + if (mDetectorType == JAVA_DETECTOR) { - if (mCascade != null) - mCascade.detectMultiScale(mGray, faces, 1.1, 2, 2 // TODO: objdetect.CV_HAAR_SCALE_IMAGE - , new Size(mFaceSize, mFaceSize), new Size()); + if (mJavaDetector != null) + mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2, 2 // TODO: objdetect.CV_HAAR_SCALE_IMAGE + , new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size()); } - else if (mDetectorType == DBT_DETECTOR) + else if (mDetectorType == NATIVE_DETECTOR) { - if (mTracker != null) - mTracker.detect(mGray, faces); + if (mNativeDetector != null) + mNativeDetector.detect(mGray, faces); } else { Log.e(TAG, "Detection method is not selected!"); } - for (Rect r : faces.toArray()) - Core.rectangle(mRgba, r.tl(), r.br(), new Scalar(0, 255, 0, 255), 3); + Rect[] facesArray = faces.toArray(); + for (int i = 0; i < facesArray.length; i++) + Core.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(), FACE_RECT_COLOR, 3); - Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.RGB_565/*.ARGB_8888*/); + Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888); try { Utils.matToBitmap(mRgba, bmp); - return bmp; } catch(Exception e) { - Log.e("org.opencv.samples.puzzle15", "Utils.matToBitmap() throws an exception: " + e.getMessage()); + Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage()); bmp.recycle(); - return null; + bmp = null; } + + return bmp; } @Override @@ -160,8 +171,8 @@ class FdView extends SampleCvViewBase { mGray.release(); if (mCascadeFile != null) mCascadeFile.delete(); - if (mTracker != null) - mTracker.release(); + if (mNativeDetector != null) + mNativeDetector.release(); mRgba = null; mGray = null;