mirror of https://github.com/opencv/opencv.git
parent
1c4f441507
commit
7b1a5fb3de
15 changed files with 288 additions and 2185 deletions
@ -1,12 +1,16 @@ |
||||
set(sample example-face-detection) |
||||
|
||||
if(BUILD_FAT_JAVA_LIB) |
||||
set(native_deps opencv_java) |
||||
else() |
||||
set(native_deps opencv_objdetect) |
||||
endif() |
||||
ocv_download(FILENAME "face_detection_yunet_2023mar.onnx" |
||||
HASH "4ae92eeb150c82ce15ac80738b3b8167" |
||||
URL |
||||
"${OPENCV_FACE_DETECT_YN_URL}" |
||||
"$ENV{OPENCV_FACE_DETECT_YN_URL}" |
||||
"https://media.githubusercontent.com/media/opencv/opencv_zoo/main/models/face_detection_yunet/face_detection_yunet_2023mar.onnx" |
||||
DESTINATION_DIR "${CMAKE_CURRENT_LIST_DIR}/res/raw" |
||||
ID OPENCV_FACE_DETECT_YN |
||||
STATUS res) |
||||
|
||||
add_android_project(${sample} "${CMAKE_CURRENT_SOURCE_DIR}" LIBRARY_DEPS "${OPENCV_ANDROID_LIB_DIR}" SDK_TARGET 11 "${ANDROID_SDK_TARGET}" NATIVE_DEPS ${native_deps}) |
||||
add_android_project(${sample} "${CMAKE_CURRENT_SOURCE_DIR}" LIBRARY_DEPS "${OPENCV_ANDROID_LIB_DIR}" SDK_TARGET 11 "${ANDROID_SDK_TARGET}") |
||||
if(TARGET ${sample}) |
||||
add_dependencies(opencv_android_examples ${sample}) |
||||
endif() |
||||
|
@ -1,23 +0,0 @@ |
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS) |
||||
|
||||
#OPENCV_INSTALL_MODULES:=off
|
||||
#OPENCV_LIB_TYPE:=SHARED
|
||||
ifdef OPENCV_ANDROID_SDK |
||||
ifneq ("","$(wildcard $(OPENCV_ANDROID_SDK)/OpenCV.mk)")
|
||||
include ${OPENCV_ANDROID_SDK}/OpenCV.mk
|
||||
else
|
||||
include ${OPENCV_ANDROID_SDK}/sdk/native/jni/OpenCV.mk
|
||||
endif
|
||||
else |
||||
include ../../sdk/native/jni/OpenCV.mk
|
||||
endif |
||||
|
||||
LOCAL_SRC_FILES := DetectionBasedTracker_jni.cpp
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)
|
||||
LOCAL_LDLIBS += -llog -ldl
|
||||
|
||||
LOCAL_MODULE := detection_based_tracker
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY) |
@ -1,4 +0,0 @@ |
||||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS := -frtti -fexceptions
|
||||
APP_ABI := armeabi-v7a
|
||||
APP_PLATFORM := android-8
|
@ -1,23 +0,0 @@ |
||||
cmake_minimum_required(VERSION 3.6) |
||||
|
||||
set(target detection_based_tracker) |
||||
project(${target} CXX) |
||||
|
||||
if (OPENCV_FROM_SDK) |
||||
message(STATUS "Using OpenCV from local SDK") |
||||
set(ANDROID_OPENCV_COMPONENTS "opencv_java" CACHE STRING "") |
||||
else() |
||||
message(STATUS "Using OpenCV from AAR (Maven repo)") |
||||
set(ANDROID_OPENCV_COMPONENTS "OpenCV::opencv_java${OPENCV_VERSION_MAJOR}" CACHE STRING "") |
||||
endif() |
||||
|
||||
message(STATUS "ANDROID_ABI=${ANDROID_ABI}") |
||||
find_package(OpenCV REQUIRED COMPONENTS ${ANDROID_OPENCV_COMPONENTS}) |
||||
|
||||
file(GLOB srcs *.cpp *.c) |
||||
file(GLOB hdrs *.hpp *.h) |
||||
|
||||
include_directories("${CMAKE_CURRENT_LIST_DIR}") |
||||
add_library(${target} SHARED ${srcs} ${hdrs}) |
||||
find_library(log_lib log) |
||||
target_link_libraries(${target} ${ANDROID_OPENCV_COMPONENTS} ${log_lib}) |
@ -1,251 +0,0 @@ |
||||
#include <DetectionBasedTracker_jni.h> |
||||
#include <opencv2/core.hpp> |
||||
#include <opencv2/objdetect.hpp> |
||||
|
||||
#include <string> |
||||
#include <vector> |
||||
|
||||
#include <android/log.h> |
||||
|
||||
#define LOG_TAG "FaceDetection/DetectionBasedTracker" |
||||
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) |
||||
|
||||
using namespace std; |
||||
using namespace cv; |
||||
|
||||
inline void vector_Rect_to_Mat(vector<Rect>& v_rect, Mat& mat) |
||||
{ |
||||
mat = Mat(v_rect, true); |
||||
} |
||||
|
||||
class CascadeDetectorAdapter: public DetectionBasedTracker::IDetector |
||||
{ |
||||
public: |
||||
CascadeDetectorAdapter(cv::Ptr<cv::CascadeClassifier> detector): |
||||
IDetector(), |
||||
Detector(detector) |
||||
{ |
||||
LOGD("CascadeDetectorAdapter::Detect::Detect"); |
||||
CV_Assert(detector); |
||||
} |
||||
|
||||
void detect(const cv::Mat &Image, std::vector<cv::Rect> &objects) |
||||
{ |
||||
LOGD("CascadeDetectorAdapter::Detect: begin"); |
||||
LOGD("CascadeDetectorAdapter::Detect: scaleFactor=%.2f, minNeighbours=%d, minObjSize=(%dx%d), maxObjSize=(%dx%d)", scaleFactor, minNeighbours, minObjSize.width, minObjSize.height, maxObjSize.width, maxObjSize.height); |
||||
Detector->detectMultiScale(Image, objects, scaleFactor, minNeighbours, 0, minObjSize, maxObjSize); |
||||
LOGD("CascadeDetectorAdapter::Detect: end"); |
||||
} |
||||
|
||||
virtual ~CascadeDetectorAdapter() |
||||
{ |
||||
LOGD("CascadeDetectorAdapter::Detect::~Detect"); |
||||
} |
||||
|
||||
private: |
||||
CascadeDetectorAdapter(); |
||||
cv::Ptr<cv::CascadeClassifier> Detector; |
||||
}; |
||||
|
||||
struct DetectorAgregator |
||||
{ |
||||
cv::Ptr<CascadeDetectorAdapter> mainDetector; |
||||
cv::Ptr<CascadeDetectorAdapter> trackingDetector; |
||||
|
||||
cv::Ptr<DetectionBasedTracker> tracker; |
||||
DetectorAgregator(cv::Ptr<CascadeDetectorAdapter>& _mainDetector, cv::Ptr<CascadeDetectorAdapter>& _trackingDetector): |
||||
mainDetector(_mainDetector), |
||||
trackingDetector(_trackingDetector) |
||||
{ |
||||
CV_Assert(_mainDetector); |
||||
CV_Assert(_trackingDetector); |
||||
|
||||
DetectionBasedTracker::Parameters DetectorParams; |
||||
tracker = makePtr<DetectionBasedTracker>(mainDetector, trackingDetector, DetectorParams); |
||||
} |
||||
}; |
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject |
||||
(JNIEnv * jenv, jclass, jstring jFileName, jint faceSize) |
||||
{ |
||||
LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject enter"); |
||||
const char* jnamestr = jenv->GetStringUTFChars(jFileName, NULL); |
||||
string stdFileName(jnamestr); |
||||
jlong result = 0; |
||||
|
||||
LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject"); |
||||
|
||||
try |
||||
{ |
||||
cv::Ptr<CascadeDetectorAdapter> mainDetector = makePtr<CascadeDetectorAdapter>( |
||||
makePtr<CascadeClassifier>(stdFileName)); |
||||
cv::Ptr<CascadeDetectorAdapter> trackingDetector = makePtr<CascadeDetectorAdapter>( |
||||
makePtr<CascadeClassifier>(stdFileName)); |
||||
result = (jlong)new DetectorAgregator(mainDetector, trackingDetector); |
||||
if (faceSize > 0) |
||||
{ |
||||
mainDetector->setMinObjectSize(Size(faceSize, faceSize)); |
||||
//trackingDetector->setMinObjectSize(Size(faceSize, faceSize));
|
||||
} |
||||
} |
||||
catch(const cv::Exception& e) |
||||
{ |
||||
LOGD("nativeCreateObject caught cv::Exception: %s", e.what()); |
||||
jclass je = jenv->FindClass("org/opencv/core/CvException"); |
||||
if(!je) |
||||
je = jenv->FindClass("java/lang/Exception"); |
||||
jenv->ThrowNew(je, e.what()); |
||||
} |
||||
catch (...) |
||||
{ |
||||
LOGD("nativeCreateObject caught unknown exception"); |
||||
jclass je = jenv->FindClass("java/lang/Exception"); |
||||
jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeCreateObject()"); |
||||
return 0; |
||||
} |
||||
|
||||
LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject exit"); |
||||
return result; |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject |
||||
(JNIEnv * jenv, jclass, jlong thiz) |
||||
{ |
||||
LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject"); |
||||
|
||||
try |
||||
{ |
||||
if(thiz != 0) |
||||
{ |
||||
((DetectorAgregator*)thiz)->tracker->stop(); |
||||
delete (DetectorAgregator*)thiz; |
||||
} |
||||
} |
||||
catch(const cv::Exception& e) |
||||
{ |
||||
LOGD("nativeestroyObject caught cv::Exception: %s", e.what()); |
||||
jclass je = jenv->FindClass("org/opencv/core/CvException"); |
||||
if(!je) |
||||
je = jenv->FindClass("java/lang/Exception"); |
||||
jenv->ThrowNew(je, e.what()); |
||||
} |
||||
catch (...) |
||||
{ |
||||
LOGD("nativeDestroyObject caught unknown exception"); |
||||
jclass je = jenv->FindClass("java/lang/Exception"); |
||||
jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeDestroyObject()"); |
||||
} |
||||
LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject exit"); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart |
||||
(JNIEnv * jenv, jclass, jlong thiz) |
||||
{ |
||||
LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart"); |
||||
|
||||
try |
||||
{ |
||||
((DetectorAgregator*)thiz)->tracker->run(); |
||||
} |
||||
catch(const cv::Exception& e) |
||||
{ |
||||
LOGD("nativeStart caught cv::Exception: %s", e.what()); |
||||
jclass je = jenv->FindClass("org/opencv/core/CvException"); |
||||
if(!je) |
||||
je = jenv->FindClass("java/lang/Exception"); |
||||
jenv->ThrowNew(je, e.what()); |
||||
} |
||||
catch (...) |
||||
{ |
||||
LOGD("nativeStart caught unknown exception"); |
||||
jclass je = jenv->FindClass("java/lang/Exception"); |
||||
jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeStart()"); |
||||
} |
||||
LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart exit"); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop |
||||
(JNIEnv * jenv, jclass, jlong thiz) |
||||
{ |
||||
LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop"); |
||||
|
||||
try |
||||
{ |
||||
((DetectorAgregator*)thiz)->tracker->stop(); |
||||
} |
||||
catch(const cv::Exception& e) |
||||
{ |
||||
LOGD("nativeStop caught cv::Exception: %s", e.what()); |
||||
jclass je = jenv->FindClass("org/opencv/core/CvException"); |
||||
if(!je) |
||||
je = jenv->FindClass("java/lang/Exception"); |
||||
jenv->ThrowNew(je, e.what()); |
||||
} |
||||
catch (...) |
||||
{ |
||||
LOGD("nativeStop caught unknown exception"); |
||||
jclass je = jenv->FindClass("java/lang/Exception"); |
||||
jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeStop()"); |
||||
} |
||||
LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop exit"); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize |
||||
(JNIEnv * jenv, jclass, jlong thiz, jint faceSize) |
||||
{ |
||||
LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize -- BEGIN"); |
||||
|
||||
try |
||||
{ |
||||
if (faceSize > 0) |
||||
{ |
||||
((DetectorAgregator*)thiz)->mainDetector->setMinObjectSize(Size(faceSize, faceSize)); |
||||
//((DetectorAgregator*)thiz)->trackingDetector->setMinObjectSize(Size(faceSize, faceSize));
|
||||
} |
||||
} |
||||
catch(const cv::Exception& e) |
||||
{ |
||||
LOGD("nativeStop caught cv::Exception: %s", e.what()); |
||||
jclass je = jenv->FindClass("org/opencv/core/CvException"); |
||||
if(!je) |
||||
je = jenv->FindClass("java/lang/Exception"); |
||||
jenv->ThrowNew(je, e.what()); |
||||
} |
||||
catch (...) |
||||
{ |
||||
LOGD("nativeSetFaceSize caught unknown exception"); |
||||
jclass je = jenv->FindClass("java/lang/Exception"); |
||||
jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeSetFaceSize()"); |
||||
} |
||||
LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize -- END"); |
||||
} |
||||
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect |
||||
(JNIEnv * jenv, jclass, jlong thiz, jlong imageGray, jlong faces) |
||||
{ |
||||
LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect"); |
||||
|
||||
try |
||||
{ |
||||
vector<Rect> RectFaces; |
||||
((DetectorAgregator*)thiz)->tracker->process(*((Mat*)imageGray)); |
||||
((DetectorAgregator*)thiz)->tracker->getObjects(RectFaces); |
||||
*((Mat*)faces) = Mat(RectFaces, true); |
||||
} |
||||
catch(const cv::Exception& e) |
||||
{ |
||||
LOGD("nativeCreateObject caught cv::Exception: %s", e.what()); |
||||
jclass je = jenv->FindClass("org/opencv/core/CvException"); |
||||
if(!je) |
||||
je = jenv->FindClass("java/lang/Exception"); |
||||
jenv->ThrowNew(je, e.what()); |
||||
} |
||||
catch (...) |
||||
{ |
||||
LOGD("nativeDetect caught unknown exception"); |
||||
jclass je = jenv->FindClass("java/lang/Exception"); |
||||
jenv->ThrowNew(je, "Unknown exception in JNI code DetectionBasedTracker.nativeDetect()"); |
||||
} |
||||
LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect END"); |
||||
} |
@ -1,61 +0,0 @@ |
||||
/* DO NOT EDIT THIS FILE - it is machine generated */ |
||||
#include <jni.h> |
||||
/* 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_facedetect_DetectionBasedTracker_nativeCreateObject |
||||
(JNIEnv *, jclass, jstring, jint); |
||||
|
||||
/*
|
||||
* Class: org_opencv_samples_fd_DetectionBasedTracker |
||||
* Method: nativeDestroyObject |
||||
* Signature: (J)V |
||||
*/ |
||||
JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject |
||||
(JNIEnv *, jclass, jlong); |
||||
|
||||
/*
|
||||
* Class: org_opencv_samples_fd_DetectionBasedTracker |
||||
* Method: nativeStart |
||||
* Signature: (J)V |
||||
*/ |
||||
JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart |
||||
(JNIEnv *, jclass, jlong); |
||||
|
||||
/*
|
||||
* Class: org_opencv_samples_fd_DetectionBasedTracker |
||||
* Method: nativeStop |
||||
* Signature: (J)V |
||||
*/ |
||||
JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop |
||||
(JNIEnv *, jclass, jlong); |
||||
|
||||
/*
|
||||
* Class: org_opencv_samples_fd_DetectionBasedTracker |
||||
* Method: nativeSetFaceSize |
||||
* Signature: (JI)V |
||||
*/ |
||||
JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize |
||||
(JNIEnv *, jclass, jlong, jint); |
||||
|
||||
/*
|
||||
* Class: org_opencv_samples_fd_DetectionBasedTracker |
||||
* Method: nativeDetect |
||||
* Signature: (JJJ)V |
||||
*/ |
||||
JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect |
||||
(JNIEnv *, jclass, jlong, jlong, jlong); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
#endif |
File diff suppressed because it is too large
Load Diff
@ -1,41 +0,0 @@ |
||||
package org.opencv.samples.facedetect; |
||||
|
||||
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); |
||||
} |
@ -0,0 +1,203 @@ |
||||
package org.opencv.samples.facedetect; |
||||
|
||||
import java.lang.Math; |
||||
import java.io.File; |
||||
import java.io.FileOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.opencv.android.CameraActivity; |
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame; |
||||
import org.opencv.android.OpenCVLoader; |
||||
import org.opencv.core.Core; |
||||
import org.opencv.core.Mat; |
||||
import org.opencv.core.MatOfByte; |
||||
import org.opencv.core.Point; |
||||
import org.opencv.core.Rect; |
||||
import org.opencv.core.Scalar; |
||||
import org.opencv.core.Size; |
||||
import org.opencv.android.CameraBridgeViewBase; |
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2; |
||||
import org.opencv.objdetect.FaceDetectorYN; |
||||
import org.opencv.imgproc.Imgproc; |
||||
|
||||
import android.app.Activity; |
||||
import android.content.Context; |
||||
import android.os.Bundle; |
||||
import android.util.Log; |
||||
import android.view.Menu; |
||||
import android.view.MenuItem; |
||||
import android.view.WindowManager; |
||||
import android.widget.Toast; |
||||
|
||||
public class FaceDetectActivity extends CameraActivity implements CvCameraViewListener2 { |
||||
|
||||
private static final String TAG = "OCVSample::Activity"; |
||||
|
||||
private static final Scalar BOX_COLOR = new Scalar(0, 255, 0); |
||||
private static final Scalar RIGHT_EYE_COLOR = new Scalar(255, 0, 0); |
||||
private static final Scalar LEFT_EYE_COLOR = new Scalar(0, 0, 255); |
||||
private static final Scalar NOSE_TIP_COLOR = new Scalar(0, 255, 0); |
||||
private static final Scalar MOUTH_RIGHT_COLOR = new Scalar(255, 0, 255); |
||||
private static final Scalar MOUTH_LEFT_COLOR = new Scalar(0, 255, 255); |
||||
|
||||
private Mat mRgba; |
||||
private Mat mBgr; |
||||
private Mat mBgrScaled; |
||||
private Size mInputSize = null; |
||||
private float mScale = 2.f; |
||||
private MatOfByte mModelBuffer; |
||||
private MatOfByte mConfigBuffer; |
||||
private FaceDetectorYN mFaceDetector; |
||||
private Mat mFaces; |
||||
|
||||
private CameraBridgeViewBase mOpenCvCameraView; |
||||
|
||||
public FaceDetectActivity() { |
||||
Log.i(TAG, "Instantiated new " + this.getClass()); |
||||
} |
||||
|
||||
/** Called when the activity is first created. */ |
||||
@Override |
||||
public void onCreate(Bundle savedInstanceState) { |
||||
Log.i(TAG, "called onCreate"); |
||||
super.onCreate(savedInstanceState); |
||||
|
||||
if (OpenCVLoader.initLocal()) { |
||||
Log.i(TAG, "OpenCV loaded successfully"); |
||||
} else { |
||||
Log.e(TAG, "OpenCV initialization failed!"); |
||||
(Toast.makeText(this, "OpenCV initialization failed!", Toast.LENGTH_LONG)).show(); |
||||
return; |
||||
} |
||||
|
||||
byte[] buffer; |
||||
try { |
||||
// load cascade file from application resources
|
||||
InputStream is = getResources().openRawResource(R.raw.face_detection_yunet_2023mar); |
||||
|
||||
int size = is.available(); |
||||
buffer = new byte[size]; |
||||
int bytesRead = is.read(buffer); |
||||
is.close(); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
Log.e(TAG, "Failed to ONNX model from resources! Exception thrown: " + e); |
||||
(Toast.makeText(this, "Failed to ONNX model from resources!", Toast.LENGTH_LONG)).show(); |
||||
return; |
||||
} |
||||
|
||||
mModelBuffer = new MatOfByte(buffer); |
||||
mConfigBuffer = new MatOfByte(); |
||||
|
||||
mFaceDetector = FaceDetectorYN.create("onnx", mModelBuffer, mConfigBuffer, new Size(320, 320)); |
||||
if (mFaceDetector == null) { |
||||
Log.e(TAG, "Failed to create FaceDetectorYN!"); |
||||
(Toast.makeText(this, "Failed to create FaceDetectorYN!", Toast.LENGTH_LONG)).show(); |
||||
return; |
||||
} else |
||||
Log.i(TAG, "FaceDetectorYN initialized successfully!"); |
||||
|
||||
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); |
||||
|
||||
setContentView(R.layout.face_detect_surface_view); |
||||
|
||||
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.fd_activity_surface_view); |
||||
mOpenCvCameraView.setVisibility(CameraBridgeViewBase.VISIBLE); |
||||
mOpenCvCameraView.setCvCameraViewListener(this); |
||||
} |
||||
|
||||
@Override |
||||
public void onPause() |
||||
{ |
||||
super.onPause(); |
||||
if (mOpenCvCameraView != null) |
||||
mOpenCvCameraView.disableView(); |
||||
} |
||||
|
||||
@Override |
||||
public void onResume() |
||||
{ |
||||
super.onResume(); |
||||
if (mOpenCvCameraView != null) |
||||
mOpenCvCameraView.enableView(); |
||||
} |
||||
|
||||
@Override |
||||
protected List<? extends CameraBridgeViewBase> getCameraViewList() { |
||||
return Collections.singletonList(mOpenCvCameraView); |
||||
} |
||||
|
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
mOpenCvCameraView.disableView(); |
||||
} |
||||
|
||||
public void onCameraViewStarted(int width, int height) { |
||||
mRgba = new Mat(); |
||||
mBgr = new Mat(); |
||||
mBgrScaled = new Mat(); |
||||
mFaces = new Mat(); |
||||
} |
||||
|
||||
public void onCameraViewStopped() { |
||||
mRgba.release(); |
||||
mBgr.release(); |
||||
mBgrScaled.release(); |
||||
mFaces.release(); |
||||
} |
||||
|
||||
public void visualize(Mat rgba, Mat faces) { |
||||
|
||||
int thickness = 2; |
||||
float[] faceData = new float[faces.cols() * faces.channels()]; |
||||
|
||||
for (int i = 0; i < faces.rows(); i++) |
||||
{ |
||||
faces.get(i, 0, faceData); |
||||
|
||||
Log.d(TAG, "Detected face (" + faceData[0] + ", " + faceData[1] + ", " + |
||||
faceData[2] + ", " + faceData[3] + ")"); |
||||
|
||||
// Draw bounding box
|
||||
Imgproc.rectangle(rgba, new Rect(Math.round(mScale*faceData[0]), Math.round(mScale*faceData[1]), |
||||
Math.round(mScale*faceData[2]), Math.round(mScale*faceData[3])), |
||||
BOX_COLOR, thickness); |
||||
// Draw landmarks
|
||||
Imgproc.circle(rgba, new Point(Math.round(mScale*faceData[4]), Math.round(mScale*faceData[5])), |
||||
2, RIGHT_EYE_COLOR, thickness); |
||||
Imgproc.circle(rgba, new Point(Math.round(mScale*faceData[6]), Math.round(mScale*faceData[7])), |
||||
2, LEFT_EYE_COLOR, thickness); |
||||
Imgproc.circle(rgba, new Point(Math.round(mScale*faceData[8]), Math.round(mScale*faceData[9])), |
||||
2, NOSE_TIP_COLOR, thickness); |
||||
Imgproc.circle(rgba, new Point(Math.round(mScale*faceData[10]), Math.round(mScale*faceData[11])), |
||||
2, MOUTH_RIGHT_COLOR, thickness); |
||||
Imgproc.circle(rgba, new Point(Math.round(mScale*faceData[12]), Math.round(mScale*faceData[13])), |
||||
2, MOUTH_LEFT_COLOR, thickness); |
||||
} |
||||
} |
||||
|
||||
public Mat onCameraFrame(CvCameraViewFrame inputFrame) { |
||||
|
||||
mRgba = inputFrame.rgba(); |
||||
|
||||
if (mInputSize == null) { |
||||
mInputSize = new Size(Math.round(mRgba.cols()/mScale), Math.round(mRgba.rows()/mScale)); |
||||
mFaceDetector.setInputSize(mInputSize); |
||||
} |
||||
|
||||
Imgproc.cvtColor(mRgba, mBgr, Imgproc.COLOR_RGBA2BGR); |
||||
Imgproc.resize(mBgr, mBgrScaled, mInputSize); |
||||
|
||||
if (mFaceDetector != null) { |
||||
int status = mFaceDetector.detect(mBgrScaled, mFaces); |
||||
Log.d(TAG, "Detector returned status " + status); |
||||
visualize(mRgba, mFaces); |
||||
} |
||||
|
||||
return mRgba; |
||||
} |
||||
} |
@ -1,244 +0,0 @@ |
||||
package org.opencv.samples.facedetect; |
||||
|
||||
import java.io.File; |
||||
import java.io.FileOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.opencv.android.CameraActivity; |
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame; |
||||
import org.opencv.android.OpenCVLoader; |
||||
import org.opencv.core.Core; |
||||
import org.opencv.core.Mat; |
||||
import org.opencv.core.MatOfRect; |
||||
import org.opencv.core.Rect; |
||||
import org.opencv.core.Scalar; |
||||
import org.opencv.core.Size; |
||||
import org.opencv.android.CameraBridgeViewBase; |
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2; |
||||
import org.opencv.objdetect.CascadeClassifier; |
||||
import org.opencv.imgproc.Imgproc; |
||||
|
||||
import android.app.Activity; |
||||
import android.content.Context; |
||||
import android.os.Bundle; |
||||
import android.util.Log; |
||||
import android.view.Menu; |
||||
import android.view.MenuItem; |
||||
import android.view.WindowManager; |
||||
import android.widget.Toast; |
||||
|
||||
public class FdActivity extends CameraActivity implements CvCameraViewListener2 { |
||||
|
||||
private static final String TAG = "OCVSample::Activity"; |
||||
private static final Scalar FACE_RECT_COLOR = new Scalar(0, 255, 0, 255); |
||||
public static final int JAVA_DETECTOR = 0; |
||||
public static final int NATIVE_DETECTOR = 1; |
||||
|
||||
private MenuItem mItemFace50; |
||||
private MenuItem mItemFace40; |
||||
private MenuItem mItemFace30; |
||||
private MenuItem mItemFace20; |
||||
private MenuItem mItemType; |
||||
|
||||
private Mat mRgba; |
||||
private Mat mGray; |
||||
private File mCascadeFile; |
||||
private CascadeClassifier mJavaDetector; |
||||
private DetectionBasedTracker mNativeDetector; |
||||
|
||||
private int mDetectorType = JAVA_DETECTOR; |
||||
private String[] mDetectorName; |
||||
|
||||
private float mRelativeFaceSize = 0.2f; |
||||
private int mAbsoluteFaceSize = 0; |
||||
|
||||
private CameraBridgeViewBase mOpenCvCameraView; |
||||
|
||||
public FdActivity() { |
||||
mDetectorName = new String[2]; |
||||
mDetectorName[JAVA_DETECTOR] = "Java"; |
||||
mDetectorName[NATIVE_DETECTOR] = "Native (tracking)"; |
||||
|
||||
Log.i(TAG, "Instantiated new " + this.getClass()); |
||||
} |
||||
|
||||
/** Called when the activity is first created. */ |
||||
@Override |
||||
public void onCreate(Bundle savedInstanceState) { |
||||
Log.i(TAG, "called onCreate"); |
||||
super.onCreate(savedInstanceState); |
||||
|
||||
if (OpenCVLoader.initLocal()) { |
||||
Log.i(TAG, "OpenCV loaded successfully"); |
||||
} else { |
||||
Log.e(TAG, "OpenCV initialization failed!"); |
||||
(Toast.makeText(this, "OpenCV initialization failed!", Toast.LENGTH_LONG)).show(); |
||||
return; |
||||
} |
||||
|
||||
// Load native library after(!) OpenCV initialization
|
||||
System.loadLibrary("detection_based_tracker"); |
||||
|
||||
try { |
||||
// load cascade file from application resources
|
||||
InputStream is = getResources().openRawResource(R.raw.lbpcascade_frontalface); |
||||
File cascadeDir = getDir("cascade", Context.MODE_PRIVATE); |
||||
mCascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml"); |
||||
FileOutputStream os = new FileOutputStream(mCascadeFile); |
||||
|
||||
byte[] buffer = new byte[4096]; |
||||
int bytesRead; |
||||
while ((bytesRead = is.read(buffer)) != -1) { |
||||
os.write(buffer, 0, bytesRead); |
||||
} |
||||
is.close(); |
||||
os.close(); |
||||
|
||||
mJavaDetector = new CascadeClassifier(mCascadeFile.getAbsolutePath()); |
||||
if (mJavaDetector.empty()) { |
||||
Log.e(TAG, "Failed to load cascade classifier"); |
||||
mJavaDetector = null; |
||||
} else |
||||
Log.i(TAG, "Loaded cascade classifier from " + mCascadeFile.getAbsolutePath()); |
||||
|
||||
mNativeDetector = new DetectionBasedTracker(mCascadeFile.getAbsolutePath(), 0); |
||||
|
||||
cascadeDir.delete(); |
||||
|
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
Log.e(TAG, "Failed to load cascade. Exception thrown: " + e); |
||||
} |
||||
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); |
||||
|
||||
setContentView(R.layout.face_detect_surface_view); |
||||
|
||||
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.fd_activity_surface_view); |
||||
mOpenCvCameraView.setVisibility(CameraBridgeViewBase.VISIBLE); |
||||
mOpenCvCameraView.setCvCameraViewListener(this); |
||||
} |
||||
|
||||
@Override |
||||
public void onPause() |
||||
{ |
||||
super.onPause(); |
||||
if (mOpenCvCameraView != null) |
||||
mOpenCvCameraView.disableView(); |
||||
} |
||||
|
||||
@Override |
||||
public void onResume() |
||||
{ |
||||
super.onResume(); |
||||
if (mOpenCvCameraView != null) |
||||
mOpenCvCameraView.enableView(); |
||||
} |
||||
|
||||
@Override |
||||
protected List<? extends CameraBridgeViewBase> getCameraViewList() { |
||||
return Collections.singletonList(mOpenCvCameraView); |
||||
} |
||||
|
||||
public void onDestroy() { |
||||
super.onDestroy(); |
||||
mOpenCvCameraView.disableView(); |
||||
} |
||||
|
||||
public void onCameraViewStarted(int width, int height) { |
||||
mGray = new Mat(); |
||||
mRgba = new Mat(); |
||||
} |
||||
|
||||
public void onCameraViewStopped() { |
||||
mGray.release(); |
||||
mRgba.release(); |
||||
} |
||||
|
||||
public Mat onCameraFrame(CvCameraViewFrame inputFrame) { |
||||
|
||||
mRgba = inputFrame.rgba(); |
||||
mGray = inputFrame.gray(); |
||||
|
||||
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 == JAVA_DETECTOR) { |
||||
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 == NATIVE_DETECTOR) { |
||||
if (mNativeDetector != null) |
||||
mNativeDetector.detect(mGray, faces); |
||||
} |
||||
else { |
||||
Log.e(TAG, "Detection method is not selected!"); |
||||
} |
||||
|
||||
Rect[] facesArray = faces.toArray(); |
||||
for (int i = 0; i < facesArray.length; i++) |
||||
Imgproc.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(), FACE_RECT_COLOR, 3); |
||||
|
||||
return mRgba; |
||||
} |
||||
|
||||
@Override |
||||
public boolean onCreateOptionsMenu(Menu menu) { |
||||
Log.i(TAG, "called onCreateOptionsMenu"); |
||||
mItemFace50 = menu.add("Face size 50%"); |
||||
mItemFace40 = menu.add("Face size 40%"); |
||||
mItemFace30 = menu.add("Face size 30%"); |
||||
mItemFace20 = menu.add("Face size 20%"); |
||||
mItemType = menu.add(mDetectorName[mDetectorType]); |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public boolean onOptionsItemSelected(MenuItem item) { |
||||
Log.i(TAG, "called onOptionsItemSelected; selected item: " + item); |
||||
if (item == mItemFace50) |
||||
setMinFaceSize(0.5f); |
||||
else if (item == mItemFace40) |
||||
setMinFaceSize(0.4f); |
||||
else if (item == mItemFace30) |
||||
setMinFaceSize(0.3f); |
||||
else if (item == mItemFace20) |
||||
setMinFaceSize(0.2f); |
||||
else if (item == mItemType) { |
||||
int tmpDetectorType = (mDetectorType + 1) % mDetectorName.length; |
||||
item.setTitle(mDetectorName[tmpDetectorType]); |
||||
setDetectorType(tmpDetectorType); |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
private void setMinFaceSize(float faceSize) { |
||||
mRelativeFaceSize = faceSize; |
||||
mAbsoluteFaceSize = 0; |
||||
} |
||||
|
||||
private void setDetectorType(int type) { |
||||
if (mDetectorType != type) { |
||||
mDetectorType = type; |
||||
|
||||
if (type == NATIVE_DETECTOR) { |
||||
Log.i(TAG, "Detection Based Tracker enabled"); |
||||
mNativeDetector.start(); |
||||
} else { |
||||
Log.i(TAG, "Cascade detector enabled"); |
||||
mNativeDetector.stop(); |
||||
} |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue