chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
set(sample example-face-detection)
|
||||
|
||||
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}")
|
||||
if(TARGET ${sample})
|
||||
add_dependencies(opencv_android_examples ${sample})
|
||||
endif()
|
||||
@@ -0,0 +1,37 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace 'org.opencv.samples.facedetect'
|
||||
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
|
||||
defaultConfig {
|
||||
applicationId "org.opencv.samples.facedetect"
|
||||
minSdkVersion @ANDROID_MIN_SDK_VERSION@
|
||||
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
|
||||
versionCode 301
|
||||
versionName "3.01"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
sourceSets {
|
||||
main {
|
||||
java.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
|
||||
res.srcDirs = @ANDROID_SAMPLE_RES_PATH@
|
||||
manifest.srcFile '@ANDROID_SAMPLE_MANIFEST_PATH@'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
if (gradle.opencv_source == "sdk_path") {
|
||||
println 'Using OpenCV from from SDK'
|
||||
implementation project(':opencv')
|
||||
} else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_central") {
|
||||
println 'Using OpenCV from Maven repo'
|
||||
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.opencv.samples.facedetect"
|
||||
>
|
||||
|
||||
<application
|
||||
android:label="@string/app_name"
|
||||
android:icon="@drawable/icon">
|
||||
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name="FaceDetectActivity"
|
||||
android:label="@string/app_name"
|
||||
android:configChanges="keyboardHidden|orientation">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
<supports-screens android:resizeable="true"
|
||||
android:smallScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:largeScreens="true"
|
||||
android:anyDensity="true" />
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false"/>
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
|
||||
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
|
||||
<uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>
|
||||
|
||||
</manifest>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,11 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
|
||||
<org.opencv.android.JavaCameraView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:id="@+id/fd_activity_surface_view" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">OCV Face Detection</string>
|
||||
</resources>
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
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();
|
||||
|
||||
Size inputSize = new Size(Math.round(mRgba.cols()/mScale), Math.round(mRgba.rows()/mScale));
|
||||
if (mInputSize == null || !mInputSize.equals(inputSize)) {
|
||||
mInputSize = inputSize;
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user