This commit is contained in:
√(noham)²
2024-07-26 16:00:08 +02:00
parent 90e2dadf18
commit c9c3228b2c
7501 changed files with 3266200 additions and 1 deletions

View File

@@ -0,0 +1,37 @@
# cmake needs this line
cmake_minimum_required(VERSION 3.1)
if(NOT DEFINED EXAMPLE_NAME)
message(FATAL_ERROR "Invalid build script: missing EXAMPLE_NAME")
endif()
if(NOT DEFINED EXAMPLE_FILE)
message(FATAL_ERROR "Invalid build script: missing EXAMPLE_FILE")
endif()
file(TO_CMAKE_PATH "${EXAMPLE_FILE}" EXAMPLE_FILE)
message(STATUS "Project: ${EXAMPLE_NAME}")
message(STATUS "File : ${EXAMPLE_FILE}")
# Define project name
project(${EXAMPLE_NAME})
# Find OpenCV, you may need to set OpenCV_DIR variable
# to the absolute path to the directory containing OpenCVConfig.cmake file
# via the command line or GUI
find_package(OpenCV REQUIRED)
# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them
message(STATUS "OpenCV library status:")
message(STATUS " config: ${OpenCV_DIR}")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
# Declare the executable target built from your sources
add_executable(${EXAMPLE_NAME} "${EXAMPLE_FILE}")
# Link your application with OpenCV libraries
target_link_libraries(${EXAMPLE_NAME} PRIVATE ${OpenCV_LIBS})

View File

@@ -0,0 +1,138 @@
if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_LIST_DIR)
#===================================================================================================
#
# Build as part of OpenCV
#
#===================================================================================================
include("${CMAKE_CURRENT_LIST_DIR}/samples_utils.cmake")
function(ocv_install_example_src relpath)
if(INSTALL_C_EXAMPLES)
file(GLOB files ${ARGN})
install(FILES ${files}
DESTINATION "${OPENCV_SAMPLES_SRC_INSTALL_PATH}/${relpath}"
COMPONENT samples)
endif()
endfunction()
if((TARGET Threads::Threads OR HAVE_PTHREAD OR MSVC OR APPLE) AND NOT OPENCV_EXAMPLES_DISABLE_THREADS)
add_definitions(-DHAVE_THREADS=1)
endif()
add_subdirectory(cpp)
add_subdirectory(java/tutorial_code)
add_subdirectory(dnn)
add_subdirectory(gpu)
add_subdirectory(tapi)
add_subdirectory(opencl)
add_subdirectory(sycl)
if(WIN32 AND HAVE_DIRECTX)
add_subdirectory(directx)
endif()
if((NOT ANDROID) AND HAVE_OPENGL)
add_subdirectory(opengl)
endif()
if(HAVE_OPENVX)
add_subdirectory(openvx)
endif()
if(UNIX AND NOT ANDROID AND HAVE_VA)
add_subdirectory(va_intel)
endif()
if(ANDROID AND (BUILD_ANDROID_EXAMPLES OR INSTALL_ANDROID_EXAMPLES))
add_subdirectory(android)
endif()
if(INSTALL_PYTHON_EXAMPLES)
add_subdirectory(python)
endif()
# The examples in this folder will work with a semihosting version of
# OpenCV. For more information about semihosting, see
# https://developer.arm.com/documentation/100863/latest
if(OPENCV_SEMIHOSTING)
add_subdirectory(semihosting)
endif()
ocv_install_example_src("." CMakeLists.txt samples_utils.cmake)
if(INSTALL_C_EXAMPLES)
install(DIRECTORY data DESTINATION "${OPENCV_SAMPLES_SRC_INSTALL_PATH}" COMPONENT samples_data)
endif()
else()
#===================================================================================================
#
# Standalone mode
#
#===================================================================================================
cmake_minimum_required(VERSION 3.1)
project(samples C CXX)
option(BUILD_EXAMPLES "Build samples" ON)
# Assuming following installation folder structure (default for UNIX):
# <install_root>/share/
# └── OpenCV/ <-- OPENCV_CONFIG_INSTALL_PATH
# ├── OpenCVConfig.cmake <-- file to be found by find_package
# ├── ...
# ├── samples/ <-- OPENCV_SAMPLES_SRC_INSTALL_PATH
# │   ├── CMakeLists.txt <-- this file
# │   ├── cpp/
find_package(OpenCV REQUIRED PATHS "..")
include("${CMAKE_CURRENT_LIST_DIR}/samples_utils.cmake")
function(ocv_install_example_src)
# not used in this branch
endfunction()
if(MSVC)
if(NOT ENABLE_BUILD_HARDENING)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
if(NOT OpenCV_SHARED)
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif()
if(${flag_var} MATCHES "/MDd")
string(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}")
endif()
endforeach(flag_var)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:atlthunk.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcrtd.lib")
if(NOT BUILD_WITH_STATIC_CRT)
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libcmt.lib")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /NODEFAULTLIB:libcmtd.lib")
endif()
endif()
endif()
if(OPENCV_EXAMPLES_DISABLE_THREADS)
# nothing
elseif(MSVC OR APPLE)
set(HAVE_THREADS 1)
else()
find_package(Threads)
endif()
if((TARGET Threads::Threads OR HAVE_THREADS) AND NOT OPENCV_EXAMPLES_DISABLE_THREADS)
set(HAVE_THREADS 1)
add_definitions(-DHAVE_THREADS=1)
endif()
add_subdirectory(cpp)
if(WIN32)
add_subdirectory(directx)
endif()
add_subdirectory(dnn)
# add_subdirectory(gpu)
add_subdirectory(opencl)
add_subdirectory(sycl)
# add_subdirectory(opengl)
# add_subdirectory(openvx)
add_subdirectory(tapi)
# add_subdirectory(va_intel)
endif()

View File

@@ -0,0 +1,239 @@
:: Usage:
:: - Drag & drop .cpp file on this file from Windows explorer
:: - Run from cmd/powershell:
:: - > _winpack_build_sample.cmd cpp\opencv_version.cpp
:: Requires:
:: - CMake
:: - MSVS 2015/2017/2019
:: (tools are searched on default paths or environment should be pre-configured)
@echo off
setlocal
SET SCRIPT_DIR=%~dp0
SET "OPENCV_SETUPVARS_SCRIPT=setup_vars_opencv4.cmd"
SET "PACKAGE_BUILD_DIR=%SCRIPT_DIR%\..\..\build"
IF NOT EXIST "%PACKAGE_BUILD_DIR%\%OPENCV_SETUPVARS_SCRIPT%" (
:: Winpack DLDT
SET "PACKAGE_BUILD_DIR=%SCRIPT_DIR%\..\..\..\build"
)
IF NOT EXIST "%PACKAGE_BUILD_DIR%\%OPENCV_SETUPVARS_SCRIPT%" (
set "MSG=OpenCV Winpack installation is required"
goto die
)
:: normalize path
for %%i in ("%PACKAGE_BUILD_DIR%") do SET "PACKAGE_BUILD_DIR=%%~fi"
if [%1]==[] (
set "MSG=Sample path is required"
goto die
)
if exist %1\* (
set "MSG=Only .cpp samples are allowed (not a directory): %1"
goto die
)
if NOT "%~x1" == ".cpp" (
set "MSG=Only .cpp samples are allowed: %~x1"
goto die
)
set SRC_FILENAME=%~dpnx1
echo SRC_FILENAME=%SRC_FILENAME%
call :dirname "%SRC_FILENAME%" SRC_DIR
echo SRC_DIR=%SRC_DIR%
set "SRC_NAME=%~n1"
echo SRC_NAME=%SRC_NAME%
echo ================================================================================
:: Path to root 'bin' dir
set "PATH=%PACKAGE_BUILD_DIR%\bin;%PATH%"
:: Detect compiler
cl /? >NUL 2>NUL <NUL
if %ERRORLEVEL% == 0 (
goto detect_cmake
)
PUSHD %CD%
CALL :try_call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat"
IF ERRORLEVEL 1 (
CALL :try_call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
)
IF ERRORLEVEL 1 (
CALL :try_call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
)
IF ERRORLEVEL 1 (
CALL :try_call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvars64.bat"
)
IF ERRORLEVEL 1 (
CALL :try_call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
)
IF ERRORLEVEL 1 (
CALL :try_call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
)
IF ERRORLEVEL 1 (
CALL :try_call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
)
POPD
cl /? >NUL 2>NUL <NUL
if %ERRORLEVEL% NEQ 0 (
set "MSG=Can't detect Microsoft Visual Studio C++ compiler (cl.exe). MSVS 2015/2017/2019 are supported only from standard locations"
goto die
)
:: Detect CMake
:detect_cmake
cmake --version >NUL 2>NUL
if %ERRORLEVEL% EQU 0 GOTO :CMAKE_FOUND
if NOT exist "C:\Program Files\CMake\bin" GOTO CMAKE_NOT_FOUND
set "PATH=%PATH%;C:\Program Files\CMake\bin"
cmake --version >NUL 2>NUL
if %ERRORLEVEL% EQU 0 GOTO :CMAKE_FOUND
:CMAKE_NOT_FOUND
set "MSG=CMake is required to build OpenCV samples. Download it from here: https://cmake.org/download/ and install into 'C:\Program Files\CMake'"
goto die
:CMAKE_FOUND
set CMAKE_FOUND=1
call :execute cmake --version
echo CMake is detected
where cmake
:: Detect available MSVS version
if NOT DEFINED VisualStudioVersion (
set "MSG=Can't determine MSVS version. 'VisualStudioVersion' is not defined"
goto die
)
if "%VisualStudioVersion%" == "14.0" (
set "CMAKE_GENERATOR=-G^"Visual Studio 14 Win64^""
set "BUILD_DIR_SUFFIX=.vc14"
if EXIST "%PACKAGE_BUILD_DIR%\x64\vc14\bin" (
set "PATH=%PACKAGE_BUILD_DIR%\x64\vc14\bin;%PATH%"
)
) else (
if "%VisualStudioVersion%" == "15.0" (
set "CMAKE_GENERATOR=-G^"Visual Studio 15 Win64^""
set "BUILD_DIR_SUFFIX=.vc15"
set "PATH=%PATH%;%SCRIPTDIR%\..\..\build\x64\vc15\bin\"
if EXIST "%PACKAGE_BUILD_DIR%\x64\vc15\bin" (
set "PATH=%PACKAGE_BUILD_DIR%\x64\vc15\bin;%PATH%"
) else (
if EXIST "%PACKAGE_BUILD_DIR%\x64\vc14\bin" (
set "PATH=%PACKAGE_BUILD_DIR%\x64\vc14\bin;%PATH%"
)
)
) else (
if "%VisualStudioVersion%" == "16.0" (
echo.==========================================
echo.* Note: MSVS 2019 requires CMake 3.14+ *
echo.==========================================
set "CMAKE_GENERATOR=-G^"Visual Studio 16 2019^" -A x64"
set "BUILD_DIR_SUFFIX=.vc16"
if EXIST "%PACKAGE_BUILD_DIR%\x64\vc16\bin" (
set "PATH=%PACKAGE_BUILD_DIR%\x64\vc16\bin;%PATH%"
) else (
if EXIST "%PACKAGE_BUILD_DIR%\x64\vc15\bin" (
set "PATH=%PACKAGE_BUILD_DIR%\x64\vc15\bin;%PATH%"
) else (
if EXIST "%PACKAGE_BUILD_DIR%\x64\vc14\bin" (
set "PATH=%PACKAGE_BUILD_DIR%\x64\vc14\bin;%PATH%"
)
)
)
) else (
set "MSG=Unsupported MSVS version. VisualStudioVersion=%VisualStudioVersion%"
goto die
)
)
)
set "BUILD_DIR=%SRC_DIR%\build_%SRC_NAME%%BUILD_DIR_SUFFIX%"
call :set_title Create build directory
if NOT exist "%BUILD_DIR%" ( call :execute md "%BUILD_DIR%" )
PUSHD "%BUILD_DIR%"
if NOT exist "%BUILD_DIR%/sample" ( call :execute md "%BUILD_DIR%/sample" )
call :execute copy /Y "%SCRIPT_DIR%/CMakeLists.example.in" "%BUILD_DIR%/sample/CMakeLists.txt"
call :set_title Configuring via CMake
call :execute cmake %CMAKE_GENERATOR% "%BUILD_DIR%\sample" -DEXAMPLE_NAME=%SRC_NAME% "-DEXAMPLE_FILE=%SRC_FILENAME%"
if %ERRORLEVEL% NEQ 0 (
set "MSG=CMake configuration step failed: %BUILD_DIR%"
goto die
)
call :set_title Build sample project via CMake
call :execute cmake --build . --config Release
if %ERRORLEVEL% NEQ 0 (
set "MSG=Build step failed: %BUILD_DIR%"
goto die
)
call :set_title Launch %SRC_NAME%
if NOT exist "%BUILD_DIR%\Release\%SRC_NAME%.exe" (
echo. "ERROR: Can't find executable file (build seems broken): %SRC_NAME%.exe"
) else (
cd "%BUILD_DIR%\Release"
call :execute "%SRC_NAME%.exe" --help
echo ================================================================================
echo ** Type '%SRC_NAME%.exe' to run sample application
echo ** Type '%SRC_NAME%.exe --help' to get list of available options (if available)
echo ** Type 'start ..\%SRC_NAME%.sln' to launch MSVS IDE
echo ** Type 'cmake --build .. --config Release' to rebuild sample
echo ** Type 'exit' to exit from interactive shell and open the build directory
echo ================================================================================
)
call :set_title Hands-on: %SRC_NAME%
cmd /k echo Current directory: %CD%
call :set_title Done: %SRC_NAME%
echo Opening build directory with project files...
explorer "%BUILD_DIR%"
POPD
echo Done%
pause
exit /B 0
::
:: Helper routines
::
:set_title
title OpenCV sample: %*
EXIT /B 0
:execute
echo =================================================================================
setlocal
echo %*
call %*
endlocal
EXIT /B %ERRORLEVEL%
:dirname file resultVar
setlocal
set _dir=%~dp1
set _dir=%_dir:~0,-1%
endlocal & set %2=%_dir%
EXIT /B 0
:try_call
IF EXIST %1 (
CALL %*
EXIT /B
) ELSE (
EXIT /B 1
)
:: 'goto die' instead of 'call'
:die
TITLE OpenCV sample: ERROR: %MSG%
echo ERROR: %MSG%
pause
EXIT /B 1

View File

@@ -0,0 +1,152 @@
@ECHO OFF
SETLOCAL
SET SCRIPT_DIR=%~dp0
SET "OPENCV_SETUPVARS_SCRIPT=setup_vars_opencv4.cmd"
SET "BUILD_DIR=%SCRIPT_DIR%\..\..\build"
IF NOT EXIST "%BUILD_DIR%\%OPENCV_SETUPVARS_SCRIPT%" (
:: Winpack DLDT
SET "BUILD_DIR=%SCRIPT_DIR%\..\..\..\build"
)
IF NOT EXIST "%BUILD_DIR%\%OPENCV_SETUPVARS_SCRIPT%" (
ECHO ERROR: OpenCV Winpack installation is required
pause
exit
)
:: normalize path
for %%i in ("%PACKAGE_BUILD_DIR%") do SET "PACKAGE_BUILD_DIR=%%~fi"
:: Detect Python binary
python -V 2>nul
IF %ERRORLEVEL% EQU 0 (
SET PYTHON=python
GOTO :PYTHON_FOUND
)
CALL :QUERY_PYTHON 3.12
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
CALL :QUERY_PYTHON 3.11
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
CALL :QUERY_PYTHON 3.10
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
CALL :QUERY_PYTHON 3.9
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
CALL :QUERY_PYTHON 3.8
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
CALL :QUERY_PYTHON 3.7
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
CALL :QUERY_PYTHON 3.6
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
CALL :QUERY_PYTHON 3.5
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
CALL :QUERY_PYTHON 3.4
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
CALL :QUERY_PYTHON 2.7
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
GOTO :PYTHON_NOT_FOUND
:QUERY_PYTHON
SETLOCAL
SET PY_VERSION=%1
SET PYTHON_DIR=
CALL :regquery "HKCU\SOFTWARE\Python\PythonCore\%PY_VERSION%\InstallPath" PYTHON_DIR
IF EXIST "%PYTHON_DIR%\python.exe" (
SET "PYTHON=%PYTHON_DIR%\python.exe"
GOTO :QUERY_PYTHON_FOUND
)
CALL :regquery "HKLM\SOFTWARE\Python\PythonCore\%PY_VERSION%\InstallPath" PYTHON_DIR
IF EXIST "%PYTHON_DIR%\python.exe" (
SET "PYTHON=%PYTHON_DIR%\python.exe"
GOTO :QUERY_PYTHON_FOUND
)
::echo Python %PY_VERSION% is not detected
ENDLOCAL
EXIT /B 1
:QUERY_PYTHON_FOUND
ECHO Found Python %PY_VERSION% from Windows Registry: %PYTHON%
ENDLOCAL & SET PYTHON=%PYTHON%
EXIT /B 0
IF exist C:\Python27-x64\python.exe (
SET PYTHON=C:\Python27-x64\python.exe
GOTO :PYTHON_FOUND
)
IF exist C:\Python27\python.exe (
SET PYTHON=C:\Python27\python.exe
GOTO :PYTHON_FOUND
)
:PYTHON_NOT_FOUND
ECHO ERROR: Python not found
IF NOT DEFINED OPENCV_BATCH_MODE ( pause )
EXIT /B
:PYTHON_FOUND
ECHO Using Python: %PYTHON%
:: Don't generate unnecessary .pyc cache files
SET PYTHONDONTWRITEBYTECODE=1
IF [%1]==[] goto rundemo
set SRC_FILENAME=%~dpnx1
echo SRC_FILENAME=%SRC_FILENAME%
call :dirname "%SRC_FILENAME%" SRC_DIR
call :dirname "%PYTHON%" PYTHON_DIR
PUSHD %SRC_DIR%
CALL "%BUILD_DIR%\%OPENCV_SETUPVARS_SCRIPT%"
:: repair SCRIPT_DIR
SET "SCRIPT_DIR=%~dp0"
ECHO Run: %*
%PYTHON% %*
SET result=%errorlevel%
IF %result% NEQ 0 (
IF NOT DEFINED OPENCV_BATCH_MODE (
SET "PATH=%PYTHON_DIR%;%PATH%"
echo ================================================================================
echo ** Type 'python sample_name.py' to run sample
echo ** Type 'exit' to exit from interactive shell and open the build directory
echo ================================================================================
cmd /k echo Current directory: %CD%
)
)
POPD
EXIT /B %result%
:rundemo
PUSHD "%SCRIPT_DIR%\python"
CALL "%BUILD_DIR%\%OPENCV_SETUPVARS_SCRIPT%"
:: repair SCRIPT_DIR
SET "SCRIPT_DIR=%~dp0"
%PYTHON% demo.py
SET result=%errorlevel%
IF %result% NEQ 0 (
IF NOT DEFINED OPENCV_BATCH_MODE ( pause )
)
POPD
EXIT /B %result%
:dirname file resultVar
setlocal
set _dir=%~dp1
set _dir=%_dir:~0,-1%
endlocal & set %2=%_dir%
EXIT /B 0
:regquery name resultVar
SETLOCAL
FOR /F "tokens=*" %%A IN ('REG QUERY "%1" /reg:64 /ve 2^>NUL ^| FIND "REG_SZ"') DO SET _val=%%A
IF "x%_val%x"=="xx" EXIT /B 1
SET _val=%_val:*REG_SZ=%
FOR /F "tokens=*" %%A IN ("%_val%") DO SET _val=%%A
ENDLOCAL & SET %2=%_val%
EXIT /B 0

View File

@@ -0,0 +1,7 @@
bin/
gen/
build.xml
local.properties
proguard-project.txt
project.properties
default.properties

View File

@@ -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.puzzle15"
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=".Puzzle15Activity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:configChanges="keyboardHidden|orientation" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-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>

View File

@@ -0,0 +1,6 @@
set(sample example-15-puzzle)
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()

View File

@@ -0,0 +1,37 @@
apply plugin: 'com.android.application'
android {
namespace 'org.opencv.samples.puzzle15'
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
defaultConfig {
applicationId "org.opencv.samples.puzzle15"
minSdkVersion @ANDROID_MIN_SDK_VERSION@
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
versionCode 301
versionName "3.01"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
java.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
res.srcDirs = @ANDROID_SAMPLE_RES_PATH@
manifest.srcFile '@ANDROID_SAMPLE_MANIFEST_PATH@'
}
}
}
dependencies {
//implementation fileTree(dir: 'libs', include: ['*.jar'])
if (gradle.opencv_source == 'sdk_path') {
println 'Using OpenCV from SDK'
implementation project(':opencv')
} else if (gradle.opencv_source == 'maven_local' || gradle.opencv_source == 'maven_central') {
println 'Using OpenCV from Maven repo'
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
}
}

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.opencv.samples.puzzle15"
>
<application
android:icon="@drawable/icon"
android:label="@string/app_name">
<activity
android:exported="true"
android:name=".Puzzle15Activity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:configChanges="keyboardHidden|orientation" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-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

View File

@@ -0,0 +1,6 @@
<resources>
<string name="app_name">OCV 15 Puzzle</string>
<string name="menu_toggle_tile_numbers">Show/hide tile numbers</string>
<string name="menu_start_new_game">Start new game</string>
</resources>

View File

@@ -0,0 +1,135 @@
package org.opencv.samples.puzzle15;
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.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import java.util.Collections;
import java.util.List;
public class Puzzle15Activity extends CameraActivity implements CvCameraViewListener, View.OnTouchListener {
private static final String TAG = "Puzzle15::Activity";
private CameraBridgeViewBase mOpenCvCameraView;
private Puzzle15Processor mPuzzle15;
private MenuItem mItemHideNumbers;
private MenuItem mItemStartNewGame;
private int mGameWidth;
private int mGameHeight;
@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);
mOpenCvCameraView.setVisibility(CameraBridgeViewBase.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
mPuzzle15 = new Puzzle15Processor();
mPuzzle15.prepareNewGame();
}
@Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
@Override
public void onResume()
{
super.onResume();
if (mOpenCvCameraView != null) {
mOpenCvCameraView.setOnTouchListener(Puzzle15Activity.this);
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");
mItemHideNumbers = menu.add("Show/hide tile numbers");
mItemStartNewGame = menu.add("Start new game");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.i(TAG, "Menu Item selected " + item);
if (item == mItemStartNewGame) {
/* We need to start new game */
mPuzzle15.prepareNewGame();
} else if (item == mItemHideNumbers) {
/* We need to enable or disable drawing of the tile numbers */
mPuzzle15.toggleTileNumbers();
}
return true;
}
public void onCameraViewStarted(int width, int height) {
mGameWidth = width;
mGameHeight = height;
mPuzzle15.prepareGameSize(width, height);
}
public void onCameraViewStopped() {
}
public boolean onTouch(View view, MotionEvent event) {
int xpos, ypos;
xpos = (view.getWidth() - mGameWidth) / 2;
xpos = (int)event.getX() - xpos;
ypos = (view.getHeight() - mGameHeight) / 2;
ypos = (int)event.getY() - ypos;
if (xpos >=0 && xpos <= mGameWidth && ypos >=0 && ypos <= mGameHeight) {
/* click is inside the picture. Deliver this event to processor */
mPuzzle15.deliverTouchEvent(xpos, ypos);
}
return false;
}
public Mat onCameraFrame(Mat inputFrame) {
return mPuzzle15.puzzleFrame(inputFrame);
}
}

View File

@@ -0,0 +1,195 @@
package org.opencv.samples.puzzle15;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.core.Point;
import org.opencv.imgproc.Imgproc;
import android.util.Log;
/**
* This class is a controller for puzzle game.
* It converts the image from Camera into the shuffled image
*/
public class Puzzle15Processor {
private static final int GRID_SIZE = 4;
private static final int GRID_AREA = GRID_SIZE * GRID_SIZE;
private static final int GRID_EMPTY_INDEX = GRID_AREA - 1;
private static final String TAG = "Puzzle15Processor";
private static final Scalar GRID_EMPTY_COLOR = new Scalar(0x33, 0x33, 0x33, 0xFF);
private int[] mIndexes;
private int[] mTextWidths;
private int[] mTextHeights;
private Mat mRgba15;
private Mat[] mCells15;
private boolean mShowTileNumbers = true;
public Puzzle15Processor() {
mTextWidths = new int[GRID_AREA];
mTextHeights = new int[GRID_AREA];
mIndexes = new int [GRID_AREA];
for (int i = 0; i < GRID_AREA; i++)
mIndexes[i] = i;
}
/* this method is intended to make processor prepared for a new game */
public synchronized void prepareNewGame() {
do {
shuffle(mIndexes);
} while (!isPuzzleSolvable());
}
/* This method is to make the processor know the size of the frames that
* will be delivered via puzzleFrame.
* If the frames will be different size - then the result is unpredictable
*/
public synchronized void prepareGameSize(int width, int height) {
mRgba15 = new Mat(height, width, CvType.CV_8UC4);
mCells15 = new Mat[GRID_AREA];
for (int i = 0; i < GRID_SIZE; i++) {
for (int j = 0; j < GRID_SIZE; j++) {
int k = i * GRID_SIZE + j;
mCells15[k] = mRgba15.submat(i * height / GRID_SIZE, (i + 1) * height / GRID_SIZE, j * width / GRID_SIZE, (j + 1) * width / GRID_SIZE);
}
}
for (int i = 0; i < GRID_AREA; i++) {
Size s = Imgproc.getTextSize(Integer.toString(i + 1), Imgproc.FONT_HERSHEY_COMPLEX, 1, 2, null);
mTextHeights[i] = (int) s.height;
mTextWidths[i] = (int) s.width;
}
}
/* this method to be called from the outside. it processes the frame and shuffles
* the tiles as specified by mIndexes array
*/
public synchronized Mat puzzleFrame(Mat inputPicture) {
Mat[] cells = new Mat[GRID_AREA];
int rows = inputPicture.rows();
int cols = inputPicture.cols();
rows = rows - rows%4;
cols = cols - cols%4;
for (int i = 0; i < GRID_SIZE; i++) {
for (int j = 0; j < GRID_SIZE; j++) {
int k = i * GRID_SIZE + j;
cells[k] = inputPicture.submat(i * inputPicture.rows() / GRID_SIZE, (i + 1) * inputPicture.rows() / GRID_SIZE, j * inputPicture.cols()/ GRID_SIZE, (j + 1) * inputPicture.cols() / GRID_SIZE);
}
}
rows = rows - rows%4;
cols = cols - cols%4;
// copy shuffled tiles
for (int i = 0; i < GRID_AREA; i++) {
int idx = mIndexes[i];
if (idx == GRID_EMPTY_INDEX)
mCells15[i].setTo(GRID_EMPTY_COLOR);
else {
cells[idx].copyTo(mCells15[i]);
if (mShowTileNumbers) {
Imgproc.putText(mCells15[i], Integer.toString(1 + idx), new Point((cols / GRID_SIZE - mTextWidths[idx]) / 2,
(rows / GRID_SIZE + mTextHeights[idx]) / 2), Imgproc.FONT_HERSHEY_COMPLEX, 1, new Scalar(255, 0, 0, 255), 2);
}
}
}
for (int i = 0; i < GRID_AREA; i++)
cells[i].release();
drawGrid(cols, rows, mRgba15);
return mRgba15;
}
public void toggleTileNumbers() {
mShowTileNumbers = !mShowTileNumbers;
}
public void deliverTouchEvent(int x, int y) {
int rows = mRgba15.rows();
int cols = mRgba15.cols();
int row = (int) Math.floor(y * GRID_SIZE / rows);
int col = (int) Math.floor(x * GRID_SIZE / cols);
if (row < 0 || row >= GRID_SIZE || col < 0 || col >= GRID_SIZE) {
Log.e(TAG, "It is not expected to get touch event outside of picture");
return ;
}
int idx = row * GRID_SIZE + col;
int idxtoswap = -1;
// left
if (idxtoswap < 0 && col > 0)
if (mIndexes[idx - 1] == GRID_EMPTY_INDEX)
idxtoswap = idx - 1;
// right
if (idxtoswap < 0 && col < GRID_SIZE - 1)
if (mIndexes[idx + 1] == GRID_EMPTY_INDEX)
idxtoswap = idx + 1;
// top
if (idxtoswap < 0 && row > 0)
if (mIndexes[idx - GRID_SIZE] == GRID_EMPTY_INDEX)
idxtoswap = idx - GRID_SIZE;
// bottom
if (idxtoswap < 0 && row < GRID_SIZE - 1)
if (mIndexes[idx + GRID_SIZE] == GRID_EMPTY_INDEX)
idxtoswap = idx + GRID_SIZE;
// swap
if (idxtoswap >= 0) {
synchronized (this) {
int touched = mIndexes[idx];
mIndexes[idx] = mIndexes[idxtoswap];
mIndexes[idxtoswap] = touched;
}
}
}
private void drawGrid(int cols, int rows, Mat drawMat) {
for (int i = 1; i < GRID_SIZE; i++) {
Imgproc.line(drawMat, new Point(0, i * rows / GRID_SIZE), new Point(cols, i * rows / GRID_SIZE), new Scalar(0, 255, 0, 255), 3);
Imgproc.line(drawMat, new Point(i * cols / GRID_SIZE, 0), new Point(i * cols / GRID_SIZE, rows), new Scalar(0, 255, 0, 255), 3);
}
}
private static void shuffle(int[] array) {
for (int i = array.length; i > 1; i--) {
int temp = array[i - 1];
int randIx = (int) (Math.random() * i);
array[i - 1] = array[randIx];
array[randIx] = temp;
}
}
private boolean isPuzzleSolvable() {
int sum = 0;
for (int i = 0; i < GRID_AREA; i++) {
if (mIndexes[i] == GRID_EMPTY_INDEX)
sum += (i / GRID_SIZE) + 1;
else {
int smaller = 0;
for (int j = i + 1; j < GRID_AREA; j++) {
if (mIndexes[j] < mIndexes[i])
smaller++;
}
sum += smaller;
}
}
return sum % 2 == 0;
}
}

View File

@@ -0,0 +1,20 @@
# ----------------------------------------------------------------------------
# CMake file for Android samples. See root CMakeLists.txt
#
# ----------------------------------------------------------------------------
add_custom_target(opencv_android_examples)
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)
add_subdirectory(tutorial-4-opencl)

View File

@@ -0,0 +1,109 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:@ANDROID_GRADLE_PLUGIN_VERSION@'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:@KOTLIN_PLUGIN_VERSION@'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
if (gradle.opencv_source == "maven_local") {
maven {
url gradle.opencv_maven_path
}
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
//allprojects {
// gradle.projectsEvaluated {
// tasks.withType(JavaCompile) {
// options.compilerArgs << "-Xlint:unchecked"
// options.compilerArgs << "-Xlint:deprecation"
// }
// }
//}
def opencv_strict_build_configuration = @ANDROID_STRICT_BUILD_CONFIGURATION@;
gradle.afterProject { project ->
if (project.pluginManager.hasPlugin('com.android.application')
|| project.pluginManager.hasPlugin('com.android.library')
|| project.pluginManager.hasPlugin('com.android.test')
|| project.pluginManager.hasPlugin('com.android.feature') ) {
if (true) {
gradle.println("Override build ABIs for the project ${project.name}")
project.android {
splits {
abi {
enable true
universalApk false
@ANDROID_ABI_FILTER@
}
}
}
}
if (true) {
gradle.println("Override lintOptions for the project ${project.name}")
project.android {
lintOptions {
// checkReleaseBuilds false
abortOnError false
}
}
}
// (you still need to re-build OpenCV with debug information to debug it)
if (true) {
gradle.println("Override doNotStrip-debug for the project ${project.name}")
project.android {
buildTypes {
debug {
packagingOptions {
doNotStrip '**/*.so' // controlled by OpenCV CMake scripts
}
}
}
}
}
if (false || project.hasProperty("doNotStrip")) {
gradle.println("Override doNotStrip-release for the project ${project.name}")
project.android {
buildTypes {
release {
packagingOptions {
doNotStrip '**/*.so' // controlled by OpenCV CMake scripts
}
}
}
}
}
// Android Gradle Plugin (AGP) 3.5+ is required
// https://github.com/android/ndk-samples/wiki/Configure-NDK-Path
def isNdkVersionSupported = project.android.metaClass.getProperties().find { it.name == 'ndkVersion' } != null
if ((false || opencv_strict_build_configuration) && isNdkVersionSupported) {
gradle.println("Override ndkVersion for the project ${project.name}")
project.android {
ndkVersion '@ANDROID_NDK_REVISION@'
}
}
}
}

View File

@@ -0,0 +1,6 @@
set(sample example-camera-calibration)
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()

View File

@@ -0,0 +1,37 @@
apply plugin: 'com.android.application'
android {
namespace 'org.opencv.samples.cameracalibration'
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
defaultConfig {
applicationId "org.opencv.samples.cameracalibration"
minSdkVersion @ANDROID_MIN_SDK_VERSION@
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
versionCode 301
versionName "3.01"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
java.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
res.srcDirs = @ANDROID_SAMPLE_RES_PATH@
manifest.srcFile '@ANDROID_SAMPLE_MANIFEST_PATH@'
}
}
}
dependencies {
//implementation fileTree(dir: 'libs', include: ['*.jar'])
if (gradle.opencv_source == "sdk_path") {
println 'Using OpenCV from SDK'
implementation project(':opencv')
} else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_central") {
println 'Using OpenCV from Maven repo'
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
}
}

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.opencv.samples.cameracalibration"
>
<application
android:label="@string/app_name"
android:icon="@drawable/icon">
<activity
android:exported="true"
android:name="CameraCalibrationActivity"
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-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.1 KiB

View File

@@ -0,0 +1,12 @@
<LinearLayout 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" >
<org.opencv.android.JavaCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/camera_calibration_java_surface_view" />
</LinearLayout>

View File

@@ -0,0 +1,22 @@
<?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/calibrate"
android:title="@string/action_calibrate"
android:showAsAction="ifRoom|withText" />
<item android:id="@+id/preview_mode"
android:title="@string/preview_mode">
<menu>
<group android:checkableBehavior="single">
<item android:id="@+id/calibration"
android:title="@string/calibration"
android:checked="true" />
<item android:id="@+id/undistortion"
android:title="@string/undistortion" />
<item android:id="@+id/comparison"
android:title="@string/comparison" />
</group>
</menu>
</item>
</group>
</menu>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">OCV Camera Calibration</string>
<string name="action_calibrate">Calibrate</string>
<string name="calibration">Calibration</string>
<string name="undistortion">Undistortion</string>
<string name="comparison">Comparison</string>
<string name="preview_mode">Preview mode</string>
<string name="calibration_successful">Successfully calibrated!\nAvg. re-projection error:</string>
<string name="calibration_unsuccessful">Unsuccessful calibration.\nTry again</string>
<string name="more_samples">Please, capture more samples</string>
<string name="calibrating">Calibrating...</string>
<string name="please_wait">Please, wait</string>
<string name="original">Original</string>
<string name="undistorted">Undistorted</string>
</resources>

View File

@@ -0,0 +1,69 @@
package org.opencv.samples.cameracalibration;
import org.opencv.core.Mat;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
public abstract class CalibrationResult {
private static final String TAG = "OCV::CalibrationResult";
private static final int CAMERA_MATRIX_ROWS = 3;
private static final int CAMERA_MATRIX_COLS = 3;
private static final int DISTORTION_COEFFICIENTS_SIZE = 5;
public static void save(Activity activity, Mat cameraMatrix, Mat distortionCoefficients) {
SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
double[] cameraMatrixArray = new double[CAMERA_MATRIX_ROWS * CAMERA_MATRIX_COLS];
cameraMatrix.get(0, 0, cameraMatrixArray);
for (int i = 0; i < CAMERA_MATRIX_ROWS; i++) {
for (int j = 0; j < CAMERA_MATRIX_COLS; j++) {
int id = i * CAMERA_MATRIX_ROWS + j;
editor.putFloat(Integer.toString(id), (float)cameraMatrixArray[id]);
}
}
double[] distortionCoefficientsArray = new double[DISTORTION_COEFFICIENTS_SIZE];
distortionCoefficients.get(0, 0, distortionCoefficientsArray);
int shift = CAMERA_MATRIX_ROWS * CAMERA_MATRIX_COLS;
for (int i = shift; i < DISTORTION_COEFFICIENTS_SIZE + shift; i++) {
editor.putFloat(Integer.toString(i), (float)distortionCoefficientsArray[i-shift]);
}
editor.apply();
Log.i(TAG, "Saved camera matrix: " + cameraMatrix.dump());
Log.i(TAG, "Saved distortion coefficients: " + distortionCoefficients.dump());
}
public static boolean tryLoad(Activity activity, Mat cameraMatrix, Mat distortionCoefficients) {
SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE);
if (sharedPref.getFloat("0", -1) == -1) {
Log.i(TAG, "No previous calibration results found");
return false;
}
double[] cameraMatrixArray = new double[CAMERA_MATRIX_ROWS * CAMERA_MATRIX_COLS];
for (int i = 0; i < CAMERA_MATRIX_ROWS; i++) {
for (int j = 0; j < CAMERA_MATRIX_COLS; j++) {
int id = i * CAMERA_MATRIX_ROWS + j;
cameraMatrixArray[id] = sharedPref.getFloat(Integer.toString(id), -1);
}
}
cameraMatrix.put(0, 0, cameraMatrixArray);
Log.i(TAG, "Loaded camera matrix: " + cameraMatrix.dump());
double[] distortionCoefficientsArray = new double[DISTORTION_COEFFICIENTS_SIZE];
int shift = CAMERA_MATRIX_ROWS * CAMERA_MATRIX_COLS;
for (int i = shift; i < DISTORTION_COEFFICIENTS_SIZE + shift; i++) {
distortionCoefficientsArray[i - shift] = sharedPref.getFloat(Integer.toString(i), -1);
}
distortionCoefficients.put(0, 0, distortionCoefficientsArray);
Log.i(TAG, "Loaded distortion coefficients: " + distortionCoefficients.dump());
return true;
}
}

View File

@@ -0,0 +1,220 @@
// This sample is based on "Camera calibration With OpenCV" tutorial:
// https://docs.opencv.org/4.x/d4/d94/tutorial_camera_calibration.html
//
// It uses standard OpenCV asymmetric circles grid pattern 11x4:
// https://github.com/opencv/opencv/blob/4.x/doc/acircles_pattern.png
// The results are the camera matrix and 5 distortion coefficients.
//
// Tap on highlighted pattern to capture pattern corners for calibration.
// Move pattern along the whole screen and capture data.
//
// When you've captured necessary amount of pattern corners (usually ~20 are enough),
// press "Calibrate" button for performing camera calibration.
package org.opencv.samples.cameracalibration;
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.OpenCVLoader;
import org.opencv.core.Mat;
import android.app.ProgressDialog;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.Toast;
import java.util.Collections;
import java.util.List;
public class CameraCalibrationActivity extends CameraActivity implements CvCameraViewListener2, OnTouchListener {
private static final String TAG = "OCVSample::Activity";
private CameraBridgeViewBase mOpenCvCameraView;
private CameraCalibrator mCalibrator;
private OnCameraFrameRender mOnCameraFrameRender;
private Menu mMenu;
private int mWidth;
private int mHeight;
public CameraCalibrationActivity() {
Log.i(TAG, "Instantiated new " + this.getClass());
}
@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;
}
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.camera_calibration_surface_view);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.camera_calibration_java_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.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();
mOpenCvCameraView.setOnTouchListener(CameraCalibrationActivity.this);
}
}
@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) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.calibration, menu);
mMenu = menu;
return true;
}
@Override
public boolean onPrepareOptionsMenu (Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.preview_mode).setEnabled(true);
if (mCalibrator != null && !mCalibrator.isCalibrated()) {
menu.findItem(R.id.preview_mode).setEnabled(false);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.calibration) {
mOnCameraFrameRender =
new OnCameraFrameRender(new CalibrationFrameRender(mCalibrator));
item.setChecked(true);
return true;
} else if (item.getItemId() == R.id.undistortion) {
mOnCameraFrameRender =
new OnCameraFrameRender(new UndistortionFrameRender(mCalibrator));
item.setChecked(true);
return true;
} else if (item.getItemId() == R.id.comparison) {
mOnCameraFrameRender =
new OnCameraFrameRender(new ComparisonFrameRender(mCalibrator, mWidth, mHeight, getResources()));
item.setChecked(true);
return true;
} 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();
return true;
}
mOnCameraFrameRender = new OnCameraFrameRender(new PreviewFrameRender());
new AsyncTask<Void, Void, Void>() {
private ProgressDialog calibrationProgress;
@Override
protected void onPreExecute() {
calibrationProgress = new ProgressDialog(CameraCalibrationActivity.this);
calibrationProgress.setTitle(res.getString(R.string.calibrating));
calibrationProgress.setMessage(res.getString(R.string.please_wait));
calibrationProgress.setCancelable(false);
calibrationProgress.setIndeterminate(true);
calibrationProgress.show();
}
@Override
protected Void doInBackground(Void... arg0) {
mCalibrator.calibrate();
return null;
}
@Override
protected void onPostExecute(Void result) {
calibrationProgress.dismiss();
mCalibrator.clearCorners();
mOnCameraFrameRender = new OnCameraFrameRender(new CalibrationFrameRender(mCalibrator));
String resultMessage = (mCalibrator.isCalibrated()) ?
res.getString(R.string.calibration_successful) + " " + mCalibrator.getAvgReprojectionError() :
res.getString(R.string.calibration_unsuccessful);
(Toast.makeText(CameraCalibrationActivity.this, resultMessage, Toast.LENGTH_SHORT)).show();
if (mCalibrator.isCalibrated()) {
CalibrationResult.save(CameraCalibrationActivity.this,
mCalibrator.getCameraMatrix(), mCalibrator.getDistortionCoefficients());
}
}
}.execute();
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
public void onCameraViewStarted(int width, int height) {
if (mWidth != width || mHeight != height) {
mWidth = width;
mHeight = height;
mCalibrator = new CameraCalibrator(mWidth, mHeight);
if (CalibrationResult.tryLoad(this, mCalibrator.getCameraMatrix(), mCalibrator.getDistortionCoefficients())) {
mCalibrator.setCalibrated();
} else {
if (mMenu != null && !mCalibrator.isCalibrated()) {
mMenu.findItem(R.id.preview_mode).setEnabled(false);
}
}
mOnCameraFrameRender = new OnCameraFrameRender(new CalibrationFrameRender(mCalibrator));
}
}
public void onCameraViewStopped() {
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
return mOnCameraFrameRender.render(inputFrame);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d(TAG, "onTouch invoked");
mCalibrator.addCorners();
return false;
}
}

View File

@@ -0,0 +1,170 @@
package org.opencv.samples.cameracalibration;
import java.util.ArrayList;
import java.util.List;
import org.opencv.calib3d.Calib3d;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfDouble;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.MatOfPoint3f;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import android.util.Log;
public class CameraCalibrator {
private static final String TAG = "OCV::CameraCalibrator";
private final Size mPatternSize = new Size(4, 11);
private final int mCornersSize = (int)(mPatternSize.width * mPatternSize.height);
private boolean mPatternWasFound = false;
private MatOfPoint2f mCorners = new MatOfPoint2f();
private List<Mat> mCornersBuffer = new ArrayList<>();
private boolean mIsCalibrated = false;
private Mat mCameraMatrix = new Mat();
private Mat mDistortionCoefficients = new Mat();
private int mFlags;
private double mRms;
private double mSquareSize = 0.0181;
private Size mImageSize;
public CameraCalibrator(int width, int height) {
mImageSize = new Size(width, height);
mFlags = Calib3d.CALIB_FIX_PRINCIPAL_POINT +
Calib3d.CALIB_ZERO_TANGENT_DIST +
Calib3d.CALIB_FIX_ASPECT_RATIO +
Calib3d.CALIB_FIX_K4 +
Calib3d.CALIB_FIX_K5;
Mat.eye(3, 3, CvType.CV_64FC1).copyTo(mCameraMatrix);
mCameraMatrix.put(0, 0, 1.0);
Mat.zeros(5, 1, CvType.CV_64FC1).copyTo(mDistortionCoefficients);
Log.i(TAG, "Instantiated new " + this.getClass());
}
public void processFrame(Mat grayFrame, Mat rgbaFrame) {
findPattern(grayFrame);
renderFrame(rgbaFrame);
}
public void calibrate() {
ArrayList<Mat> rvecs = new ArrayList<>();
ArrayList<Mat> tvecs = new ArrayList<>();
Mat reprojectionErrors = new Mat();
ArrayList<Mat> objectPoints = new ArrayList<>();
objectPoints.add(Mat.zeros(mCornersSize, 1, CvType.CV_32FC3));
calcBoardCornerPositions(objectPoints.get(0));
for (int i = 1; i < mCornersBuffer.size(); i++) {
objectPoints.add(objectPoints.get(0));
}
Calib3d.calibrateCamera(objectPoints, mCornersBuffer, mImageSize,
mCameraMatrix, mDistortionCoefficients, rvecs, tvecs, mFlags);
mIsCalibrated = Core.checkRange(mCameraMatrix)
&& Core.checkRange(mDistortionCoefficients);
mRms = computeReprojectionErrors(objectPoints, rvecs, tvecs, reprojectionErrors);
Log.i(TAG, String.format("Average re-projection error: %f", mRms));
Log.i(TAG, "Camera matrix: " + mCameraMatrix.dump());
Log.i(TAG, "Distortion coefficients: " + mDistortionCoefficients.dump());
}
public void clearCorners() {
mCornersBuffer.clear();
}
private void calcBoardCornerPositions(Mat corners) {
final int cn = 3;
float[] positions = new float[mCornersSize * cn];
for (int i = 0; i < mPatternSize.height; i++) {
for (int j = 0; j < mPatternSize.width * cn; j += cn) {
positions[(int) (i * mPatternSize.width * cn + j + 0)] =
(2 * (j / cn) + i % 2) * (float) mSquareSize;
positions[(int) (i * mPatternSize.width * cn + j + 1)] =
i * (float) mSquareSize;
positions[(int) (i * mPatternSize.width * cn + j + 2)] = 0;
}
}
corners.create(mCornersSize, 1, CvType.CV_32FC3);
corners.put(0, 0, positions);
}
private double computeReprojectionErrors(List<Mat> objectPoints,
List<Mat> rvecs, List<Mat> tvecs, Mat perViewErrors) {
MatOfPoint2f cornersProjected = new MatOfPoint2f();
double totalError = 0;
double error;
float[] viewErrors = new float[objectPoints.size()];
MatOfDouble distortionCoefficients = new MatOfDouble(mDistortionCoefficients);
int totalPoints = 0;
for (int i = 0; i < objectPoints.size(); i++) {
MatOfPoint3f points = new MatOfPoint3f(objectPoints.get(i));
Calib3d.projectPoints(points, rvecs.get(i), tvecs.get(i),
mCameraMatrix, distortionCoefficients, cornersProjected);
error = Core.norm(mCornersBuffer.get(i), cornersProjected, Core.NORM_L2);
int n = objectPoints.get(i).rows();
viewErrors[i] = (float) Math.sqrt(error * error / n);
totalError += error * error;
totalPoints += n;
}
perViewErrors.create(objectPoints.size(), 1, CvType.CV_32FC1);
perViewErrors.put(0, 0, viewErrors);
return Math.sqrt(totalError / totalPoints);
}
private void findPattern(Mat grayFrame) {
mPatternWasFound = Calib3d.findCirclesGrid(grayFrame, mPatternSize,
mCorners, Calib3d.CALIB_CB_ASYMMETRIC_GRID);
}
public void addCorners() {
if (mPatternWasFound) {
mCornersBuffer.add(mCorners.clone());
}
}
private void drawPoints(Mat rgbaFrame) {
Calib3d.drawChessboardCorners(rgbaFrame, mPatternSize, mCorners, mPatternWasFound);
}
private void renderFrame(Mat rgbaFrame) {
drawPoints(rgbaFrame);
Imgproc.putText(rgbaFrame, "Captured: " + mCornersBuffer.size(), new Point(rgbaFrame.cols() / 3 * 2, rgbaFrame.rows() * 0.1),
Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 0));
}
public Mat getCameraMatrix() {
return mCameraMatrix;
}
public Mat getDistortionCoefficients() {
return mDistortionCoefficients;
}
public int getCornersBufferSize() {
return mCornersBuffer.size();
}
public double getAvgReprojectionError() {
return mRms;
}
public boolean isCalibrated() {
return mIsCalibrated;
}
public void setCalibrated() {
mIsCalibrated = true;
}
}

View File

@@ -0,0 +1,103 @@
package org.opencv.samples.cameracalibration;
import java.util.ArrayList;
import java.util.List;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.calib3d.Calib3d;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.core.Range;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;
import android.content.res.Resources;
abstract class FrameRender {
protected CameraCalibrator mCalibrator;
public abstract Mat render(CvCameraViewFrame inputFrame);
}
class PreviewFrameRender extends FrameRender {
@Override
public Mat render(CvCameraViewFrame inputFrame) {
return inputFrame.rgba();
}
}
class CalibrationFrameRender extends FrameRender {
public CalibrationFrameRender(CameraCalibrator calibrator) {
mCalibrator = calibrator;
}
@Override
public Mat render(CvCameraViewFrame inputFrame) {
Mat rgbaFrame = inputFrame.rgba();
Mat grayFrame = inputFrame.gray();
mCalibrator.processFrame(grayFrame, rgbaFrame);
return rgbaFrame;
}
}
class UndistortionFrameRender extends FrameRender {
public UndistortionFrameRender(CameraCalibrator calibrator) {
mCalibrator = calibrator;
}
@Override
public Mat render(CvCameraViewFrame inputFrame) {
Mat renderedFrame = new Mat(inputFrame.rgba().size(), inputFrame.rgba().type());
Calib3d.undistort(inputFrame.rgba(), renderedFrame,
mCalibrator.getCameraMatrix(), mCalibrator.getDistortionCoefficients());
return renderedFrame;
}
}
class ComparisonFrameRender extends FrameRender {
private int mWidth;
private int mHeight;
private Resources mResources;
public ComparisonFrameRender(CameraCalibrator calibrator, int width, int height, Resources resources) {
mCalibrator = calibrator;
mWidth = width;
mHeight = height;
mResources = resources;
}
@Override
public Mat render(CvCameraViewFrame inputFrame) {
Mat undistortedFrame = new Mat(inputFrame.rgba().size(), inputFrame.rgba().type());
Calib3d.undistort(inputFrame.rgba(), undistortedFrame,
mCalibrator.getCameraMatrix(), mCalibrator.getDistortionCoefficients());
Mat comparisonFrame = inputFrame.rgba();
undistortedFrame.colRange(new Range(0, mWidth / 2)).copyTo(comparisonFrame.colRange(new Range(mWidth / 2, mWidth)));
List<MatOfPoint> border = new ArrayList<MatOfPoint>();
final int shift = (int)(mWidth * 0.005);
border.add(new MatOfPoint(new Point(mWidth / 2 - shift, 0), new Point(mWidth / 2 + shift, 0),
new Point(mWidth / 2 + shift, mHeight), new Point(mWidth / 2 - shift, mHeight)));
Imgproc.fillPoly(comparisonFrame, border, new Scalar(255, 255, 255));
Imgproc.putText(comparisonFrame, mResources.getString(R.string.original), new Point(mWidth * 0.1, mHeight * 0.1),
Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 0));
Imgproc.putText(comparisonFrame, mResources.getString(R.string.undistorted), new Point(mWidth * 0.6, mHeight * 0.1),
Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 0));
return comparisonFrame;
}
}
class OnCameraFrameRender {
private FrameRender mFrameRender;
public OnCameraFrameRender(FrameRender frameRender) {
mFrameRender = frameRender;
}
public Mat render(CvCameraViewFrame inputFrame) {
return mFrameRender.render(inputFrame);
}
}

View File

@@ -0,0 +1,6 @@
set(sample example-color-blob-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()

View File

@@ -0,0 +1,37 @@
apply plugin: 'com.android.application'
android {
namespace 'org.opencv.samples.colorblobdetect'
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
defaultConfig {
applicationId "org.opencv.samples.colorblobdetect"
minSdkVersion @ANDROID_MIN_SDK_VERSION@
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
versionCode 301
versionName "3.01"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
java.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
res.srcDirs = @ANDROID_SAMPLE_RES_PATH@
manifest.srcFile '@ANDROID_SAMPLE_MANIFEST_PATH@'
}
}
}
dependencies {
//implementation fileTree(dir: 'libs', include: ['*.jar'])
if (gradle.opencv_source == "sdk_path") {
println 'Using OpenCV from from SDK'
implementation project(':opencv')
} else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_central") {
println 'Using OpenCV from Maven repo'
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
}
}

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.opencv.samples.colorblobdetect"
>
<application
android:label="@string/app_name"
android:icon="@drawable/icon"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<activity
android:exported="true"
android:name="ColorBlobDetectionActivity"
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-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

View File

@@ -0,0 +1,11 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<org.opencv.android.JavaCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/color_blob_detection_activity_surface_view" />
</LinearLayout>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">OCV Color Blob Detection</string>
</resources>

View File

@@ -0,0 +1,192 @@
package org.opencv.samples.colorblobdetect;
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.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
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.imgproc.Imgproc;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
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";
private boolean mIsColorSelected = false;
private Mat mRgba;
private Scalar mBlobColorRgba;
private Scalar mBlobColorHsv;
private ColorBlobDetector mDetector;
private Mat mSpectrum;
private Size SPECTRUM_SIZE;
private Scalar CONTOUR_COLOR;
private CameraBridgeViewBase mOpenCvCameraView;
public ColorBlobDetectionActivity() {
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;
}
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.color_blob_detection_surface_view);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.color_blob_detection_activity_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.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();
mOpenCvCameraView.setOnTouchListener(ColorBlobDetectionActivity.this);
}
}
@Override
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
return Collections.singletonList(mOpenCvCameraView);
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
public void onCameraViewStarted(int width, int height) {
mRgba = new Mat(height, width, CvType.CV_8UC4);
mDetector = new ColorBlobDetector();
mSpectrum = new Mat();
mBlobColorRgba = new Scalar(255);
mBlobColorHsv = new Scalar(255);
SPECTRUM_SIZE = new Size(200, 64);
CONTOUR_COLOR = new Scalar(255,0,0,255);
}
public void onCameraViewStopped() {
mRgba.release();
}
public boolean onTouch(View v, MotionEvent event) {
int cols = mRgba.cols();
int rows = mRgba.rows();
int xOffset = (mOpenCvCameraView.getWidth() - cols) / 2;
int yOffset = (mOpenCvCameraView.getHeight() - rows) / 2;
int x = (int)event.getX() - xOffset;
int y = (int)event.getY() - yOffset;
Log.i(TAG, "Touch image coordinates: (" + x + ", " + y + ")");
if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false;
Rect touchedRect = new Rect();
touchedRect.x = (x>4) ? x-4 : 0;
touchedRect.y = (y>4) ? y-4 : 0;
touchedRect.width = (x+4 < cols) ? x + 4 - touchedRect.x : cols - touchedRect.x;
touchedRect.height = (y+4 < rows) ? y + 4 - touchedRect.y : rows - touchedRect.y;
Mat touchedRegionRgba = mRgba.submat(touchedRect);
Mat touchedRegionHsv = new Mat();
Imgproc.cvtColor(touchedRegionRgba, touchedRegionHsv, Imgproc.COLOR_RGB2HSV_FULL);
// Calculate average color of touched region
mBlobColorHsv = Core.sumElems(touchedRegionHsv);
int pointCount = touchedRect.width*touchedRect.height;
for (int i = 0; i < mBlobColorHsv.val.length; i++)
mBlobColorHsv.val[i] /= pointCount;
mBlobColorRgba = convertScalarHsv2Rgba(mBlobColorHsv);
Log.i(TAG, "Touched rgba color: (" + mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] +
", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3] + ")");
mDetector.setHsvColor(mBlobColorHsv);
Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE, 0, 0, Imgproc.INTER_LINEAR_EXACT);
mIsColorSelected = true;
touchedRegionRgba.release();
touchedRegionHsv.release();
return false; // don't need subsequent touch events
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();
if (mIsColorSelected) {
mDetector.process(mRgba);
List<MatOfPoint> contours = mDetector.getContours();
Log.i(TAG, "Contours count: " + contours.size());
Imgproc.drawContours(mRgba, contours, -1, CONTOUR_COLOR);
Mat colorLabel = mRgba.submat(4, 68, 4, 68);
colorLabel.setTo(mBlobColorRgba);
Mat spectrumLabel = mRgba.submat(4, 4 + mSpectrum.rows(), 70, 70 + mSpectrum.cols());
mSpectrum.copyTo(spectrumLabel);
}
return mRgba;
}
private Scalar convertScalarHsv2Rgba(Scalar hsvColor) {
Mat pointMatRgba = new Mat();
Mat pointMatHsv = new Mat(1, 1, CvType.CV_8UC3, hsvColor);
Imgproc.cvtColor(pointMatHsv, pointMatRgba, Imgproc.COLOR_HSV2RGB_FULL, 4);
return new Scalar(pointMatRgba.get(0, 0));
}
}

View File

@@ -0,0 +1,108 @@
package org.opencv.samples.colorblobdetect;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;
public class ColorBlobDetector {
// Lower and Upper bounds for range checking in HSV color space
private Scalar mLowerBound = new Scalar(0);
private Scalar mUpperBound = new Scalar(0);
// Minimum contour area in percent for contours filtering
private static double mMinContourArea = 0.1;
// Color radius for range checking in HSV color space
private Scalar mColorRadius = new Scalar(25,50,50,0);
private Mat mSpectrum = new Mat();
private List<MatOfPoint> mContours = new ArrayList<MatOfPoint>();
// Cache
Mat mPyrDownMat = new Mat();
Mat mHsvMat = new Mat();
Mat mMask = new Mat();
Mat mDilatedMask = new Mat();
Mat mHierarchy = new Mat();
public void setColorRadius(Scalar radius) {
mColorRadius = radius;
}
public void setHsvColor(Scalar hsvColor) {
double minH = (hsvColor.val[0] >= mColorRadius.val[0]) ? hsvColor.val[0]-mColorRadius.val[0] : 0;
double maxH = (hsvColor.val[0]+mColorRadius.val[0] <= 255) ? hsvColor.val[0]+mColorRadius.val[0] : 255;
mLowerBound.val[0] = minH;
mUpperBound.val[0] = maxH;
mLowerBound.val[1] = hsvColor.val[1] - mColorRadius.val[1];
mUpperBound.val[1] = hsvColor.val[1] + mColorRadius.val[1];
mLowerBound.val[2] = hsvColor.val[2] - mColorRadius.val[2];
mUpperBound.val[2] = hsvColor.val[2] + mColorRadius.val[2];
mLowerBound.val[3] = 0;
mUpperBound.val[3] = 255;
Mat spectrumHsv = new Mat(1, (int)(maxH-minH), CvType.CV_8UC3);
for (int j = 0; j < maxH-minH; j++) {
byte[] tmp = {(byte)(minH+j), (byte)255, (byte)255};
spectrumHsv.put(0, j, tmp);
}
Imgproc.cvtColor(spectrumHsv, mSpectrum, Imgproc.COLOR_HSV2RGB_FULL, 4);
}
public Mat getSpectrum() {
return mSpectrum;
}
public void setMinContourArea(double area) {
mMinContourArea = area;
}
public void process(Mat rgbaImage) {
Imgproc.pyrDown(rgbaImage, mPyrDownMat);
Imgproc.pyrDown(mPyrDownMat, mPyrDownMat);
Imgproc.cvtColor(mPyrDownMat, mHsvMat, Imgproc.COLOR_RGB2HSV_FULL);
Core.inRange(mHsvMat, mLowerBound, mUpperBound, mMask);
Imgproc.dilate(mMask, mDilatedMask, new Mat());
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(mDilatedMask, contours, mHierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
// Find max contour area
double maxArea = 0;
Iterator<MatOfPoint> each = contours.iterator();
while (each.hasNext()) {
MatOfPoint wrapper = each.next();
double area = Imgproc.contourArea(wrapper);
if (area > maxArea)
maxArea = area;
}
// Filter contours by area and resize to fit the original image size
mContours.clear();
each = contours.iterator();
while (each.hasNext()) {
MatOfPoint contour = each.next();
if (Imgproc.contourArea(contour) > mMinContourArea*maxArea) {
Core.multiply(contour, new Scalar(4,4), contour);
mContours.add(contour);
}
}
}
public List<MatOfPoint> getContours() {
return mContours;
}
}

View File

@@ -0,0 +1,16 @@
set(sample example-face-detection)
ocv_download(FILENAME "face_detection_yunet_2023mar.onnx"
HASH "4ae92eeb150c82ce15ac80738b3b8167"
URL
"${OPENCV_FACE_DETECT_YN_URL}"
"$ENV{OPENCV_FACE_DETECT_YN_URL}"
"https://media.githubusercontent.com/media/opencv/opencv_zoo/main/models/face_detection_yunet/face_detection_yunet_2023mar.onnx"
DESTINATION_DIR "${CMAKE_CURRENT_LIST_DIR}/res/raw"
ID OPENCV_FACE_DETECT_YN
STATUS res)
add_android_project(${sample} "${CMAKE_CURRENT_SOURCE_DIR}" LIBRARY_DEPS "${OPENCV_ANDROID_LIB_DIR}" SDK_TARGET 11 "${ANDROID_SDK_TARGET}")
if(TARGET ${sample})
add_dependencies(opencv_android_examples ${sample})
endif()

View File

@@ -0,0 +1,37 @@
apply plugin: 'com.android.application'
android {
namespace 'org.opencv.samples.facedetect'
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
defaultConfig {
applicationId "org.opencv.samples.facedetect"
minSdkVersion @ANDROID_MIN_SDK_VERSION@
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
versionCode 301
versionName "3.01"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
java.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
res.srcDirs = @ANDROID_SAMPLE_RES_PATH@
manifest.srcFile '@ANDROID_SAMPLE_MANIFEST_PATH@'
}
}
}
dependencies {
//implementation fileTree(dir: 'libs', include: ['*.jar'])
if (gradle.opencv_source == "sdk_path") {
println 'Using OpenCV from from SDK'
implementation project(':opencv')
} else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_central") {
println 'Using OpenCV from Maven repo'
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
}
}

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.opencv.samples.facedetect"
>
<application
android:label="@string/app_name"
android:icon="@drawable/icon">
<activity
android:exported="true"
android:name="FaceDetectActivity"
android:label="@string/app_name"
android:configChanges="keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<supports-screens android:resizeable="true"
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,11 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<org.opencv.android.JavaCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/fd_activity_surface_view" />
</LinearLayout>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">OCV Face Detection</string>
</resources>

View File

@@ -0,0 +1,204 @@
package org.opencv.samples.facedetect;
import java.lang.Math;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import org.opencv.android.CameraActivity;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.objdetect.FaceDetectorYN;
import org.opencv.imgproc.Imgproc;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
import android.widget.Toast;
public class FaceDetectActivity extends CameraActivity implements CvCameraViewListener2 {
private static final String TAG = "OCVSample::Activity";
private static final Scalar BOX_COLOR = new Scalar(0, 255, 0);
private static final Scalar RIGHT_EYE_COLOR = new Scalar(255, 0, 0);
private static final Scalar LEFT_EYE_COLOR = new Scalar(0, 0, 255);
private static final Scalar NOSE_TIP_COLOR = new Scalar(0, 255, 0);
private static final Scalar MOUTH_RIGHT_COLOR = new Scalar(255, 0, 255);
private static final Scalar MOUTH_LEFT_COLOR = new Scalar(0, 255, 255);
private Mat mRgba;
private Mat mBgr;
private Mat mBgrScaled;
private Size mInputSize = null;
private float mScale = 2.f;
private MatOfByte mModelBuffer;
private MatOfByte mConfigBuffer;
private FaceDetectorYN mFaceDetector;
private Mat mFaces;
private CameraBridgeViewBase mOpenCvCameraView;
public FaceDetectActivity() {
Log.i(TAG, "Instantiated new " + this.getClass());
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
if (OpenCVLoader.initLocal()) {
Log.i(TAG, "OpenCV loaded successfully");
} else {
Log.e(TAG, "OpenCV initialization failed!");
(Toast.makeText(this, "OpenCV initialization failed!", Toast.LENGTH_LONG)).show();
return;
}
byte[] buffer;
try {
// load cascade file from application resources
InputStream is = getResources().openRawResource(R.raw.face_detection_yunet_2023mar);
int size = is.available();
buffer = new byte[size];
int bytesRead = is.read(buffer);
is.close();
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "Failed to ONNX model from resources! Exception thrown: " + e);
(Toast.makeText(this, "Failed to ONNX model from resources!", Toast.LENGTH_LONG)).show();
return;
}
mModelBuffer = new MatOfByte(buffer);
mConfigBuffer = new MatOfByte();
mFaceDetector = FaceDetectorYN.create("onnx", mModelBuffer, mConfigBuffer, new Size(320, 320));
if (mFaceDetector == null) {
Log.e(TAG, "Failed to create FaceDetectorYN!");
(Toast.makeText(this, "Failed to create FaceDetectorYN!", Toast.LENGTH_LONG)).show();
return;
} else
Log.i(TAG, "FaceDetectorYN initialized successfully!");
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.face_detect_surface_view);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.fd_activity_surface_view);
mOpenCvCameraView.setVisibility(CameraBridgeViewBase.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
}
@Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
@Override
public void onResume()
{
super.onResume();
if (mOpenCvCameraView != null)
mOpenCvCameraView.enableView();
}
@Override
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
return Collections.singletonList(mOpenCvCameraView);
}
public void onDestroy() {
super.onDestroy();
mOpenCvCameraView.disableView();
}
public void onCameraViewStarted(int width, int height) {
mRgba = new Mat();
mBgr = new Mat();
mBgrScaled = new Mat();
mFaces = new Mat();
}
public void onCameraViewStopped() {
mRgba.release();
mBgr.release();
mBgrScaled.release();
mFaces.release();
}
public void visualize(Mat rgba, Mat faces) {
int thickness = 2;
float[] faceData = new float[faces.cols() * faces.channels()];
for (int i = 0; i < faces.rows(); i++)
{
faces.get(i, 0, faceData);
Log.d(TAG, "Detected face (" + faceData[0] + ", " + faceData[1] + ", " +
faceData[2] + ", " + faceData[3] + ")");
// Draw bounding box
Imgproc.rectangle(rgba, new Rect(Math.round(mScale*faceData[0]), Math.round(mScale*faceData[1]),
Math.round(mScale*faceData[2]), Math.round(mScale*faceData[3])),
BOX_COLOR, thickness);
// Draw landmarks
Imgproc.circle(rgba, new Point(Math.round(mScale*faceData[4]), Math.round(mScale*faceData[5])),
2, RIGHT_EYE_COLOR, thickness);
Imgproc.circle(rgba, new Point(Math.round(mScale*faceData[6]), Math.round(mScale*faceData[7])),
2, LEFT_EYE_COLOR, thickness);
Imgproc.circle(rgba, new Point(Math.round(mScale*faceData[8]), Math.round(mScale*faceData[9])),
2, NOSE_TIP_COLOR, thickness);
Imgproc.circle(rgba, new Point(Math.round(mScale*faceData[10]), Math.round(mScale*faceData[11])),
2, MOUTH_RIGHT_COLOR, thickness);
Imgproc.circle(rgba, new Point(Math.round(mScale*faceData[12]), Math.round(mScale*faceData[13])),
2, MOUTH_LEFT_COLOR, thickness);
}
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();
Size inputSize = new Size(Math.round(mRgba.cols()/mScale), Math.round(mRgba.rows()/mScale));
if (mInputSize == null || !mInputSize.equals(inputSize)) {
mInputSize = inputSize;
mFaceDetector.setInputSize(mInputSize);
}
Imgproc.cvtColor(mRgba, mBgr, Imgproc.COLOR_RGBA2BGR);
Imgproc.resize(mBgr, mBgrScaled, mInputSize);
if (mFaceDetector != null) {
int status = mFaceDetector.detect(mBgrScaled, mFaces);
Log.d(TAG, "Detector returned status " + status);
visualize(mRgba, mFaces);
}
return mRgba;
}
}

View File

@@ -0,0 +1,6 @@
set(sample example-image-manipulations)
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()

View File

@@ -0,0 +1,37 @@
apply plugin: 'com.android.application'
android {
namespace 'org.opencv.samples.imagemanipulations'
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
defaultConfig {
applicationId "org.opencv.samples.imagemanipulations"
minSdkVersion @ANDROID_MIN_SDK_VERSION@
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
versionCode 301
versionName "3.01"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
java.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
res.srcDirs = @ANDROID_SAMPLE_RES_PATH@
manifest.srcFile '@ANDROID_SAMPLE_MANIFEST_PATH@'
}
}
}
dependencies {
//implementation fileTree(dir: 'libs', include: ['*.jar'])
if (gradle.opencv_source == "sdk_path") {
println 'Using OpenCV from from SDK'
implementation project(':opencv')
} else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_central") {
println 'Using OpenCV from Maven repo'
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
}
}

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.opencv.samples.imagemanipulations"
>
<application
android:label="@string/app_name"
android:icon="@drawable/icon">
<activity
android:exported="true"
android:name="ImageManipulationsActivity"
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-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

View File

@@ -0,0 +1,11 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<org.opencv.android.JavaCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/image_manipulations_activity_surface_view" />
</LinearLayout>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">OCV Image Manipulations</string>
</resources>

View File

@@ -0,0 +1,313 @@
package org.opencv.samples.imagemanipulations;
import java.util.Arrays;
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.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfFloat;
import org.opencv.core.MatOfInt;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.imgproc.Imgproc;
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 ImageManipulationsActivity extends CameraActivity implements CvCameraViewListener2 {
private static final String TAG = "OCVSample::Activity";
public static final int VIEW_MODE_RGBA = 0;
public static final int VIEW_MODE_HIST = 1;
public static final int VIEW_MODE_CANNY = 2;
public static final int VIEW_MODE_SEPIA = 3;
public static final int VIEW_MODE_SOBEL = 4;
public static final int VIEW_MODE_ZOOM = 5;
public static final int VIEW_MODE_PIXELIZE = 6;
public static final int VIEW_MODE_POSTERIZE = 7;
private MenuItem mItemPreviewRGBA;
private MenuItem mItemPreviewHist;
private MenuItem mItemPreviewCanny;
private MenuItem mItemPreviewSepia;
private MenuItem mItemPreviewSobel;
private MenuItem mItemPreviewZoom;
private MenuItem mItemPreviewPixelize;
private MenuItem mItemPreviewPosterize;
private CameraBridgeViewBase mOpenCvCameraView;
private Size mSize0;
private Mat mIntermediateMat;
private Mat mMat0;
private MatOfInt mChannels[];
private MatOfInt mHistSize;
private int mHistSizeNum = 25;
private MatOfFloat mRanges;
private Scalar mColorsRGB[];
private Scalar mColorsHue[];
private Scalar mWhilte;
private Point mP1;
private Point mP2;
private float mBuff[];
private Mat mSepiaKernel;
public static int viewMode = VIEW_MODE_RGBA;
public ImageManipulationsActivity() {
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;
}
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.image_manipulations_surface_view);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.image_manipulations_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();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.i(TAG, "called onCreateOptionsMenu");
mItemPreviewRGBA = menu.add("Preview RGBA");
mItemPreviewHist = menu.add("Histograms");
mItemPreviewCanny = menu.add("Canny");
mItemPreviewSepia = menu.add("Sepia");
mItemPreviewSobel = menu.add("Sobel");
mItemPreviewZoom = menu.add("Zoom");
mItemPreviewPixelize = menu.add("Pixelize");
mItemPreviewPosterize = menu.add("Posterize");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.i(TAG, "called onOptionsItemSelected; selected item: " + item);
if (item == mItemPreviewRGBA)
viewMode = VIEW_MODE_RGBA;
if (item == mItemPreviewHist)
viewMode = VIEW_MODE_HIST;
else if (item == mItemPreviewCanny)
viewMode = VIEW_MODE_CANNY;
else if (item == mItemPreviewSepia)
viewMode = VIEW_MODE_SEPIA;
else if (item == mItemPreviewSobel)
viewMode = VIEW_MODE_SOBEL;
else if (item == mItemPreviewZoom)
viewMode = VIEW_MODE_ZOOM;
else if (item == mItemPreviewPixelize)
viewMode = VIEW_MODE_PIXELIZE;
else if (item == mItemPreviewPosterize)
viewMode = VIEW_MODE_POSTERIZE;
return true;
}
public void onCameraViewStarted(int width, int height) {
mIntermediateMat = new Mat();
mSize0 = new Size();
mChannels = new MatOfInt[] { new MatOfInt(0), new MatOfInt(1), new MatOfInt(2) };
mBuff = new float[mHistSizeNum];
mHistSize = new MatOfInt(mHistSizeNum);
mRanges = new MatOfFloat(0f, 256f);
mMat0 = new Mat();
mColorsRGB = new Scalar[] { new Scalar(200, 0, 0, 255), new Scalar(0, 200, 0, 255), new Scalar(0, 0, 200, 255) };
mColorsHue = new Scalar[] {
new Scalar(255, 0, 0, 255), new Scalar(255, 60, 0, 255), new Scalar(255, 120, 0, 255), new Scalar(255, 180, 0, 255), new Scalar(255, 240, 0, 255),
new Scalar(215, 213, 0, 255), new Scalar(150, 255, 0, 255), new Scalar(85, 255, 0, 255), new Scalar(20, 255, 0, 255), new Scalar(0, 255, 30, 255),
new Scalar(0, 255, 85, 255), new Scalar(0, 255, 150, 255), new Scalar(0, 255, 215, 255), new Scalar(0, 234, 255, 255), new Scalar(0, 170, 255, 255),
new Scalar(0, 120, 255, 255), new Scalar(0, 60, 255, 255), new Scalar(0, 0, 255, 255), new Scalar(64, 0, 255, 255), new Scalar(120, 0, 255, 255),
new Scalar(180, 0, 255, 255), new Scalar(255, 0, 255, 255), new Scalar(255, 0, 215, 255), new Scalar(255, 0, 85, 255), new Scalar(255, 0, 0, 255)
};
mWhilte = Scalar.all(255);
mP1 = new Point();
mP2 = new Point();
// Fill sepia kernel
mSepiaKernel = new Mat(4, 4, CvType.CV_32F);
mSepiaKernel.put(0, 0, /* R */0.189f, 0.769f, 0.393f, 0f);
mSepiaKernel.put(1, 0, /* G */0.168f, 0.686f, 0.349f, 0f);
mSepiaKernel.put(2, 0, /* B */0.131f, 0.534f, 0.272f, 0f);
mSepiaKernel.put(3, 0, /* A */0.000f, 0.000f, 0.000f, 1f);
}
public void onCameraViewStopped() {
// Explicitly deallocate Mats
if (mIntermediateMat != null)
mIntermediateMat.release();
mIntermediateMat = null;
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
Mat rgba = inputFrame.rgba();
Size sizeRgba = rgba.size();
Mat rgbaInnerWindow;
int rows = (int) sizeRgba.height;
int cols = (int) sizeRgba.width;
int left = cols / 8;
int top = rows / 8;
int width = cols * 3 / 4;
int height = rows * 3 / 4;
switch (ImageManipulationsActivity.viewMode) {
case ImageManipulationsActivity.VIEW_MODE_RGBA:
break;
case ImageManipulationsActivity.VIEW_MODE_HIST:
Mat hist = new Mat();
int thikness = (int) (sizeRgba.width / (mHistSizeNum + 10) / 5);
if(thikness > 5) thikness = 5;
int offset = (int) ((sizeRgba.width - (5*mHistSizeNum + 4*10)*thikness)/2);
// RGB
for(int c=0; c<3; c++) {
Imgproc.calcHist(Arrays.asList(rgba), mChannels[c], mMat0, hist, mHistSize, mRanges);
Core.normalize(hist, hist, sizeRgba.height/2, 0, Core.NORM_INF);
hist.get(0, 0, mBuff);
for(int h=0; h<mHistSizeNum; h++) {
mP1.x = mP2.x = offset + (c * (mHistSizeNum + 10) + h) * thikness;
mP1.y = sizeRgba.height-1;
mP2.y = mP1.y - 2 - (int)mBuff[h];
Imgproc.line(rgba, mP1, mP2, mColorsRGB[c], thikness);
}
}
// Value and Hue
Imgproc.cvtColor(rgba, mIntermediateMat, Imgproc.COLOR_RGB2HSV_FULL);
// Value
Imgproc.calcHist(Arrays.asList(mIntermediateMat), mChannels[2], mMat0, hist, mHistSize, mRanges);
Core.normalize(hist, hist, sizeRgba.height/2, 0, Core.NORM_INF);
hist.get(0, 0, mBuff);
for(int h=0; h<mHistSizeNum; h++) {
mP1.x = mP2.x = offset + (3 * (mHistSizeNum + 10) + h) * thikness;
mP1.y = sizeRgba.height-1;
mP2.y = mP1.y - 2 - (int)mBuff[h];
Imgproc.line(rgba, mP1, mP2, mWhilte, thikness);
}
// Hue
Imgproc.calcHist(Arrays.asList(mIntermediateMat), mChannels[0], mMat0, hist, mHistSize, mRanges);
Core.normalize(hist, hist, sizeRgba.height/2, 0, Core.NORM_INF);
hist.get(0, 0, mBuff);
for(int h=0; h<mHistSizeNum; h++) {
mP1.x = mP2.x = offset + (4 * (mHistSizeNum + 10) + h) * thikness;
mP1.y = sizeRgba.height-1;
mP2.y = mP1.y - 2 - (int)mBuff[h];
Imgproc.line(rgba, mP1, mP2, mColorsHue[h], thikness);
}
break;
case ImageManipulationsActivity.VIEW_MODE_CANNY:
rgbaInnerWindow = rgba.submat(top, top + height, left, left + width);
Imgproc.Canny(rgbaInnerWindow, mIntermediateMat, 80, 90);
Imgproc.cvtColor(mIntermediateMat, rgbaInnerWindow, Imgproc.COLOR_GRAY2BGRA, 4);
rgbaInnerWindow.release();
break;
case ImageManipulationsActivity.VIEW_MODE_SOBEL:
Mat gray = inputFrame.gray();
Mat grayInnerWindow = gray.submat(top, top + height, left, left + width);
rgbaInnerWindow = rgba.submat(top, top + height, left, left + width);
Imgproc.Sobel(grayInnerWindow, mIntermediateMat, CvType.CV_8U, 1, 1);
Core.convertScaleAbs(mIntermediateMat, mIntermediateMat, 10, 0);
Imgproc.cvtColor(mIntermediateMat, rgbaInnerWindow, Imgproc.COLOR_GRAY2BGRA, 4);
grayInnerWindow.release();
rgbaInnerWindow.release();
break;
case ImageManipulationsActivity.VIEW_MODE_SEPIA:
rgbaInnerWindow = rgba.submat(top, top + height, left, left + width);
Core.transform(rgbaInnerWindow, rgbaInnerWindow, mSepiaKernel);
rgbaInnerWindow.release();
break;
case ImageManipulationsActivity.VIEW_MODE_ZOOM:
Mat zoomCorner = rgba.submat(0, rows / 2 - rows / 10, 0, cols / 2 - cols / 10);
Mat mZoomWindow = rgba.submat(rows / 2 - 9 * rows / 100, rows / 2 + 9 * rows / 100, cols / 2 - 9 * cols / 100, cols / 2 + 9 * cols / 100);
Imgproc.resize(mZoomWindow, zoomCorner, zoomCorner.size(), 0, 0, Imgproc.INTER_LINEAR_EXACT);
Size wsize = mZoomWindow.size();
Imgproc.rectangle(mZoomWindow, new Point(1, 1), new Point(wsize.width - 2, wsize.height - 2), new Scalar(255, 0, 0, 255), 2);
zoomCorner.release();
mZoomWindow.release();
break;
case ImageManipulationsActivity.VIEW_MODE_PIXELIZE:
rgbaInnerWindow = rgba.submat(top, top + height, left, left + width);
Imgproc.resize(rgbaInnerWindow, mIntermediateMat, mSize0, 0.1, 0.1, Imgproc.INTER_NEAREST);
Imgproc.resize(mIntermediateMat, rgbaInnerWindow, rgbaInnerWindow.size(), 0., 0., Imgproc.INTER_NEAREST);
rgbaInnerWindow.release();
break;
case ImageManipulationsActivity.VIEW_MODE_POSTERIZE:
/*
Imgproc.cvtColor(rgbaInnerWindow, mIntermediateMat, Imgproc.COLOR_RGBA2RGB);
Imgproc.pyrMeanShiftFiltering(mIntermediateMat, mIntermediateMat, 5, 50);
Imgproc.cvtColor(mIntermediateMat, rgbaInnerWindow, Imgproc.COLOR_RGB2RGBA);
*/
rgbaInnerWindow = rgba.submat(top, top + height, left, left + width);
Imgproc.Canny(rgbaInnerWindow, mIntermediateMat, 80, 90);
rgbaInnerWindow.setTo(new Scalar(0, 0, 0, 255), mIntermediateMat);
Core.convertScaleAbs(rgbaInnerWindow, mIntermediateMat, 1./16, 0);
Core.convertScaleAbs(mIntermediateMat, rgbaInnerWindow, 16, 0);
rgbaInnerWindow.release();
break;
}
return rgba;
}
}

View File

@@ -0,0 +1,26 @@
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})
endif()

View File

@@ -0,0 +1,37 @@
apply plugin: 'com.android.application'
android {
namespace 'org.opencv.samples.opencv_mobilenet'
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
defaultConfig {
applicationId "org.opencv.samples.opencv_mobilenet"
minSdkVersion @ANDROID_MIN_SDK_VERSION@
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
versionCode 341
versionName "3.41"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
java.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
res.srcDirs = @ANDROID_SAMPLE_RES_PATH@
manifest.srcFile '@ANDROID_SAMPLE_MANIFEST_PATH@'
}
}
}
dependencies {
//implementation fileTree(dir: 'libs', include: ['*.jar'])
if (gradle.opencv_source == "sdk_path") {
println 'Using OpenCV from SDK'
implementation project(':opencv')
} else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_central") {
println 'Using OpenCV from Maven repo'
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
}
}

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.opencv.samples.opencv_mobilenet">
<application
android:label="@string/app_name"
android:icon="@drawable/icon">
<!-- //! [mobilenet_tutorial] -->
<activity
android:exported="true"
android:name=".MainActivity"
android:screenOrientation="landscape"> <!--Screen orientation-->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<!--Allow to use a camera-->
<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>
<!-- //! [mobilenet_tutorial] -->

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="org.opencv.samples.opencv_mobilenet.MainActivity">
<org.opencv.android.JavaCameraView
android:id="@+id/CameraView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible" />
</FrameLayout>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">OCV Mobilenet Objdetect</string>
</resources>

View File

@@ -0,0 +1,196 @@
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.util.Log;
import android.widget.Toast;
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.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;
import org.opencv.dnn.Net;
import org.opencv.dnn.Dnn;
import org.opencv.imgproc.Imgproc;
import java.io.InputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
public class MainActivity extends CameraActivity implements CvCameraViewListener2 {
@Override
public void onResume() {
super.onResume();
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.
mOpenCvCameraView = (CameraBridgeViewBase)findViewById(R.id.CameraView);
mOpenCvCameraView.setVisibility(CameraBridgeViewBase.VISIBLE);
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) {
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
final int IN_WIDTH = 300;
final int IN_HEIGHT = 300;
final float WH_RATIO = (float)IN_WIDTH / IN_HEIGHT;
final double IN_SCALE_FACTOR = 0.007843;
final double MEAN_VAL = 127.5;
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);
net.setInput(blob);
Mat detections = net.forward();
int cols = frame.cols();
int rows = frame.rows();
detections = detections.reshape(1, (int)detections.total() / 7);
for (int i = 0; i < detections.rows(); ++i) {
double confidence = detections.get(i, 2)[0];
if (confidence > THRESHOLD) {
int classId = (int)detections.get(i, 1)[0];
int left = (int)(detections.get(i, 3)[0] * cols);
int top = (int)(detections.get(i, 4)[0] * rows);
int right = (int)(detections.get(i, 5)[0] * cols);
int bottom = (int)(detections.get(i, 6)[0] * rows);
// Draw rectangle around detected object.
Imgproc.rectangle(frame, new Point(left, top), new Point(right, bottom),
new Scalar(0, 255, 0));
String label = classNames[classId] + ": " + confidence;
int[] baseLine = new int[1];
Size labelSize = Imgproc.getTextSize(label, Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, 1, baseLine);
// Draw background for label.
Imgproc.rectangle(frame, new Point(left, top - labelSize.height),
new Point(left + labelSize.width, top + baseLine[0]),
new Scalar(255, 255, 255), Imgproc.FILLED);
// Write class name and confidence.
Imgproc.putText(frame, label, new Point(left, top),
Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar(0, 0, 0));
}
}
//! [mobilenet_handle_frame]
return frame;
}
public void onCameraViewStopped() {}
//! [mobilenet_tutorial_resource]
private MatOfByte loadFileFromResource(int id) {
byte[] buffer;
try {
// load cascade file from application resources
InputStream is = getResources().openRawResource(id);
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 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",
"cow", "diningtable", "dog", "horse",
"motorbike", "person", "pottedplant",
"sheep", "sofa", "train", "tvmonitor"};
private MatOfByte mConfigBuffer;
private MatOfByte mModelBuffer;
private Net net;
private CameraBridgeViewBase mOpenCvCameraView;
}
//! [mobilenet_tutorial]

View File

@@ -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>

View File

@@ -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()

View File

@@ -0,0 +1,35 @@
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@
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_central") {
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
}
}

View File

@@ -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

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">OpenCV QR Detector</string>
</resources>

View File

@@ -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;
}
}

View File

@@ -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());
}
}

View File

@@ -0,0 +1,6 @@
set(sample example-tutorial-1-camerapreview)
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()

View File

@@ -0,0 +1,37 @@
apply plugin: 'com.android.application'
android {
namespace 'org.opencv.samples.tutorial1'
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
defaultConfig {
applicationId "org.opencv.samples.tutorial1"
minSdkVersion @ANDROID_MIN_SDK_VERSION@
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
versionCode 301
versionName "3.01"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
java.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
res.srcDirs = @ANDROID_SAMPLE_RES_PATH@
manifest.srcFile '@ANDROID_SAMPLE_MANIFEST_PATH@'
}
}
}
dependencies {
//implementation fileTree(dir: 'libs', include: ['*.jar'])
if (gradle.opencv_source == "sdk_path") {
println 'Using OpenCV from SDK'
implementation project(':opencv')
} else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_central") {
println 'Using OpenCV from Maven repo'
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
}
}

View File

@@ -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.tutorial1"
>
<application
android:label="@string/app_name"
android:icon="@drawable/icon"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<activity
android:exported="true"
android:name="Tutorial1Activity"
android:label="@string/app_name"
android:configChanges="keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<supports-screens android:resizeable="true"
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true" />
<!--[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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,17 @@
<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" >
<!-- [camera_view] -->
<org.opencv.android.JavaCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"
android:id="@+id/tutorial1_activity_java_surface_view"
opencv:show_fps="true"
opencv:camera_id="any" />
<!-- [camera_view] -->
</FrameLayout>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">OCV T1 Preview</string>
</resources>

View File

@@ -0,0 +1,97 @@
package org.opencv.samples.tutorial1;
import org.opencv.android.CameraActivity;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.Toast;
import java.util.Collections;
import java.util.List;
public class Tutorial1Activity extends CameraActivity implements CvCameraViewListener2 {
private static final String TAG = "OCVSample::Activity";
private CameraBridgeViewBase mOpenCvCameraView;
public Tutorial1Activity() {
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);
//! [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);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_java_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.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);
}
@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();
}
}

View File

@@ -0,0 +1,12 @@
set(sample example-tutorial-2-mixedprocessing)
if(BUILD_FAT_JAVA_LIB)
set(native_deps opencv_java)
else()
set(native_deps opencv_features2d)
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()

View File

@@ -0,0 +1,61 @@
apply plugin: 'com.android.application'
android {
namespace 'org.opencv.samples.tutorial2'
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
defaultConfig {
applicationId "org.opencv.samples.tutorial2"
minSdkVersion @ANDROID_MIN_SDK_VERSION@
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
versionCode 301
versionName "3.01"
externalNativeBuild {
cmake {
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"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
java.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
res.srcDirs = @ANDROID_SAMPLE_RES_PATH@
manifest.srcFile '@ANDROID_SAMPLE_MANIFEST_PATH@'
}
}
externalNativeBuild {
cmake {
path '@ANDROID_SAMPLE_JNI_PATH@/CMakeLists.txt'
}
}
buildFeatures {
if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_central") {
prefab true
}
}
}
dependencies {
//implementation fileTree(dir: 'libs', include: ['*.jar'])
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_central") {
println 'Using OpenCV from Maven repo'
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
}
}

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.opencv.samples.tutorial2"
>
<application
android:label="@string/app_name"
android:icon="@drawable/icon">
<activity
android:exported="true"
android:name="Tutorial2Activity"
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-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>

View File

@@ -0,0 +1,22 @@
cmake_minimum_required(VERSION 3.6)
set(target mixed_sample)
project(${target} CXX)
if (OPENCV_FROM_SDK)
message(STATUS "Using OpenCV from local SDK")
set(ANDROID_OPENCV_COMPONENTS "opencv_java" CACHE STRING "")
else()
message(STATUS "Using OpenCV from AAR (Maven repo)")
set(ANDROID_OPENCV_COMPONENTS "OpenCV::opencv_java${OPENCV_VERSION_MAJOR}" CACHE STRING "")
endif()
message(STATUS "ANDROID_ABI=${ANDROID_ABI}")
find_package(OpenCV REQUIRED COMPONENTS ${ANDROID_OPENCV_COMPONENTS})
file(GLOB srcs *.cpp *.c)
file(GLOB hdrs *.hpp *.h)
include_directories("${CMAKE_CURRENT_LIST_DIR}")
add_library(${target} SHARED ${srcs} ${hdrs})
target_link_libraries(${target} ${ANDROID_OPENCV_COMPONENTS})

View File

@@ -0,0 +1,27 @@
#include <jni.h>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <vector>
using namespace std;
using namespace cv;
extern "C" {
JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial2_Tutorial2Activity_FindFeatures(JNIEnv*, jobject, jlong addrGray, jlong addrRgba);
JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial2_Tutorial2Activity_FindFeatures(JNIEnv*, jobject, jlong addrGray, jlong addrRgba)
{
Mat& mGr = *(Mat*)addrGray;
Mat& mRgb = *(Mat*)addrRgba;
vector<KeyPoint> v;
Ptr<FeatureDetector> detector = FastFeatureDetector::create(50);
detector->detect(mGr, v);
for( unsigned int i = 0; i < v.size(); i++ )
{
const KeyPoint& kp = v[i];
circle(mRgb, Point(kp.pt.x, kp.pt.y), 10, Scalar(255,0,0,255));
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,11 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<org.opencv.android.JavaCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/tutorial2_activity_surface_view" />
</LinearLayout>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">OCV T2 Mixed Processing</string>
</resources>

View File

@@ -0,0 +1,166 @@
package org.opencv.samples.tutorial2;
import org.opencv.android.CameraActivity;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.imgproc.Imgproc;
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 Tutorial2Activity extends CameraActivity implements CvCameraViewListener2 {
private static final String TAG = "OCVSample::Activity";
private static final int VIEW_MODE_RGBA = 0;
private static final int VIEW_MODE_GRAY = 1;
private static final int VIEW_MODE_CANNY = 2;
private static final int VIEW_MODE_FEATURES = 5;
private int mViewMode;
private Mat mRgba;
private Mat mIntermediateMat;
private Mat mGray;
private MenuItem mItemPreviewRGBA;
private MenuItem mItemPreviewGray;
private MenuItem mItemPreviewCanny;
private MenuItem mItemPreviewFeatures;
private CameraBridgeViewBase mOpenCvCameraView;
public Tutorial2Activity() {
Log.i(TAG, "Instantiated new " + this.getClass());
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
if (OpenCVLoader.initLocal()) {
Log.i(TAG, "OpenCV loaded successfully");
} else {
Log.e(TAG, "OpenCV initialization failed!");
(Toast.makeText(this, "OpenCV initialization failed!", Toast.LENGTH_LONG)).show();
return;
}
// Load native library after(!) OpenCV initialization
System.loadLibrary("mixed_sample");
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.tutorial2_surface_view);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial2_activity_surface_view);
mOpenCvCameraView.setVisibility(CameraBridgeViewBase.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.i(TAG, "called onCreateOptionsMenu");
mItemPreviewRGBA = menu.add("Preview RGBA");
mItemPreviewGray = menu.add("Preview GRAY");
mItemPreviewCanny = menu.add("Canny");
mItemPreviewFeatures = menu.add("Find features");
return 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();
}
public void onCameraViewStarted(int width, int height) {
mRgba = new Mat(height, width, CvType.CV_8UC4);
mIntermediateMat = new Mat(height, width, CvType.CV_8UC4);
mGray = new Mat(height, width, CvType.CV_8UC1);
}
public void onCameraViewStopped() {
mRgba.release();
mGray.release();
mIntermediateMat.release();
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
final int viewMode = mViewMode;
switch (viewMode) {
case VIEW_MODE_GRAY:
// input frame has gray scale format
Imgproc.cvtColor(inputFrame.gray(), mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
break;
case VIEW_MODE_RGBA:
// input frame has RBGA format
mRgba = inputFrame.rgba();
break;
case VIEW_MODE_CANNY:
// input frame has gray scale format
mRgba = inputFrame.rgba();
Imgproc.Canny(inputFrame.gray(), mIntermediateMat, 80, 100);
Imgproc.cvtColor(mIntermediateMat, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
break;
case VIEW_MODE_FEATURES:
// input frame has RGBA format
mRgba = inputFrame.rgba();
mGray = inputFrame.gray();
FindFeatures(mGray.getNativeObjAddr(), mRgba.getNativeObjAddr());
break;
}
return mRgba;
}
public boolean onOptionsItemSelected(MenuItem item) {
Log.i(TAG, "called onOptionsItemSelected; selected item: " + item);
if (item == mItemPreviewRGBA) {
mViewMode = VIEW_MODE_RGBA;
} else if (item == mItemPreviewGray) {
mViewMode = VIEW_MODE_GRAY;
} else if (item == mItemPreviewCanny) {
mViewMode = VIEW_MODE_CANNY;
} else if (item == mItemPreviewFeatures) {
mViewMode = VIEW_MODE_FEATURES;
}
return true;
}
public native void FindFeatures(long matAddrGr, long matAddrRgba);
}

View File

@@ -0,0 +1,6 @@
set(sample example-tutorial-3-cameracontrol)
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()

View File

@@ -0,0 +1,37 @@
apply plugin: 'com.android.application'
android {
namespace 'org.opencv.samples.tutorial3'
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
defaultConfig {
applicationId "org.opencv.samples.tutorial3"
minSdkVersion @ANDROID_MIN_SDK_VERSION@
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
versionCode 301
versionName "3.01"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
java.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
res.srcDirs = @ANDROID_SAMPLE_RES_PATH@
manifest.srcFile '@ANDROID_SAMPLE_MANIFEST_PATH@'
}
}
}
dependencies {
//implementation fileTree(dir: 'libs', include: ['*.jar'])
if (gradle.opencv_source == "sdk_path") {
println 'Using OpenCV from SDK'
implementation project(':opencv')
} else if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_central") {
println 'Using OpenCV from Maven repo'
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
}
}

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.opencv.samples.tutorial3"
>
<application
android:label="@string/app_name"
android:icon="@drawable/icon">
<activity
android:exported="true"
android:name="Tutorial3Activity"
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-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"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,12 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<org.opencv.samples.tutorial3.Tutorial3View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:id="@+id/tutorial3_activity_java_surface_view" />
</LinearLayout>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">OCV T3 Camera Control</string>
</resources>

View File

@@ -0,0 +1,198 @@
package org.opencv.samples.tutorial3;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.ListIterator;
import org.opencv.android.CameraActivity;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
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;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.Toast;
public class Tutorial3Activity extends CameraActivity implements CvCameraViewListener2, OnTouchListener {
private static final String TAG = "OCVSample::Activity";
private Tutorial3View mOpenCvCameraView;
private List<Size> mResolutionList;
private Menu mMenu;
private boolean mCameraStarted = false;
private boolean mMenuItemsCreated = false;
private MenuItem[] mEffectMenuItems;
private SubMenu mColorEffectsMenu;
private MenuItem[] mResolutionMenuItems;
private SubMenu mResolutionMenu;
public Tutorial3Activity() {
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;
}
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.tutorial3_surface_view);
mOpenCvCameraView = (Tutorial3View) findViewById(R.id.tutorial3_activity_java_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.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();
mOpenCvCameraView.setOnTouchListener(Tutorial3Activity.this);
}
}
@Override
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
return Collections.singletonList(mOpenCvCameraView);
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
@Override
public void onCameraViewStarted(int width, int height) {
mCameraStarted = true;
setupMenuItems();
}
public void onCameraViewStopped() {
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
return inputFrame.rgba();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
mMenu = menu;
setupMenuItems();
return true;
}
private void setupMenuItems() {
if (mMenu == null || !mCameraStarted || mMenuItemsCreated) {
return;
}
List<String> effects = mOpenCvCameraView.getEffectList();
if (effects == null) {
Log.e(TAG, "Color effects are not supported by device!");
return;
}
mColorEffectsMenu = mMenu.addSubMenu("Color Effect");
mEffectMenuItems = new MenuItem[effects.size()];
int idx = 0;
ListIterator<String> effectItr = effects.listIterator();
for (String effect: effects) {
mEffectMenuItems[idx] = mColorEffectsMenu.add(1, idx, Menu.NONE, effect);
idx++;
}
mResolutionMenu = mMenu.addSubMenu("Resolution");
mResolutionList = mOpenCvCameraView.getResolutionList();
mResolutionMenuItems = new MenuItem[mResolutionList.size()];
idx = 0;
for (Size resolution: mResolutionList) {
mResolutionMenuItems[idx] = mResolutionMenu.add(2, idx, Menu.NONE,
Integer.valueOf(resolution.width).toString() + "x" + Integer.valueOf(resolution.height).toString());
idx++;
}
mMenuItemsCreated = true;
}
public boolean onOptionsItemSelected(MenuItem item) {
Log.i(TAG, "called onOptionsItemSelected; selected item: " + item);
if (item.getGroupId() == 1)
{
mOpenCvCameraView.setEffect((String) item.getTitle());
Toast.makeText(this, mOpenCvCameraView.getEffect(), Toast.LENGTH_SHORT).show();
}
else if (item.getGroupId() == 2)
{
int id = item.getItemId();
Size resolution = mResolutionList.get(id);
mOpenCvCameraView.setResolution(resolution);
resolution = mOpenCvCameraView.getResolution();
String caption = Integer.valueOf(resolution.width).toString() + "x" + Integer.valueOf(resolution.height).toString();
Toast.makeText(this, caption, Toast.LENGTH_SHORT).show();
}
return true;
}
@SuppressLint("SimpleDateFormat")
@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 = "sample_picture_" + currentDateandTime + ".jpg";
mOpenCvCameraView.takePicture(fileName);
Toast.makeText(this, fileName + " saved", Toast.LENGTH_SHORT).show();
return false;
}
}

View File

@@ -0,0 +1,118 @@
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;
public class Tutorial3View extends JavaCameraView implements PictureCallback {
private static final String TAG = "Sample::Tutorial3View";
private String mPictureFileName;
public Tutorial3View(Context context, AttributeSet attrs) {
super(context, attrs);
}
public List<String> getEffectList() {
return mCamera.getParameters().getSupportedColorEffects();
}
public boolean isEffectSupported() {
return (mCamera.getParameters().getColorEffect() != null);
}
public String getEffect() {
return mCamera.getParameters().getColorEffect();
}
public void setEffect(String effect) {
Camera.Parameters params = mCamera.getParameters();
params.setColorEffect(effect);
mCamera.setParameters(params);
}
public List<Size> getResolutionList() {
return mCamera.getParameters().getSupportedPreviewSizes();
}
public void setResolution(Size resolution) {
disconnectCamera();
mMaxHeight = resolution.height;
mMaxWidth = resolution.width;
connectCamera(getWidth(), getHeight());
}
public Size getResolution() {
return mCamera.getParameters().getPreviewSize();
}
public void takePicture(final String fileName) {
Log.i(TAG, "Taking picture");
this.mPictureFileName = fileName;
// Postview and jpeg are sent in the same buffers if the queue is not empty when performing a capture.
// Clear up buffers to avoid mCamera.takePicture to be stuck because of a memory issue
mCamera.setPreviewCallback(null);
// PictureCallback is implemented by the current class
mCamera.takePicture(null, null, this);
}
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.i(TAG, "Saving a bitmap to file");
// The camera preview was automatically stopped. Start it again.
mCamera.startPreview();
mCamera.setPreviewCallback(this);
// Write the image in a file (in jpeg format)
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);
}
}
}
}

View File

@@ -0,0 +1,17 @@
set(sample example-tutorial-4-opencl)
if(BUILD_FAT_JAVA_LIB)
set(native_deps opencv_java)
else()
set(native_deps opencv_imgproc)
endif()
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
COPY_LIBS YES
)
if(TARGET ${sample})
add_dependencies(opencv_android_examples ${sample})
endif()

View File

@@ -0,0 +1,63 @@
apply plugin: 'com.android.application'
android {
namespace 'org.opencv.samples.tutorial4'
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
defaultConfig {
applicationId "org.opencv.samples.tutorial4"
minSdkVersion @ANDROID_MIN_SDK_VERSION@
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
versionCode 301
versionName "3.01"
externalNativeBuild {
cmake {
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"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
java.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
res.srcDirs = @ANDROID_SAMPLE_RES_PATH@
manifest.srcFile '@ANDROID_SAMPLE_MANIFEST_PATH@'
}
}
externalNativeBuild {
cmake {
path '@ANDROID_SAMPLE_JNI_PATH@/CMakeLists.txt'
}
}
buildFeatures {
if (gradle.opencv_source == "maven_local" || gradle.opencv_source == "maven_central") {
prefab true
}
}
}
dependencies {
//implementation fileTree(dir: 'libs', include: ['*.jar'])
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_central") {
println 'Using OpenCV from Maven repo'
implementation 'org.opencv:opencv:@OPENCV_VERSION_PLAIN@'
}
}

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.opencv.samples.tutorial4"
android:versionCode="1"
android:versionName="1.0" >
<uses-feature android:glEsVersion="0x00020000" android:required="true"/>
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera2" android:required="false"/>
<uses-permission android:name="android.permission.CAMERA"/>
<application
android:allowBackup="true"
android:icon="@drawable/icon">
<activity
android:exported="true"
android:name=".Tutorial4Activity"
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>
</manifest>

View File

@@ -0,0 +1,309 @@
#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/opencl.hpp>
#endif
#include <GLES2/gl2.h>
#include <EGL/egl.h>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#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[] = \
"__constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST; \n" \
"\n" \
"__kernel void Laplacian( \n" \
" __read_only image2d_t imgIn, \n" \
" __write_only image2d_t imgOut \n" \
" ) { \n" \
" \n" \
" const int2 pos = {get_global_id(0), get_global_id(1)}; \n" \
" \n" \
" float4 sum = (float4) 0.0f; \n" \
" sum += read_imagef(imgIn, sampler, pos + (int2)(-1,0)); \n" \
" sum += read_imagef(imgIn, sampler, pos + (int2)(+1,0)); \n" \
" sum += read_imagef(imgIn, sampler, pos + (int2)(0,-1)); \n" \
" sum += read_imagef(imgIn, sampler, pos + (int2)(0,+1)); \n" \
" sum -= read_imagef(imgIn, sampler, pos) * 4; \n" \
" \n" \
" write_imagef(imgOut, pos, sum*10); \n" \
"} \n";
static void dumpCLinfo()
{
LOGD("*** OpenCL info ***");
try
{
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
LOGD("OpenCL info: Found %d OpenCL platforms", platforms.size());
for (int i = 0; i < platforms.size(); ++i)
{
std::string name = platforms[i].getInfo<CL_PLATFORM_NAME>();
std::string version = platforms[i].getInfo<CL_PLATFORM_VERSION>();
std::string profile = platforms[i].getInfo<CL_PLATFORM_PROFILE>();
std::string extensions = platforms[i].getInfo<CL_PLATFORM_EXTENSIONS>();
LOGD( "OpenCL info: Platform[%d] = %s, ver = %s, prof = %s, ext = %s",
i, name.c_str(), version.c_str(), profile.c_str(), extensions.c_str() );
}
std::vector<cl::Device> devices;
platforms[0].getDevices(CL_DEVICE_TYPE_ALL, &devices);
for (int i = 0; i < devices.size(); ++i)
{
std::string name = devices[i].getInfo<CL_DEVICE_NAME>();
std::string extensions = devices[i].getInfo<CL_DEVICE_EXTENSIONS>();
cl_ulong type = devices[i].getInfo<CL_DEVICE_TYPE>();
LOGD( "OpenCL info: Device[%d] = %s (%s), ext = %s",
i, name.c_str(), (type==CL_DEVICE_TYPE_GPU ? "GPU" : "CPU"), extensions.c_str() );
}
}
catch(const cl::Error& e)
{
LOGE( "OpenCL info: error while gathering OpenCL info: %s (%d)", e.what(), e.err() );
}
catch(const std::exception& e)
{
LOGE( "OpenCL info: error while gathering OpenCL info: %s", e.what() );
}
catch(...)
{
LOGE( "OpenCL info: unknown error while gathering OpenCL info" );
}
LOGD("*******************");
}
cl::Context theContext;
cl::CommandQueue theQueue;
cl::Program theProgB2B, theProgI2B, theProgI2I;
bool haveOpenCL = false;
//![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());
EGLContext mEglContext = eglGetCurrentContext();
if (mEglContext == EGL_NO_CONTEXT)
LOGE("initCL: eglGetCurrentContext() returned 'EGL_NO_CONTEXT', error = %x", eglGetError());
cl_context_properties props[] =
{ CL_GL_CONTEXT_KHR, (cl_context_properties) mEglContext,
CL_EGL_DISPLAY_KHR, (cl_context_properties) mEglDisplay,
CL_CONTEXT_PLATFORM, 0,
0 };
try
{
haveOpenCL = false;
cl::Platform p = cl::Platform::getDefault();
std::string ext = p.getInfo<CL_PLATFORM_EXTENSIONS>();
if(ext.find("cl_khr_gl_sharing") == std::string::npos)
LOGE("Warning: CL-GL sharing isn't supported by PLATFORM");
props[5] = (cl_context_properties) p();
theContext = cl::Context(CL_DEVICE_TYPE_GPU, props);
std::vector<cl::Device> devs = theContext.getInfo<CL_CONTEXT_DEVICES>();
LOGD("Context returned %d devices, taking the 1st one", devs.size());
ext = devs[0].getInfo<CL_DEVICE_EXTENSIONS>();
if(ext.find("cl_khr_gl_sharing") == std::string::npos)
LOGE("Warning: CL-GL sharing isn't supported by DEVICE");
theQueue = cl::CommandQueue(theContext, devs[0]);
cl::Program::Sources src(1, std::make_pair(oclProgI2I, sizeof(oclProgI2I)));
theProgI2I = cl::Program(theContext, src);
theProgI2I.build(devs);
cv::ocl::attachContext(p.getInfo<CL_PLATFORM_NAME>(), p(), theContext(), devs[0]());
if( cv::ocl::useOpenCL() )
LOGD("OpenCV+OpenCL works OK!");
else
LOGE("Can't init OpenCV with OpenCL TAPI");
haveOpenCL = true;
}
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");
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)
{
LOGD("Processing OpenCL Direct (image2d)");
if(!haveOpenCL)
{
LOGE("OpenCL isn't initialized");
return;
}
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;
images.push_back(imgIn);
images.push_back(imgOut);
int64_t t = getTimeMs();
theQueue.enqueueAcquireGLObjects(&images);
theQueue.finish();
LOGD("enqueueAcquireGLObjects() costs %d ms", getTimeInterval(t));
t = getTimeMs();
cl::Kernel Laplacian(theProgI2I, "Laplacian"); //TODO: may be done once
Laplacian.setArg(0, imgIn);
Laplacian.setArg(1, imgOut);
theQueue.finish();
LOGD("Kernel() costs %d ms", getTimeInterval(t));
t = getTimeMs();
theQueue.enqueueNDRangeKernel(Laplacian, cl::NullRange, cl::NDRange(w, h), cl::NullRange);
theQueue.finish();
LOGD("enqueueNDRangeKernel() costs %d ms", getTimeInterval(t));
t = getTimeMs();
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)
{
LOGD("Processing OpenCL via OpenCV");
if(!haveOpenCL)
{
LOGE("OpenCL isn't initialized");
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);
theQueue.enqueueAcquireGLObjects(&images);
theQueue.finish();
cv::UMat uIn, uOut, uTmp;
cv::ocl::convertFromImage(imgIn(), uIn);
LOGD("loading texture data to OpenCV UMat costs %d ms", getTimeInterval(t));
theQueue.enqueueReleaseGLObjects(&images);
t = getTimeMs();
//cv::blur(uIn, uOut, cv::Size(5, 5));
cv::Laplacian(uIn, uTmp, CV_8U);
cv:multiply(uTmp, 10, uOut);
cv::ocl::finish();
LOGD("OpenCV processing costs %d ms", getTimeInterval(t));
t = getTimeMs();
cl::ImageGL imgOut(theContext, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, texOut);
images.clear();
images.push_back(imgOut);
theQueue.enqueueAcquireGLObjects(&images);
cl_mem clBuffer = (cl_mem)uOut.handle(cv::ACCESS_READ);
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] = { (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)
{
LOGD("Processing on CPU");
int64_t t;
// let's modify pixels in FBO texture in C++ code (on CPU)
static cv::Mat m;
m.create(h, w, CV_8UC4);
// read
t = getTimeMs();
// expecting FBO to be bound
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m.data);
LOGD("glReadPixels() costs %d ms", getTimeInterval(t));
// modify
t = getTimeMs();
cv::Laplacian(m, m, CV_8U);
m *= 10;
LOGD("Laplacian() costs %d ms", getTimeInterval(t));
// write back
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texOut);
t = getTimeMs();
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m.data);
LOGD("glTexSubImage2D() costs %d ms", getTimeInterval(t));
}
enum ProcMode {PROC_MODE_NO_PROC=0, PROC_MODE_CPU=1, PROC_MODE_OCL_DIRECT=2, PROC_MODE_OCL_OCV=3};
void processFrame(int tex1, int tex2, int w, int h, int mode)
{
switch(mode)
{
//case PROC_MODE_NO_PROC:
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);
}
}

View File

@@ -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

View File

@@ -0,0 +1,42 @@
cmake_minimum_required(VERSION 3.6)
set(target JNIpart)
project(${target} CXX)
if (OPENCV_FROM_SDK)
message(STATUS "Using OpenCV from local SDK")
set(ANDROID_OPENCV_COMPONENTS "opencv_java" CACHE STRING "")
else()
message(STATUS "Using OpenCV from AAR (Maven repo)")
set(ANDROID_OPENCV_COMPONENTS "OpenCV::opencv_java${OPENCV_VERSION_MAJOR}" CACHE STRING "")
endif()
message(STATUS "ANDROID_ABI=${ANDROID_ABI}")
find_package(OpenCV REQUIRED COMPONENTS ${ANDROID_OPENCV_COMPONENTS})
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 -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()

View File

@@ -0,0 +1,19 @@
#include <android/log.h>
#define LOG_TAG "JNIpart"
//#define LOGD(...)
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
#include <time.h> // clock_gettime
static inline int64_t getTimeMs()
{
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
return (int64_t) now.tv_sec*1000 + now.tv_nsec/1000000;
}
static inline int getTimeInterval(int64_t startTime)
{
return int(getTimeMs() - startTime);
}

View File

@@ -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"

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<lint>
</lint>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,26 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<org.opencv.samples.tutorial4.MyGLSurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/my_gl_surface_view" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation = "vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/fps_text_view"
android:text="FPS:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/proc_mode_text_view"
android:text="Processing mode:" />
</LinearLayout>
</FrameLayout>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">OpenCV Tutorial 4 - Use OpenCL</string>
</resources>

View File

@@ -0,0 +1,115 @@
package org.opencv.samples.tutorial4;
import org.opencv.android.CameraGLSurfaceView;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
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";
protected int procMode = NativePart.PROCESSING_MODE_NO_PROCESSING;
static final String[] procModeName = new String[] {"No Processing", "CPU", "OpenCL Direct", "OpenCL via OpenCV"};
protected int frameCounter;
protected long lastNanoTime;
TextView mFpsText = null;
public MyGLSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent e) {
if(e.getAction() == MotionEvent.ACTION_DOWN)
((Activity)getContext()).openOptionsMenu();
return true;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
super.surfaceCreated(holder);
//NativePart.initCL();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
//NativePart.closeCL();
super.surfaceDestroyed(holder);
}
public void setProcessingMode(int newMode) {
if(newMode>=0 && newMode<procModeName.length)
procMode = newMode;
else
Log.e(LOGTAG, "Ignoring invalid processing mode: " + newMode);
((Activity) getContext()).runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getContext(), "Selected mode: " + procModeName[procMode], Toast.LENGTH_LONG).show();
}
});
}
@Override
public void onCameraViewStarted(int width, int height) {
((Activity) getContext()).runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getContext(), "onCameraViewStarted", Toast.LENGTH_SHORT).show();
}
});
if (NativePart.builtWithOpenCL())
NativePart.initCL();
frameCounter = 0;
lastNanoTime = System.nanoTime();
}
@Override
public void onCameraViewStopped() {
((Activity) getContext()).runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getContext(), "onCameraViewStopped", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public boolean onCameraTexture(int texIn, int texOut, int width, int height) {
// FPS
frameCounter++;
if(frameCounter >= 30)
{
final int fps = (int) (frameCounter * 1e9 / (System.nanoTime() - lastNanoTime));
Log.i(LOGTAG, "drawFrame() FPS: "+fps);
if(mFpsText != null) {
Runnable fpsUpdater = new Runnable() {
public void run() {
mFpsText.setText("FPS: " + fps);
}
};
new Handler(Looper.getMainLooper()).post(fpsUpdater);
} else {
Log.d(LOGTAG, "mFpsText == null");
mFpsText = (TextView)((Activity) getContext()).findViewById(R.id.fps_text_view);
}
frameCounter = 0;
lastNanoTime = System.nanoTime();
}
if(procMode == NativePart.PROCESSING_MODE_NO_PROCESSING)
return false;
NativePart.processFrame(texIn, texOut, width, height, procMode);
return true;
}
}
//![minimal_surface_view]

Some files were not shown because too many files have changed in this diff Show More