mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 15:53:03 +04:00
Merge branch 4.x
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace 'org.opencv.samples.puzzle15'
|
||||
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
|
||||
defaultConfig {
|
||||
applicationId "org.opencv.samples.puzzle15"
|
||||
@@ -27,5 +28,11 @@ android {
|
||||
|
||||
dependencies {
|
||||
//implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation project(':opencv')
|
||||
if (gradle.opencv_source == 'sdk_path') {
|
||||
println 'Using OpenCV from SDK'
|
||||
implementation project(':opencv')
|
||||
} else if (gradle.opencv_source == 'maven_local' || gradle.opencv_source == 'maven_cenral') {
|
||||
println 'Using OpenCV from Maven repo'
|
||||
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package org.opencv.samples.puzzle15;
|
||||
|
||||
import org.opencv.android.BaseLoaderCallback;
|
||||
import org.opencv.android.CameraActivity;
|
||||
import org.opencv.android.LoaderCallbackInterface;
|
||||
import org.opencv.android.OpenCVLoader;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.android.CameraBridgeViewBase;
|
||||
@@ -16,6 +14,7 @@ import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -29,36 +28,22 @@ public class Puzzle15Activity extends CameraActivity implements CvCameraViewList
|
||||
private MenuItem mItemHideNumbers;
|
||||
private MenuItem mItemStartNewGame;
|
||||
|
||||
|
||||
private int mGameWidth;
|
||||
private int mGameHeight;
|
||||
|
||||
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
|
||||
|
||||
@Override
|
||||
public void onManagerConnected(int status) {
|
||||
switch (status) {
|
||||
case LoaderCallbackInterface.SUCCESS:
|
||||
{
|
||||
Log.i(TAG, "OpenCV loaded successfully");
|
||||
|
||||
/* Now enable camera view to start receiving frames */
|
||||
mOpenCvCameraView.setOnTouchListener(Puzzle15Activity.this);
|
||||
mOpenCvCameraView.enableView();
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
super.onManagerConnected(status);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Log.d(TAG, "Creating and setting view");
|
||||
mOpenCvCameraView = (CameraBridgeViewBase) new JavaCameraView(this, -1);
|
||||
setContentView(mOpenCvCameraView);
|
||||
@@ -80,12 +65,9 @@ public class Puzzle15Activity extends CameraActivity implements CvCameraViewList
|
||||
public void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
if (!OpenCVLoader.initDebug()) {
|
||||
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
|
||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
|
||||
} else {
|
||||
Log.d(TAG, "OpenCV library found inside package. Using it!");
|
||||
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
|
||||
if (mOpenCvCameraView != null) {
|
||||
mOpenCvCameraView.setOnTouchListener(Puzzle15Activity.this);
|
||||
mOpenCvCameraView.enableView();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,12 @@ ocv_warnings_disable(CMAKE_CXX_FLAGS -Wmissing-declarations)
|
||||
|
||||
add_subdirectory(15-puzzle)
|
||||
add_subdirectory(face-detection)
|
||||
add_subdirectory(qr-detection)
|
||||
add_subdirectory(image-manipulations)
|
||||
add_subdirectory(camera-calibration)
|
||||
add_subdirectory(color-blob-detection)
|
||||
add_subdirectory(mobilenet-objdetect)
|
||||
add_subdirectory(video-recorder)
|
||||
add_subdirectory(tutorial-1-camerapreview)
|
||||
add_subdirectory(tutorial-2-mixedprocessing)
|
||||
add_subdirectory(tutorial-3-cameracontrol)
|
||||
|
||||
@@ -19,6 +19,11 @@ allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
if (gradle.opencv_source == "maven_local") {
|
||||
maven {
|
||||
url gradle.opencv_maven_path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace 'org.opencv.samples.cameracalibration'
|
||||
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
|
||||
defaultConfig {
|
||||
applicationId "org.opencv.samples.cameracalibration"
|
||||
@@ -27,5 +28,11 @@ android {
|
||||
|
||||
dependencies {
|
||||
//implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation project(':opencv')
|
||||
if (gradle.opencv_source == "sdk_path") {
|
||||
println 'Using OpenCV from SDK'
|
||||
implementation project(':opencv')
|
||||
} else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_cenral") {
|
||||
println 'Using OpenCV from Maven repo'
|
||||
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
|
||||
}
|
||||
}
|
||||
|
||||
+17
-32
@@ -13,12 +13,10 @@
|
||||
|
||||
package org.opencv.samples.cameracalibration;
|
||||
|
||||
import org.opencv.android.BaseLoaderCallback;
|
||||
import org.opencv.android.CameraActivity;
|
||||
import org.opencv.android.CameraBridgeViewBase;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
|
||||
import org.opencv.android.LoaderCallbackInterface;
|
||||
import org.opencv.android.OpenCVLoader;
|
||||
import org.opencv.core.Mat;
|
||||
|
||||
@@ -49,24 +47,6 @@ public class CameraCalibrationActivity extends CameraActivity implements CvCamer
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
|
||||
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
|
||||
@Override
|
||||
public void onManagerConnected(int status) {
|
||||
switch (status) {
|
||||
case LoaderCallbackInterface.SUCCESS:
|
||||
{
|
||||
Log.i(TAG, "OpenCV loaded successfully");
|
||||
mOpenCvCameraView.enableView();
|
||||
mOpenCvCameraView.setOnTouchListener(CameraCalibrationActivity.this);
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
super.onManagerConnected(status);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public CameraCalibrationActivity() {
|
||||
Log.i(TAG, "Instantiated new " + this.getClass());
|
||||
}
|
||||
@@ -75,6 +55,15 @@ public class CameraCalibrationActivity extends CameraActivity implements CvCamer
|
||||
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;
|
||||
}
|
||||
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
setContentView(R.layout.camera_calibration_surface_view);
|
||||
@@ -96,12 +85,9 @@ public class CameraCalibrationActivity extends CameraActivity implements CvCamer
|
||||
public void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
if (!OpenCVLoader.initDebug()) {
|
||||
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
|
||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
|
||||
} else {
|
||||
Log.d(TAG, "OpenCV library found inside package. Using it!");
|
||||
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
|
||||
if (mOpenCvCameraView != null) {
|
||||
mOpenCvCameraView.enableView();
|
||||
mOpenCvCameraView.setOnTouchListener(CameraCalibrationActivity.this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,23 +122,22 @@ public class CameraCalibrationActivity extends CameraActivity implements CvCamer
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.calibration:
|
||||
if (item.getItemId() == R.id.calibration) {
|
||||
mOnCameraFrameRender =
|
||||
new OnCameraFrameRender(new CalibrationFrameRender(mCalibrator));
|
||||
item.setChecked(true);
|
||||
return true;
|
||||
case R.id.undistortion:
|
||||
} else if (item.getItemId() == R.id.undistortion) {
|
||||
mOnCameraFrameRender =
|
||||
new OnCameraFrameRender(new UndistortionFrameRender(mCalibrator));
|
||||
item.setChecked(true);
|
||||
return true;
|
||||
case R.id.comparison:
|
||||
} else if (item.getItemId() == R.id.comparison) {
|
||||
mOnCameraFrameRender =
|
||||
new OnCameraFrameRender(new ComparisonFrameRender(mCalibrator, mWidth, mHeight, getResources()));
|
||||
item.setChecked(true);
|
||||
return true;
|
||||
case R.id.calibrate:
|
||||
} else if (item.getItemId() == R.id.calibrate) {
|
||||
final Resources res = getResources();
|
||||
if (mCalibrator.getCornersBufferSize() < 2) {
|
||||
(Toast.makeText(this, res.getString(R.string.more_samples), Toast.LENGTH_SHORT)).show();
|
||||
@@ -196,7 +181,7 @@ public class CameraCalibrationActivity extends CameraActivity implements CvCamer
|
||||
}
|
||||
}.execute();
|
||||
return true;
|
||||
default:
|
||||
} else {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace 'org.opencv.samples.colorblobdetect'
|
||||
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
|
||||
defaultConfig {
|
||||
applicationId "org.opencv.samples.colorblobdetect"
|
||||
@@ -27,5 +28,11 @@ android {
|
||||
|
||||
dependencies {
|
||||
//implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation project(':opencv')
|
||||
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_cenral") {
|
||||
println 'Using OpenCV from Maven repo'
|
||||
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
|
||||
}
|
||||
}
|
||||
|
||||
+13
-26
@@ -3,10 +3,8 @@ package org.opencv.samples.colorblobdetect;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.opencv.android.BaseLoaderCallback;
|
||||
import org.opencv.android.CameraActivity;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
|
||||
import org.opencv.android.LoaderCallbackInterface;
|
||||
import org.opencv.android.OpenCVLoader;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.CvType;
|
||||
@@ -28,6 +26,7 @@ import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.view.SurfaceView;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class ColorBlobDetectionActivity extends CameraActivity implements OnTouchListener, CvCameraViewListener2 {
|
||||
private static final String TAG = "OCVSample::Activity";
|
||||
@@ -43,24 +42,6 @@ public class ColorBlobDetectionActivity extends CameraActivity implements OnTouc
|
||||
|
||||
private CameraBridgeViewBase mOpenCvCameraView;
|
||||
|
||||
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
|
||||
@Override
|
||||
public void onManagerConnected(int status) {
|
||||
switch (status) {
|
||||
case LoaderCallbackInterface.SUCCESS:
|
||||
{
|
||||
Log.i(TAG, "OpenCV loaded successfully");
|
||||
mOpenCvCameraView.enableView();
|
||||
mOpenCvCameraView.setOnTouchListener(ColorBlobDetectionActivity.this);
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
super.onManagerConnected(status);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public ColorBlobDetectionActivity() {
|
||||
Log.i(TAG, "Instantiated new " + this.getClass());
|
||||
}
|
||||
@@ -70,6 +51,15 @@ public class ColorBlobDetectionActivity extends CameraActivity implements OnTouc
|
||||
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;
|
||||
}
|
||||
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
@@ -92,12 +82,9 @@ public class ColorBlobDetectionActivity extends CameraActivity implements OnTouc
|
||||
public void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
if (!OpenCVLoader.initDebug()) {
|
||||
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
|
||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
|
||||
} else {
|
||||
Log.d(TAG, "OpenCV library found inside package. Using it!");
|
||||
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
|
||||
if (mOpenCvCameraView != null) {
|
||||
mOpenCvCameraView.enableView();
|
||||
mOpenCvCameraView.setOnTouchListener(ColorBlobDetectionActivity.this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,6 +1,7 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace 'org.opencv.samples.facedetect'
|
||||
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
|
||||
defaultConfig {
|
||||
applicationId "org.opencv.samples.facedetect"
|
||||
@@ -8,13 +9,6 @@ android {
|
||||
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
|
||||
versionCode 301
|
||||
versionName "3.01"
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DOpenCV_DIR=" + project(':opencv').projectDir + "/@ANDROID_PROJECT_JNI_PATH@"@OPENCV_ANDROID_CMAKE_EXTRA_ARGS@
|
||||
targets "detection_based_tracker"
|
||||
}
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
@@ -30,14 +24,15 @@ android {
|
||||
manifest.srcFile '@ANDROID_SAMPLE_MANIFEST_PATH@'
|
||||
}
|
||||
}
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path '@ANDROID_SAMPLE_JNI_PATH@/CMakeLists.txt'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation project(':opencv')
|
||||
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_cenral") {
|
||||
println 'Using OpenCV from Maven repo'
|
||||
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name="FdActivity"
|
||||
android:name="FaceDetectActivity"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="landscape"
|
||||
android:configChanges="keyboardHidden|orientation">
|
||||
|
||||
@@ -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,15 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
|
||||
set(target detection_based_tracker)
|
||||
project(${target} CXX)
|
||||
|
||||
set(ANDROID_OPENCV_COMPONENTS "opencv_java" CACHE STRING "")
|
||||
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})
|
||||
target_link_libraries(${target} ${ANDROID_OPENCV_COMPONENTS})
|
||||
@@ -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
-41
@@ -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);
|
||||
}
|
||||
+203
@@ -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,259 +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.BaseLoaderCallback;
|
||||
import org.opencv.android.CameraActivity;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
|
||||
import org.opencv.android.LoaderCallbackInterface;
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
|
||||
@Override
|
||||
public void onManagerConnected(int status) {
|
||||
switch (status) {
|
||||
case LoaderCallbackInterface.SUCCESS:
|
||||
{
|
||||
Log.i(TAG, "OpenCV loaded successfully");
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
mOpenCvCameraView.enableView();
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
super.onManagerConnected(status);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
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 (!OpenCVLoader.initDebug()) {
|
||||
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
|
||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
|
||||
} else {
|
||||
Log.d(TAG, "OpenCV library found inside package. Using it!");
|
||||
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace 'org.opencv.samples.imagemanipulations'
|
||||
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
|
||||
defaultConfig {
|
||||
applicationId "org.opencv.samples.imagemanipulations"
|
||||
@@ -27,5 +28,11 @@ android {
|
||||
|
||||
dependencies {
|
||||
//implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation project(':opencv')
|
||||
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_cenral") {
|
||||
println 'Using OpenCV from Maven repo'
|
||||
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
|
||||
}
|
||||
}
|
||||
|
||||
+12
-26
@@ -4,10 +4,8 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.opencv.android.BaseLoaderCallback;
|
||||
import org.opencv.android.CameraActivity;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
|
||||
import org.opencv.android.LoaderCallbackInterface;
|
||||
import org.opencv.android.OpenCVLoader;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.CvType;
|
||||
@@ -26,6 +24,7 @@ import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class ImageManipulationsActivity extends CameraActivity implements CvCameraViewListener2 {
|
||||
private static final String TAG = "OCVSample::Activity";
|
||||
@@ -67,23 +66,6 @@ public class ImageManipulationsActivity extends CameraActivity implements CvCame
|
||||
|
||||
public static int viewMode = VIEW_MODE_RGBA;
|
||||
|
||||
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
|
||||
@Override
|
||||
public void onManagerConnected(int status) {
|
||||
switch (status) {
|
||||
case LoaderCallbackInterface.SUCCESS:
|
||||
{
|
||||
Log.i(TAG, "OpenCV loaded successfully");
|
||||
mOpenCvCameraView.enableView();
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
super.onManagerConnected(status);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public ImageManipulationsActivity() {
|
||||
Log.i(TAG, "Instantiated new " + this.getClass());
|
||||
}
|
||||
@@ -93,6 +75,15 @@ public class ImageManipulationsActivity extends CameraActivity implements CvCame
|
||||
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;
|
||||
}
|
||||
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
setContentView(R.layout.image_manipulations_surface_view);
|
||||
@@ -114,13 +105,8 @@ public class ImageManipulationsActivity extends CameraActivity implements CvCame
|
||||
public void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
if (!OpenCVLoader.initDebug()) {
|
||||
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
|
||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
|
||||
} else {
|
||||
Log.d(TAG, "OpenCV library found inside package. Using it!");
|
||||
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
|
||||
}
|
||||
if (mOpenCvCameraView != null)
|
||||
mOpenCvCameraView.enableView();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
set(sample example-mobilenet-objdetect)
|
||||
|
||||
ocv_download(FILENAME "mobilenet_iter_73000.caffemodel"
|
||||
HASH "bbcb3b6a0afe1ec89e1288096b5b8c66"
|
||||
URL
|
||||
"${OPENCV_MOBILENET_SSD_WEIGHTS_URL}"
|
||||
"$ENV{OPENCV_MOBILENET_SSD_WEIGHTS_URL}"
|
||||
"https://raw.githubusercontent.com/chuanqi305/MobileNet-SSD/97406996b1eee2d40eb0a00ae567cf41e23369f9/mobilenet_iter_73000.caffemodel"
|
||||
DESTINATION_DIR "${CMAKE_CURRENT_LIST_DIR}/res/raw"
|
||||
ID OPENCV_MOBILENET_SSD_WEIGHTS
|
||||
STATUS res)
|
||||
|
||||
ocv_download(FILENAME "deploy.prototxt"
|
||||
HASH "f1978dc4fe20c680e850ce99830c5945"
|
||||
URL
|
||||
"${OPENCV_MOBILENET_SSD_CONFIG_URL}"
|
||||
"$ENV{OPENCV_MOBILENET_SSD_CONFIG_URL}"
|
||||
"https://raw.githubusercontent.com/chuanqi305/MobileNet-SSD/97406996b1eee2d40eb0a00ae567cf41e23369f9/deploy.prototxt"
|
||||
DESTINATION_DIR "${CMAKE_CURRENT_LIST_DIR}/res/raw"
|
||||
ID OPENCV_MOBILENET_SSD_CONFIG
|
||||
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})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace 'org.opencv.samples.opencv_mobilenet'
|
||||
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
|
||||
defaultConfig {
|
||||
applicationId "org.opencv.samples.opencv_mobilenet"
|
||||
@@ -27,5 +28,11 @@ android {
|
||||
|
||||
dependencies {
|
||||
//implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation project(':opencv')
|
||||
if (gradle.opencv_source == "sdk_path") {
|
||||
println 'Using OpenCV from SDK'
|
||||
implementation project(':opencv')
|
||||
} else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_cenral") {
|
||||
println 'Using OpenCV from Maven repo'
|
||||
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.opencv.samples.opencv_mobilenet"
|
||||
>
|
||||
package="org.opencv.samples.opencv_mobilenet">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.AppCompat.NoActionBar"> <!--Full screen mode-->
|
||||
android:icon="@drawable/icon">
|
||||
<!-- //! [mobilenet_tutorial] -->
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name=".MainActivity"
|
||||
@@ -29,3 +25,4 @@
|
||||
<uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>
|
||||
|
||||
</manifest>
|
||||
<!-- //! [mobilenet_tutorial] -->
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
@@ -1,3 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">opencv_mobilenet</string>
|
||||
<string name="app_name">OCV Mobilenet Objdetect</string>
|
||||
</resources>
|
||||
|
||||
+86
-54
@@ -1,19 +1,25 @@
|
||||
package org.opencv.samples.opencv_mobilenet;
|
||||
|
||||
/*
|
||||
// snippet was added for Android tutorial
|
||||
//! [mobilenet_tutorial_package]
|
||||
package com.example.myapplication;
|
||||
//! [mobilenet_tutorial_package]
|
||||
*/
|
||||
//! [mobilenet_tutorial]
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetManager;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.opencv.android.BaseLoaderCallback;
|
||||
import org.opencv.android.CameraActivity;
|
||||
import org.opencv.android.CameraBridgeViewBase;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
|
||||
import org.opencv.android.LoaderCallbackInterface;
|
||||
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.Scalar;
|
||||
import org.opencv.core.Size;
|
||||
@@ -21,40 +27,44 @@ import org.opencv.dnn.Net;
|
||||
import org.opencv.dnn.Dnn;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class MainActivity extends AppCompatActivity implements CvCameraViewListener2 {
|
||||
|
||||
// Initialize OpenCV manager.
|
||||
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
|
||||
@Override
|
||||
public void onManagerConnected(int status) {
|
||||
switch (status) {
|
||||
case LoaderCallbackInterface.SUCCESS: {
|
||||
Log.i(TAG, "OpenCV loaded successfully");
|
||||
mOpenCvCameraView.enableView();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
super.onManagerConnected(status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
public class MainActivity extends CameraActivity implements CvCameraViewListener2 {
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION, this, mLoaderCallback);
|
||||
if (mOpenCvCameraView != null)
|
||||
mOpenCvCameraView.enableView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
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;
|
||||
}
|
||||
|
||||
//! [init_model_from_memory]
|
||||
mModelBuffer = loadFileFromResource(R.raw.mobilenet_iter_73000);
|
||||
mConfigBuffer = loadFileFromResource(R.raw.deploy);
|
||||
if (mModelBuffer == null || mConfigBuffer == null) {
|
||||
Log.e(TAG, "Failed to load model from resources");
|
||||
} else
|
||||
Log.i(TAG, "Model files loaded successfully");
|
||||
|
||||
net = Dnn.readNet("caffe", mModelBuffer, mConfigBuffer);
|
||||
Log.i(TAG, "Network loaded successfully");
|
||||
//! [init_model_from_memory]
|
||||
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
// Set up camera listener.
|
||||
@@ -63,12 +73,30 @@ public class MainActivity extends AppCompatActivity implements CvCameraViewListe
|
||||
mOpenCvCameraView.setCvCameraViewListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause()
|
||||
{
|
||||
super.onPause();
|
||||
if (mOpenCvCameraView != null)
|
||||
mOpenCvCameraView.disableView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
|
||||
return Collections.singletonList(mOpenCvCameraView);
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mOpenCvCameraView != null)
|
||||
mOpenCvCameraView.disableView();
|
||||
|
||||
mModelBuffer.release();
|
||||
mConfigBuffer.release();
|
||||
}
|
||||
|
||||
// Load a network.
|
||||
public void onCameraViewStarted(int width, int height) {
|
||||
String proto = getPath("MobileNetSSD_deploy.prototxt", this);
|
||||
String weights = getPath("MobileNetSSD_deploy.caffemodel", this);
|
||||
net = Dnn.readNetFromCaffe(proto, weights);
|
||||
Log.i(TAG, "Network loaded successfully");
|
||||
}
|
||||
|
||||
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
|
||||
@@ -80,10 +108,12 @@ public class MainActivity extends AppCompatActivity implements CvCameraViewListe
|
||||
final double THRESHOLD = 0.2;
|
||||
|
||||
// Get a new frame
|
||||
Log.d(TAG, "handle new frame!");
|
||||
Mat frame = inputFrame.rgba();
|
||||
Imgproc.cvtColor(frame, frame, Imgproc.COLOR_RGBA2RGB);
|
||||
|
||||
// Forward image through network.
|
||||
//! [mobilenet_handle_frame]
|
||||
Mat blob = Dnn.blobFromImage(frame, IN_SCALE_FACTOR,
|
||||
new Size(IN_WIDTH, IN_HEIGHT),
|
||||
new Scalar(MEAN_VAL, MEAN_VAL, MEAN_VAL), /*swapRB*/false, /*crop*/false);
|
||||
@@ -121,37 +151,36 @@ public class MainActivity extends AppCompatActivity implements CvCameraViewListe
|
||||
Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar(0, 0, 0));
|
||||
}
|
||||
}
|
||||
//! [mobilenet_handle_frame]
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
public void onCameraViewStopped() {}
|
||||
|
||||
// Upload file to storage and return a path.
|
||||
private static String getPath(String file, Context context) {
|
||||
AssetManager assetManager = context.getAssets();
|
||||
|
||||
BufferedInputStream inputStream = null;
|
||||
//! [mobilenet_tutorial_resource]
|
||||
private MatOfByte loadFileFromResource(int id) {
|
||||
byte[] buffer;
|
||||
try {
|
||||
// Read data from assets.
|
||||
inputStream = new BufferedInputStream(assetManager.open(file));
|
||||
byte[] data = new byte[inputStream.available()];
|
||||
inputStream.read(data);
|
||||
inputStream.close();
|
||||
// load cascade file from application resources
|
||||
InputStream is = getResources().openRawResource(id);
|
||||
|
||||
// Create copy file in storage.
|
||||
File outFile = new File(context.getFilesDir(), file);
|
||||
FileOutputStream os = new FileOutputStream(outFile);
|
||||
os.write(data);
|
||||
os.close();
|
||||
// Return a path to file which may be read in common way.
|
||||
return outFile.getAbsolutePath();
|
||||
} catch (IOException ex) {
|
||||
Log.i(TAG, "Failed to upload a file");
|
||||
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 null;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static final String TAG = "OpenCV/Sample/MobileNet";
|
||||
return new MatOfByte(buffer);
|
||||
}
|
||||
//! [mobilenet_tutorial_resource]
|
||||
|
||||
private static final String TAG = "OpenCV-MobileNet";
|
||||
private static final String[] classNames = {"background",
|
||||
"aeroplane", "bicycle", "bird", "boat",
|
||||
"bottle", "bus", "car", "cat", "chair",
|
||||
@@ -159,6 +188,9 @@ public class MainActivity extends AppCompatActivity implements CvCameraViewListe
|
||||
"motorbike", "person", "pottedplant",
|
||||
"sheep", "sofa", "train", "tvmonitor"};
|
||||
|
||||
private Net net;
|
||||
private MatOfByte mConfigBuffer;
|
||||
private MatOfByte mModelBuffer;
|
||||
private Net net;
|
||||
private CameraBridgeViewBase mOpenCvCameraView;
|
||||
}
|
||||
//! [mobilenet_tutorial]
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.opencv.samples.qrdetection"
|
||||
android:versionCode="301"
|
||||
android:versionName="3.01" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="8"/>
|
||||
|
||||
<application
|
||||
android:icon="@drawable/icon"
|
||||
android:label="@string/app_name" >
|
||||
|
||||
<activity
|
||||
android:name=".QRdetectionActivity"
|
||||
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-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>
|
||||
@@ -0,0 +1,6 @@
|
||||
set(sample example-qr-detection)
|
||||
|
||||
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,36 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace 'org.opencv.samples.qrdetection'
|
||||
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
|
||||
defaultConfig {
|
||||
applicationId "org.opencv.samples.qrdetection"
|
||||
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@
|
||||
aidl.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") {
|
||||
implementation project(':opencv')
|
||||
} else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_cenral") {
|
||||
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.opencv.samples.qrdetection">
|
||||
|
||||
<application
|
||||
android:icon="@drawable/icon"
|
||||
android:label="@string/app_name">
|
||||
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name=".QRdetectionActivity"
|
||||
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-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,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">OpenCV QR Detector</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,87 @@
|
||||
package org.opencv.samples.qrdetection;
|
||||
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfPoint;
|
||||
import org.opencv.core.Scalar;
|
||||
import org.opencv.core.Size;
|
||||
import org.opencv.core.Point;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
import org.opencv.objdetect.GraphicalCodeDetector;
|
||||
import org.opencv.objdetect.QRCodeDetector;
|
||||
import org.opencv.objdetect.QRCodeDetectorAruco;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class QRProcessor {
|
||||
private GraphicalCodeDetector detector;
|
||||
private static final String TAG = "QRProcessor";
|
||||
private Scalar LineColor = new Scalar(255, 0, 0);
|
||||
private Scalar FontColor = new Scalar(0, 0, 255);
|
||||
|
||||
public QRProcessor(boolean useArucoDetector) {
|
||||
if (useArucoDetector)
|
||||
detector = new QRCodeDetectorAruco();
|
||||
else
|
||||
detector = new QRCodeDetector();
|
||||
}
|
||||
|
||||
private boolean findQRs(Mat inputFrame, List<String> decodedInfo, MatOfPoint points,
|
||||
boolean tryDecode, boolean multiDetect) {
|
||||
boolean result = false;
|
||||
if (multiDetect) {
|
||||
if (tryDecode)
|
||||
result = detector.detectAndDecodeMulti(inputFrame, decodedInfo, points);
|
||||
else
|
||||
result = detector.detectMulti(inputFrame, points);
|
||||
}
|
||||
else {
|
||||
if(tryDecode) {
|
||||
String s = detector.detectAndDecode(inputFrame, points);
|
||||
result = !points.empty();
|
||||
if (result)
|
||||
decodedInfo.add(s);
|
||||
}
|
||||
else {
|
||||
result = detector.detect(inputFrame, points);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void renderQRs(Mat inputFrame, List<String> decodedInfo, MatOfPoint points) {
|
||||
for (int i = 0; i < points.rows(); i++) {
|
||||
for (int j = 0; j < points.cols(); j++) {
|
||||
Point pt1 = new Point(points.get(i, j));
|
||||
Point pt2 = new Point(points.get(i, (j + 1) % 4));
|
||||
Imgproc.line(inputFrame, pt1, pt2, LineColor, 3);
|
||||
}
|
||||
if (!decodedInfo.isEmpty()) {
|
||||
String decode = decodedInfo.get(i);
|
||||
if (decode.length() > 15) {
|
||||
decode = decode.substring(0, 12) + "...";
|
||||
}
|
||||
int baseline[] = {0};
|
||||
Size textSize = Imgproc.getTextSize(decode, Imgproc.FONT_HERSHEY_COMPLEX, .95, 3, baseline);
|
||||
Scalar sum = Core.sumElems(points.row(i));
|
||||
Point start = new Point(sum.val[0] / 4. - textSize.width / 2., sum.val[1] / 4. - textSize.height / 2.);
|
||||
Imgproc.putText(inputFrame, decode, start, Imgproc.FONT_HERSHEY_COMPLEX, .95, FontColor, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* this method to be called from the outside. It processes the frame to find QR codes. */
|
||||
public synchronized Mat handleFrame(Mat inputFrame, boolean tryDecode, boolean multiDetect) {
|
||||
List<String> decodedInfo = new ArrayList<String>();
|
||||
MatOfPoint points = new MatOfPoint();
|
||||
boolean result = findQRs(inputFrame, decodedInfo, points, tryDecode, multiDetect);
|
||||
if (result) {
|
||||
renderQRs(inputFrame, decodedInfo, points);
|
||||
}
|
||||
points.release();
|
||||
return inputFrame;
|
||||
}
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
package org.opencv.samples.qrdetection;
|
||||
|
||||
import org.opencv.android.CameraActivity;
|
||||
import org.opencv.android.OpenCVLoader;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.android.CameraBridgeViewBase;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener;
|
||||
import org.opencv.android.JavaCameraView;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class QRdetectionActivity extends CameraActivity implements CvCameraViewListener {
|
||||
|
||||
private static final String TAG = "QRdetection::Activity";
|
||||
|
||||
private CameraBridgeViewBase mOpenCvCameraView;
|
||||
private QRProcessor mQRDetector;
|
||||
private MenuItem mItemQRCodeDetectorAruco;
|
||||
private MenuItem mItemQRCodeDetector;
|
||||
private MenuItem mItemTryDecode;
|
||||
private MenuItem mItemMulti;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Log.d(TAG, "Creating and setting view");
|
||||
mOpenCvCameraView = new JavaCameraView(this, -1);
|
||||
setContentView(mOpenCvCameraView);
|
||||
mOpenCvCameraView.setVisibility(CameraBridgeViewBase.VISIBLE);
|
||||
mOpenCvCameraView.setCvCameraViewListener(this);
|
||||
mQRDetector = new QRProcessor(true);
|
||||
}
|
||||
|
||||
@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();
|
||||
if (mOpenCvCameraView != null)
|
||||
mOpenCvCameraView.disableView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
Log.i(TAG, "called onCreateOptionsMenu");
|
||||
mItemQRCodeDetectorAruco = menu.add("Aruco-based QR code detector");
|
||||
mItemQRCodeDetectorAruco.setCheckable(true);
|
||||
mItemQRCodeDetectorAruco.setChecked(true);
|
||||
|
||||
mItemQRCodeDetector = menu.add("Legacy QR code detector");
|
||||
mItemQRCodeDetector.setCheckable(true);
|
||||
mItemQRCodeDetector.setChecked(false);
|
||||
|
||||
mItemTryDecode = menu.add("Try to decode QR codes");
|
||||
mItemTryDecode.setCheckable(true);
|
||||
mItemTryDecode.setChecked(true);
|
||||
|
||||
mItemMulti = menu.add("Use multi detect/decode");
|
||||
mItemMulti.setCheckable(true);
|
||||
mItemMulti.setChecked(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
Log.i(TAG, "Menu Item selected " + item);
|
||||
if (item == mItemQRCodeDetector && !mItemQRCodeDetector.isChecked()) {
|
||||
mQRDetector = new QRProcessor(false);
|
||||
mItemQRCodeDetector.setChecked(true);
|
||||
mItemQRCodeDetectorAruco.setChecked(false);
|
||||
} else if (item == mItemQRCodeDetectorAruco && !mItemQRCodeDetectorAruco.isChecked()) {
|
||||
mQRDetector = new QRProcessor(true);
|
||||
mItemQRCodeDetector.setChecked(false);
|
||||
mItemQRCodeDetectorAruco.setChecked(true);
|
||||
} else if (item == mItemTryDecode) {
|
||||
mItemTryDecode.setChecked(!mItemTryDecode.isChecked());
|
||||
} else if (item == mItemMulti) {
|
||||
mItemMulti.setChecked(!mItemMulti.isChecked());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onCameraViewStarted(int width, int height) {
|
||||
}
|
||||
|
||||
public void onCameraViewStopped() {
|
||||
}
|
||||
|
||||
public Mat onCameraFrame(Mat inputFrame) {
|
||||
return mQRDetector.handleFrame(inputFrame, mItemTryDecode.isChecked(), mItemMulti.isChecked());
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace 'org.opencv.samples.tutorial1'
|
||||
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
|
||||
defaultConfig {
|
||||
applicationId "org.opencv.samples.tutorial1"
|
||||
@@ -27,5 +28,11 @@ android {
|
||||
|
||||
dependencies {
|
||||
//implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation project(':opencv')
|
||||
if (gradle.opencv_source == "sdk_path") {
|
||||
println 'Using OpenCV from SDK'
|
||||
implementation project(':opencv')
|
||||
} else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_cenral") {
|
||||
println 'Using OpenCV from Maven repo'
|
||||
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,11 +27,13 @@
|
||||
android:largeScreens="true"
|
||||
android:anyDensity="true" />
|
||||
|
||||
//! [camera_permissions]
|
||||
<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"/>
|
||||
//! [camera_permissions]
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
|
||||
<!-- [camera_view] -->
|
||||
<org.opencv.android.JavaCameraView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
@@ -11,5 +12,6 @@
|
||||
android:id="@+id/tutorial1_activity_java_surface_view"
|
||||
opencv:show_fps="true"
|
||||
opencv:camera_id="any" />
|
||||
<!-- [camera_view] -->
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
+20
-29
@@ -1,9 +1,7 @@
|
||||
package org.opencv.samples.tutorial1;
|
||||
|
||||
import org.opencv.android.BaseLoaderCallback;
|
||||
import org.opencv.android.CameraActivity;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
|
||||
import org.opencv.android.LoaderCallbackInterface;
|
||||
import org.opencv.android.OpenCVLoader;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.android.CameraBridgeViewBase;
|
||||
@@ -11,9 +9,9 @@ import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -22,25 +20,6 @@ public class Tutorial1Activity extends CameraActivity implements CvCameraViewLis
|
||||
private static final String TAG = "OCVSample::Activity";
|
||||
|
||||
private CameraBridgeViewBase mOpenCvCameraView;
|
||||
private boolean mIsJavaCamera = true;
|
||||
private MenuItem mItemSwitchCamera = null;
|
||||
|
||||
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
|
||||
@Override
|
||||
public void onManagerConnected(int status) {
|
||||
switch (status) {
|
||||
case LoaderCallbackInterface.SUCCESS:
|
||||
{
|
||||
Log.i(TAG, "OpenCV loaded successfully");
|
||||
mOpenCvCameraView.enableView();
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
super.onManagerConnected(status);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public Tutorial1Activity() {
|
||||
Log.i(TAG, "Instantiated new " + this.getClass());
|
||||
@@ -51,7 +30,20 @@ public class Tutorial1Activity extends CameraActivity implements CvCameraViewLis
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
Log.i(TAG, "called onCreate");
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
//! [ocv_loader_init]
|
||||
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;
|
||||
}
|
||||
//! [ocv_loader_init]
|
||||
|
||||
//! [keep_screen]
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
//! [keep_screen]
|
||||
|
||||
setContentView(R.layout.tutorial1_surface_view);
|
||||
|
||||
@@ -74,13 +66,8 @@ public class Tutorial1Activity extends CameraActivity implements CvCameraViewLis
|
||||
public void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
if (!OpenCVLoader.initDebug()) {
|
||||
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
|
||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
|
||||
} else {
|
||||
Log.d(TAG, "OpenCV library found inside package. Using it!");
|
||||
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
|
||||
}
|
||||
if (mOpenCvCameraView != null)
|
||||
mOpenCvCameraView.enableView();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -88,18 +75,22 @@ public class Tutorial1Activity extends CameraActivity implements CvCameraViewLis
|
||||
return Collections.singletonList(mOpenCvCameraView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mOpenCvCameraView != null)
|
||||
mOpenCvCameraView.disableView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraViewStarted(int width, int height) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraViewStopped() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
|
||||
return inputFrame.rgba();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace 'org.opencv.samples.tutorial2'
|
||||
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
|
||||
defaultConfig {
|
||||
applicationId "org.opencv.samples.tutorial2"
|
||||
@@ -11,7 +12,14 @@ android {
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DOpenCV_DIR=" + project(':opencv').projectDir + "/@ANDROID_PROJECT_JNI_PATH@"@OPENCV_ANDROID_CMAKE_EXTRA_ARGS@
|
||||
if (gradle.opencv_source == "sdk_path") {
|
||||
arguments "-DOpenCV_DIR=" + project(':opencv').projectDir + "/@ANDROID_PROJECT_JNI_PATH@",
|
||||
"-DOPENCV_FROM_SDK=TRUE"@OPENCV_ANDROID_CMAKE_EXTRA_ARGS@
|
||||
|
||||
} else {
|
||||
arguments "-DOPENCV_VERSION_MAJOR=@OPENCV_VERSION_MAJOR@",
|
||||
"-DOPENCV_FROM_SDK=FALSE"@OPENCV_ANDROID_CMAKE_EXTRA_ARGS@
|
||||
}
|
||||
targets "mixed_sample"
|
||||
}
|
||||
}
|
||||
@@ -35,9 +43,20 @@ android {
|
||||
path '@ANDROID_SAMPLE_JNI_PATH@/CMakeLists.txt'
|
||||
}
|
||||
}
|
||||
buildFeatures {
|
||||
if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_cenral") {
|
||||
prefab true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation project(':opencv')
|
||||
if (gradle.opencv_source == "sdk_path") {
|
||||
println 'Using OpenCV from SDK'
|
||||
implementation project(':opencv')
|
||||
} else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_cenral") {
|
||||
println 'Using OpenCV from Maven repo'
|
||||
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
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_MODULE := mixed_sample
|
||||
LOCAL_SRC_FILES := jni_part.cpp
|
||||
LOCAL_LDLIBS += -llog -ldl
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -1,4 +0,0 @@
|
||||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS := -frtti -fexceptions
|
||||
APP_ABI := armeabi-v7a
|
||||
APP_PLATFORM := android-8
|
||||
@@ -3,7 +3,14 @@ cmake_minimum_required(VERSION 3.6)
|
||||
set(target mixed_sample)
|
||||
project(${target} CXX)
|
||||
|
||||
set(ANDROID_OPENCV_COMPONENTS "opencv_java" CACHE STRING "")
|
||||
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})
|
||||
|
||||
|
||||
+15
-30
@@ -1,9 +1,7 @@
|
||||
package org.opencv.samples.tutorial2;
|
||||
|
||||
import org.opencv.android.BaseLoaderCallback;
|
||||
import org.opencv.android.CameraActivity;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
|
||||
import org.opencv.android.LoaderCallbackInterface;
|
||||
import org.opencv.android.OpenCVLoader;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
@@ -16,6 +14,7 @@ import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -40,27 +39,6 @@ public class Tutorial2Activity extends CameraActivity implements CvCameraViewLis
|
||||
|
||||
private CameraBridgeViewBase mOpenCvCameraView;
|
||||
|
||||
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
|
||||
@Override
|
||||
public void onManagerConnected(int status) {
|
||||
switch (status) {
|
||||
case LoaderCallbackInterface.SUCCESS:
|
||||
{
|
||||
Log.i(TAG, "OpenCV loaded successfully");
|
||||
|
||||
// Load native library after(!) OpenCV initialization
|
||||
System.loadLibrary("mixed_sample");
|
||||
|
||||
mOpenCvCameraView.enableView();
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
super.onManagerConnected(status);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public Tutorial2Activity() {
|
||||
Log.i(TAG, "Instantiated new " + this.getClass());
|
||||
}
|
||||
@@ -70,6 +48,18 @@ public class Tutorial2Activity extends CameraActivity implements CvCameraViewLis
|
||||
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("mixed_sample");
|
||||
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
setContentView(R.layout.tutorial2_surface_view);
|
||||
@@ -101,13 +91,8 @@ public class Tutorial2Activity extends CameraActivity implements CvCameraViewLis
|
||||
public void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
if (!OpenCVLoader.initDebug()) {
|
||||
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
|
||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
|
||||
} else {
|
||||
Log.d(TAG, "OpenCV library found inside package. Using it!");
|
||||
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
|
||||
}
|
||||
if (mOpenCvCameraView != null)
|
||||
mOpenCvCameraView.enableView();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace 'org.opencv.samples.tutorial3'
|
||||
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
|
||||
defaultConfig {
|
||||
applicationId "org.opencv.samples.tutorial3"
|
||||
@@ -27,5 +28,11 @@ android {
|
||||
|
||||
dependencies {
|
||||
//implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation project(':opencv')
|
||||
if (gradle.opencv_source == "sdk_path") {
|
||||
println 'Using OpenCV from SDK'
|
||||
implementation project(':opencv')
|
||||
} else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_cenral") {
|
||||
println 'Using OpenCV from Maven repo'
|
||||
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
|
||||
}
|
||||
}
|
||||
|
||||
+24
-28
@@ -6,17 +6,18 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import org.opencv.android.BaseLoaderCallback;
|
||||
import org.opencv.android.CameraActivity;
|
||||
import org.opencv.android.CameraBridgeViewBase;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
|
||||
import org.opencv.android.LoaderCallbackInterface;
|
||||
import org.opencv.android.OpenCVLoader;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.Camera.Size;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
@@ -43,24 +44,6 @@ public class Tutorial3Activity extends CameraActivity implements CvCameraViewLis
|
||||
private MenuItem[] mResolutionMenuItems;
|
||||
private SubMenu mResolutionMenu;
|
||||
|
||||
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
|
||||
@Override
|
||||
public void onManagerConnected(int status) {
|
||||
switch (status) {
|
||||
case LoaderCallbackInterface.SUCCESS:
|
||||
{
|
||||
Log.i(TAG, "OpenCV loaded successfully");
|
||||
mOpenCvCameraView.enableView();
|
||||
mOpenCvCameraView.setOnTouchListener(Tutorial3Activity.this);
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
super.onManagerConnected(status);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public Tutorial3Activity() {
|
||||
Log.i(TAG, "Instantiated new " + this.getClass());
|
||||
}
|
||||
@@ -70,6 +53,15 @@ public class Tutorial3Activity extends CameraActivity implements CvCameraViewLis
|
||||
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;
|
||||
}
|
||||
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
setContentView(R.layout.tutorial3_surface_view);
|
||||
@@ -93,12 +85,9 @@ public class Tutorial3Activity extends CameraActivity implements CvCameraViewLis
|
||||
public void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
if (!OpenCVLoader.initDebug()) {
|
||||
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
|
||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
|
||||
} else {
|
||||
Log.d(TAG, "OpenCV library found inside package. Using it!");
|
||||
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
|
||||
if (mOpenCvCameraView != null) {
|
||||
mOpenCvCameraView.enableView();
|
||||
mOpenCvCameraView.setOnTouchListener(Tutorial3Activity.this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,10 +180,17 @@ public class Tutorial3Activity extends CameraActivity implements CvCameraViewLis
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
Log.i(TAG,"onTouch event");
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
|
||||
requestPermissions(permissions, 1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
|
||||
String currentDateandTime = sdf.format(new Date());
|
||||
String fileName = Environment.getExternalStorageDirectory().getPath() +
|
||||
"/sample_picture_" + currentDateandTime + ".jpg";
|
||||
String fileName = "sample_picture_" + currentDateandTime + ".jpg";
|
||||
mOpenCvCameraView.takePicture(fileName);
|
||||
Toast.makeText(this, fileName + " saved", Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
|
||||
+40
-9
@@ -1,14 +1,24 @@
|
||||
package org.opencv.samples.tutorial3;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.opencv.android.JavaCameraView;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.hardware.Camera;
|
||||
import android.hardware.Camera.PictureCallback;
|
||||
import android.hardware.Camera.Size;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -73,15 +83,36 @@ public class Tutorial3View extends JavaCameraView implements PictureCallback {
|
||||
mCamera.setPreviewCallback(this);
|
||||
|
||||
// Write the image in a file (in jpeg format)
|
||||
try {
|
||||
FileOutputStream fos = new FileOutputStream(mPictureFileName);
|
||||
|
||||
fos.write(data);
|
||||
fos.close();
|
||||
|
||||
} catch (java.io.IOException e) {
|
||||
Log.e("PictureDemo", "Exception in photoCallback", e);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ContentResolver resolver = getContext().getContentResolver();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, mPictureFileName);
|
||||
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg");
|
||||
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
|
||||
Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
|
||||
try {
|
||||
OutputStream fos = resolver.openOutputStream(Objects.requireNonNull(imageUri));
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
|
||||
Objects.requireNonNull(fos).close();
|
||||
} catch (java.io.IOException e) {
|
||||
Log.e("PictureDemo", "Exception in photoCallback", e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
} else {
|
||||
mPictureFileName = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath()
|
||||
+ "/" + mPictureFileName;
|
||||
try {
|
||||
FileOutputStream fos = new FileOutputStream(mPictureFileName);
|
||||
fos.write(data);
|
||||
fos.close();
|
||||
} catch (java.io.IOException e) {
|
||||
Log.e("PictureDemo", "Exception in photoCallback", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,4 @@
|
||||
set(sample example-tutorial-4-opencl)
|
||||
if(NOT DEFINED ANDROID_OPENCL_SDK)
|
||||
message(STATUS "Sample ${sample} is disabled, because ANDROID_OPENCL_SDK is not specified")
|
||||
return()
|
||||
endif()
|
||||
if(ANDROID_NATIVE_API_LEVEL LESS 14)
|
||||
message(STATUS "Sample ${sample} is disabled, because ANDROID_NATIVE_API_LEVEL < 14")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(BUILD_FAT_JAVA_LIB)
|
||||
set(native_deps opencv_java)
|
||||
@@ -14,12 +6,10 @@ else()
|
||||
set(native_deps opencv_imgproc)
|
||||
endif()
|
||||
|
||||
include_directories(${ANDROID_OPENCL_SDK}/include)
|
||||
link_directories(${ANDROID_OPENCL_SDK}/lib/${ANDROID_NDK_ABI_NAME})
|
||||
add_android_project(${sample} "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
LIBRARY_DEPS "${OPENCV_ANDROID_LIB_DIR}"
|
||||
SDK_TARGET 21 "${ANDROID_SDK_TARGET}"
|
||||
NATIVE_DEPS ${native_deps} -lGLESv2 -lEGL -lOpenCL
|
||||
NATIVE_DEPS ${native_deps} -lGLESv2 -lEGL
|
||||
COPY_LIBS YES
|
||||
)
|
||||
if(TARGET ${sample})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace 'org.opencv.samples.tutorial4'
|
||||
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
|
||||
defaultConfig {
|
||||
applicationId "org.opencv.samples.tutorial4"
|
||||
@@ -11,7 +12,16 @@ android {
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DOpenCV_DIR=" + project(':opencv').projectDir + "/@ANDROID_PROJECT_JNI_PATH@"@OPENCV_ANDROID_CMAKE_EXTRA_ARGS@
|
||||
if (gradle.opencv_source == "sdk_path") {
|
||||
arguments "-DOpenCV_DIR=" + project(':opencv').projectDir + "/@ANDROID_PROJECT_JNI_PATH@",
|
||||
"-DOPENCV_FROM_SDK=TRUE",
|
||||
"-DANDROID_OPENCL_SDK=@ANDROID_OPENCL_SDK@" @OPENCV_ANDROID_CMAKE_EXTRA_ARGS@
|
||||
|
||||
} else {
|
||||
arguments "-DOPENCV_VERSION_MAJOR=@OPENCV_VERSION_MAJOR@",
|
||||
"-DOPENCV_FROM_SDK=FALSE",
|
||||
"-DANDROID_OPENCL_SDK=@ANDROID_OPENCL_SDK@" @OPENCV_ANDROID_CMAKE_EXTRA_ARGS@
|
||||
}
|
||||
targets "JNIpart"
|
||||
}
|
||||
}
|
||||
@@ -35,9 +45,20 @@ android {
|
||||
path '@ANDROID_SAMPLE_JNI_PATH@/CMakeLists.txt'
|
||||
}
|
||||
}
|
||||
buildFeatures {
|
||||
if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_cenral") {
|
||||
prefab true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation project(':opencv')
|
||||
if (gradle.opencv_source == "sdk_path") {
|
||||
println 'Using OpenCV from SDK'
|
||||
implementation project(':opencv')
|
||||
} else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_cenral") {
|
||||
println 'Using OpenCV from Maven repo'
|
||||
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
# add OpenCV
|
||||
include $(CLEAR_VARS)
|
||||
OPENCV_INSTALL_MODULES:=on
|
||||
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
|
||||
|
||||
ifndef OPENCL_SDK
|
||||
$(error Specify OPENCL_SDK to Android OpenCL SDK location)
|
||||
endif
|
||||
|
||||
# add OpenCL
|
||||
LOCAL_C_INCLUDES += $(OPENCL_SDK)/include
|
||||
LOCAL_LDLIBS += -L$(OPENCL_SDK)/lib/$(TARGET_ARCH_ABI) -lOpenCL
|
||||
|
||||
LOCAL_MODULE := JNIpart
|
||||
LOCAL_SRC_FILES := jni.c CLprocessor.cpp
|
||||
LOCAL_LDLIBS += -llog -lGLESv2 -lEGL
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -1,4 +0,0 @@
|
||||
APP_STL := gnustl_static
|
||||
APP_GNUSTL_FORCE_CPP_FEATURES := exceptions rtti
|
||||
APP_ABI := armeabi-v7a
|
||||
APP_PLATFORM := android-14
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifdef OPENCL_FOUND
|
||||
#define __CL_ENABLE_EXCEPTIONS
|
||||
#define CL_USE_DEPRECATED_OPENCL_1_1_APIS /*let's give a chance for OpenCL 1.1 devices*/
|
||||
#include <CL/cl.hpp>
|
||||
#include <CL/opencl.hpp>
|
||||
#endif
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
#include <EGL/egl.h>
|
||||
@@ -10,7 +12,9 @@
|
||||
#include <opencv2/core/ocl.hpp>
|
||||
|
||||
#include "common.hpp"
|
||||
#include "CLprocessor.hpp"
|
||||
|
||||
#ifdef OPENCL_FOUND
|
||||
const char oclProgB2B[] = "// clBuffer to clBuffer";
|
||||
const char oclProgI2B[] = "// clImage to clBuffer";
|
||||
const char oclProgI2I[] = \
|
||||
@@ -33,7 +37,7 @@ const char oclProgI2I[] = \
|
||||
" write_imagef(imgOut, pos, sum*10); \n" \
|
||||
"} \n";
|
||||
|
||||
void dumpCLinfo()
|
||||
static void dumpCLinfo()
|
||||
{
|
||||
LOGD("*** OpenCL info ***");
|
||||
try
|
||||
@@ -83,10 +87,11 @@ cl::CommandQueue theQueue;
|
||||
cl::Program theProgB2B, theProgI2B, theProgI2I;
|
||||
bool haveOpenCL = false;
|
||||
|
||||
extern "C" void initCL()
|
||||
//![init_opencl]
|
||||
int initCL()
|
||||
{
|
||||
dumpCLinfo();
|
||||
|
||||
LOGE("initCL: start initCL");
|
||||
EGLDisplay mEglDisplay = eglGetCurrentDisplay();
|
||||
if (mEglDisplay == EGL_NO_DISPLAY)
|
||||
LOGE("initCL: eglGetCurrentDisplay() returned 'EGL_NO_DISPLAY', error = %x", eglGetError());
|
||||
@@ -133,21 +138,26 @@ extern "C" void initCL()
|
||||
catch(const cl::Error& e)
|
||||
{
|
||||
LOGE("cl::Error: %s (%d)", e.what(), e.err());
|
||||
return 1;
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
LOGE("std::exception: %s", e.what());
|
||||
return 2;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
LOGE( "OpenCL info: unknown error while initializing OpenCL stuff" );
|
||||
return 3;
|
||||
}
|
||||
LOGD("initCL completed");
|
||||
}
|
||||
|
||||
extern "C" void closeCL()
|
||||
{
|
||||
if (haveOpenCL)
|
||||
return 0;
|
||||
else
|
||||
return 4;
|
||||
}
|
||||
//![init_opencl]
|
||||
|
||||
#define GL_TEXTURE_2D 0x0DE1
|
||||
void procOCL_I2I(int texIn, int texOut, int w, int h)
|
||||
@@ -160,6 +170,7 @@ void procOCL_I2I(int texIn, int texOut, int w, int h)
|
||||
}
|
||||
|
||||
LOGD("procOCL_I2I(%d, %d, %d, %d)", texIn, texOut, w, h);
|
||||
//![process_pure_opencl]
|
||||
cl::ImageGL imgIn (theContext, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, texIn);
|
||||
cl::ImageGL imgOut(theContext, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, texOut);
|
||||
std::vector < cl::Memory > images;
|
||||
@@ -187,6 +198,7 @@ void procOCL_I2I(int texIn, int texOut, int w, int h)
|
||||
theQueue.enqueueReleaseGLObjects(&images);
|
||||
theQueue.finish();
|
||||
LOGD("enqueueReleaseGLObjects() costs %d ms", getTimeInterval(t));
|
||||
//![process_pure_opencl]
|
||||
}
|
||||
|
||||
void procOCL_OCV(int texIn, int texOut, int w, int h)
|
||||
@@ -198,6 +210,7 @@ void procOCL_OCV(int texIn, int texOut, int w, int h)
|
||||
return;
|
||||
}
|
||||
|
||||
//![process_tapi]
|
||||
int64_t t = getTimeMs();
|
||||
cl::ImageGL imgIn (theContext, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, texIn);
|
||||
std::vector < cl::Memory > images(1, imgIn);
|
||||
@@ -224,11 +237,22 @@ void procOCL_OCV(int texIn, int texOut, int w, int h)
|
||||
cl_command_queue q = (cl_command_queue)cv::ocl::Queue::getDefault().ptr();
|
||||
size_t offset = 0;
|
||||
size_t origin[3] = { 0, 0, 0 };
|
||||
size_t region[3] = { w, h, 1 };
|
||||
size_t region[3] = { (size_t)w, (size_t)h, 1 };
|
||||
CV_Assert(clEnqueueCopyBufferToImage (q, clBuffer, imgOut(), offset, origin, region, 0, NULL, NULL) == CL_SUCCESS);
|
||||
theQueue.enqueueReleaseGLObjects(&images);
|
||||
cv::ocl::finish();
|
||||
LOGD("uploading results to texture costs %d ms", getTimeInterval(t));
|
||||
//![process_tapi]
|
||||
}
|
||||
#else
|
||||
int initCL()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
#endif
|
||||
|
||||
void closeCL()
|
||||
{
|
||||
}
|
||||
|
||||
void drawFrameProcCPU(int w, int h, int texOut)
|
||||
@@ -263,7 +287,7 @@ void drawFrameProcCPU(int w, int h, int texOut)
|
||||
|
||||
enum ProcMode {PROC_MODE_NO_PROC=0, PROC_MODE_CPU=1, PROC_MODE_OCL_DIRECT=2, PROC_MODE_OCL_OCV=3};
|
||||
|
||||
extern "C" void processFrame(int tex1, int tex2, int w, int h, int mode)
|
||||
void processFrame(int tex1, int tex2, int w, int h, int mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
@@ -271,12 +295,14 @@ extern "C" void processFrame(int tex1, int tex2, int w, int h, int mode)
|
||||
case PROC_MODE_CPU:
|
||||
drawFrameProcCPU(w, h, tex2);
|
||||
break;
|
||||
#ifdef OPENCL_FOUND
|
||||
case PROC_MODE_OCL_DIRECT:
|
||||
procOCL_I2I(tex1, tex2, w, h);
|
||||
break;
|
||||
case PROC_MODE_OCL_OCV:
|
||||
procOCL_OCV(tex1, tex2, w, h);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
LOGE("Unexpected processing mode: %d", mode);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef __CL_PROCESSOR_HPP__
|
||||
#define __CL_PROCESSOR_HPP__
|
||||
|
||||
int initCL();
|
||||
void closeCL();
|
||||
void processFrame(int tex1, int tex2, int w, int h, int mode);
|
||||
|
||||
#endif
|
||||
@@ -1,15 +1,42 @@
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
|
||||
set(target mixed_sample)
|
||||
set(target JNIpart)
|
||||
project(${target} CXX)
|
||||
|
||||
set(ANDROID_OPENCV_COMPONENTS "opencv_java" CACHE STRING "")
|
||||
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})
|
||||
find_package(OpenCL QUIET)
|
||||
|
||||
file(GLOB srcs *.cpp *.c)
|
||||
file(GLOB hdrs *.hpp *.h)
|
||||
|
||||
include_directories("${CMAKE_CURRENT_LIST_DIR}")
|
||||
add_library(${target} SHARED ${srcs} ${hdrs})
|
||||
target_link_libraries(${target} ${ANDROID_OPENCV_COMPONENTS} -lGLESv2 -lEGL -lOpenCL)
|
||||
|
||||
target_link_libraries(${target} ${ANDROID_OPENCV_COMPONENTS} -lGLESv2 -lEGL -llog)
|
||||
|
||||
if(OpenCL_FOUND)
|
||||
include_directories(${OpenCL_INCLUDE_DIRS})
|
||||
target_link_libraries(${target} ${OpenCL_LIBRARIES})
|
||||
add_definitions("-DOPENCL_FOUND")
|
||||
elseif(NOT ("${ANDROID_OPENCL_SDK}" STREQUAL ""))
|
||||
include_directories(${ANDROID_OPENCL_SDK}/include)
|
||||
link_directories(${ANDROID_OPENCL_SDK}/lib)
|
||||
target_link_directories(${target} PRIVATE ${ANDROID_OPENCL_SDK}/lib)
|
||||
|
||||
set_target_properties(${target} PROPERTIES LINK_FLAGS "-Wl,--allow-shlib-undefined")
|
||||
target_link_libraries(${target} -lOpenCL)
|
||||
|
||||
add_definitions("-DOPENCL_FOUND")
|
||||
add_definitions("-DCL_HPP_MINIMUM_OPENCL_VERSION=120")
|
||||
add_definitions("-DCL_HPP_TARGET_OPENCL_VERSION=120")
|
||||
add_definitions("-DCL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY")
|
||||
endif()
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
#include <jni.h>
|
||||
|
||||
int initCL();
|
||||
void closeCL();
|
||||
void processFrame(int tex1, int tex2, int w, int h, int mode);
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_samples_tutorial4_NativePart_initCL(JNIEnv * env, jclass cls)
|
||||
{
|
||||
return initCL();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativePart_closeCL(JNIEnv * env, jclass cls)
|
||||
{
|
||||
closeCL();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativePart_processFrame(JNIEnv * env, jclass cls, jint tex1, jint tex2, jint w, jint h, jint mode)
|
||||
{
|
||||
processFrame(tex1, tex2, w, h, mode);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#include <jni.h>
|
||||
#include "CLprocessor.hpp"
|
||||
|
||||
extern "C" {
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_samples_tutorial4_NativePart_builtWithOpenCL(JNIEnv * env, jclass cls);
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_samples_tutorial4_NativePart_initCL(JNIEnv * env, jclass cls);
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativePart_closeCL(JNIEnv * env, jclass cls);
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativePart_processFrame(JNIEnv * env, jclass cls, jint tex1, jint tex2, jint w, jint h, jint mode);
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_samples_tutorial4_NativePart_builtWithOpenCL(JNIEnv * env, jclass cls)
|
||||
{
|
||||
#ifdef OPENCL_FOUND
|
||||
return JNI_TRUE;
|
||||
#else
|
||||
return JNI_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_samples_tutorial4_NativePart_initCL(JNIEnv * env, jclass cls)
|
||||
{
|
||||
return initCL();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativePart_closeCL(JNIEnv * env, jclass cls)
|
||||
{
|
||||
closeCL();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_NativePart_processFrame(JNIEnv * env, jclass cls, jint tex1, jint tex2, jint w, jint h, jint mode)
|
||||
{
|
||||
processFrame(tex1, tex2, w, h, mode);
|
||||
}
|
||||
} // extern "C"
|
||||
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<group android:checkableBehavior="single">
|
||||
<item android:id="@+id/no_proc" android:title="No processing" />
|
||||
<item android:id="@+id/cpu" android:title="Use CPU code" />
|
||||
<item android:id="@+id/ocl_direct" android:title="Use OpenCL direct" />
|
||||
<item android:id="@+id/ocl_ocv" android:title="Use OpenCL via OpenCV" />
|
||||
</group>
|
||||
</menu>
|
||||
+4
-1
@@ -13,6 +13,7 @@ import android.view.SurfaceHolder;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
//![minimal_surface_view]
|
||||
public class MyGLSurfaceView extends CameraGLSurfaceView implements CameraGLSurfaceView.CameraTextureListener {
|
||||
|
||||
static final String LOGTAG = "MyGLSurfaceView";
|
||||
@@ -65,7 +66,8 @@ public class MyGLSurfaceView extends CameraGLSurfaceView implements CameraGLSurf
|
||||
Toast.makeText(getContext(), "onCameraViewStarted", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
NativePart.initCL();
|
||||
if (NativePart.builtWithOpenCL())
|
||||
NativePart.initCL();
|
||||
frameCounter = 0;
|
||||
lastNanoTime = System.nanoTime();
|
||||
}
|
||||
@@ -110,3 +112,4 @@ public class MyGLSurfaceView extends CameraGLSurfaceView implements CameraGLSurf
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//![minimal_surface_view]
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package org.opencv.samples.tutorial4;
|
||||
|
||||
//![native_part]
|
||||
public class NativePart {
|
||||
static
|
||||
{
|
||||
System.loadLibrary("opencv_java4");
|
||||
System.loadLibrary("opencv_java5");
|
||||
System.loadLibrary("JNIpart");
|
||||
}
|
||||
|
||||
@@ -12,7 +13,9 @@ public class NativePart {
|
||||
public static final int PROCESSING_MODE_OCL_DIRECT = 2;
|
||||
public static final int PROCESSING_MODE_OCL_OCV = 3;
|
||||
|
||||
public static native boolean builtWithOpenCL();
|
||||
public static native int initCL();
|
||||
public static native void closeCL();
|
||||
public static native void processFrame(int tex1, int tex2, int w, int h, int mode);
|
||||
}
|
||||
//![native_part]
|
||||
|
||||
+39
-41
@@ -1,6 +1,5 @@
|
||||
package org.opencv.samples.tutorial4;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
@@ -10,11 +9,20 @@ import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class Tutorial4Activity extends Activity {
|
||||
import org.opencv.android.CameraActivity;
|
||||
|
||||
public class Tutorial4Activity extends CameraActivity {
|
||||
|
||||
private MyGLSurfaceView mView;
|
||||
private TextView mProcMode;
|
||||
|
||||
private boolean builtWithOpenCL = false;
|
||||
|
||||
private MenuItem mItemNoProc;
|
||||
private MenuItem mItemCpu;
|
||||
private MenuItem mItemOclDirect;
|
||||
private MenuItem mItemOclOpenCV;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -38,6 +46,7 @@ public class Tutorial4Activity extends Activity {
|
||||
}
|
||||
});
|
||||
|
||||
builtWithOpenCL = NativePart.builtWithOpenCL();
|
||||
mView.setProcessingMode(NativePart.PROCESSING_MODE_NO_PROCESSING);
|
||||
}
|
||||
|
||||
@@ -55,48 +64,37 @@ public class Tutorial4Activity extends Activity {
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.menu, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
mItemNoProc = menu.add("No processing");
|
||||
mItemCpu = menu.add("Use CPU code");
|
||||
if (builtWithOpenCL) {
|
||||
mItemOclOpenCV = menu.add("Use OpenCL via OpenCV");
|
||||
mItemOclDirect = menu.add("Use OpenCL direct");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.no_proc:
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
mProcMode.setText("Processing mode: No Processing");
|
||||
}
|
||||
});
|
||||
mView.setProcessingMode(NativePart.PROCESSING_MODE_NO_PROCESSING);
|
||||
return true;
|
||||
case R.id.cpu:
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
mProcMode.setText("Processing mode: CPU");
|
||||
}
|
||||
});
|
||||
mView.setProcessingMode(NativePart.PROCESSING_MODE_CPU);
|
||||
return true;
|
||||
case R.id.ocl_direct:
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
mProcMode.setText("Processing mode: OpenCL direct");
|
||||
}
|
||||
});
|
||||
mView.setProcessingMode(NativePart.PROCESSING_MODE_OCL_DIRECT);
|
||||
return true;
|
||||
case R.id.ocl_ocv:
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
mProcMode.setText("Processing mode: OpenCL via OpenCV (TAPI)");
|
||||
}
|
||||
});
|
||||
mView.setProcessingMode(NativePart.PROCESSING_MODE_OCL_OCV);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
String procName = "Not selected";
|
||||
int procMode = NativePart.PROCESSING_MODE_NO_PROCESSING;
|
||||
|
||||
if (item == mItemNoProc) {
|
||||
procMode = NativePart.PROCESSING_MODE_NO_PROCESSING;
|
||||
procName = "Processing mode: No Processing";
|
||||
} else if (item == mItemCpu) {
|
||||
procMode = NativePart.PROCESSING_MODE_CPU;
|
||||
procName = "Processing mode: CPU";
|
||||
} else if (item == mItemOclOpenCV && builtWithOpenCL) {
|
||||
procMode = NativePart.PROCESSING_MODE_OCL_OCV;
|
||||
procName = "Processing mode: OpenCL via OpenCV (TAPI)";
|
||||
} else if (item == mItemOclDirect && builtWithOpenCL) {
|
||||
procMode = NativePart.PROCESSING_MODE_OCL_DIRECT;
|
||||
procName = "Processing mode: OpenCL direct";
|
||||
}
|
||||
|
||||
mView.setProcessingMode(procMode);
|
||||
mProcMode.setText(procName);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
set(sample example-video-recorder)
|
||||
|
||||
if(BUILD_FAT_JAVA_LIB)
|
||||
set(native_deps opencv_java)
|
||||
else()
|
||||
set(native_deps videoio)
|
||||
endif()
|
||||
|
||||
add_android_project(${sample} "${CMAKE_CURRENT_SOURCE_DIR}" LIBRARY_DEPS "${OPENCV_ANDROID_LIB_DIR}" SDK_TARGET 11 "${ANDROID_SDK_TARGET}" NATIVE_DEPS ${native_deps})
|
||||
if(TARGET ${sample})
|
||||
add_dependencies(opencv_android_examples ${sample})
|
||||
endif()
|
||||
@@ -0,0 +1,36 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace 'org.opencv.samples.recorder'
|
||||
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
|
||||
defaultConfig {
|
||||
applicationId "org.opencv.samples.recorder"
|
||||
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@
|
||||
aidl.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") {
|
||||
implementation project(':opencv')
|
||||
} else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_cenral") {
|
||||
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.opencv.samples.recorder"
|
||||
>
|
||||
|
||||
<application
|
||||
android:label="@string/app_name"
|
||||
android:icon="@drawable/icon"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
|
||||
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name="RecorderActivity"
|
||||
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>
|
||||
|
||||
<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-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
<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,38 @@
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:opencv="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="50dp"
|
||||
android:layout_margin="10dp"
|
||||
android:text="Start Camera" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textview1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="right"
|
||||
android:layout_margin="10dp"
|
||||
android:text="Status: Initialized"
|
||||
android:textColor="#FF0000" />
|
||||
|
||||
<org.opencv.android.JavaCameraView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/recorder_activity_java_surface_view"
|
||||
opencv:show_fps="true"
|
||||
opencv:camera_id="any" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_view"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">OpenCV Video Recorder</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,340 @@
|
||||
package org.opencv.samples.recorder;
|
||||
|
||||
import org.opencv.android.CameraActivity;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
|
||||
import org.opencv.android.OpenCVLoader;
|
||||
import org.opencv.android.Utils;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.Size;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
import org.opencv.videoio.VideoCapture;
|
||||
import org.opencv.videoio.VideoWriter;
|
||||
import org.opencv.android.CameraBridgeViewBase;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
|
||||
import org.opencv.videoio.Videoio;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.WindowManager;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class RecorderActivity extends CameraActivity implements CvCameraViewListener2, View.OnClickListener {
|
||||
private static final String TAG = "OCVSample::Activity";
|
||||
private static final String FILENAME_MP4 = "sample_video1.mp4";
|
||||
private static final String FILENAME_AVI = "sample_video1.avi";
|
||||
|
||||
private static final int STATUS_FINISHED_PLAYBACK = 0;
|
||||
private static final int STATUS_PREVIEW = 1;
|
||||
private static final int STATUS_RECORDING = 2;
|
||||
private static final int STATUS_PLAYING = 3;
|
||||
private static final int STATUS_ERROR = 4;
|
||||
|
||||
private String mVideoFilename;
|
||||
private boolean mUseBuiltInMJPG = false;
|
||||
|
||||
private int mStatus = STATUS_FINISHED_PLAYBACK;
|
||||
private int mFPS = 30;
|
||||
private int mWidth = 0, mHeight = 0;
|
||||
|
||||
private CameraBridgeViewBase mOpenCvCameraView;
|
||||
private ImageView mImageView;
|
||||
private Button mTriggerButton;
|
||||
private TextView mStatusTextView;
|
||||
Runnable mPlayerThread;
|
||||
|
||||
private VideoWriter mVideoWriter = null;
|
||||
private VideoCapture mVideoCapture = null;
|
||||
private Mat mVideoFrame;
|
||||
private Mat mRenderFrame;
|
||||
|
||||
public RecorderActivity() {
|
||||
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);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
setContentView(R.layout.recorder_surface_view);
|
||||
|
||||
mStatusTextView = (TextView) findViewById(R.id.textview1);
|
||||
mStatusTextView.bringToFront();
|
||||
|
||||
if (OpenCVLoader.initLocal()) {
|
||||
Log.i(TAG, "OpenCV loaded successfully");
|
||||
} else {
|
||||
Log.e(TAG, "OpenCV initialization failed!");
|
||||
mStatus = STATUS_ERROR;
|
||||
mStatusTextView.setText("Error: Can't initialize OpenCV");
|
||||
return;
|
||||
}
|
||||
|
||||
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.recorder_activity_java_surface_view);
|
||||
mOpenCvCameraView.setVisibility(SurfaceView.GONE);
|
||||
mOpenCvCameraView.setCvCameraViewListener(this);
|
||||
mOpenCvCameraView.disableView();
|
||||
|
||||
mImageView = (ImageView) findViewById(R.id.image_view);
|
||||
|
||||
mTriggerButton = (Button) findViewById(R.id.btn1);
|
||||
mTriggerButton.setOnClickListener(this);
|
||||
mTriggerButton.bringToFront();
|
||||
|
||||
if (mUseBuiltInMJPG)
|
||||
mVideoFilename = getFilesDir() + "/" + FILENAME_AVI;
|
||||
else
|
||||
mVideoFilename = getFilesDir() + "/" + FILENAME_MP4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause()
|
||||
{
|
||||
Log.d(TAG, "Pause");
|
||||
super.onPause();
|
||||
if (mOpenCvCameraView != null)
|
||||
mOpenCvCameraView.disableView();
|
||||
mImageView.setVisibility(SurfaceView.GONE);
|
||||
if (mVideoWriter != null) {
|
||||
mVideoWriter.release();
|
||||
mVideoWriter = null;
|
||||
}
|
||||
if (mVideoCapture != null) {
|
||||
mVideoCapture.release();
|
||||
mVideoCapture = null;
|
||||
}
|
||||
mStatus = STATUS_FINISHED_PLAYBACK;
|
||||
mStatusTextView.setText("Status: Finished playback");
|
||||
mTriggerButton.setText("Start Camera");
|
||||
|
||||
mVideoFrame.release();
|
||||
mRenderFrame.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume()
|
||||
{
|
||||
Log.d(TAG, "onResume");
|
||||
super.onResume();
|
||||
|
||||
mVideoFrame = new Mat();
|
||||
mRenderFrame = new Mat();
|
||||
|
||||
changeStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
|
||||
return Collections.singletonList(mOpenCvCameraView);
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
Log.d(TAG, "called onDestroy");
|
||||
super.onDestroy();
|
||||
if (mOpenCvCameraView != null)
|
||||
mOpenCvCameraView.disableView();
|
||||
if (mVideoWriter != null)
|
||||
mVideoWriter.release();
|
||||
if (mVideoCapture != null)
|
||||
mVideoCapture.release();
|
||||
}
|
||||
|
||||
public void onCameraViewStarted(int width, int height) {
|
||||
Log.d(TAG, "Camera view started " + String.valueOf(width) + "x" + String.valueOf(height));
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
}
|
||||
|
||||
public void onCameraViewStopped() {
|
||||
Log.d(TAG, "Camera view stopped");
|
||||
}
|
||||
|
||||
public Mat onCameraFrame(CvCameraViewFrame inputFrame)
|
||||
{
|
||||
Log.d(TAG, "Camera frame arrived");
|
||||
|
||||
Mat rgbMat = inputFrame.rgba();
|
||||
|
||||
Log.d(TAG, "Size: " + rgbMat.width() + "x" + rgbMat.height());
|
||||
|
||||
if (mVideoWriter != null && mVideoWriter.isOpened()) {
|
||||
Imgproc.cvtColor(rgbMat, mVideoFrame, Imgproc.COLOR_RGBA2BGR);
|
||||
mVideoWriter.write(mVideoFrame);
|
||||
}
|
||||
|
||||
return rgbMat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Log.i(TAG,"onClick event");
|
||||
changeStatus();
|
||||
}
|
||||
|
||||
public void changeStatus() {
|
||||
switch(mStatus) {
|
||||
case STATUS_ERROR:
|
||||
Toast.makeText(this, "Error", Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case STATUS_FINISHED_PLAYBACK:
|
||||
if (!startPreview()) {
|
||||
setErrorStatus();
|
||||
break;
|
||||
}
|
||||
mStatus = STATUS_PREVIEW;
|
||||
mStatusTextView.setText("Status: Camera preview");
|
||||
mTriggerButton.setText("Start recording");
|
||||
break;
|
||||
case STATUS_PREVIEW:
|
||||
if (!startRecording()) {
|
||||
setErrorStatus();
|
||||
break;
|
||||
}
|
||||
mStatus = STATUS_RECORDING;
|
||||
mStatusTextView.setText("Status: recording video");
|
||||
mTriggerButton.setText(" Stop and play video");
|
||||
break;
|
||||
case STATUS_RECORDING:
|
||||
if (!stopRecording()) {
|
||||
setErrorStatus();
|
||||
break;
|
||||
}
|
||||
if (!startPlayback()) {
|
||||
setErrorStatus();
|
||||
break;
|
||||
}
|
||||
mStatus = STATUS_PLAYING;
|
||||
mStatusTextView.setText("Status: Playing video");
|
||||
mTriggerButton.setText("Stop playback");
|
||||
break;
|
||||
case STATUS_PLAYING:
|
||||
if (!stopPlayback()) {
|
||||
setErrorStatus();
|
||||
break;
|
||||
}
|
||||
mStatus = STATUS_FINISHED_PLAYBACK;
|
||||
mStatusTextView.setText("Status: Finished playback");
|
||||
mTriggerButton.setText("Start Camera");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void setErrorStatus() {
|
||||
mStatus = STATUS_ERROR;
|
||||
mStatusTextView.setText("Status: Error");
|
||||
}
|
||||
|
||||
public boolean startPreview() {
|
||||
mOpenCvCameraView.enableView();
|
||||
mOpenCvCameraView.setVisibility(View.VISIBLE);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean startRecording() {
|
||||
Log.i(TAG,"Starting recording");
|
||||
|
||||
File file = new File(mVideoFilename);
|
||||
file.delete();
|
||||
|
||||
mVideoWriter = new VideoWriter();
|
||||
if (!mUseBuiltInMJPG) {
|
||||
mVideoWriter.open(mVideoFilename, Videoio.CAP_ANDROID, VideoWriter.fourcc('H', '2', '6', '4'), mFPS, new Size(mWidth, mHeight));
|
||||
if (!mVideoWriter.isOpened()) {
|
||||
Log.i(TAG,"Can't record H264. Switching to MJPG");
|
||||
mUseBuiltInMJPG = true;
|
||||
mVideoFilename = getFilesDir() + "/" + FILENAME_AVI;
|
||||
}
|
||||
}
|
||||
|
||||
if (mUseBuiltInMJPG) {
|
||||
mVideoWriter.open(mVideoFilename, VideoWriter.fourcc('M', 'J', 'P', 'G'), mFPS, new Size(mWidth, mHeight));
|
||||
}
|
||||
|
||||
Log.d(TAG, "Size: " + String.valueOf(mWidth) + "x" + String.valueOf(mHeight));
|
||||
Log.d(TAG, "File: " + mVideoFilename);
|
||||
|
||||
if (mVideoWriter.isOpened()) {
|
||||
Toast.makeText(this, "Record started to file " + mVideoFilename, Toast.LENGTH_LONG).show();
|
||||
return true;
|
||||
} else {
|
||||
Toast.makeText(this, "Failed to start a record", Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean stopRecording() {
|
||||
Log.i(TAG, "Finishing recording");
|
||||
mOpenCvCameraView.disableView();
|
||||
mOpenCvCameraView.setVisibility(SurfaceView.GONE);
|
||||
mVideoWriter.release();
|
||||
mVideoWriter = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean startPlayback() {
|
||||
mImageView.setVisibility(SurfaceView.VISIBLE);
|
||||
|
||||
if (!mUseBuiltInMJPG){
|
||||
mVideoCapture = new VideoCapture(mVideoFilename, Videoio.CAP_ANDROID);
|
||||
} else {
|
||||
mVideoCapture = new VideoCapture(mVideoFilename, Videoio.CAP_OPENCV_MJPEG);
|
||||
}
|
||||
|
||||
if (!mVideoCapture.isOpened()) {
|
||||
Log.e(TAG, "Can't open video");
|
||||
Toast.makeText(this, "Can't open file " + mVideoFilename, Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
Toast.makeText(this, "Starting playback from file " + mVideoFilename, Toast.LENGTH_SHORT).show();
|
||||
|
||||
mPlayerThread = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mVideoCapture == null || !mVideoCapture.isOpened()) {
|
||||
return;
|
||||
}
|
||||
mVideoCapture.read(mVideoFrame);
|
||||
if (mVideoFrame.empty()) {
|
||||
if (mStatus == STATUS_PLAYING) {
|
||||
changeStatus();
|
||||
}
|
||||
return;
|
||||
}
|
||||
// VideoCapture with CAP_ANDROID generates RGB frames instead of BGR
|
||||
// https://github.com/opencv/opencv/issues/24687
|
||||
Imgproc.cvtColor(mVideoFrame, mRenderFrame, mUseBuiltInMJPG ? Imgproc.COLOR_BGR2RGBA: Imgproc.COLOR_RGB2RGBA);
|
||||
Bitmap bmp = Bitmap.createBitmap(mRenderFrame.cols(), mRenderFrame.rows(), Bitmap.Config.ARGB_8888);
|
||||
Utils.matToBitmap(mRenderFrame, bmp);
|
||||
mImageView.setImageBitmap(bmp);
|
||||
Handler h = new Handler();
|
||||
h.postDelayed(this, 33);
|
||||
}
|
||||
};
|
||||
|
||||
mPlayerThread.run();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean stopPlayback() {
|
||||
mVideoCapture.release();
|
||||
mVideoCapture = null;
|
||||
mImageView.setVisibility(SurfaceView.GONE);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user