diff --git a/README.md b/README.md index 76d02dbde7..88c4af1b03 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ ## BGSLibrary A Background Subtraction Library -[![Release](https://img.shields.io/badge/Release-v2.0.0-blue.svg)](https://github.com/andrewssobral/bgslibrary/wiki/Build-status) [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](http://www.gnu.org/licenses/gpl-3.0) [![Platform: Windows, Linux, OS X](https://img.shields.io/badge/Platform-Windows%2C%20Linux%2C%20OS%20X-blue.svg)](https://github.com/andrewssobral/bgslibrary/wiki/Build-status) [![OpenCV](https://img.shields.io/badge/OpenCV-2.x%2C%203.x-blue.svg)](https://github.com/andrewssobral/bgslibrary/wiki/Build-status) [![Wrapper: Python, MATLAB](https://img.shields.io/badge/Wrapper-Python%2C%20MATLAB-orange.svg)](https://github.com/andrewssobral/bgslibrary/wiki/Build-status) [![Algorithms](https://img.shields.io/badge/Algorithms-40-red.svg)](https://github.com/andrewssobral/bgslibrary/wiki/List-of-available-algorithms) +[![Release](https://img.shields.io/badge/Release-v2.0.0-blue.svg)](https://github.com/andrewssobral/bgslibrary/wiki/Build-status) [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](http://www.gnu.org/licenses/gpl-3.0) [![Platform: Windows, Linux, OS X](https://img.shields.io/badge/Platform-Windows%2C%20Linux%2C%20OS%20X-blue.svg)](https://github.com/andrewssobral/bgslibrary/wiki/Build-status) [![OpenCV](https://img.shields.io/badge/OpenCV-2.x%2C%203.x-blue.svg)](https://github.com/andrewssobral/bgslibrary/wiki/Build-status) [![Wrapper: Python, MATLAB](https://img.shields.io/badge/Wrapper-Java%2C%20Python%2C%20MATLAB-orange.svg)](https://github.com/andrewssobral/bgslibrary/wiki/Build-status) [![Algorithms](https://img.shields.io/badge/Algorithms-43-red.svg)](https://github.com/andrewssobral/bgslibrary/wiki/List-of-available-algorithms) [![bgslibrary](http://i.giphy.com/5A94AZahSIVOw.gif)](https://youtu.be/_UbERwuQ0OU) -Page Update: **18/03/2017** +Page Update: **01/04/2017** Library Version: **2.0.0** (see **[Build Status](https://github.com/andrewssobral/bgslibrary/wiki/Build-status)** and **[Release Notes](https://github.com/andrewssobral/bgslibrary/wiki/Release-notes)** for more info) -The **BGSLibrary** was developed by [Andrews Sobral](http://andrewssobral.wixsite.com/home) and provides an easy-to-use C++ framework based on [OpenCV](http://www.opencv.org/) to perform foreground-background separation in videos. The bgslibrary is compatible with OpenCV 2.x and 3.x, and compiles under Windows, Linux, and Mac OS X. Currently the library contains **40** algorithms. The source code is available under [GNU GPLv3 license](https://www.gnu.org/licenses/gpl-3.0.en.html), the library is free and open source for academic purposes. +The **BGSLibrary** was developed by [Andrews Sobral](http://andrewssobral.wixsite.com/home) and provides an easy-to-use C++ framework based on [OpenCV](http://www.opencv.org/) to perform foreground-background separation in videos. The bgslibrary is compatible with OpenCV 2.x and 3.x, and compiles under Windows, Linux, and Mac OS X. Currently the library contains **43** algorithms. The source code is available under [GNU GPLv3 license](https://www.gnu.org/licenses/gpl-3.0.en.html), the library is free and open source for academic purposes. * [List of available algorithms](https://github.com/andrewssobral/bgslibrary/wiki/List-of-available-algorithms) * [Algorithms benchmark](https://github.com/andrewssobral/bgslibrary/wiki/Algorithms-benchmark) @@ -32,6 +32,7 @@ The **BGSLibrary** was developed by [Andrews Sobral](http://andrewssobral.wixsit * * [Python](https://github.com/andrewssobral/bgslibrary/wiki/Wrapper:-Python) ***(NEW)*** * * [MATLAB](https://github.com/andrewssobral/bgslibrary/wiki/Wrapper:-MATLAB) ***(NEW)*** +* * [Java](https://github.com/andrewssobral/bgslibrary/wiki/Wrapper:-Java) ***(NEW)*** * [Docker images](https://github.com/andrewssobral/bgslibrary/wiki/Docker-images) * [How to integrate BGSLibrary in your own CPP code](https://github.com/andrewssobral/bgslibrary/wiki/How-to-integrate-BGSLibrary-in-your-own-CPP-code) diff --git a/wrapper_java/.gitignore b/wrapper_java/.gitignore new file mode 100644 index 0000000000..ca2b249f97 --- /dev/null +++ b/wrapper_java/.gitignore @@ -0,0 +1,9 @@ +nbproject/ +build.xml +build/ +dist/ +build_*/ +*.dll +*.bat +*.sh +*.lib diff --git a/wrapper_java/CMakeLists.txt b/wrapper_java/CMakeLists.txt new file mode 100644 index 0000000000..88b9845275 --- /dev/null +++ b/wrapper_java/CMakeLists.txt @@ -0,0 +1,85 @@ +cmake_minimum_required(VERSION 2.8) +project(libbgs_java_module) + +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +if(UNIX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -std=gnu++0x") + set(CMAKE_MACOSX_RPATH 1) +endif(UNIX) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") +#set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules) + +# compilation mode setup +set(CMAKE_BUILD_TYPE Release) +#set(CMAKE_BUILD_TYPE Debug) + +if(WIN32) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") +endif(WIN32) + +set(bgs_out_dir ".") +# First for the generic no-config case (e.g. with mingw) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${bgs_out_dir}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${bgs_out_dir}) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${bgs_out_dir}) +# Second, for multi-config builds (e.g. msvc) +foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${bgs_out_dir}) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${bgs_out_dir}) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${bgs_out_dir}) +endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES) + +if(UNIX) + # add some standard warnings + ADD_DEFINITIONS(-Wno-variadic-macros -Wno-long-long -Wall -Wextra -Winit-self -Woverloaded-virtual -Wsign-promo -Wno-unused-parameter -pedantic -Woverloaded-virtual -Wno-unknown-pragmas) + + # -ansi does not compile with sjn module + #ADD_DEFINITIONS(-ansi) + + # if you like to have warinings about conversions, e.g. double->int or double->float etc., or float compare + #ADD_DEFINITIONS(-Wconversion -Wfloat-equal) +endif(UNIX) + +find_package(JNI REQUIRED) +if (JNI_FOUND) + message (STATUS "JNI_INCLUDE_DIRS=${JNI_INCLUDE_DIRS}") + message (STATUS "JNI_LIBRARIES=${JNI_LIBRARIES}") +endif() + +set(OpenCV_STATIC OFF) +find_package(OpenCV REQUIRED) +if (OpenCV_FOUND) + message(STATUS "OpenCV library status:") + message(STATUS " version: ${OpenCV_VERSION}") + message(STATUS " libraries: ${OpenCV_LIBS}") + message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}") +endif() + +file(GLOB_RECURSE analysis_src ../package_analysis/*.cpp) +file(GLOB_RECURSE analysis_inc ../package_analysis/*.h) +file(GLOB_RECURSE bgs_src ../package_bgs/*.cpp package_bgs/*.c) +file(GLOB_RECURSE bgs_inc ../package_bgs/*.h) + +include_directories(${CMAKE_SOURCE_DIR} ${JNI_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS}) + +add_library(libbgs STATIC ${bgs_src} ${analysis_src}) +target_link_libraries(libbgs ${OpenCV_LIBS}) +set_property(TARGET libbgs PROPERTY PUBLIC_HEADER ${bgs_inc} ${analysis_inc}) +if(WIN32) + # set_property(TARGET libbgs PROPERTY SUFFIX ".lib") +else() + set_property(TARGET libbgs PROPERTY OUTPUT_NAME "bgs") +endif() + +set(SOURCE_FILES bgslibrary_java_module.cpp) +add_library(libbgs_java_module SHARED ${SOURCE_FILES}) +set_target_properties(libbgs_java_module PROPERTIES POSITION_INDEPENDENT_CODE ON) +target_link_libraries(libbgs_java_module libbgs ${OpenCV_LIBS}) +if(WIN32) + # set_property(TARGET libbgs_java_module PROPERTY SUFFIX ".lib") +else() + set_property(TARGET libbgs_java_module PROPERTY OUTPUT_NAME "bgs_java_module") +endif() diff --git a/wrapper_java/README.md b/wrapper_java/README.md new file mode 100644 index 0000000000..bd1a595210 --- /dev/null +++ b/wrapper_java/README.md @@ -0,0 +1,55 @@ +### For Windows users + +* Running CMAKE with Visual Studio 2015 and OpenCV 3.2.0 (x64) + +* * Working directory: **bgslibrary\wrapper_java** + +``` +:: Set OpenCV env +echo "Setting up OpenCV env" +set OpenCV_DIR=C:\OpenCV3.2.0\build +set PATH=%PATH%;%OpenCV_DIR%\x64\vc14\bin + +:: Run CMake +echo "Running CMake" +rmdir /S /Q build_cmake +if not exist "build_cmake" mkdir build_cmake +cd build_cmake +cmake -DOpenCV_DIR=%OpenCV_DIR% -G "Visual Studio 14 Win64" .. +cd .. +``` + +* Open **libbgs_java_module.sln** in your Visual Studio IDE and switch to **RELEASE** mode + +* Click on **ALL_BUILD** and build + +* Copy **libbgs_java_module.dll** to **bgslibrary\wrapper_java** + +* Compile Java source + +``` +:: Compile +echo "Compiling" +javac -cp .;src/;libs/opencv-320.jar src/bgslibrary/Main.java +``` + +* Run + +``` +:: Run +echo "Running Main class" +java -cp .;src/;libs/opencv-320.jar -Djava.library.path=. bgslibrary.Main +``` + +[![bgslibrary](https://sites.google.com/site/andrewssobral/bgslib_java_wrapper_screen.png)]() + + +#### Generating JNI files (optional) + +``` +:: Generate JNI +cd src +echo "Generating JNI" +javah -cp .;../libs/opencv-320.jar bgslibrary.Main +cd .. +``` diff --git a/wrapper_java/bgslibrary_java_module.cpp b/wrapper_java/bgslibrary_java_module.cpp new file mode 100644 index 0000000000..275847022c --- /dev/null +++ b/wrapper_java/bgslibrary_java_module.cpp @@ -0,0 +1,298 @@ +/* +This file is part of BGSLibrary. + +BGSLibrary is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +BGSLibrary is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with BGSLibrary. If not, see . +*/ +#include +#include + +#include "bgslibrary_java_module.hpp" + +static IBGS *ptrBGS = nullptr; +static std::string algorithm = ""; + +namespace bgslibrary +{ + IBGS* init_alg(std::string alg_name) + { + if (alg_name.compare("FrameDifference") == 0) + return (IBGS *)malloc(sizeof(FrameDifference)); + if (alg_name.compare("StaticFrameDifference") == 0) + return (IBGS *)malloc(sizeof(StaticFrameDifference)); + if (alg_name.compare("WeightedMovingMean") == 0) + return (IBGS *)malloc(sizeof(WeightedMovingMean)); + if (alg_name.compare("WeightedMovingVariance") == 0) + return (IBGS *)malloc(sizeof(WeightedMovingVariance)); +#if CV_MAJOR_VERSION == 2 + if (alg_name.compare("MixtureOfGaussianV1") == 0) + return (IBGS *)malloc(sizeof(MixtureOfGaussianV1)); // only for OpenCV 2.x +#endif + if (alg_name.compare("MixtureOfGaussianV2") == 0) + return (IBGS *)malloc(sizeof(MixtureOfGaussianV2)); + if (alg_name.compare("AdaptiveBackgroundLearning") == 0) + return (IBGS *)malloc(sizeof(AdaptiveBackgroundLearning)); + if (alg_name.compare("AdaptiveSelectiveBackgroundLearning") == 0) + return (IBGS *)malloc(sizeof(AdaptiveSelectiveBackgroundLearning)); +#if CV_MAJOR_VERSION == 2 && CV_MINOR_VERSION >= 4 && CV_SUBMINOR_VERSION >= 3 + if (alg_name.compare("GMG") == 0) + return (IBGS *)malloc(sizeof(GMG)); // only for OpenCV >= 2.4.3 +#endif +#if CV_MAJOR_VERSION == 3 + if (alg_name.compare("KNN") == 0) + return (IBGS *)malloc(sizeof(KNN)); // only for OpenCV 3.x +#endif + if (alg_name.compare("DPAdaptiveMedian") == 0) + return (IBGS *)malloc(sizeof(DPAdaptiveMedian)); + if (alg_name.compare("DPGrimsonGMM") == 0) + return (IBGS *)malloc(sizeof(DPGrimsonGMM)); + if (alg_name.compare("DPZivkovicAGMM") == 0) + return (IBGS *)malloc(sizeof(DPZivkovicAGMM)); + if (alg_name.compare("DPMean") == 0) + return (IBGS *)malloc(sizeof(DPMean)); + if (alg_name.compare("DPWrenGA") == 0) + return (IBGS *)malloc(sizeof(DPWrenGA)); + if (alg_name.compare("DPPratiMediod") == 0) + return (IBGS *)malloc(sizeof(DPPratiMediod)); + if (alg_name.compare("DPEigenbackground") == 0) + return (IBGS *)malloc(sizeof(DPEigenbackground)); + if (alg_name.compare("DPTexture") == 0) + return (IBGS *)malloc(sizeof(DPTexture)); + if (alg_name.compare("T2FGMM_UM") == 0) + return (IBGS *)malloc(sizeof(T2FGMM_UM)); + if (alg_name.compare("T2FGMM_UV") == 0) + return (IBGS *)malloc(sizeof(T2FGMM_UV)); + if (alg_name.compare("T2FMRF_UM") == 0) + return (IBGS *)malloc(sizeof(T2FMRF_UM)); + if (alg_name.compare("T2FMRF_UV") == 0) + return (IBGS *)malloc(sizeof(T2FMRF_UV)); + if (alg_name.compare("FuzzySugenoIntegral") == 0) + return (IBGS *)malloc(sizeof(FuzzySugenoIntegral)); + if (alg_name.compare("FuzzyChoquetIntegral") == 0) + return (IBGS *)malloc(sizeof(FuzzyChoquetIntegral)); + if (alg_name.compare("LBSimpleGaussian") == 0) + return (IBGS *)malloc(sizeof(LBSimpleGaussian)); + if (alg_name.compare("LBFuzzyGaussian") == 0) + return (IBGS *)malloc(sizeof(LBFuzzyGaussian)); + if (alg_name.compare("LBMixtureOfGaussians") == 0) + return (IBGS *)malloc(sizeof(LBMixtureOfGaussians)); + if (alg_name.compare("LBAdaptiveSOM") == 0) + return (IBGS *)malloc(sizeof(LBAdaptiveSOM)); + if (alg_name.compare("LBFuzzyAdaptiveSOM") == 0) + return (IBGS *)malloc(sizeof(LBFuzzyAdaptiveSOM)); + if (alg_name.compare("LBP_MRF") == 0) + return (IBGS *)malloc(sizeof(LBP_MRF)); + if (alg_name.compare("MultiLayer") == 0) + return (IBGS *)malloc(sizeof(MultiLayer)); + if (alg_name.compare("PixelBasedAdaptiveSegmenter") == 0) + return (IBGS *)malloc(sizeof(PixelBasedAdaptiveSegmenter)); + if (alg_name.compare("VuMeter") == 0) + return (IBGS *)malloc(sizeof(VuMeter)); + if (alg_name.compare("KDE") == 0) + return (IBGS *)malloc(sizeof(KDE)); + if (alg_name.compare("IndependentMultimodal") == 0) + return (IBGS *)malloc(sizeof(IndependentMultimodal)); + if (alg_name.compare("MultiCue") == 0) + return (IBGS *)malloc(sizeof(MultiCue)); + if (alg_name.compare("SigmaDelta") == 0) + return (IBGS *)malloc(sizeof(SigmaDelta)); + if (alg_name.compare("SuBSENSE") == 0) + return (IBGS *)malloc(sizeof(SuBSENSE)); + if (alg_name.compare("LOBSTER") == 0) + return (IBGS *)malloc(sizeof(LOBSTER)); + if (alg_name.compare("PAWCS") == 0) + return (IBGS *)malloc(sizeof(PAWCS)); + if (alg_name.compare("TwoPoints") == 0) + return (IBGS *)malloc(sizeof(TwoPoints)); + if (alg_name.compare("ViBe") == 0) + return (IBGS *)malloc(sizeof(ViBe)); + if (alg_name.compare("CodeBook") == 0) + return (IBGS *)malloc(sizeof(CodeBook)); + return NULL; + } + + IBGS* get_alg(std::string alg_name) + { + if (alg_name.compare("FrameDifference") == 0) + return new (ptrBGS) FrameDifference(); + if (alg_name.compare("StaticFrameDifference") == 0) + return new (ptrBGS) StaticFrameDifference(); + if (alg_name.compare("WeightedMovingMean") == 0) + return new (ptrBGS) WeightedMovingMean(); + if (alg_name.compare("WeightedMovingVariance") == 0) + return new (ptrBGS) WeightedMovingVariance(); +#if CV_MAJOR_VERSION == 2 + if (alg_name.compare("MixtureOfGaussianV1") == 0) + return new (ptrBGS) MixtureOfGaussianV1(); // only for OpenCV 2.x +#endif + if (alg_name.compare("MixtureOfGaussianV2") == 0) + return new (ptrBGS) MixtureOfGaussianV2(); + if (alg_name.compare("AdaptiveBackgroundLearning") == 0) + return new (ptrBGS) AdaptiveBackgroundLearning(); + if (alg_name.compare("AdaptiveSelectiveBackgroundLearning") == 0) + return new (ptrBGS) AdaptiveSelectiveBackgroundLearning(); +#if CV_MAJOR_VERSION == 2 && CV_MINOR_VERSION >= 4 && CV_SUBMINOR_VERSION >= 3 + if (alg_name.compare("GMG") == 0) + return new (ptrBGS) GMG(); // only for OpenCV >= 2.4.3 +#endif +#if CV_MAJOR_VERSION == 3 + if (alg_name.compare("KNN") == 0) + return new (ptrBGS) KNN(); // only on OpenCV 3.x +#endif + if (alg_name.compare("DPAdaptiveMedian") == 0) + return new (ptrBGS) DPAdaptiveMedian(); + if (alg_name.compare("DPGrimsonGMM") == 0) + return new (ptrBGS) DPGrimsonGMM(); + if (alg_name.compare("DPZivkovicAGMM") == 0) + return new (ptrBGS) DPZivkovicAGMM(); + if (alg_name.compare("DPMean") == 0) + return new (ptrBGS) DPMean(); + if (alg_name.compare("DPWrenGA") == 0) + return new (ptrBGS) DPWrenGA(); + if (alg_name.compare("DPPratiMediod") == 0) + return new (ptrBGS) DPPratiMediod(); + if (alg_name.compare("DPEigenbackground") == 0) + return new (ptrBGS) DPEigenbackground(); + if (alg_name.compare("DPTexture") == 0) + return new (ptrBGS) DPTexture(); + if (alg_name.compare("T2FGMM_UM") == 0) + return new (ptrBGS) T2FGMM_UM(); + if (alg_name.compare("T2FGMM_UV") == 0) + return new (ptrBGS) T2FGMM_UV(); + if (alg_name.compare("T2FMRF_UM") == 0) + return new (ptrBGS) T2FMRF_UM(); + if (alg_name.compare("T2FMRF_UV") == 0) + return new (ptrBGS) T2FMRF_UV(); + if (alg_name.compare("FuzzySugenoIntegral") == 0) + return new (ptrBGS) FuzzySugenoIntegral(); + if (alg_name.compare("FuzzyChoquetIntegral") == 0) + return new (ptrBGS) FuzzyChoquetIntegral(); + if (alg_name.compare("LBSimpleGaussian") == 0) + return new (ptrBGS) LBSimpleGaussian(); + if (alg_name.compare("LBFuzzyGaussian") == 0) + return new (ptrBGS) LBFuzzyGaussian(); + if (alg_name.compare("LBMixtureOfGaussians") == 0) + return new (ptrBGS) LBMixtureOfGaussians(); + if (alg_name.compare("LBAdaptiveSOM") == 0) + return new (ptrBGS) LBAdaptiveSOM(); + if (alg_name.compare("LBFuzzyAdaptiveSOM") == 0) + return new (ptrBGS) LBFuzzyAdaptiveSOM(); + if (alg_name.compare("LBP_MRF") == 0) + return new (ptrBGS) LBP_MRF(); + if (alg_name.compare("MultiLayer") == 0) + return new (ptrBGS) MultiLayer(); + if (alg_name.compare("PixelBasedAdaptiveSegmenter") == 0) + return new (ptrBGS) PixelBasedAdaptiveSegmenter(); + if (alg_name.compare("VuMeter") == 0) + return new (ptrBGS) VuMeter(); + if (alg_name.compare("KDE") == 0) + return new (ptrBGS) KDE(); + if (alg_name.compare("IndependentMultimodal") == 0) + return new (ptrBGS) IndependentMultimodal(); + if (alg_name.compare("MultiCue") == 0) + return new (ptrBGS) MultiCue(); + if (alg_name.compare("SigmaDelta") == 0) + return new (ptrBGS) SigmaDelta(); + if (alg_name.compare("SuBSENSE") == 0) + return new (ptrBGS) SuBSENSE(); + if (alg_name.compare("LOBSTER") == 0) + return new (ptrBGS) LOBSTER(); + if (alg_name.compare("PAWCS") == 0) + return new (ptrBGS) PAWCS(); + if (alg_name.compare("TwoPoints") == 0) + return new (ptrBGS) TwoPoints(); + if (alg_name.compare("ViBe") == 0) + return new (ptrBGS) ViBe(); + if (alg_name.compare("CodeBook") == 0) + return new (ptrBGS) CodeBook(); + return NULL; + } +} + +bool constructObject(std::string algorithm) +{ + if (ptrBGS != nullptr) destroyObject(); + + ptrBGS = bgslibrary::init_alg(algorithm); + if (ptrBGS != nullptr) + { + ptrBGS = bgslibrary::get_alg(algorithm); + if (ptrBGS == nullptr) + { + std::cout << "Failed to construct an object on memory. Algorithm not initialized." << std::endl; + return false; + } + else + { + ptrBGS->setShowOutput(false); + return true; + } + } + else + { + std::cout << "Failed to allocate memory. Algorithm not found?" << std::endl; + return false; + } +} + +void computeForegroundMask(const cv::Mat &img_input, cv::Mat &img_output) +{ + if (ptrBGS != nullptr) + { + cv::Mat fgmask, bgmodel; + + ptrBGS->process(img_input, fgmask, bgmodel); + + if (fgmask.empty()) + fgmask = cv::Mat::zeros(img_input.size(), CV_8UC1); + if (bgmodel.empty()) + bgmodel = cv::Mat::zeros(img_input.size(), CV_8UC3); + + fgmask.copyTo(img_output); + + fgmask.release(); + bgmodel.release(); + } + else + std::cout << "Algorithm not initialized." << std::endl; +} + +void destroyObject() +{ + if (ptrBGS != nullptr) + { + // explicitly call destructor for "placement new" + ptrBGS->~IBGS(); + free(ptrBGS); + ptrBGS = nullptr; + } +} + +JNIEXPORT void JNICALL Java_bgslibrary_BgsLib_constructObject(JNIEnv *env, jclass, jstring jstr) +{ + GetJStringContent(env, jstr, algorithm); + constructObject(algorithm); +} + +JNIEXPORT void JNICALL Java_bgslibrary_BgsLib_computeForegroundMask +(JNIEnv *, jclass, jlong input_matPtr, jlong output_matPtr) +{ + cv::Mat& in_mat = *reinterpret_cast(input_matPtr); + cv::Mat& fg_mat = *reinterpret_cast(output_matPtr); + computeForegroundMask(in_mat, fg_mat); +} + +JNIEXPORT void JNICALL Java_bgslibrary_BgsLib_destroyObject(JNIEnv *, jclass) +{ + destroyObject(); +} diff --git a/wrapper_java/bgslibrary_java_module.hpp b/wrapper_java/bgslibrary_java_module.hpp new file mode 100644 index 0000000000..9f402558e3 --- /dev/null +++ b/wrapper_java/bgslibrary_java_module.hpp @@ -0,0 +1,55 @@ +/* +This file is part of BGSLibrary. + +BGSLibrary is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +BGSLibrary is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with BGSLibrary. If not, see . +*/ +#pragma once + +#include +#include +#include +#include + +#include "src/bgslibrary_BgsLib.h" +#include "../package_bgs/bgslibrary.h" + +bool constructObject(std::string algorithm); +void computeForegroundMask(const cv::Mat &img_input, cv::Mat &img_output); +void destroyObject(); + +template +std::string ToString(T val) +{ + std::stringstream stream; + stream << val; + return stream.str(); +} + +jstring StringToJString(JNIEnv * env, const std::string & nativeString) +{ + return env->NewStringUTF(nativeString.c_str()); +} + +void GetJStringContent(JNIEnv *AEnv, jstring AStr, std::string &ARes) +{ + if (!AStr) + { + ARes.clear(); + return; + } + + const auto *s = AEnv->GetStringUTFChars(AStr, nullptr); + ARes = s; + AEnv->ReleaseStringUTFChars(AStr, s); +} diff --git a/wrapper_java/config/.gitignore b/wrapper_java/config/.gitignore new file mode 100644 index 0000000000..4e2a98bb11 --- /dev/null +++ b/wrapper_java/config/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except these files +!.gitignore diff --git a/wrapper_java/images/320x240.gif b/wrapper_java/images/320x240.gif new file mode 100644 index 0000000000..f88252131a Binary files /dev/null and b/wrapper_java/images/320x240.gif differ diff --git a/wrapper_java/images/640x480.png b/wrapper_java/images/640x480.png new file mode 100644 index 0000000000..90dd040b8b Binary files /dev/null and b/wrapper_java/images/640x480.png differ diff --git a/wrapper_java/libs/README.md b/wrapper_java/libs/README.md new file mode 100644 index 0000000000..15698e23e0 --- /dev/null +++ b/wrapper_java/libs/README.md @@ -0,0 +1,3 @@ +### Windows version + +The 'opencv-320.jar' file was copied from 'C:\OpenCV3.2.0\build\java'. diff --git a/wrapper_java/libs/opencv-320.jar b/wrapper_java/libs/opencv-320.jar new file mode 100644 index 0000000000..9542446ca0 Binary files /dev/null and b/wrapper_java/libs/opencv-320.jar differ diff --git a/wrapper_java/src/bgslibrary/.gitignore b/wrapper_java/src/bgslibrary/.gitignore new file mode 100644 index 0000000000..6b468b62a9 --- /dev/null +++ b/wrapper_java/src/bgslibrary/.gitignore @@ -0,0 +1 @@ +*.class diff --git a/wrapper_java/src/bgslibrary/BgsLib.java b/wrapper_java/src/bgslibrary/BgsLib.java new file mode 100644 index 0000000000..c9b46084da --- /dev/null +++ b/wrapper_java/src/bgslibrary/BgsLib.java @@ -0,0 +1,54 @@ +/* +This file is part of BGSLibrary. + +BGSLibrary is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +BGSLibrary is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with BGSLibrary. If not, see . + */ +package bgslibrary; + +import org.opencv.core.Core; + +public class BgsLib +{ + static + { + System.loadLibrary(Core.NATIVE_LIBRARY_NAME); + System.loadLibrary("libbgs_java_module"); + } + + private static final String[] algorithms = + { + "FrameDifference", "StaticFrameDifference", "WeightedMovingMean", + "WeightedMovingVariance", "MixtureOfGaussianV1", "MixtureOfGaussianV2", + "AdaptiveBackgroundLearning", "AdaptiveSelectiveBackgroundLearning", + "GMG", "KNN", "DPAdaptiveMedian", "DPGrimsonGMM", "DPZivkovicAGMM", + "DPMean", "DPWrenGA", "DPPratiMediod", "DPEigenbackground", "DPTexture", + "T2FGMM_UM", "T2FGMM_UV", "T2FMRF_UM", "T2FMRF_UV", "FuzzySugenoIntegral", + "FuzzyChoquetIntegral", "LBSimpleGaussian", "LBFuzzyGaussian", + "LBMixtureOfGaussians", "LBAdaptiveSOM", "LBFuzzyAdaptiveSOM", "LBP_MRF", + "MultiLayer", "PixelBasedAdaptiveSegmenter", "VuMeter", "KDE", + "IndependentMultimodal", "MultiCue", "SigmaDelta", "SuBSENSE", "LOBSTER", + "PAWCS", "TwoPoints", "ViBe", "CodeBook" + }; + + public static final String[] getListAlgorithms() + { + return algorithms; + } + + public static native void constructObject(String str); + + public static native void computeForegroundMask(long input_matPtr, long output_matPtr); + + public static native void destroyObject(); +} diff --git a/wrapper_java/src/bgslibrary/ImagePanel.java b/wrapper_java/src/bgslibrary/ImagePanel.java new file mode 100644 index 0000000000..d97d548cf4 --- /dev/null +++ b/wrapper_java/src/bgslibrary/ImagePanel.java @@ -0,0 +1,44 @@ +package bgslibrary; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JPanel; + +class ImagePanel extends JPanel +{ + private Image img; + + public ImagePanel(String img) + { + this(new ImageIcon(img).getImage()); + } + + public ImagePanel(Image img) + { + this.img = img; + Dimension size = new Dimension(img.getWidth(null), img.getHeight(null)); + setPreferredSize(size); + setMinimumSize(size); + setMaximumSize(size); + setSize(size); + setLayout(null); + setBorder(BorderFactory.createLineBorder(Color.black)); + } + + public void updateImage(Image img) + { + this.img = img; + validate(); + repaint(); + } + + @Override + public void paintComponent(Graphics g) + { + g.drawImage(img, 0, 0, null); + } +} diff --git a/wrapper_java/src/bgslibrary/Main.java b/wrapper_java/src/bgslibrary/Main.java new file mode 100644 index 0000000000..10489ec43f --- /dev/null +++ b/wrapper_java/src/bgslibrary/Main.java @@ -0,0 +1,207 @@ +/* +This file is part of BGSLibrary. + +BGSLibrary is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +BGSLibrary is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with BGSLibrary. If not, see . + */ +package bgslibrary; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; +import java.io.InputStream; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import org.opencv.core.Core; +import org.opencv.core.CvType; +import org.opencv.core.Mat; +import org.opencv.core.MatOfByte; +import org.opencv.imgproc.Imgproc; +import org.opencv.videoio.VideoCapture; + +public final class Main +{ + static + { + System.loadLibrary(Core.NATIVE_LIBRARY_NAME); + } + + private static BgsLib bgslib; + + private JFrame window; + private JButton startButton, stopButton; + private ImagePanel image; + private JComboBox comboBox; + private String selectedAlgorithm; + + public Main() + { + buildGUI(); + } + + private void buildGUI() + { + window = new JFrame("Camera Panel"); + + startButton = new JButton("Start"); + stopButton = new JButton("Stop"); + + window.add(startButton, BorderLayout.WEST); + window.add(stopButton, BorderLayout.EAST); + + //image = new ImagePanel(new ImageIcon("images/320x240.gif").getImage()); + image = new ImagePanel(new ImageIcon("images/640x480.png").getImage()); + window.add(image, BorderLayout.CENTER); + + String[] options = {"* Select a background subtraction algorithm"}; + options = Utils.generalConcatAll(options, bgslib.getListAlgorithms()); + + comboBox = new JComboBox(options); + comboBox.addActionListener(new ActionListener() + { + + @Override + public void actionPerformed(ActionEvent e) + { + if(begin == true) + { + JOptionPane.showMessageDialog(null, "Stop capture first.", "Warning", + JOptionPane.WARNING_MESSAGE); + comboBox.setSelectedIndex(0); + selectedAlgorithm = null; + return; + } + + String item = comboBox.getSelectedItem().toString(); + + if(item.startsWith("*")) + selectedAlgorithm = null; + else + selectedAlgorithm = item; + + //System.out.println("Selected algorithm: " + selectedAlgorithm); + } + }); + window.add(comboBox, BorderLayout.SOUTH); + + window.setSize(default_width + 130, default_height + 28); + window.setLocationRelativeTo(null); + window.setVisible(true); + window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + window.setResizable(false); + + startButton.addActionListener((ActionEvent e) -> + { + start(); + }); + + stopButton.addActionListener((ActionEvent e) -> + { + stop(); + }); + } + + private Boolean begin = false; + private VideoCapture video = null; + private CaptureThread thread = null; + + private void start() + { + if (begin == false) + { + video = new VideoCapture(0); + + if (video.isOpened()) + { + if(selectedAlgorithm != null) + BgsLib.constructObject(selectedAlgorithm); + + thread = new CaptureThread(); + thread.start(); + begin = true; + } + } + } + + private MatOfByte matOfByte = new MatOfByte(); + private BufferedImage bufImage = null; + private InputStream in; + private final int default_width = 640; + private final int default_height = 480; + private Mat frameaux = new Mat(); + private Mat frame = new Mat(default_height, default_width, CvType.CV_8UC3); + private Mat fgmask = new Mat(); + + class CaptureThread extends Thread + { + @Override + public void run() + { + if (video.isOpened()) + { + while (begin == true) + { + video.retrieve(frameaux); + Imgproc.resize(frameaux, frame, frame.size()); + + if(selectedAlgorithm != null) + { + BgsLib.computeForegroundMask(frame.getNativeObjAddr(), fgmask.getNativeObjAddr()); + bufImage = Utils.toBufferedImage(fgmask); + } + else + bufImage = Utils.toBufferedImage(frame); + + image.updateImage(bufImage); + + try + { + Thread.sleep(5); + } + catch (Exception ex) + { + } + } + } + } + } + + private void stop() + { + begin = false; + try + { + Thread.sleep(500); + } + catch (Exception ex) + { + } + + if(video != null) + { + video.release(); + video = null; + } + + BgsLib.destroyObject(); + } + + public static void main(String[] args) + { + new Main(); + } +} diff --git a/wrapper_java/src/bgslibrary/Utils.java b/wrapper_java/src/bgslibrary/Utils.java new file mode 100644 index 0000000000..fd59447dbf --- /dev/null +++ b/wrapper_java/src/bgslibrary/Utils.java @@ -0,0 +1,102 @@ +/* +This file is part of BGSLibrary. + +BGSLibrary is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +BGSLibrary is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with BGSLibrary. If not, see . + */ +package bgslibrary; + +import java.awt.FlowLayout; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferByte; +import java.math.BigInteger; +import java.security.SecureRandom; +import java.util.UUID; +import javax.swing.ImageIcon; +import javax.swing.JFrame; +import javax.swing.JLabel; +import org.opencv.core.Mat; +import org.opencv.imgcodecs.Imgcodecs; + +public class Utils +{ + static final private SecureRandom random = new SecureRandom(); + + static final public String nextSessionId() + { + return new BigInteger(130, random).toString(32); + } + + static final public String nextUUID() + { + return UUID.randomUUID().toString(); + } + + static final public BufferedImage toBufferedImage(Mat m) + { + int type = BufferedImage.TYPE_BYTE_GRAY; + if (m.channels() > 1) + type = BufferedImage.TYPE_3BYTE_BGR; + int bufferSize = m.channels() * m.cols() * m.rows(); + byte[] b = new byte[bufferSize]; + m.get(0, 0, b); // get all the pixels + BufferedImage image = new BufferedImage(m.cols(), m.rows(), type); + final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); + System.arraycopy(b, 0, targetPixels, 0, b.length); + return image; + } + + static final public void imshow(Mat image) + { + try + { + BufferedImage bufImage = toBufferedImage(image); + JFrame frame = new JFrame("Image"); + frame.getContentPane().setLayout(new FlowLayout()); + frame.getContentPane().add(new JLabel(new ImageIcon(bufImage))); + frame.pack(); + frame.setSize(image.width() + 40, image.height() + 60); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + static final public void writeImage(Mat image, String fileName) + { + //System.out.println(String.format("Writing image at %s", fileName)); + Imgcodecs.imwrite(fileName, image); + } + + static final public String[] generalConcatAll(String[]... jobs) + { + int len = 0; + for (final String[] job : jobs) + len += job.length; + + final String[] result = new String[len]; + + int currentPos = 0; + for (final String[] job : jobs) + { + System.arraycopy(job, 0, result, currentPos, job.length); + currentPos += job.length; + } + + return result; + } +} diff --git a/wrapper_java/src/bgslibrary_BgsLib.h b/wrapper_java/src/bgslibrary_BgsLib.h new file mode 100644 index 0000000000..06ff9941a0 --- /dev/null +++ b/wrapper_java/src/bgslibrary_BgsLib.h @@ -0,0 +1,37 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class bgslibrary_BgsLib */ + +#ifndef _Included_bgslibrary_BgsLib +#define _Included_bgslibrary_BgsLib +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: bgslibrary_BgsLib + * Method: constructObject + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_bgslibrary_BgsLib_constructObject + (JNIEnv *, jclass, jstring); + +/* + * Class: bgslibrary_BgsLib + * Method: computeForegroundMask + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_bgslibrary_BgsLib_computeForegroundMask + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: bgslibrary_BgsLib + * Method: destroyObject + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_bgslibrary_BgsLib_destroyObject + (JNIEnv *, jclass); + +#ifdef __cplusplus +} +#endif +#endif