1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 07:43:03 +04:00

Merge branch 4.x

This commit is contained in:
Alexander Alekhin
2021-12-30 16:23:27 +00:00
951 changed files with 158314 additions and 152668 deletions
+1 -2
View File
@@ -110,8 +110,6 @@ if(MSVC)
endif()
endif()
add_definitions(-DDISABLE_OPENCV_24_COMPATIBILITY=1) # Avoid C-like legacy API
if(OPENCV_EXAMPLES_DISABLE_THREADS)
# nothing
elseif(MSVC OR APPLE)
@@ -120,6 +118,7 @@ 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()
+2
View File
@@ -23,6 +23,8 @@ 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
@@ -1,8 +1,8 @@
// This sample is based on "Camera calibration With OpenCV" tutorial:
// https://docs.opencv.org/3.4/d4/d94/tutorial_camera_calibration.html
// https://docs.opencv.org/5.x/d4/d94/tutorial_camera_calibration.html
//
// It uses standard OpenCV asymmetric circles grid pattern 11x4:
// https://github.com/opencv/opencv/blob/3.4/doc/acircles_pattern.png
// https://github.com/opencv/opencv/blob/5.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.
+4 -1
View File
@@ -58,6 +58,7 @@ foreach(sample_filename ${cpp_samples})
endif()
if(HAVE_OPENGL AND sample_filename MATCHES "detect_mser")
target_compile_definitions(${tgt} PRIVATE HAVE_OPENGL)
ocv_target_link_libraries(${tgt} PRIVATE "${OPENGL_LIBRARIES}")
endif()
if(sample_filename MATCHES "simd_")
# disabled intentionally - demonstration purposes only
@@ -74,6 +75,8 @@ include("tutorial_code/calib3d/real_time_pose_estimation/CMakeLists.txt" OPTIONA
if(OpenCV_FOUND AND NOT CMAKE_VERSION VERSION_LESS "3.1")
add_subdirectory("example_cmake")
endif()
if(OpenCV_FOUND AND NOT CMAKE_VERSION VERSION_LESS "3.9")
if(OpenCV_FOUND AND NOT CMAKE_VERSION VERSION_LESS "3.9"
AND NOT OPENCV_EXAMPLES_SKIP_PARALLEL_BACKEND
)
add_subdirectory("tutorial_code/core/parallel_backend")
endif()
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -126,7 +126,7 @@ int main(int argc, char *argv[])
// These descriptors are going to be detecting and computing BLOBS with 6 different params
// Param for first BLOB detector we want all
typeDesc.push_back("BLOB"); // see http://docs.opencv.org/master/d0/d7a/classcv_1_1SimpleBlobDetector.html
typeDesc.push_back("BLOB"); // see http://docs.opencv.org/5.x/d0/d7a/classcv_1_1SimpleBlobDetector.html
pBLOB.push_back(pDefaultBLOB);
pBLOB.back().filterByArea = true;
pBLOB.back().minArea = 1;
+2 -2
View File
@@ -89,10 +89,10 @@ static void help(char** argv)
"\tThis will detect only the face in image.jpg.\n";
cout << " \n\nThe classifiers for face and eyes can be downloaded from : "
" \nhttps://github.com/opencv/opencv/tree/master/data/haarcascades";
" \nhttps://github.com/opencv/opencv/tree/5.x/data/haarcascades";
cout << "\n\nThe classifiers for nose and mouth can be downloaded from : "
" \nhttps://github.com/opencv/opencv_contrib/tree/master/modules/face/data/cascades\n";
" \nhttps://github.com/opencv/opencv_contrib/tree/5.x/modules/face/data/cascades\n";
}
static void detectFaces(Mat& img, vector<Rect_<int> >& faces, string cascade_path)
+5 -5
View File
@@ -16,14 +16,14 @@ struct ParamColorMap {
String winName="False color";
static const String ColorMaps[] = { "Autumn", "Bone", "Jet", "Winter", "Rainbow", "Ocean", "Summer", "Spring",
"Cool", "HSV", "Pink", "Hot", "Parula", "Magma", "Inferno", "Plasma", "Viridis",
"Cividis", "Twilight", "Twilight Shifted", "Turbo", "User defined (random)" };
"Cividis", "Twilight", "Twilight Shifted", "Turbo", "Deep Green", "User defined (random)" };
static void TrackColorMap(int x, void *r)
{
ParamColorMap *p = (ParamColorMap*)r;
Mat dst;
p->iColormap= x;
if (x == COLORMAP_TURBO + 1)
if (x == COLORMAP_DEEPGREEN + 1)
{
Mat lutRND(256, 1, CV_8UC3);
randu(lutRND, Scalar(0, 0, 0), Scalar(255, 255, 255));
@@ -97,10 +97,10 @@ int main(int argc, char** argv)
imshow("Gray image",img);
namedWindow(winName);
createTrackbar("colormap", winName,&p.iColormap,1,TrackColorMap,(void*)&p);
createTrackbar("colormap", winName, NULL, COLORMAP_DEEPGREEN + 1, TrackColorMap, (void*)&p);
setTrackbarMin("colormap", winName, COLORMAP_AUTUMN);
setTrackbarMax("colormap", winName, COLORMAP_TURBO+1);
setTrackbarPos("colormap", winName, -1);
setTrackbarMax("colormap", winName, COLORMAP_DEEPGREEN + 1);
setTrackbarPos("colormap", winName, COLORMAP_AUTUMN);
TrackColorMap(0, (void*)&p);
+1 -1
View File
@@ -15,7 +15,7 @@ int main( int argc, const char** argv )
cout << "This program demonstrates the use of template matching with mask." << endl
<< endl
<< "Available methods: https://docs.opencv.org/master/df/dfb/group__imgproc__object.html#ga3a7850640f1fe1f58fe91a2d7583695d" << endl
<< "Available methods: https://docs.opencv.org/5.x/df/dfb/group__imgproc__object.html#ga3a7850640f1fe1f58fe91a2d7583695d" << endl
<< " TM_SQDIFF = " << (int)TM_SQDIFF << endl
<< " TM_SQDIFF_NORMED = " << (int)TM_SQDIFF_NORMED << endl
<< " TM_CCORR = " << (int)TM_CCORR << endl
+5 -5
View File
@@ -24,11 +24,11 @@ int main(int argc, char *argv[])
vector<String> typeAlgoMatch;
vector<String> fileName;
// This descriptor are going to be detect and compute
typeDesc.push_back("AKAZE-DESCRIPTOR_KAZE_UPRIGHT"); // see https://docs.opencv.org/master/d8/d30/classcv_1_1AKAZE.html
typeDesc.push_back("AKAZE"); // see http://docs.opencv.org/master/d8/d30/classcv_1_1AKAZE.html
typeDesc.push_back("ORB"); // see http://docs.opencv.org/master/de/dbf/classcv_1_1BRISK.html
typeDesc.push_back("BRISK"); // see http://docs.opencv.org/master/db/d95/classcv_1_1ORB.html
// This algorithm would be used to match descriptors see http://docs.opencv.org/master/db/d39/classcv_1_1DescriptorMatcher.html#ab5dc5036569ecc8d47565007fa518257
typeDesc.push_back("AKAZE-DESCRIPTOR_KAZE_UPRIGHT"); // see https://docs.opencv.org/5.x/d8/d30/classcv_1_1AKAZE.html
typeDesc.push_back("AKAZE"); // see http://docs.opencv.org/5.x/d8/d30/classcv_1_1AKAZE.html
typeDesc.push_back("ORB"); // see http://docs.opencv.org/5.x/de/dbf/classcv_1_1BRISK.html
typeDesc.push_back("BRISK"); // see http://docs.opencv.org/5.x/db/d95/classcv_1_1ORB.html
// This algorithm would be used to match descriptors see http://docs.opencv.org/5.x/db/d39/classcv_1_1DescriptorMatcher.html#ab5dc5036569ecc8d47565007fa518257
typeAlgoMatch.push_back("BruteForce");
typeAlgoMatch.push_back("BruteForce-L1");
typeAlgoMatch.push_back("BruteForce-Hamming");
@@ -2,25 +2,36 @@ cmake_minimum_required(VERSION 3.9)
find_package(OpenCV REQUIRED COMPONENTS opencv_core)
find_package(OpenMP)
if(OpenMP_FOUND)
project(opencv_example_openmp_backend)
add_executable(opencv_example_openmp_backend example-openmp.cpp)
target_link_libraries(opencv_example_openmp_backend PRIVATE
opencv_core
OpenMP::OpenMP_CXX
)
if(NOT OPENCV_EXAMPLES_SKIP_PARALLEL_BACKEND_OPENMP
AND NOT OPENCV_EXAMPLES_SKIP_OPENMP
)
find_package(OpenMP)
if(OpenMP_FOUND)
project(opencv_example_openmp_backend)
add_executable(opencv_example_openmp_backend example-openmp.cpp)
target_link_libraries(opencv_example_openmp_backend PRIVATE
opencv_core
OpenMP::OpenMP_CXX
)
endif()
endif()
# TODO: find_package(TBB)
find_path(TBB_INCLUDE_DIR NAMES "tbb/tbb.h")
find_library(TBB_LIBRARY NAMES "tbb")
if(TBB_INCLUDE_DIR AND TBB_LIBRARY AND NOT OPENCV_EXAMPLE_SKIP_TBB)
project(opencv_example_tbb_backend)
add_executable(opencv_example_tbb_backend example-tbb.cpp)
target_include_directories(opencv_example_tbb_backend SYSTEM PRIVATE ${TBB_INCLUDE_DIR})
target_link_libraries(opencv_example_tbb_backend PRIVATE
opencv_core
${TBB_LIBRARY}
)
if(NOT OPENCV_EXAMPLES_SKIP_PARALLEL_BACKEND_TBB
AND NOT OPENCV_EXAMPLES_SKIP_TBB
AND NOT OPENCV_EXAMPLE_SKIP_TBB # deprecated (to be removed in OpenCV 5.0)
)
find_package(TBB QUIET)
if(NOT TBB_FOUND)
find_path(TBB_INCLUDE_DIR NAMES "tbb/tbb.h")
find_library(TBB_LIBRARY NAMES "tbb")
endif()
if(TBB_INCLUDE_DIR AND TBB_LIBRARY)
project(opencv_example_tbb_backend)
add_executable(opencv_example_tbb_backend example-tbb.cpp)
target_include_directories(opencv_example_tbb_backend SYSTEM PRIVATE ${TBB_INCLUDE_DIR})
target_link_libraries(opencv_example_tbb_backend PRIVATE
opencv_core
${TBB_LIBRARY}
)
endif()
endif()
@@ -0,0 +1,253 @@
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>
#include <opencv2/gapi/imgproc.hpp>
#include <opencv2/gapi/s11n.hpp>
#include <opencv2/gapi/garg.hpp>
#include <opencv2/gapi/gcommon.hpp>
#include <opencv2/gapi/cpu/gcpukernel.hpp>
#include <opencv2/gapi/fluid/core.hpp>
#include <opencv2/gapi/fluid/imgproc.hpp>
static void gscalar_example()
{
//! [gscalar_implicit]
cv::GMat a;
cv::GMat b = a + 1;
//! [gscalar_implicit]
}
static void typed_example()
{
const cv::Size sz(32, 32);
cv::Mat
in_mat1 (sz, CV_8UC1),
in_mat2 (sz, CV_8UC1),
out_mat_untyped(sz, CV_8UC1),
out_mat_typed1 (sz, CV_8UC1),
out_mat_typed2 (sz, CV_8UC1);
cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(255));
cv::randu(in_mat2, cv::Scalar::all(0), cv::Scalar::all(255));
//! [Untyped_Example]
// Untyped G-API ///////////////////////////////////////////////////////////
cv::GComputation cvtU([]()
{
cv::GMat in1, in2;
cv::GMat out = cv::gapi::add(in1, in2);
return cv::GComputation({in1, in2}, {out});
});
std::vector<cv::Mat> u_ins = {in_mat1, in_mat2};
std::vector<cv::Mat> u_outs = {out_mat_untyped};
cvtU.apply(u_ins, u_outs);
//! [Untyped_Example]
//! [Typed_Example]
// Typed G-API /////////////////////////////////////////////////////////////
cv::GComputationT<cv::GMat (cv::GMat, cv::GMat)> cvtT([](cv::GMat m1, cv::GMat m2)
{
return m1+m2;
});
cvtT.apply(in_mat1, in_mat2, out_mat_typed1);
auto cvtTC = cvtT.compile(cv::descr_of(in_mat1), cv::descr_of(in_mat2));
cvtTC(in_mat1, in_mat2, out_mat_typed2);
//! [Typed_Example]
}
static void bind_serialization_example()
{
// ! [bind after deserialization]
cv::GCompiled compd;
std::vector<char> bytes;
auto graph = cv::gapi::deserialize<cv::GComputation>(bytes);
auto meta = cv::gapi::deserialize<cv::GMetaArgs>(bytes);
compd = graph.compile(std::move(meta), cv::compile_args());
auto in_args = cv::gapi::deserialize<cv::GRunArgs>(bytes);
auto out_args = cv::gapi::deserialize<cv::GRunArgs>(bytes);
compd(std::move(in_args), cv::gapi::bind(out_args));
// ! [bind after deserialization]
}
static void bind_deserialization_example()
{
// ! [bind before serialization]
std::vector<cv::GRunArgP> graph_outs;
cv::GRunArgs out_args;
for (auto &&out : graph_outs) {
out_args.emplace_back(cv::gapi::bind(out));
}
const auto sargsout = cv::gapi::serialize(out_args);
// ! [bind before serialization]
}
struct SimpleCustomType {
bool val;
bool operator==(const SimpleCustomType& other) const {
return val == other.val;
}
};
struct SimpleCustomType2 {
int val;
std::string name;
std::vector<float> vec;
std::map<int, uint64_t> mmap;
bool operator==(const SimpleCustomType2& other) const {
return val == other.val && name == other.name &&
vec == other.vec && mmap == other.mmap;
}
};
// ! [S11N usage]
namespace cv {
namespace gapi {
namespace s11n {
namespace detail {
template<> struct S11N<SimpleCustomType> {
static void serialize(IOStream &os, const SimpleCustomType &p) {
os << p.val;
}
static SimpleCustomType deserialize(IIStream &is) {
SimpleCustomType p;
is >> p.val;
return p;
}
};
template<> struct S11N<SimpleCustomType2> {
static void serialize(IOStream &os, const SimpleCustomType2 &p) {
os << p.val << p.name << p.vec << p.mmap;
}
static SimpleCustomType2 deserialize(IIStream &is) {
SimpleCustomType2 p;
is >> p.val >> p.name >> p.vec >> p.mmap;
return p;
}
};
} // namespace detail
} // namespace s11n
} // namespace gapi
} // namespace cv
// ! [S11N usage]
namespace cv {
namespace detail {
template<> struct CompileArgTag<SimpleCustomType> {
static const char* tag() {
return "org.opencv.test.simple_custom_type";
}
};
template<> struct CompileArgTag<SimpleCustomType2> {
static const char* tag() {
return "org.opencv.test.simple_custom_type_2";
}
};
} // namespace detail
} // namespace cv
static void s11n_example()
{
SimpleCustomType customVar1 { false };
SimpleCustomType2 customVar2 { 1248, "World", {1280, 720, 640, 480},
{ {5, 32434142342}, {7, 34242432} } };
std::vector<char> sArgs = cv::gapi::serialize(
cv::compile_args(customVar1, customVar2));
cv::GCompileArgs dArgs = cv::gapi::deserialize<cv::GCompileArgs,
SimpleCustomType,
SimpleCustomType2>(sArgs);
SimpleCustomType dCustomVar1 = cv::gapi::getCompileArg<SimpleCustomType>(dArgs).value();
SimpleCustomType2 dCustomVar2 = cv::gapi::getCompileArg<SimpleCustomType2>(dArgs).value();
(void) dCustomVar1;
(void) dCustomVar2;
}
G_TYPED_KERNEL(IAdd, <cv::GMat(cv::GMat)>, "test.custom.add") {
static cv::GMatDesc outMeta(const cv::GMatDesc &in) { return in; }
};
G_TYPED_KERNEL(IFilter2D, <cv::GMat(cv::GMat)>, "test.custom.filter2d") {
static cv::GMatDesc outMeta(const cv::GMatDesc &in) { return in; }
};
G_TYPED_KERNEL(IRGB2YUV, <cv::GMat(cv::GMat)>, "test.custom.add") {
static cv::GMatDesc outMeta(const cv::GMatDesc &in) { return in; }
};
GAPI_OCV_KERNEL(CustomAdd, IAdd) { static void run(cv::Mat, cv::Mat &) {} };
GAPI_OCV_KERNEL(CustomFilter2D, IFilter2D) { static void run(cv::Mat, cv::Mat &) {} };
GAPI_OCV_KERNEL(CustomRGB2YUV, IRGB2YUV) { static void run(cv::Mat, cv::Mat &) {} };
int main(int argc, char *argv[])
{
if (argc < 3)
return -1;
cv::Mat input = cv::imread(argv[1]);
cv::Mat output;
{
//! [graph_def]
cv::GMat in;
cv::GMat gx = cv::gapi::Sobel(in, CV_32F, 1, 0);
cv::GMat gy = cv::gapi::Sobel(in, CV_32F, 0, 1);
cv::GMat g = cv::gapi::sqrt(cv::gapi::mul(gx, gx) + cv::gapi::mul(gy, gy));
cv::GMat out = cv::gapi::convertTo(g, CV_8U);
//! [graph_def]
//! [graph_decl_apply]
//! [graph_cap_full]
cv::GComputation sobelEdge(cv::GIn(in), cv::GOut(out));
//! [graph_cap_full]
sobelEdge.apply(input, output);
//! [graph_decl_apply]
//! [apply_with_param]
cv::GKernelPackage kernels = cv::gapi::combine
(cv::gapi::core::fluid::kernels(),
cv::gapi::imgproc::fluid::kernels());
sobelEdge.apply(input, output, cv::compile_args(kernels));
//! [apply_with_param]
//! [graph_cap_sub]
cv::GComputation sobelEdgeSub(cv::GIn(gx, gy), cv::GOut(out));
//! [graph_cap_sub]
}
//! [graph_gen]
cv::GComputation sobelEdgeGen([](){
cv::GMat in;
cv::GMat gx = cv::gapi::Sobel(in, CV_32F, 1, 0);
cv::GMat gy = cv::gapi::Sobel(in, CV_32F, 0, 1);
cv::GMat g = cv::gapi::sqrt(cv::gapi::mul(gx, gx) + cv::gapi::mul(gy, gy));
cv::GMat out = cv::gapi::convertTo(g, CV_8U);
return cv::GComputation(in, out);
});
//! [graph_gen]
cv::imwrite(argv[2], output);
//! [kernels_snippet]
cv::GKernelPackage pkg = cv::gapi::kernels
< CustomAdd
, CustomFilter2D
, CustomRGB2YUV
>();
//! [kernels_snippet]
// Just call typed example with no input/output - avoid warnings about
// unused functions
typed_example();
gscalar_example();
bind_serialization_example();
bind_deserialization_example();
s11n_example();
return 0;
}
@@ -0,0 +1,68 @@
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/cpu/imgproc.hpp>
#include <opencv2/gapi/imgproc.hpp>
int main(int argc, char *argv[])
{
(void) argc;
(void) argv;
bool need_first_conversion = true;
bool need_second_conversion = false;
cv::Size szOut(4, 4);
cv::GComputation cc([&](){
// ! [GIOProtoArgs usage]
auto ins = cv::GIn();
cv::GMat in1;
if (need_first_conversion)
ins += cv::GIn(in1);
cv::GMat in2;
if (need_second_conversion)
ins += cv::GIn(in2);
auto outs = cv::GOut();
cv::GMat out1 = cv::gapi::resize(in1, szOut);
if (need_first_conversion)
outs += cv::GOut(out1);
cv::GMat out2 = cv::gapi::resize(in2, szOut);
if (need_second_conversion)
outs += cv::GOut(out2);
// ! [GIOProtoArgs usage]
return cv::GComputation(std::move(ins), std::move(outs));
});
// ! [GRunArgs usage]
auto in_vector = cv::gin();
cv::Mat in_mat1( 8, 8, CV_8UC3);
cv::Mat in_mat2(16, 16, CV_8UC3);
cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(255));
cv::randu(in_mat2, cv::Scalar::all(0), cv::Scalar::all(255));
if (need_first_conversion)
in_vector += cv::gin(in_mat1);
if (need_second_conversion)
in_vector += cv::gin(in_mat2);
// ! [GRunArgs usage]
// ! [GRunArgsP usage]
auto out_vector = cv::gout();
cv::Mat out_mat1, out_mat2;
if (need_first_conversion)
out_vector += cv::gout(out_mat1);
if (need_second_conversion)
out_vector += cv::gout(out_mat2);
// ! [GRunArgsP usage]
auto stream = cc.compileStreaming(cv::compile_args(cv::gapi::imgproc::cpu::kernels()));
stream.setSource(std::move(in_vector));
stream.start();
stream.pull(std::move(out_vector));
stream.stop();
return 0;
}
@@ -0,0 +1,157 @@
// [filter2d_api]
#include <opencv2/gapi.hpp>
G_TYPED_KERNEL(GFilter2D,
<cv::GMat(cv::GMat,int,cv::Mat,cv::Point,double,int,cv::Scalar)>,
"org.opencv.imgproc.filters.filter2D")
{
static cv::GMatDesc // outMeta's return value type
outMeta(cv::GMatDesc in , // descriptor of input GMat
int ddepth , // depth parameter
cv::Mat /* coeffs */, // (unused)
cv::Point /* anchor */, // (unused)
double /* scale */, // (unused)
int /* border */, // (unused)
cv::Scalar /* bvalue */ ) // (unused)
{
return in.withDepth(ddepth);
}
};
// [filter2d_api]
cv::GMat filter2D(cv::GMat ,
int ,
cv::Mat ,
cv::Point ,
double ,
int ,
cv::Scalar);
// [filter2d_wrap]
cv::GMat filter2D(cv::GMat in,
int ddepth,
cv::Mat k,
cv::Point anchor = cv::Point(-1,-1),
double scale = 0.,
int border = cv::BORDER_DEFAULT,
cv::Scalar bval = cv::Scalar(0))
{
return GFilter2D::on(in, ddepth, k, anchor, scale, border, bval);
}
// [filter2d_wrap]
// [compound]
#include <opencv2/gapi/gcompoundkernel.hpp> // GAPI_COMPOUND_KERNEL()
using PointArray2f = cv::GArray<cv::Point2f>;
G_TYPED_KERNEL(HarrisCorners,
<PointArray2f(cv::GMat,int,double,double,int,double)>,
"org.opencv.imgproc.harris_corner")
{
static cv::GArrayDesc outMeta(const cv::GMatDesc &,
int,
double,
double,
int,
double)
{
// No special metadata for arrays in G-API (yet)
return cv::empty_array_desc();
}
};
// Define Fluid-backend-local kernels which form GoodFeatures
G_TYPED_KERNEL(HarrisResponse,
<cv::GMat(cv::GMat,double,int,double)>,
"org.opencv.fluid.harris_response")
{
static cv::GMatDesc outMeta(const cv::GMatDesc &in,
double,
int,
double)
{
return in.withType(CV_32F, 1);
}
};
G_TYPED_KERNEL(ArrayNMS,
<PointArray2f(cv::GMat,int,double)>,
"org.opencv.cpu.nms_array")
{
static cv::GArrayDesc outMeta(const cv::GMatDesc &,
int,
double)
{
return cv::empty_array_desc();
}
};
GAPI_COMPOUND_KERNEL(GFluidHarrisCorners, HarrisCorners)
{
static PointArray2f
expand(cv::GMat in,
int maxCorners,
double quality,
double minDist,
int blockSize,
double k)
{
cv::GMat response = HarrisResponse::on(in, quality, blockSize, k);
return ArrayNMS::on(response, maxCorners, minDist);
}
};
// Then implement HarrisResponse as Fluid kernel and NMSresponse
// as a generic (OpenCV) kernel
// [compound]
// [filter2d_ocv]
#include <opencv2/gapi/cpu/gcpukernel.hpp> // GAPI_OCV_KERNEL()
#include <opencv2/imgproc.hpp> // cv::filter2D()
GAPI_OCV_KERNEL(GCPUFilter2D, GFilter2D)
{
static void
run(const cv::Mat &in, // in - derived from GMat
const int ddepth, // opaque (passed as-is)
const cv::Mat &k, // opaque (passed as-is)
const cv::Point &anchor, // opaque (passed as-is)
const double delta, // opaque (passed as-is)
const int border, // opaque (passed as-is)
const cv::Scalar &, // opaque (passed as-is)
cv::Mat &out) // out - derived from GMat (retval)
{
cv::filter2D(in, out, ddepth, k, anchor, delta, border);
}
};
// [filter2d_ocv]
int main(int, char *[])
{
std::cout << "This sample is non-complete. It is used as code snippents in documentation." << std::endl;
cv::Mat conv_kernel_mat;
{
// [filter2d_on]
cv::GMat in;
cv::GMat out = GFilter2D::on(/* GMat */ in,
/* int */ -1,
/* Mat */ conv_kernel_mat,
/* Point */ cv::Point(-1,-1),
/* double */ 0.,
/* int */ cv::BORDER_DEFAULT,
/* Scalar */ cv::Scalar(0));
// [filter2d_on]
}
{
// [filter2d_wrap_call]
cv::GMat in;
cv::GMat out = filter2D(in, -1, conv_kernel_mat);
// [filter2d_wrap_call]
}
return 0;
}
@@ -63,7 +63,7 @@ int main()
//! [kernel_pkg_proper]
//! [kernel_pkg]
// Prepare the kernel package and run the graph
cv::gapi::GKernelPackage fluid_kernels = cv::gapi::combine // Define a custom kernel package:
cv::GKernelPackage fluid_kernels = cv::gapi::combine // Define a custom kernel package:
(cv::gapi::core::fluid::kernels(), // ...with Fluid Core kernels
cv::gapi::imgproc::fluid::kernels()); // ...and Fluid ImgProc kernels
//! [kernel_pkg]
@@ -4,6 +4,17 @@
#include <list>
#include <iostream>
#if !defined(HAVE_THREADS)
int main()
{
std::cout << "This sample is built without threading support. Sample code is disabled." << std::endl;
return 0;
}
#else
#include <thread>
#include <mutex>
#include <condition_variable>
@@ -200,3 +211,5 @@ int main()
return 0;
}
#endif
+59
View File
@@ -0,0 +1,59 @@
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
CommandLineParser parser(argc, argv, "{@audio||}");
string file = parser.get<string>("@audio");
if (file.empty())
{
return 1;
}
Mat frame;
vector<vector<Mat>> audioData;
VideoCapture cap;
vector<int> params { CAP_PROP_AUDIO_STREAM, 0,
CAP_PROP_VIDEO_STREAM, -1,
CAP_PROP_AUDIO_DATA_DEPTH, CV_16S };
cap.open(file, CAP_MSMF, params);
if (!cap.isOpened())
{
cerr << "ERROR! Can't to open file: " + file << endl;
return -1;
}
const int audioBaseIndex = (int)cap.get(CAP_PROP_AUDIO_BASE_INDEX);
const int numberOfChannels = (int)cap.get(CAP_PROP_AUDIO_TOTAL_CHANNELS);
cout << "CAP_PROP_AUDIO_DATA_DEPTH: " << depthToString((int)cap.get(CAP_PROP_AUDIO_DATA_DEPTH)) << endl;
cout << "CAP_PROP_AUDIO_SAMPLES_PER_SECOND: " << cap.get(CAP_PROP_AUDIO_SAMPLES_PER_SECOND) << endl;
cout << "CAP_PROP_AUDIO_TOTAL_CHANNELS: " << numberOfChannels << endl;
cout << "CAP_PROP_AUDIO_TOTAL_STREAMS: " << cap.get(CAP_PROP_AUDIO_TOTAL_STREAMS) << endl;
int numberOfSamples = 0;
audioData.resize(numberOfChannels);
for (;;)
{
if (cap.grab())
{
for (int nCh = 0; nCh < numberOfChannels; nCh++)
{
cap.retrieve(frame, audioBaseIndex+nCh);
audioData[nCh].push_back(frame);
numberOfSamples+=frame.cols;
}
}
else { break; }
}
cout << "Number of samples: " << numberOfSamples << endl;
return 0;
}
@@ -0,0 +1,69 @@
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
cv::CommandLineParser parser(argc, argv, "{@audio||}");
string file = parser.get<string>("@audio");
if (file.empty())
{
return 1;
}
Mat videoFrame;
Mat audioFrame;
vector<vector<Mat>> audioData;
VideoCapture cap;
vector<int> params { CAP_PROP_AUDIO_STREAM, 0,
CAP_PROP_VIDEO_STREAM, 0,
CAP_PROP_AUDIO_DATA_DEPTH, CV_16S };
cap.open(file, CAP_MSMF, params);
if (!cap.isOpened())
{
cerr << "ERROR! Can't to open file: " + file << endl;
return -1;
}
const int audioBaseIndex = (int)cap.get(CAP_PROP_AUDIO_BASE_INDEX);
const int numberOfChannels = (int)cap.get(CAP_PROP_AUDIO_TOTAL_CHANNELS);
cout << "CAP_PROP_AUDIO_DATA_DEPTH: " << depthToString((int)cap.get(CAP_PROP_AUDIO_DATA_DEPTH)) << endl;
cout << "CAP_PROP_AUDIO_SAMPLES_PER_SECOND: " << cap.get(CAP_PROP_AUDIO_SAMPLES_PER_SECOND) << endl;
cout << "CAP_PROP_AUDIO_TOTAL_CHANNELS: " << cap.get(CAP_PROP_AUDIO_TOTAL_CHANNELS) << endl;
cout << "CAP_PROP_AUDIO_TOTAL_STREAMS: " << cap.get(CAP_PROP_AUDIO_TOTAL_STREAMS) << endl;
int numberOfSamples = 0;
int numberOfFrames = 0;
audioData.resize(numberOfChannels);
for (;;)
{
if (cap.grab())
{
cap.retrieve(videoFrame);
for (int nCh = 0; nCh < numberOfChannels; nCh++)
{
cap.retrieve(audioFrame, audioBaseIndex+nCh);
if (!audioFrame.empty())
audioData[nCh].push_back(audioFrame);
numberOfSamples+=audioFrame.cols;
}
if (!videoFrame.empty())
{
numberOfFrames++;
imshow("Live", videoFrame);
if (waitKey(5) >= 0)
break;
}
} else { break; }
}
cout << "Number of audio samples: " << numberOfSamples << endl
<< "Number of video frames: " << numberOfFrames << endl;
return 0;
}
-352
View File
@@ -1,352 +0,0 @@
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
static bool g_printStreamSetting;
static int g_imageStreamProfileIdx;
static int g_depthStreamProfileIdx;
static bool g_irStreamShow;
static double g_imageBrightness;
static double g_imageContrast;
static bool g_printTiming;
static bool g_showClosedPoint;
static int g_closedDepthPoint[2];
static void printUsage(const char *arg0)
{
const char *filename = arg0;
while (*filename)
filename++;
while ((arg0 <= filename) && ('\\' != *filename) && ('/' != *filename))
filename--;
filename++;
cout << "This program demonstrates usage of camera supported\nby Intel Perceptual computing SDK." << endl << endl;
cout << "usage: " << filename << "[-ps] [-isp=IDX] [-dsp=IDX]\n [-ir] [-imb=VAL] [-imc=VAL]" << endl << endl;
cout << " -ps, print streams setting and profiles" << endl;
cout << " -isp=IDX, set profile index of the image stream" << endl;
cout << " -dsp=IDX, set profile index of the depth stream" << endl;
cout << " -ir, show data from IR stream" << endl;
cout << " -imb=VAL, set brightness value for an image stream" << endl;
cout << " -imc=VAL, set contrast value for a image stream" << endl;
cout << " -pts, print frame index and frame time" << endl;
cout << " --show-closed, print frame index and frame time" << endl;
cout << endl;
}
static void parseCMDLine(int argc, char* argv[])
{
cv::CommandLineParser parser(argc, argv,
"{ h help | | }"
"{ ps print-streams | | }"
"{ isp image-stream-prof | -1 | }"
"{ dsp depth-stream-prof | -1 | }"
"{ir||}{imb||}{imc||}{pts||}{show-closed||}");
if (parser.has("h"))
{
printUsage(argv[0]);
exit(0);
}
g_printStreamSetting = parser.has("ps");
g_imageStreamProfileIdx = parser.get<int>("isp");
g_depthStreamProfileIdx = parser.get<int>("dsp");
g_irStreamShow = parser.has("ir");
if (parser.has("imb"))
g_imageBrightness = parser.get<double>("imb");
else
g_imageBrightness = -DBL_MAX;
if (parser.has("imc"))
g_imageContrast = parser.get<double>("imc");
else
g_imageContrast = -DBL_MAX;
g_printTiming = parser.has("pts");
g_showClosedPoint = parser.has("show-closed");
if (!parser.check())
{
parser.printErrors();
exit(-1);
}
if (g_showClosedPoint && (-1 == g_depthStreamProfileIdx))
{
cerr << "For --show-closed depth profile has be selected" << endl;
exit(-1);
}
}
static void printStreamProperties(VideoCapture &capture)
{
size_t profilesCount = (size_t)capture.get(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_INTELPERC_PROFILE_COUNT);
cout << "Image stream." << endl;
cout << " Brightness = " << capture.get(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_BRIGHTNESS) << endl;
cout << " Contrast = " << capture.get(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_CONTRAST) << endl;
cout << " Saturation = " << capture.get(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_SATURATION) << endl;
cout << " Hue = " << capture.get(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_HUE) << endl;
cout << " Gamma = " << capture.get(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_GAMMA) << endl;
cout << " Sharpness = " << capture.get(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_SHARPNESS) << endl;
cout << " Gain = " << capture.get(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_GAIN) << endl;
cout << " Backligh = " << capture.get(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_BACKLIGHT) << endl;
cout << "Image streams profiles:" << endl;
for (size_t i = 0; i < profilesCount; i++)
{
capture.set(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_INTELPERC_PROFILE_IDX, (double)i);
cout << " Profile[" << i << "]: ";
cout << "width = " <<
(int)capture.get(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_FRAME_WIDTH);
cout << ", height = " <<
(int)capture.get(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_FRAME_HEIGHT);
cout << ", fps = " <<
capture.get(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_FPS);
cout << endl;
}
profilesCount = (size_t)capture.get(CAP_INTELPERC_DEPTH_GENERATOR | CAP_PROP_INTELPERC_PROFILE_COUNT);
cout << "Depth stream." << endl;
cout << " Low confidence value = " << capture.get(CAP_INTELPERC_DEPTH_GENERATOR | CAP_PROP_INTELPERC_DEPTH_LOW_CONFIDENCE_VALUE) << endl;
cout << " Saturation value = " << capture.get(CAP_INTELPERC_DEPTH_GENERATOR | CAP_PROP_INTELPERC_DEPTH_SATURATION_VALUE) << endl;
cout << " Confidence threshold = " << capture.get(CAP_INTELPERC_DEPTH_GENERATOR | CAP_PROP_INTELPERC_DEPTH_CONFIDENCE_THRESHOLD) << endl;
cout << " Focal length = (" << capture.get(CAP_INTELPERC_DEPTH_GENERATOR | CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_HORZ) << ", "
<< capture.get(CAP_INTELPERC_DEPTH_GENERATOR | CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_VERT) << ")" << endl;
cout << "Depth streams profiles:" << endl;
for (size_t i = 0; i < profilesCount; i++)
{
capture.set(CAP_INTELPERC_DEPTH_GENERATOR | CAP_PROP_INTELPERC_PROFILE_IDX, (double)i);
cout << " Profile[" << i << "]: ";
cout << "width = " <<
(int)capture.get(CAP_INTELPERC_DEPTH_GENERATOR | CAP_PROP_FRAME_WIDTH);
cout << ", height = " <<
(int)capture.get(CAP_INTELPERC_DEPTH_GENERATOR | CAP_PROP_FRAME_HEIGHT);
cout << ", fps = " <<
capture.get(CAP_INTELPERC_DEPTH_GENERATOR | CAP_PROP_FPS);
cout << endl;
}
}
static void imshowImage(const char *winname, Mat &image, VideoCapture &capture)
{
if (g_showClosedPoint)
{
Mat uvMap;
if (capture.retrieve(uvMap, CAP_INTELPERC_UVDEPTH_MAP))
{
float *uvmap = (float *)uvMap.ptr() + 2 * (g_closedDepthPoint[0] * uvMap.cols + g_closedDepthPoint[1]);
int x = (int)((*uvmap) * image.cols); uvmap++;
int y = (int)((*uvmap) * image.rows);
if ((0 <= x) && (0 <= y))
{
static const int pointSize = 4;
for (int row = y; row < min(y + pointSize, image.rows); row++)
{
uchar* ptrDst = image.ptr(row) + x * 3 + 2;//+2 -> Red
for (int col = 0; col < min(pointSize, image.cols - x); col++, ptrDst+=3)
{
*ptrDst = 255;
}
}
}
}
}
imshow(winname, image);
}
static void imshowIR(const char *winname, Mat &ir)
{
Mat image;
if (g_showClosedPoint)
{
image.create(ir.rows, ir.cols, CV_8UC3);
for (int row = 0; row < ir.rows; row++)
{
uchar* ptrDst = image.ptr(row);
short* ptrSrc = (short*)ir.ptr(row);
for (int col = 0; col < ir.cols; col++, ptrSrc++)
{
uchar val = (uchar) ((*ptrSrc) >> 2);
*ptrDst = val; ptrDst++;
*ptrDst = val; ptrDst++;
*ptrDst = val; ptrDst++;
}
}
static const int pointSize = 4;
for (int row = g_closedDepthPoint[0]; row < min(g_closedDepthPoint[0] + pointSize, image.rows); row++)
{
uchar* ptrDst = image.ptr(row) + g_closedDepthPoint[1] * 3 + 2;//+2 -> Red
for (int col = 0; col < min(pointSize, image.cols - g_closedDepthPoint[1]); col++, ptrDst+=3)
{
*ptrDst = 255;
}
}
}
else
{
image.create(ir.rows, ir.cols, CV_8UC1);
for (int row = 0; row < ir.rows; row++)
{
uchar* ptrDst = image.ptr(row);
short* ptrSrc = (short*)ir.ptr(row);
for (int col = 0; col < ir.cols; col++, ptrSrc++, ptrDst++)
{
*ptrDst = (uchar) ((*ptrSrc) >> 2);
}
}
}
imshow(winname, image);
}
static void imshowDepth(const char *winname, Mat &depth, VideoCapture &capture)
{
short lowValue = (short)capture.get(CAP_INTELPERC_DEPTH_GENERATOR | CAP_PROP_INTELPERC_DEPTH_LOW_CONFIDENCE_VALUE);
short saturationValue = (short)capture.get(CAP_INTELPERC_DEPTH_GENERATOR | CAP_PROP_INTELPERC_DEPTH_SATURATION_VALUE);
Mat image;
if (g_showClosedPoint)
{
image.create(depth.rows, depth.cols, CV_8UC3);
for (int row = 0; row < depth.rows; row++)
{
uchar* ptrDst = image.ptr(row);
short* ptrSrc = (short*)depth.ptr(row);
for (int col = 0; col < depth.cols; col++, ptrSrc++)
{
if ((lowValue == (*ptrSrc)) || (saturationValue == (*ptrSrc)))
{
*ptrDst = 0; ptrDst++;
*ptrDst = 0; ptrDst++;
*ptrDst = 0; ptrDst++;
}
else
{
uchar val = (uchar) ((*ptrSrc) >> 2);
*ptrDst = val; ptrDst++;
*ptrDst = val; ptrDst++;
*ptrDst = val; ptrDst++;
}
}
}
static const int pointSize = 4;
for (int row = g_closedDepthPoint[0]; row < min(g_closedDepthPoint[0] + pointSize, image.rows); row++)
{
uchar* ptrDst = image.ptr(row) + g_closedDepthPoint[1] * 3 + 2;//+2 -> Red
for (int col = 0; col < min(pointSize, image.cols - g_closedDepthPoint[1]); col++, ptrDst+=3)
{
*ptrDst = 255;
}
}
}
else
{
image.create(depth.rows, depth.cols, CV_8UC1);
for (int row = 0; row < depth.rows; row++)
{
uchar* ptrDst = image.ptr(row);
short* ptrSrc = (short*)depth.ptr(row);
for (int col = 0; col < depth.cols; col++, ptrSrc++, ptrDst++)
{
if ((lowValue == (*ptrSrc)) || (saturationValue == (*ptrSrc)))
*ptrDst = 0;
else
*ptrDst = (uchar) ((*ptrSrc) >> 2);
}
}
}
imshow(winname, image);
}
int main(int argc, char* argv[])
{
parseCMDLine(argc, argv);
VideoCapture capture;
capture.open(CAP_INTELPERC);
if (!capture.isOpened())
{
cerr << "Can not open a capture object." << endl;
return -1;
}
if (g_printStreamSetting)
printStreamProperties(capture);
if (-1 != g_imageStreamProfileIdx)
{
if (!capture.set(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_INTELPERC_PROFILE_IDX, (double)g_imageStreamProfileIdx))
{
cerr << "Can not setup a image stream." << endl;
return -1;
}
}
if (-1 != g_depthStreamProfileIdx)
{
if (!capture.set(CAP_INTELPERC_DEPTH_GENERATOR | CAP_PROP_INTELPERC_PROFILE_IDX, (double)g_depthStreamProfileIdx))
{
cerr << "Can not setup a depth stream." << endl;
return -1;
}
}
else if (g_irStreamShow)
{
if (!capture.set(CAP_INTELPERC_DEPTH_GENERATOR | CAP_PROP_INTELPERC_PROFILE_IDX, 0.0))
{
cerr << "Can not setup a IR stream." << endl;
return -1;
}
}
else
{
cout << "Streams not selected" << endl;
return 0;
}
//Setup additional properties only after set profile of the stream
if ( (-10000.0 < g_imageBrightness) && (g_imageBrightness < 10000.0))
capture.set(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_BRIGHTNESS, g_imageBrightness);
if ( (0 < g_imageContrast) && (g_imageContrast < 10000.0))
capture.set(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_BRIGHTNESS, g_imageContrast);
int frame = 0;
for(;;frame++)
{
Mat bgrImage;
Mat depthImage;
Mat irImage;
if (!capture.grab())
{
cout << "Can not grab images." << endl;
return -1;
}
if ((-1 != g_depthStreamProfileIdx) && (capture.retrieve(depthImage, CAP_INTELPERC_DEPTH_MAP)))
{
if (g_showClosedPoint)
{
double minVal = 0.0; double maxVal = 0.0;
minMaxIdx(depthImage, &minVal, &maxVal, g_closedDepthPoint);
}
imshowDepth("depth image", depthImage, capture);
}
if ((g_irStreamShow) && (capture.retrieve(irImage, CAP_INTELPERC_IR_MAP)))
imshowIR("ir image", irImage);
if ((-1 != g_imageStreamProfileIdx) && (capture.retrieve(bgrImage, CAP_INTELPERC_IMAGE)))
imshowImage("color image", bgrImage, capture);
if (g_printTiming)
{
cout << "Image frame: " << capture.get(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_POS_FRAMES)
<< ", Depth(IR) frame: " << capture.get(CAP_INTELPERC_DEPTH_GENERATOR | CAP_PROP_POS_FRAMES) << endl;
cout << "Image frame: " << capture.get(CAP_INTELPERC_IMAGE_GENERATOR | CAP_PROP_POS_MSEC)
<< ", Depth(IR) frame: " << capture.get(CAP_INTELPERC_DEPTH_GENERATOR | CAP_PROP_POS_MSEC) << endl;
}
if( waitKey(30) >= 0 )
break;
}
return 0;
}
+57
View File
@@ -0,0 +1,57 @@
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int, char**)
{
Mat frame;
vector<Mat> audioData;
VideoCapture cap;
vector<int> params { CAP_PROP_AUDIO_STREAM, 0,
CAP_PROP_VIDEO_STREAM, -1 };
cap.open(0, CAP_MSMF, params);
if (!cap.isOpened())
{
cerr << "ERROR! Can't to open microphone" << endl;
return -1;
}
const int audioBaseIndex = (int)cap.get(CAP_PROP_AUDIO_BASE_INDEX);
const int numberOfChannels = (int)cap.get(CAP_PROP_AUDIO_TOTAL_CHANNELS);
cout << "CAP_PROP_AUDIO_DATA_DEPTH: " << depthToString((int)cap.get(CAP_PROP_AUDIO_DATA_DEPTH)) << endl;
cout << "CAP_PROP_AUDIO_SAMPLES_PER_SECOND: " << cap.get(CAP_PROP_AUDIO_SAMPLES_PER_SECOND) << endl;
cout << "CAP_PROP_AUDIO_TOTAL_CHANNELS: " << numberOfChannels << endl;
cout << "CAP_PROP_AUDIO_TOTAL_STREAMS: " << cap.get(CAP_PROP_AUDIO_TOTAL_STREAMS) << endl;
const double cvTickFreq = getTickFrequency();
int64 sysTimeCurr = getTickCount();
int64 sysTimePrev = sysTimeCurr;
while ((sysTimeCurr-sysTimePrev)/cvTickFreq < 10)
{
if (cap.grab())
{
for (int nCh = 0; nCh < numberOfChannels; nCh++)
{
cap.retrieve(frame, audioBaseIndex+nCh);
audioData.push_back(frame);
sysTimeCurr = getTickCount();
}
}
else
{
cerr << "Grab error" << endl;
break;
}
}
int numberOfSamles = 0;
for (auto item : audioData)
numberOfSamles+=item.cols;
cout << "Number of samples: " << numberOfSamles << endl;
return 0;
}
+33
View File
@@ -0,0 +1,33 @@
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
using namespace cv;
using namespace std;
int main()
{
VideoCapture capture(CAP_INTELPERC);
for(;;)
{
Mat depthMap;
Mat image;
Mat irImage;
Mat adjMap;
capture.grab();
capture.retrieve(depthMap,CAP_INTELPERC_DEPTH_MAP);
capture.retrieve(image,CAP_INTELPERC_IMAGE);
capture.retrieve(irImage,CAP_INTELPERC_IR_MAP);
normalize(depthMap, adjMap, 0, 255, NORM_MINMAX, CV_8UC1);
applyColorMap(adjMap, adjMap, COLORMAP_JET);
imshow("RGB", image);
imshow("IR", irImage);
imshow("DEPTH", adjMap);
if( waitKey( 30 ) >= 0 )
break;
}
return 0;
}
+6 -6
View File
@@ -7,7 +7,7 @@ Check [a wiki](https://github.com/opencv/opencv/wiki/Deep-Learning-in-OpenCV) fo
If OpenCV is built with [Intel's Inference Engine support](https://github.com/opencv/opencv/wiki/Intel%27s-Deep-Learning-Inference-Engine-backend) you can use [Intel's pre-trained](https://github.com/opencv/open_model_zoo) models.
There are different preprocessing parameters such mean subtraction or scale factors for different models.
You may check the most popular models and their parameters at [models.yml](https://github.com/opencv/opencv/blob/master/samples/dnn/models.yml) configuration file. It might be also used for aliasing samples parameters. In example,
You may check the most popular models and their parameters at [models.yml](https://github.com/opencv/opencv/blob/5.x/samples/dnn/models.yml) configuration file. It might be also used for aliasing samples parameters. In example,
```bash
python object_detection.py opencv_fd --model /path/to/caffemodel --config /path/to/prototxt
@@ -27,7 +27,7 @@ You can download sample models using ```download_models.py```. For example, the
python download_models.py --save_dir FaceDetector opencv_fd
```
You can use default configuration files adopted for OpenCV from [here](https://github.com/opencv/opencv_extra/tree/master/testdata/dnn).
You can use default configuration files adopted for OpenCV from [here](https://github.com/opencv/opencv_extra/tree/5.x/testdata/dnn).
You also can use the script to download necessary files from your code. Assume you have the following code inside ```your_script.py```:
@@ -50,14 +50,14 @@ python your_script.py
**Note** that you can provide a directory using **save_dir** parameter or via **OPENCV_SAVE_DIR** environment variable.
#### Face detection
[An origin model](https://github.com/opencv/opencv/tree/master/samples/dnn/face_detector)
[An origin model](https://github.com/opencv/opencv/tree/5.x/samples/dnn/face_detector)
with single precision floating point weights has been quantized using [TensorFlow framework](https://www.tensorflow.org/).
To achieve the best accuracy run the model on BGR images resized to `300x300` applying mean subtraction
of values `(104, 177, 123)` for each blue, green and red channels correspondingly.
The following are accuracy metrics obtained using [COCO object detection evaluation
tool](http://cocodataset.org/#detections-eval) on [FDDB dataset](http://vis-www.cs.umass.edu/fddb/)
(see [script](https://github.com/opencv/opencv/blob/master/modules/dnn/misc/face_detector_accuracy.py))
(see [script](https://github.com/opencv/opencv/blob/5.x/modules/dnn/misc/face_detector_accuracy.py))
applying resize to `300x300` and keeping an origin images' sizes.
```
AP - Average Precision | FP32/FP16 | UINT8 | FP32/FP16 | UINT8 |
@@ -79,6 +79,6 @@ AR @[ IoU=0.50:0.95 | area= large | maxDets=100 ] | 0.528 | 0.528 |
## References
* [Models downloading script](https://github.com/opencv/opencv/samples/dnn/download_models.py)
* [Configuration files adopted for OpenCV](https://github.com/opencv/opencv_extra/tree/master/testdata/dnn)
* [Configuration files adopted for OpenCV](https://github.com/opencv/opencv_extra/tree/5.x/testdata/dnn)
* [How to import models from TensorFlow Object Detection API](https://github.com/opencv/opencv/wiki/TensorFlow-Object-Detection-API)
* [Names of classes from different datasets](https://github.com/opencv/opencv/tree/master/samples/data/dnn)
* [Names of classes from different datasets](https://github.com/opencv/opencv/tree/5.x/samples/data/dnn)
+55 -15
View File
@@ -1,5 +1,6 @@
#include <fstream>
#include <sstream>
#include <iostream>
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
@@ -17,6 +18,7 @@ std::string keys =
"{ std | 0.0 0.0 0.0 | Preprocess input image by dividing on a standard deviation.}"
"{ crop | false | Preprocess input image by center cropping.}"
"{ framework f | | Optional name of an origin framework of the model. Detect it automatically if it does not set. }"
"{ needSoftmax | false | Use Softmax to post-process the output of the net.}"
"{ classes | | Optional path to a text file with names of classes. }"
"{ backend | 0 | Choose one of computation backends: "
"0: automatically (by default), "
@@ -24,7 +26,8 @@ std::string keys =
"2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
"3: OpenCV implementation, "
"4: VKCOM, "
"5: CUDA },"
"5: CUDA, "
"6: WebNN }"
"{ target | 0 | Choose one of target computation devices: "
"0: CPU target (by default), "
"1: OpenCL, "
@@ -70,6 +73,9 @@ int main(int argc, char** argv)
String framework = parser.get<String>("framework");
int backendId = parser.get<int>("backend");
int targetId = parser.get<int>("target");
bool needSoftmax = parser.get<bool>("needSoftmax");
std::cout<<"mean: "<<mean<<std::endl;
std::cout<<"std: "<<std<<std::endl;
// Open file with classes names.
if (parser.has("classes"))
@@ -141,28 +147,62 @@ int main(int argc, char** argv)
net.setInput(blob);
//! [Set input blob]
//! [Make forward pass]
Mat prob = net.forward();
//! [Make forward pass]
//! [Get a class with a highest score]
Point classIdPoint;
// double t_sum = 0.0;
// double t;
int classId;
double confidence;
minMaxLoc(prob.reshape(1, 1), 0, &confidence, 0, &classIdPoint);
int classId = classIdPoint.x;
//! [Get a class with a highest score]
cv::TickMeter timeRecorder;
timeRecorder.reset();
Mat prob = net.forward();
double t1;
timeRecorder.start();
prob = net.forward();
timeRecorder.stop();
t1 = timeRecorder.getTimeMilli();
// Put efficiency information.
std::vector<double> layersTimes;
double freq = getTickFrequency() / 1000;
double t = net.getPerfProfile(layersTimes) / freq;
std::string label = format("Inference time: %.2f ms", t);
timeRecorder.reset();
for(int i = 0; i < 200; i++) {
//! [Make forward pass]
timeRecorder.start();
prob = net.forward();
timeRecorder.stop();
//! [Get a class with a highest score]
Point classIdPoint;
minMaxLoc(prob.reshape(1, 1), 0, &confidence, 0, &classIdPoint);
classId = classIdPoint.x;
//! [Get a class with a highest score]
// Put efficiency information.
// std::vector<double> layersTimes;
// double freq = getTickFrequency() / 1000;
// t = net.getPerfProfile(layersTimes) / freq;
// t_sum += t;
}
if (needSoftmax == true)
{
float maxProb = 0.0;
float sum = 0.0;
Mat softmaxProb;
maxProb = *std::max_element(prob.begin<float>(), prob.end<float>());
cv::exp(prob-maxProb, softmaxProb);
sum = (float)cv::sum(softmaxProb)[0];
softmaxProb /= sum;
Point classIdPoint;
minMaxLoc(softmaxProb.reshape(1, 1), 0, &confidence, 0, &classIdPoint);
classId = classIdPoint.x;
}
std::string label = format("Inference time of 1 round: %.2f ms", t1);
std::string label2 = format("Average time of 200 rounds: %.2f ms", timeRecorder.getTimeMilli()/200);
putText(frame, label, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));
putText(frame, label2, Point(0, 35), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));
// Print predicted class.
label = format("%s: %.4f", (classes.empty() ? format("Class #%d", classId).c_str() :
classes[classId].c_str()),
confidence);
putText(frame, label, Point(0, 40), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));
putText(frame, label, Point(0, 55), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));
imshow(kWinName, frame);
}
+201 -54
View File
@@ -8,125 +8,272 @@
using namespace cv;
using namespace std;
static Mat visualize(Mat input, Mat faces, int thickness=2)
static
void visualize(Mat& input, int frame, Mat& faces, double fps, int thickness = 2)
{
Mat output = input.clone();
std::string fpsString = cv::format("FPS : %.2f", (float)fps);
if (frame >= 0)
cout << "Frame " << frame << ", ";
cout << "FPS: " << fpsString << endl;
for (int i = 0; i < faces.rows; i++)
{
// Print results
cout << "Face " << i
<< ", top-left coordinates: (" << faces.at<float>(i, 0) << ", " << faces.at<float>(i, 1) << "), "
<< "box width: " << faces.at<float>(i, 2) << ", box height: " << faces.at<float>(i, 3) << ", "
<< "score: " << faces.at<float>(i, 14) << "\n";
<< "score: " << cv::format("%.2f", faces.at<float>(i, 14))
<< endl;
// Draw bounding box
rectangle(output, Rect2i(int(faces.at<float>(i, 0)), int(faces.at<float>(i, 1)), int(faces.at<float>(i, 2)), int(faces.at<float>(i, 3))), Scalar(0, 255, 0), thickness);
rectangle(input, Rect2i(int(faces.at<float>(i, 0)), int(faces.at<float>(i, 1)), int(faces.at<float>(i, 2)), int(faces.at<float>(i, 3))), Scalar(0, 255, 0), thickness);
// Draw landmarks
circle(output, Point2i(int(faces.at<float>(i, 4)), int(faces.at<float>(i, 5))), 2, Scalar(255, 0, 0), thickness);
circle(output, Point2i(int(faces.at<float>(i, 6)), int(faces.at<float>(i, 7))), 2, Scalar( 0, 0, 255), thickness);
circle(output, Point2i(int(faces.at<float>(i, 8)), int(faces.at<float>(i, 9))), 2, Scalar( 0, 255, 0), thickness);
circle(output, Point2i(int(faces.at<float>(i, 10)), int(faces.at<float>(i, 11))), 2, Scalar(255, 0, 255), thickness);
circle(output, Point2i(int(faces.at<float>(i, 12)), int(faces.at<float>(i, 13))), 2, Scalar( 0, 255, 255), thickness);
circle(input, Point2i(int(faces.at<float>(i, 4)), int(faces.at<float>(i, 5))), 2, Scalar(255, 0, 0), thickness);
circle(input, Point2i(int(faces.at<float>(i, 6)), int(faces.at<float>(i, 7))), 2, Scalar(0, 0, 255), thickness);
circle(input, Point2i(int(faces.at<float>(i, 8)), int(faces.at<float>(i, 9))), 2, Scalar(0, 255, 0), thickness);
circle(input, Point2i(int(faces.at<float>(i, 10)), int(faces.at<float>(i, 11))), 2, Scalar(255, 0, 255), thickness);
circle(input, Point2i(int(faces.at<float>(i, 12)), int(faces.at<float>(i, 13))), 2, Scalar(0, 255, 255), thickness);
}
return output;
putText(input, fpsString, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 2);
}
int main(int argc, char ** argv)
int main(int argc, char** argv)
{
CommandLineParser parser(argc, argv,
"{help h | | Print this message.}"
"{input i | | Path to the input image. Omit for detecting on default camera.}"
"{model m | yunet.onnx | Path to the model. Download yunet.onnx in https://github.com/ShiqiYu/libfacedetection.train/tree/master/tasks/task1/onnx.}"
"{score_threshold | 0.9 | Filter out faces of score < score_threshold.}"
"{nms_threshold | 0.3 | Suppress bounding boxes of iou >= nms_threshold.}"
"{top_k | 5000 | Keep top_k bounding boxes before NMS.}"
"{save s | false | Set true to save results. This flag is invalid when using camera.}"
"{vis v | true | Set true to open a window for result visualization. This flag is invalid when using camera.}"
"{help h | | Print this message}"
"{image1 i1 | | Path to the input image1. Omit for detecting through VideoCapture}"
"{image2 i2 | | Path to the input image2. When image1 and image2 parameters given then the program try to find a face on both images and runs face recognition algorithm}"
"{video v | 0 | Path to the input video}"
"{scale sc | 1.0 | Scale factor used to resize input video frames}"
"{fd_model fd | yunet.onnx | Path to the model. Download yunet.onnx in https://github.com/ShiqiYu/libfacedetection.train/tree/master/tasks/task1/onnx }"
"{fr_model fr | face_recognizer_fast.onnx | Path to the face recognition model. Download the model at https://drive.google.com/file/d/1ClK9WiB492c5OZFKveF3XiHCejoOxINW/view}"
"{score_threshold | 0.9 | Filter out faces of score < score_threshold}"
"{nms_threshold | 0.3 | Suppress bounding boxes of iou >= nms_threshold}"
"{top_k | 5000 | Keep top_k bounding boxes before NMS}"
"{save s | false | Set true to save results. This flag is invalid when using camera}"
);
if (argc == 1 || parser.has("help"))
if (parser.has("help"))
{
parser.printMessage();
return -1;
return 0;
}
String modelPath = parser.get<String>("model");
String fd_modelPath = parser.get<String>("fd_model");
String fr_modelPath = parser.get<String>("fr_model");
float scoreThreshold = parser.get<float>("score_threshold");
float nmsThreshold = parser.get<float>("nms_threshold");
int topK = parser.get<int>("top_k");
bool save = parser.get<bool>("save");
bool vis = parser.get<bool>("vis");
double cosine_similar_thresh = 0.363;
double l2norm_similar_thresh = 1.128;
//! [initialize_FaceDetectorYN]
// Initialize FaceDetectorYN
Ptr<FaceDetectorYN> detector = FaceDetectorYN::create(modelPath, "", Size(320, 320), scoreThreshold, nmsThreshold, topK);
Ptr<FaceDetectorYN> detector = FaceDetectorYN::create(fd_modelPath, "", Size(320, 320), scoreThreshold, nmsThreshold, topK);
//! [initialize_FaceDetectorYN]
TickMeter tm;
// If input is an image
if (parser.has("input"))
if (parser.has("image1"))
{
String input = parser.get<String>("input");
Mat image = imread(input);
String input1 = parser.get<String>("image1");
Mat image1 = imread(samples::findFile(input1));
if (image1.empty())
{
std::cerr << "Cannot read image: " << input1 << std::endl;
return 2;
}
tm.start();
//! [inference]
// Set input size before inference
detector->setInputSize(image.size());
detector->setInputSize(image1.size());
// Inference
Mat faces;
detector->detect(image, faces);
Mat faces1;
detector->detect(image1, faces1);
if (faces1.rows < 1)
{
std::cerr << "Cannot find a face in " << input1 << std::endl;
return 1;
}
//! [inference]
tm.stop();
// Draw results on the input image
Mat result = visualize(image, faces);
visualize(image1, -1, faces1, tm.getFPS());
// Save results if save is true
if(save)
if (save)
{
cout << "Results saved to result.jpg\n";
imwrite("result.jpg", result);
cout << "Saving result.jpg...\n";
imwrite("result.jpg", image1);
}
// Visualize results
if (vis)
imshow("image1", image1);
pollKey(); // handle UI events to show content
if (parser.has("image2"))
{
namedWindow(input, WINDOW_AUTOSIZE);
imshow(input, result);
waitKey(0);
String input2 = parser.get<String>("image2");
Mat image2 = imread(samples::findFile(input2));
if (image2.empty())
{
std::cerr << "Cannot read image2: " << input2 << std::endl;
return 2;
}
tm.reset();
tm.start();
detector->setInputSize(image2.size());
Mat faces2;
detector->detect(image2, faces2);
if (faces2.rows < 1)
{
std::cerr << "Cannot find a face in " << input2 << std::endl;
return 1;
}
tm.stop();
visualize(image2, -1, faces2, tm.getFPS());
if (save)
{
cout << "Saving result2.jpg...\n";
imwrite("result2.jpg", image2);
}
imshow("image2", image2);
pollKey();
//! [initialize_FaceRecognizerSF]
// Initialize FaceRecognizerSF
Ptr<FaceRecognizerSF> faceRecognizer = FaceRecognizerSF::create(fr_modelPath, "");
//! [initialize_FaceRecognizerSF]
//! [facerecognizer]
// Aligning and cropping facial image through the first face of faces detected.
Mat aligned_face1, aligned_face2;
faceRecognizer->alignCrop(image1, faces1.row(0), aligned_face1);
faceRecognizer->alignCrop(image2, faces2.row(0), aligned_face2);
// Run feature extraction with given aligned_face
Mat feature1, feature2;
faceRecognizer->feature(aligned_face1, feature1);
feature1 = feature1.clone();
faceRecognizer->feature(aligned_face2, feature2);
feature2 = feature2.clone();
//! [facerecognizer]
//! [match]
double cos_score = faceRecognizer->match(feature1, feature2, FaceRecognizerSF::DisType::FR_COSINE);
double L2_score = faceRecognizer->match(feature1, feature2, FaceRecognizerSF::DisType::FR_NORM_L2);
//! [match]
if (cos_score >= cosine_similar_thresh)
{
std::cout << "They have the same identity;";
}
else
{
std::cout << "They have different identities;";
}
std::cout << " Cosine Similarity: " << cos_score << ", threshold: " << cosine_similar_thresh << ". (higher value means higher similarity, max 1.0)\n";
if (L2_score <= l2norm_similar_thresh)
{
std::cout << "They have the same identity;";
}
else
{
std::cout << "They have different identities.";
}
std::cout << " NormL2 Distance: " << L2_score << ", threshold: " << l2norm_similar_thresh << ". (lower value means higher similarity, min 0.0)\n";
}
cout << "Press any key to exit..." << endl;
waitKey(0);
}
else
{
int deviceId = 0;
VideoCapture cap;
cap.open(deviceId, CAP_ANY);
int frameWidth = int(cap.get(CAP_PROP_FRAME_WIDTH));
int frameHeight = int(cap.get(CAP_PROP_FRAME_HEIGHT));
int frameWidth, frameHeight;
float scale = parser.get<float>("scale");
VideoCapture capture;
std::string video = parser.get<string>("video");
if (video.size() == 1 && isdigit(video[0]))
capture.open(parser.get<int>("video"));
else
capture.open(samples::findFileOrKeep(video)); // keep GStreamer pipelines
if (capture.isOpened())
{
frameWidth = int(capture.get(CAP_PROP_FRAME_WIDTH) * scale);
frameHeight = int(capture.get(CAP_PROP_FRAME_HEIGHT) * scale);
cout << "Video " << video
<< ": width=" << frameWidth
<< ", height=" << frameHeight
<< endl;
}
else
{
cout << "Could not initialize video capturing: " << video << "\n";
return 1;
}
detector->setInputSize(Size(frameWidth, frameHeight));
Mat frame;
TickMeter tm;
String msg = "FPS: ";
while(waitKey(1) < 0) // Press any key to exit
cout << "Press 'SPACE' to save frame, any other key to exit..." << endl;
int nFrame = 0;
for (;;)
{
// Get frame
if (!cap.read(frame))
Mat frame;
if (!capture.read(frame))
{
cerr << "No frames grabbed!\n";
cerr << "Can't grab frame! Stop\n";
break;
}
resize(frame, frame, Size(frameWidth, frameHeight));
// Inference
Mat faces;
tm.start();
detector->detect(frame, faces);
tm.stop();
Mat result = frame.clone();
// Draw results on the input image
Mat result = visualize(frame, faces);
putText(result, msg + to_string(tm.getFPS()), Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));
visualize(result, nFrame, faces, tm.getFPS());
// Visualize results
imshow("Live", result);
tm.reset();
int key = waitKey(1);
bool saveFrame = save;
if (key == ' ')
{
saveFrame = true;
key = 0; // handled
}
if (saveFrame)
{
std::string frame_name = cv::format("frame_%05d.png", nFrame);
std::string result_name = cv::format("result_%05d.jpg", nFrame);
cout << "Saving '" << frame_name << "' and '" << result_name << "' ...\n";
imwrite(frame_name, frame);
imwrite(result_name, result);
}
++nFrame;
if (key > 0)
break;
}
cout << "Processed " << nFrame << " frames" << endl;
}
}
cout << "Done." << endl;
return 0;
}
+90 -36
View File
@@ -12,90 +12,144 @@ def str2bool(v):
raise NotImplementedError
parser = argparse.ArgumentParser()
parser.add_argument('--input', '-i', type=str, help='Path to the input image.')
parser.add_argument('--model', '-m', type=str, default='yunet.onnx', help='Path to the model. Download the model at https://github.com/ShiqiYu/libfacedetection.train/tree/master/tasks/task1/onnx.')
parser.add_argument('--image1', '-i1', type=str, help='Path to the input image1. Omit for detecting on default camera.')
parser.add_argument('--image2', '-i2', type=str, help='Path to the input image2. When image1 and image2 parameters given then the program try to find a face on both images and runs face recognition algorithm.')
parser.add_argument('--video', '-v', type=str, help='Path to the input video.')
parser.add_argument('--scale', '-sc', type=float, default=1.0, help='Scale factor used to resize input video frames.')
parser.add_argument('--face_detection_model', '-fd', type=str, default='yunet.onnx', help='Path to the face detection model. Download the model at https://github.com/ShiqiYu/libfacedetection.train/tree/master/tasks/task1/onnx.')
parser.add_argument('--face_recognition_model', '-fr', type=str, default='face_recognizer_fast.onnx', help='Path to the face recognition model. Download the model at https://drive.google.com/file/d/1ClK9WiB492c5OZFKveF3XiHCejoOxINW/view.')
parser.add_argument('--score_threshold', type=float, default=0.9, help='Filtering out faces of score < score_threshold.')
parser.add_argument('--nms_threshold', type=float, default=0.3, help='Suppress bounding boxes of iou >= nms_threshold.')
parser.add_argument('--top_k', type=int, default=5000, help='Keep top_k bounding boxes before NMS.')
parser.add_argument('--save', '-s', type=str2bool, default=False, help='Set true to save results. This flag is invalid when using camera.')
parser.add_argument('--vis', '-v', type=str2bool, default=True, help='Set true to open a window for result visualization. This flag is invalid when using camera.')
args = parser.parse_args()
def visualize(input, faces, thickness=2):
output = input.copy()
def visualize(input, faces, fps, thickness=2):
if faces[1] is not None:
for idx, face in enumerate(faces[1]):
print('Face {}, top-left coordinates: ({:.0f}, {:.0f}), box width: {:.0f}, box height {:.0f}, score: {:.2f}'.format(idx, face[0], face[1], face[2], face[3], face[-1]))
coords = face[:-1].astype(np.int32)
cv.rectangle(output, (coords[0], coords[1]), (coords[0]+coords[2], coords[1]+coords[3]), (0, 255, 0), 2)
cv.circle(output, (coords[4], coords[5]), 2, (255, 0, 0), 2)
cv.circle(output, (coords[6], coords[7]), 2, (0, 0, 255), 2)
cv.circle(output, (coords[8], coords[9]), 2, (0, 255, 0), 2)
cv.circle(output, (coords[10], coords[11]), 2, (255, 0, 255), 2)
cv.circle(output, (coords[12], coords[13]), 2, (0, 255, 255), 2)
return output
cv.rectangle(input, (coords[0], coords[1]), (coords[0]+coords[2], coords[1]+coords[3]), (0, 255, 0), thickness)
cv.circle(input, (coords[4], coords[5]), 2, (255, 0, 0), thickness)
cv.circle(input, (coords[6], coords[7]), 2, (0, 0, 255), thickness)
cv.circle(input, (coords[8], coords[9]), 2, (0, 255, 0), thickness)
cv.circle(input, (coords[10], coords[11]), 2, (255, 0, 255), thickness)
cv.circle(input, (coords[12], coords[13]), 2, (0, 255, 255), thickness)
cv.putText(input, 'FPS: {:.2f}'.format(fps), (1, 16), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
if __name__ == '__main__':
# Instantiate FaceDetectorYN
## [initialize_FaceDetectorYN]
detector = cv.FaceDetectorYN.create(
args.model,
args.face_detection_model,
"",
(320, 320),
args.score_threshold,
args.nms_threshold,
args.top_k
)
## [initialize_FaceDetectorYN]
tm = cv.TickMeter()
# If input is an image
if args.input is not None:
image = cv.imread(args.input)
if args.image1 is not None:
img1 = cv.imread(cv.samples.findFile(args.image1))
tm.start()
## [inference]
# Set input size before inference
detector.setInputSize((image.shape[1], image.shape[0]))
detector.setInputSize((img1.shape[1], img1.shape[0]))
# Inference
faces = detector.detect(image)
faces1 = detector.detect(img1)
## [inference]
tm.stop()
assert faces1[1] is not None, 'Cannot find a face in {}'.format(args.image1)
# Draw results on the input image
result = visualize(image, faces)
visualize(img1, faces1, tm.getFPS())
# Save results if save is true
if args.save:
print('Resutls saved to result.jpg\n')
cv.imwrite('result.jpg', result)
print('Results saved to result.jpg\n')
cv.imwrite('result.jpg', img1)
# Visualize results in a new window
if args.vis:
cv.namedWindow(args.input, cv.WINDOW_AUTOSIZE)
cv.imshow(args.input, result)
cv.waitKey(0)
cv.imshow("image1", img1)
if args.image2 is not None:
img2 = cv.imread(cv.samples.findFile(args.image2))
tm.reset()
tm.start()
detector.setInputSize((img2.shape[1], img2.shape[0]))
faces2 = detector.detect(img2)
tm.stop()
assert faces2[1] is not None, 'Cannot find a face in {}'.format(args.image2)
visualize(img2, faces2, tm.getFPS())
cv.imshow("image2", img2)
## [initialize_FaceRecognizerSF]
recognizer = cv.FaceRecognizerSF.create(
args.face_recognition_model,"")
## [initialize_FaceRecognizerSF]
## [facerecognizer]
# Align faces
face1_align = recognizer.alignCrop(img1, faces1[1][0])
face2_align = recognizer.alignCrop(img2, faces2[1][0])
# Extract features
face1_feature = recognizer.feature(face1_align)
face2_feature = recognizer.feature(face2_align)
## [facerecognizer]
cosine_similarity_threshold = 0.363
l2_similarity_threshold = 1.128
## [match]
cosine_score = recognizer.match(face1_feature, face2_feature, cv.FaceRecognizerSF_FR_COSINE)
l2_score = recognizer.match(face1_feature, face2_feature, cv.FaceRecognizerSF_FR_NORM_L2)
## [match]
msg = 'different identities'
if cosine_score >= cosine_similarity_threshold:
msg = 'the same identity'
print('They have {}. Cosine Similarity: {}, threshold: {} (higher value means higher similarity, max 1.0).'.format(msg, cosine_score, cosine_similarity_threshold))
msg = 'different identities'
if l2_score <= l2_similarity_threshold:
msg = 'the same identity'
print('They have {}. NormL2 Distance: {}, threshold: {} (lower value means higher similarity, min 0.0).'.format(msg, l2_score, l2_similarity_threshold))
cv.waitKey(0)
else: # Omit input to call default camera
deviceId = 0
if args.video is not None:
deviceId = args.video
else:
deviceId = 0
cap = cv.VideoCapture(deviceId)
frameWidth = int(cap.get(cv.CAP_PROP_FRAME_WIDTH))
frameHeight = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT))
frameWidth = int(cap.get(cv.CAP_PROP_FRAME_WIDTH)*args.scale)
frameHeight = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT)*args.scale)
detector.setInputSize([frameWidth, frameHeight])
tm = cv.TickMeter()
while cv.waitKey(1) < 0:
hasFrame, frame = cap.read()
if not hasFrame:
print('No frames grabbed!')
break
frame = cv.resize(frame, (frameWidth, frameHeight))
# Inference
tm.start()
faces = detector.detect(frame) # faces is a tuple
tm.stop()
# Draw results on the input image
frame = visualize(frame, faces)
visualize(frame, faces, tm.getFPS())
cv.putText(frame, 'FPS: {}'.format(tm.getFPS()), (0, 15), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0))
# Visualize results in a new Window
# Visualize results
cv.imshow('Live', frame)
tm.reset()
cv.destroyAllWindows()
-103
View File
@@ -1,103 +0,0 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "opencv2/dnn.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
#include "opencv2/objdetect.hpp"
using namespace cv;
using namespace std;
int main(int argc, char ** argv)
{
if (argc != 5)
{
std::cerr << "Usage " << argv[0] << ": "
<< "<det_onnx_path> "
<< "<reg_onnx_path> "
<< "<image1>"
<< "<image2>\n";
return -1;
}
String det_onnx_path = argv[1];
String reg_onnx_path = argv[2];
String image1_path = argv[3];
String image2_path = argv[4];
std::cout<<image1_path<<" "<<image2_path<<std::endl;
Mat image1 = imread(image1_path);
Mat image2 = imread(image2_path);
float score_thresh = 0.9f;
float nms_thresh = 0.3f;
double cosine_similar_thresh = 0.363;
double l2norm_similar_thresh = 1.128;
int top_k = 5000;
// Initialize FaceDetector
Ptr<FaceDetectorYN> faceDetector;
faceDetector = FaceDetectorYN::create(det_onnx_path, "", image1.size(), score_thresh, nms_thresh, top_k);
Mat faces_1;
faceDetector->detect(image1, faces_1);
if (faces_1.rows < 1)
{
std::cerr << "Cannot find a face in " << image1_path << "\n";
return -1;
}
faceDetector = FaceDetectorYN::create(det_onnx_path, "", image2.size(), score_thresh, nms_thresh, top_k);
Mat faces_2;
faceDetector->detect(image2, faces_2);
if (faces_2.rows < 1)
{
std::cerr << "Cannot find a face in " << image2_path << "\n";
return -1;
}
// Initialize FaceRecognizerSF
Ptr<FaceRecognizerSF> faceRecognizer = FaceRecognizerSF::create(reg_onnx_path, "");
Mat aligned_face1, aligned_face2;
faceRecognizer->alignCrop(image1, faces_1.row(0), aligned_face1);
faceRecognizer->alignCrop(image2, faces_2.row(0), aligned_face2);
Mat feature1, feature2;
faceRecognizer->feature(aligned_face1, feature1);
feature1 = feature1.clone();
faceRecognizer->feature(aligned_face2, feature2);
feature2 = feature2.clone();
double cos_score = faceRecognizer->match(feature1, feature2, FaceRecognizerSF::DisType::FR_COSINE);
double L2_score = faceRecognizer->match(feature1, feature2, FaceRecognizerSF::DisType::FR_NORM_L2);
if(cos_score >= cosine_similar_thresh)
{
std::cout << "They have the same identity;";
}
else
{
std::cout << "They have different identities;";
}
std::cout << " Cosine Similarity: " << cos_score << ", threshold: " << cosine_similar_thresh << ". (higher value means higher similarity, max 1.0)\n";
if(L2_score <= l2norm_similar_thresh)
{
std::cout << "They have the same identity;";
}
else
{
std::cout << "They have different identities.";
}
std::cout << " NormL2 Distance: " << L2_score << ", threshold: " << l2norm_similar_thresh << ". (lower value means higher similarity, min 0.0)\n";
return 0;
}
-57
View File
@@ -1,57 +0,0 @@
import argparse
import numpy as np
import cv2 as cv
parser = argparse.ArgumentParser()
parser.add_argument('--input1', '-i1', type=str, help='Path to the input image1.')
parser.add_argument('--input2', '-i2', type=str, help='Path to the input image2.')
parser.add_argument('--face_detection_model', '-fd', type=str, help='Path to the face detection model. Download the model at https://github.com/ShiqiYu/libfacedetection.train/tree/master/tasks/task1/onnx.')
parser.add_argument('--face_recognition_model', '-fr', type=str, help='Path to the face recognition model. Download the model at https://drive.google.com/file/d/1ClK9WiB492c5OZFKveF3XiHCejoOxINW/view.')
args = parser.parse_args()
# Read the input image
img1 = cv.imread(args.input1)
img2 = cv.imread(args.input2)
# Instantiate face detector and recognizer
detector = cv.FaceDetectorYN.create(
args.face_detection_model,
"",
(img1.shape[1], img1.shape[0])
)
recognizer = cv.FaceRecognizerSF.create(
args.face_recognition_model,
""
)
# Detect face
detector.setInputSize((img1.shape[1], img1.shape[0]))
face1 = detector.detect(img1)
detector.setInputSize((img2.shape[1], img2.shape[0]))
face2 = detector.detect(img2)
assert face1[1].shape[0] > 0, 'Cannot find a face in {}'.format(args.input1)
assert face2[1].shape[0] > 0, 'Cannot find a face in {}'.format(args.input2)
# Align faces
face1_align = recognizer.alignCrop(img1, face1[1][0])
face2_align = recognizer.alignCrop(img2, face2[1][0])
# Extract features
face1_feature = recognizer.faceFeature(face1_align)
face2_feature = recognizer.faceFeature(face2_align)
# Calculate distance (0: cosine, 1: L2)
cosine_similarity_threshold = 0.363
cosine_score = recognizer.faceMatch(face1_feature, face2_feature, 0)
msg = 'different identities'
if cosine_score >= cosine_similarity_threshold:
msg = 'the same identity'
print('They have {}. Cosine Similarity: {}, threshold: {} (higher value means higher similarity, max 1.0).'.format(msg, cosine_score, cosine_similarity_threshold))
l2_similarity_threshold = 1.128
l2_score = recognizer.faceMatch(face1_feature, face2_feature, 1)
msg = 'different identities'
if l2_score <= l2_similarity_threshold:
msg = 'the same identity'
print('They have {}. NormL2 Distance: {}, threshold: {} (lower value means higher similarity, min 0.0).'.format(msg, l2_score, l2_similarity_threshold))
+1 -1
View File
@@ -69,7 +69,7 @@ function recognize(face) {
function loadModels(callback) {
var utils = new Utils('');
var proto = 'https://raw.githubusercontent.com/opencv/opencv/master/samples/dnn/face_detector/deploy_lowres.prototxt';
var proto = 'https://raw.githubusercontent.com/opencv/opencv/5.x/samples/dnn/face_detector/deploy_lowres.prototxt';
var weights = 'https://raw.githubusercontent.com/opencv/opencv_3rdparty/dnn_samples_face_detector_20180205_fp16/res10_300x300_ssd_iter_140000_fp16.caffemodel';
var recognModel = 'https://raw.githubusercontent.com/pyannote/pyannote-data/master/openface.nn4.small2.v1.t7';
utils.createFileFromUrl('face_detector.prototxt', proto, () => {
+10 -6
View File
@@ -5,7 +5,11 @@
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#ifdef CV_CXX11
#if defined(CV_CXX11) && defined(HAVE_THREADS)
#define USE_THREADS 1
#endif
#ifdef USE_THREADS
#include <mutex>
#include <thread>
#include <queue>
@@ -56,7 +60,7 @@ void drawPred(int classId, float conf, int left, int top, int right, int bottom,
void callback(int pos, void* userdata);
#ifdef CV_CXX11
#ifdef USE_THREADS
template <typename T>
class QueueFPS : public std::queue<T>
{
@@ -106,7 +110,7 @@ private:
TickMeter tm;
std::mutex mutex;
};
#endif // CV_CXX11
#endif // USE_THREADS
int main(int argc, char** argv)
{
@@ -171,7 +175,7 @@ int main(int argc, char** argv)
else
cap.open(parser.get<int>("device"));
#ifdef CV_CXX11
#ifdef USE_THREADS
bool process = true;
// Frames capturing thread
@@ -271,7 +275,7 @@ int main(int argc, char** argv)
framesThread.join();
processingThread.join();
#else // CV_CXX11
#else // USE_THREADS
if (asyncNumReq)
CV_Error(Error::StsNotImplemented, "Asynchronous forward is supported only with Inference Engine backend.");
@@ -302,7 +306,7 @@ int main(int argc, char** argv)
imshow(kWinName, frame);
}
#endif // CV_CXX11
#endif // USE_THREADS
return 0;
}
+2 -2
View File
@@ -3,11 +3,11 @@
//
// it can be used for body pose detection, using either the COCO model(18 parts):
// http://posefs1.perception.cs.cmu.edu/OpenPose/models/pose/coco/pose_iter_440000.caffemodel
// https://raw.githubusercontent.com/opencv/opencv_extra/master/testdata/dnn/openpose_pose_coco.prototxt
// https://raw.githubusercontent.com/opencv/opencv_extra/5.x/testdata/dnn/openpose_pose_coco.prototxt
//
// or the MPI model(16 parts):
// http://posefs1.perception.cs.cmu.edu/OpenPose/models/pose/mpi/pose_iter_160000.caffemodel
// https://raw.githubusercontent.com/opencv/opencv_extra/master/testdata/dnn/openpose_pose_mpi_faster_4_stages.prototxt
// https://raw.githubusercontent.com/opencv/opencv_extra/5.x/testdata/dnn/openpose_pose_mpi_faster_4_stages.prototxt
//
// (to simplify this sample, the body models are restricted to a single person.)
//
+1 -1
View File
@@ -300,7 +300,7 @@ class SiamRPNTracker:
# clip boundary
cx, cy, width, height = self._bbox_clip(cx, cy, width, height, img.shape[:2])
# udpate state
# update state
self.center_pos = np.array([cx, cy])
self.w = width
self.h = height
+87 -26
View File
@@ -2,7 +2,6 @@ import numpy as np
import cv2 as cv
import argparse
import os
import soundfile as sf # Temporary import to load audio files
'''
You can download the converted onnx model from https://drive.google.com/drive/folders/1wLtxyao4ItAg8tt4Sb63zt6qXzhcQoR6?usp=sharing
@@ -399,11 +398,6 @@ def predict(features, net, decoder):
decoder : Decoder object
return : Predicted text
'''
# This is a workaround https://github.com/opencv/opencv/issues/19091
# expanding 1 dimentions allows us to pass it to the network
# from python. This should be resolved in the future.
features = np.expand_dims(features,axis=3)
# make prediction
net.setInput(features)
output = net.forward()
@@ -412,6 +406,63 @@ def predict(features, net, decoder):
prediction = decoder.decode(output.squeeze(0))
return prediction[0]
def readAudioFile(file, audioStream):
cap = cv.VideoCapture(file)
samplingRate = 16000
params = np.asarray([cv.CAP_PROP_AUDIO_STREAM, audioStream,
cv.CAP_PROP_VIDEO_STREAM, -1,
cv.CAP_PROP_AUDIO_DATA_DEPTH, cv.CV_32F,
cv.CAP_PROP_AUDIO_SAMPLES_PER_SECOND, samplingRate
])
cap.open(file, cv.CAP_ANY, params)
if cap.isOpened() is False:
print("Error : Can't read audio file:", file, "with audioStream = ", audioStream)
return
audioBaseIndex = int (cap.get(cv.CAP_PROP_AUDIO_BASE_INDEX))
inputAudio = []
while(1):
if (cap.grab()):
frame = np.asarray([])
frame = cap.retrieve(frame, audioBaseIndex)
for i in range(len(frame[1][0])):
inputAudio.append(frame[1][0][i])
else:
break
inputAudio = np.asarray(inputAudio, dtype=np.float64)
return inputAudio, samplingRate
def readAudioMicrophone(microTime):
cap = cv.VideoCapture()
samplingRate = 16000
params = np.asarray([cv.CAP_PROP_AUDIO_STREAM, 0,
cv.CAP_PROP_VIDEO_STREAM, -1,
cv.CAP_PROP_AUDIO_DATA_DEPTH, cv.CV_32F,
cv.CAP_PROP_AUDIO_SAMPLES_PER_SECOND, samplingRate
])
cap.open(0, cv.CAP_ANY, params)
if cap.isOpened() is False:
print("Error: Can't open microphone")
print("Error: problems with audio reading, check input arguments")
return
audioBaseIndex = int(cap.get(cv.CAP_PROP_AUDIO_BASE_INDEX))
cvTickFreq = cv.getTickFrequency()
sysTimeCurr = cv.getTickCount()
sysTimePrev = sysTimeCurr
inputAudio = []
while ((sysTimeCurr - sysTimePrev) / cvTickFreq < microTime):
if (cap.grab()):
frame = np.asarray([])
frame = cap.retrieve(frame, audioBaseIndex)
for i in range(len(frame[1][0])):
inputAudio.append(frame[1][0][i])
sysTimeCurr = cv.getTickCount()
else:
print("Error: Grab error")
break
inputAudio = np.asarray(inputAudio, dtype=np.float64)
print("Number of samples: ", len(inputAudio))
return inputAudio, samplingRate
if __name__ == '__main__':
# Computation backends supported by layers
@@ -421,7 +472,10 @@ if __name__ == '__main__':
parser = argparse.ArgumentParser(description='This script runs Jasper Speech recognition model',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--input_audio', type=str, required=True, help='Path to input audio file. OR Path to a txt file with relative path to multiple audio files in different lines')
parser.add_argument('--input_type', type=str, required=True, help='file or microphone')
parser.add_argument('--micro_time', type=int, default=15, help='Duration of microphone work in seconds. Must be more than 6 sec')
parser.add_argument('--input_audio', type=str, help='Path to input audio file. OR Path to a txt file with relative path to multiple audio files in different lines')
parser.add_argument('--audio_stream', type=int, default=0, help='CAP_PROP_AUDIO_STREAM value')
parser.add_argument('--show_spectrogram', action='store_true', help='Whether to show a spectrogram of the input audio.')
parser.add_argument('--model', type=str, default='jasper.onnx', help='Path to the onnx file of Jasper. default="jasper.onnx"')
parser.add_argument('--output', type=str, help='Path to file where recognized audio transcript must be saved. Leave this to print on console.')
@@ -442,28 +496,35 @@ if __name__ == '__main__':
raise OSError("Input audio file does not exist")
if not os.path.isfile(args.model):
raise OSError("Jasper model file does not exist")
if args.input_audio.endswith('.txt'):
with open(args.input_audio) as f:
content = f.readlines()
content = [x.strip() for x in content]
audio_file_paths = content
for audio_file_path in audio_file_paths:
if not os.path.isfile(audio_file_path):
raise OSError("Audio file({audio_file_path}) does not exist")
else:
audio_file_paths = [args.input_audio]
audio_file_paths = [os.path.abspath(x) for x in audio_file_paths]
# Read audio Files
features = []
try:
if args.input_type == "file":
if args.input_audio.endswith('.txt'):
with open(args.input_audio) as f:
content = f.readlines()
content = [x.strip() for x in content]
audio_file_paths = content
for audio_file_path in audio_file_paths:
if not os.path.isfile(audio_file_path):
raise OSError("Audio file({audio_file_path}) does not exist")
else:
audio_file_paths = [args.input_audio]
audio_file_paths = [os.path.abspath(x) for x in audio_file_paths]
# Read audio Files
for audio_file_path in audio_file_paths:
audio = sf.read(audio_file_path)
# If audio is stereo, just take one channel.
X = audio[0] if audio[0].ndim==1 else audio[0][:,0]
features.append(X)
except:
raise Exception(f"Soundfile cannot read {args.input_audio}. Try a different format")
audio = readAudioFile(audio_file_path, args.audio_stream)
if audio is None:
raise Exception(f"Can't read {args.input_audio}. Try a different format")
features.append(audio[0])
elif args.input_type == "microphone":
# Read audio from microphone
audio = readAudioMicrophone(args.micro_time)
if audio is None:
raise Exception(f"Can't open microphone. Try a different format")
features.append(audio[0])
else:
raise Exception(f"input_type {args.input_type} doesn't exist. Please enter 'file' or 'microphone'")
# Get Filterbank Features
feature_extractor = FilterbankFeatures()
+3 -3
View File
@@ -270,12 +270,12 @@ def createSSDGraph(modelPath, configPath, outputPath):
addConstNode('concat/axis_flatten', [-1], graph_def)
addConstNode('PriorBox/concat/axis', [-2], graph_def)
for label in ['ClassPredictor', 'BoxEncodingPredictor' if box_predictor is 'convolutional' else 'BoxPredictor']:
for label in ['ClassPredictor', 'BoxEncodingPredictor' if box_predictor == 'convolutional' else 'BoxPredictor']:
concatInputs = []
for i in range(num_layers):
# Flatten predictions
flatten = NodeDef()
if box_predictor is 'convolutional':
if box_predictor == 'convolutional':
inpName = 'BoxPredictor_%d/%s/BiasAdd' % (i, label)
else:
if i == 0:
@@ -308,7 +308,7 @@ def createSSDGraph(modelPath, configPath, outputPath):
priorBox = NodeDef()
priorBox.name = 'PriorBox_%d' % i
priorBox.op = 'PriorBox'
if box_predictor is 'convolutional':
if box_predictor == 'convolutional':
priorBox.input.append('BoxPredictor_%d/BoxEncodingPredictor/BiasAdd' % i)
else:
if i == 0:
+2 -2
View File
@@ -26,9 +26,9 @@ sudo apt install -y wget unzip
# [wget]
# [download]
wget -O opencv.zip https://github.com/opencv/opencv/archive/master.zip
wget -O opencv.zip https://github.com/opencv/opencv/archive/5.x.zip
unzip opencv.zip
mv opencv-master opencv
mv opencv-5.x opencv
# [download]
# [prepare]
+1 -1
View File
@@ -27,7 +27,7 @@ sudo apt install -y git
# [download]
git clone https://github.com/opencv/opencv.git
git -C opencv checkout master
git -C opencv checkout 5.x
# [download]
# [prepare]
+2 -2
View File
@@ -12,14 +12,14 @@ fi
sudo apt update && sudo apt install -y cmake g++ wget unzip
# Download and unpack sources
wget -O opencv.zip https://github.com/opencv/opencv/archive/master.zip
wget -O opencv.zip https://github.com/opencv/opencv/archive/5.x.zip
unzip opencv.zip
# Create build directory
mkdir -p build && cd build
# Configure
cmake ../opencv-master
cmake ../opencv-5.x
# Build
cmake --build .
@@ -12,8 +12,8 @@ fi
sudo apt update && sudo apt install -y cmake g++ wget unzip
# Download and unpack sources
wget -O opencv.zip https://github.com/opencv/opencv/archive/master.zip
wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/master.zip
wget -O opencv.zip https://github.com/opencv/opencv/archive/5.x.zip
wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/5.x.zip
unzip opencv.zip
unzip opencv_contrib.zip
@@ -21,7 +21,7 @@ unzip opencv_contrib.zip
mkdir -p build && cd build
# Configure
cmake -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib-master/modules ../opencv-master
cmake -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib-5.x/modules ../opencv-5.x
# Build
cmake --build .
+1 -1
View File
@@ -23,7 +23,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND)
endif()
foreach(sample_filename ${all_samples})
ocv_define_sample(tgt ${sample_filename} opengl)
ocv_target_link_libraries(${tgt} PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_OPENGL_SAMPLES_REQUIRED_DEPS})
ocv_target_link_libraries(${tgt} PRIVATE "${OPENGL_LIBRARIES}" "${OPENCV_OPENGL_SAMPLES_REQUIRED_DEPS}")
if(sample_filename STREQUAL "opengl_interop.cpp")
ocv_target_link_libraries(${tgt} PRIVATE ${X11_LIBRARIES})
ocv_target_include_directories(${tgt} ${X11_INCLUDE_DIR})
+804
View File
@@ -0,0 +1,804 @@
import numpy as np
import cv2 as cv
import math
import argparse
class AudioDrawing:
'''
Used for drawing audio graphics
'''
def __init__(self, args):
self.inputType = args.inputType
self.draw = args.draw
self.graph = args.graph
self.audio = cv.samples.findFile(args.audio)
self.audioStream = args.audioStream
self.windowType = args.windowType
self.windLen = args.windLen
self.overlap = args.overlap
self.enableGrid = args.enableGrid
self.rows = args.rows
self.cols = args.cols
self.xmarkup = args.xmarkup
self.ymarkup = args.ymarkup
self.zmarkup = args.zmarkup
self.microTime = args.microTime
self.frameSizeTime = args.frameSizeTime
self.updateTime = args.updateTime
self.waitTime = args.waitTime
if self.initAndCheckArgs(args) is False:
exit()
def Draw(self):
if self.draw == "static":
if self.inputType == "file":
samplingRate, inputAudio = self.readAudioFile(self.audio)
elif self.inputType == "microphone":
samplingRate, inputAudio = self.readAudioMicrophone()
duration = len(inputAudio) // samplingRate
# since the dimensional grid is counted in integer seconds,
# if the input audio has an incomplete last second,
# then it is filled with zeros to complete
remainder = len(inputAudio) % samplingRate
if remainder != 0:
sizeToFullSec = samplingRate - remainder
zeroArr = np.zeros(sizeToFullSec)
inputAudio = np.concatenate((inputAudio, zeroArr), axis=0)
duration += 1
print("Update duration of audio to full second with ",
sizeToFullSec, " zero samples")
print("New number of samples ", len(inputAudio))
if duration <= self.xmarkup:
self.xmarkup = duration + 1
if self.graph == "ampl":
imgAmplitude = self.drawAmplitude(inputAudio)
imgAmplitude = self.drawAmplitudeScale(imgAmplitude, inputAudio, samplingRate)
cv.imshow("Display window", imgAmplitude)
cv.waitKey(0)
elif self.graph == "spec":
stft = self.STFT(inputAudio)
imgSpec = self.drawSpectrogram(stft)
imgSpec = self.drawSpectrogramColorbar(imgSpec, inputAudio, samplingRate, stft)
cv.imshow("Display window", imgSpec)
cv.waitKey(0)
elif self.graph == "ampl_and_spec":
imgAmplitude = self.drawAmplitude(inputAudio)
imgAmplitude = self.drawAmplitudeScale(imgAmplitude, inputAudio, samplingRate)
stft = self.STFT(inputAudio)
imgSpec = self.drawSpectrogram(stft)
imgSpec = self.drawSpectrogramColorbar(imgSpec, inputAudio, samplingRate, stft)
imgTotal = self.concatenateImages(imgAmplitude, imgSpec)
cv.imshow("Display window", imgTotal)
cv.waitKey(0)
elif self.draw == "dynamic":
if self.inputType == "file":
self.dynamicFile(self.audio)
elif self.inputType == "microphone":
self.dynamicMicrophone()
def readAudioFile(self, file):
cap = cv.VideoCapture(file)
params = [cv.CAP_PROP_AUDIO_STREAM, self.audioStream,
cv.CAP_PROP_VIDEO_STREAM, -1,
cv.CAP_PROP_AUDIO_DATA_DEPTH, cv.CV_16S]
params = np.asarray(params)
cap.open(file, cv.CAP_ANY, params)
if cap.isOpened() == False:
print("Error : Can't read audio file: '", self.audio, "' with audioStream = ", self.audioStream)
print("Error: problems with audio reading, check input arguments")
exit()
audioBaseIndex = int(cap.get(cv.CAP_PROP_AUDIO_BASE_INDEX))
numberOfChannels = int(cap.get(cv.CAP_PROP_AUDIO_TOTAL_CHANNELS))
print("CAP_PROP_AUDIO_DATA_DEPTH: ", str((int(cap.get(cv.CAP_PROP_AUDIO_DATA_DEPTH)))))
print("CAP_PROP_AUDIO_SAMPLES_PER_SECOND: ", cap.get(cv.CAP_PROP_AUDIO_SAMPLES_PER_SECOND))
print("CAP_PROP_AUDIO_TOTAL_CHANNELS: ", numberOfChannels)
print("CAP_PROP_AUDIO_TOTAL_STREAMS: ", cap.get(cv.CAP_PROP_AUDIO_TOTAL_STREAMS))
frame = []
frame = np.asarray(frame)
inputAudio = []
while (1):
if (cap.grab()):
frame = []
frame = np.asarray(frame)
frame = cap.retrieve(frame, audioBaseIndex)
for i in range(len(frame[1][0])):
inputAudio.append(frame[1][0][i])
else:
break
inputAudio = np.asarray(inputAudio)
print("Number of samples: ", len(inputAudio))
samplingRate = int(cap.get(cv.CAP_PROP_AUDIO_SAMPLES_PER_SECOND))
return samplingRate, inputAudio
def readAudioMicrophone(self):
cap = cv.VideoCapture()
params = [cv.CAP_PROP_AUDIO_STREAM, 0, cv.CAP_PROP_VIDEO_STREAM, -1]
params = np.asarray(params)
cap.open(0, cv.CAP_ANY, params)
if cap.isOpened() == False:
print("Error: Can't open microphone")
print("Error: problems with audio reading, check input arguments")
exit()
audioBaseIndex = int(cap.get(cv.CAP_PROP_AUDIO_BASE_INDEX))
numberOfChannels = int(cap.get(cv.CAP_PROP_AUDIO_TOTAL_CHANNELS))
print("CAP_PROP_AUDIO_DATA_DEPTH: ", str((int(cap.get(cv.CAP_PROP_AUDIO_DATA_DEPTH)))))
print("CAP_PROP_AUDIO_SAMPLES_PER_SECOND: ", cap.get(cv.CAP_PROP_AUDIO_SAMPLES_PER_SECOND))
print("CAP_PROP_AUDIO_TOTAL_CHANNELS: ", numberOfChannels)
print("CAP_PROP_AUDIO_TOTAL_STREAMS: ", cap.get(cv.CAP_PROP_AUDIO_TOTAL_STREAMS))
cvTickFreq = cv.getTickFrequency()
sysTimeCurr = cv.getTickCount()
sysTimePrev = sysTimeCurr
frame = []
frame = np.asarray(frame)
inputAudio = []
while ((sysTimeCurr - sysTimePrev) / cvTickFreq < self.microTime):
if (cap.grab()):
frame = []
frame = np.asarray(frame)
frame = cap.retrieve(frame, audioBaseIndex)
for i in range(len(frame[1][0])):
inputAudio.append(frame[1][0][i])
sysTimeCurr = cv.getTickCount()
else:
print("Error: Grab error")
break
inputAudio = np.asarray(inputAudio)
print("Number of samples: ", len(inputAudio))
samplingRate = int(cap.get(cv.CAP_PROP_AUDIO_SAMPLES_PER_SECOND))
return samplingRate, inputAudio
def drawAmplitude(self, inputAudio):
color = (247, 111, 87)
thickness = 5
frameVectorRows = 500
middle = frameVectorRows // 2
# usually the input data is too big, so it is necessary
# to reduce size using interpolation of data
frameVectorCols = 40000
if len(inputAudio) < frameVectorCols:
frameVectorCols = len(inputAudio)
img = np.zeros((frameVectorRows, frameVectorCols, 3), np.uint8)
img += 255 # white background
audio = np.array(0)
audio = cv.resize(inputAudio, (1, frameVectorCols), interpolation=cv.INTER_LINEAR)
reshapeAudio = np.reshape(audio, (-1))
# normalization data by maximum element
minCv, maxCv, _, _ = cv.minMaxLoc(reshapeAudio)
maxElem = int(max(abs(minCv), abs(maxCv)))
# if all data values are zero (silence)
if maxElem == 0:
maxElem = 1
for i in range(len(reshapeAudio)):
reshapeAudio[i] = middle - reshapeAudio[i] * middle // maxElem
for i in range(1, frameVectorCols, 1):
cv.line(img, (i - 1, int(reshapeAudio[i - 1])), (i, int(reshapeAudio[i])), color, thickness)
img = cv.resize(img, (900, 400), interpolation=cv.INTER_AREA)
return img
def drawAmplitudeScale(self, inputImg, inputAudio, samplingRate, xmin=None, xmax=None):
# function of layout drawing for graph of volume amplitudes
# x axis for time
# y axis for amplitudes
# parameters for the new image size
preCol = 100
aftCol = 100
preLine = 40
aftLine = 50
frameVectorRows = inputImg.shape[0]
frameVectorCols = inputImg.shape[1]
totalRows = preLine + frameVectorRows + aftLine
totalCols = preCol + frameVectorCols + aftCol
imgTotal = np.zeros((totalRows, totalCols, 3), np.uint8)
imgTotal += 255 # white background
imgTotal[preLine: preLine + frameVectorRows, preCol: preCol + frameVectorCols] = inputImg
# calculating values on x axis
if xmin is None:
xmin = 0
if xmax is None:
xmax = len(inputAudio) / samplingRate
if xmax > self.xmarkup:
xList = np.linspace(xmin, xmax, self.xmarkup).astype(int)
else:
# this case is used to display a dynamic update
tmp = np.arange(xmin, xmax, 1).astype(int) + 1
xList = np.concatenate((np.zeros(self.xmarkup - len(tmp)), tmp[:]), axis=None)
# calculating values on y axis
ymin = np.min(inputAudio)
ymax = np.max(inputAudio)
yList = np.linspace(ymin, ymax, self.ymarkup)
# parameters for layout drawing
textThickness = 1
gridThickness = 1
gridColor = (0, 0, 0)
textColor = (0, 0, 0)
font = cv.FONT_HERSHEY_SIMPLEX
fontScale = 0.5
# horizontal axis under the graph
cv.line(imgTotal, (preCol, totalRows - aftLine),
(preCol + frameVectorCols, totalRows - aftLine),
gridColor, gridThickness)
# vertical axis for amplitude
cv.line(imgTotal, (preCol, preLine), (preCol, preLine + frameVectorRows),
gridColor, gridThickness)
# parameters for layout calculation
serifSize = 10
indentDownX = serifSize * 2
indentDownY = serifSize // 2
indentLeftX = serifSize
indentLeftY = 2 * preCol // 3
# drawing layout for x axis
numX = frameVectorCols // (self.xmarkup - 1)
for i in range(len(xList)):
a1 = preCol + i * numX
a2 = frameVectorRows + preLine
b1 = a1
b2 = a2 + serifSize
if self.enableGrid is True:
d1 = a1
d2 = preLine
cv.line(imgTotal, (a1, a2), (d1, d2), gridColor, gridThickness)
cv.line(imgTotal, (a1, a2), (b1, b2), gridColor, gridThickness)
cv.putText(imgTotal, str(int(xList[i])), (b1 - indentLeftX, b2 + indentDownX),
font, fontScale, textColor, textThickness)
# drawing layout for y axis
numY = frameVectorRows // (self.ymarkup - 1)
for i in range(len(yList)):
a1 = preCol
a2 = totalRows - aftLine - i * numY
b1 = preCol - serifSize
b2 = a2
if self.enableGrid is True:
d1 = preCol + frameVectorCols
d2 = a2
cv.line(imgTotal, (a1, a2), (d1, d2), gridColor, gridThickness)
cv.line(imgTotal, (a1, a2), (b1, b2), gridColor, gridThickness)
cv.putText(imgTotal, str(int(yList[i])), (b1 - indentLeftY, b2 + indentDownY),
font, fontScale, textColor, textThickness)
imgTotal = cv.resize(imgTotal, (self.cols, self.rows), interpolation=cv.INTER_AREA)
return imgTotal
def STFT(self, inputAudio):
"""
The Short-time Fourier transform (STFT), is a Fourier-related transform used to determine
the sinusoidal frequency and phase content of local sections of a signal as it changes over
time.
In practice, the procedure for computing STFTs is to divide a longer time signal into
shorter segments of equal length and then compute the Fourier transform separately on each
shorter segment. This reveals the Fourier spectrum on each shorter segment. One then usually
plots the changing spectra as a function of time, known as a spectrogram or waterfall plot.
https://en.wikipedia.org/wiki/Short-time_Fourier_transform
"""
time_step = self.windLen - self.overlap
stft = []
if self.windowType == "Hann":
# https://en.wikipedia.org/wiki/Window_function#Hann_and_Hamming_windows
Hann_wind = []
for i in range (1 - self.windLen, self.windLen, 2):
Hann_wind.append(i * (0.5 + 0.5 * math.cos(math.pi * i / (self.windLen - 1))))
Hann_wind = np.asarray(Hann_wind)
elif self.windowType == "Hamming":
# https://en.wikipedia.org/wiki/Window_function#Hann_and_Hamming_windows
Hamming_wind = []
for i in range (1 - self.windLen, self.windLen, 2):
Hamming_wind.append(i * (0.53836 - 0.46164 * (math.cos(2 * math.pi * i / (self.windLen - 1)))))
Hamming_wind = np.asarray(Hamming_wind)
for index in np.arange(0, len(inputAudio), time_step).astype(int):
section = inputAudio[index:index + self.windLen]
zeroArray = np.zeros(self.windLen - len(section))
section = np.concatenate((section, zeroArray), axis=None)
if self.windowType == "Hann":
section *= Hann_wind
elif self.windowType == "Hamming":
section *= Hamming_wind
dst = np.empty(0)
dst = cv.dft(section, dst, flags=cv.DFT_COMPLEX_OUTPUT)
reshape_dst = np.reshape(dst, (-1))
# we need only the first part of the spectrum, the second part is symmetrical
complexArr = np.zeros(len(dst) // 4, dtype=complex)
for i in range(len(dst) // 4):
complexArr[i] = complex(reshape_dst[2 * i], reshape_dst[2 * i + 1])
stft.append(np.abs(complexArr))
stft = np.array(stft).transpose()
# convert elements to the decibel scale
np.log10(stft, out=stft, where=(stft != 0.))
return 10 * stft
def drawSpectrogram(self, stft):
frameVectorRows = stft.shape[0]
frameVectorCols = stft.shape[1]
# Normalization of image values from 0 to 255 to get more contrast image
# and this normalization will be taken into account in the scale drawing
colormapImageRows = 255
imgSpec = np.zeros((frameVectorRows, frameVectorCols, 3), np.uint8)
stftMat = np.zeros((frameVectorRows, frameVectorCols), np.float64)
cv.normalize(stft, stftMat, 1.0, 0.0, cv.NORM_INF)
for i in range(frameVectorRows):
for j in range(frameVectorCols):
imgSpec[frameVectorRows - i - 1, j] = int(stftMat[i][j] * colormapImageRows)
imgSpec = cv.applyColorMap(imgSpec, cv.COLORMAP_INFERNO)
imgSpec = cv.resize(imgSpec, (900, 400), interpolation=cv.INTER_LINEAR)
return imgSpec
def drawSpectrogramColorbar(self, inputImg, inputAudio, samplingRate, stft, xmin=None, xmax=None):
# function of layout drawing for the three-dimensional graph of the spectrogram
# x axis for time
# y axis for frequencies
# z axis for magnitudes of frequencies shown by color scale
# parameters for the new image size
preCol = 100
aftCol = 100
preLine = 40
aftLine = 50
colColor = 20
ind_col = 20
frameVectorRows = inputImg.shape[0]
frameVectorCols = inputImg.shape[1]
totalRows = preLine + frameVectorRows + aftLine
totalCols = preCol + frameVectorCols + aftCol + colColor
imgTotal = np.zeros((totalRows, totalCols, 3), np.uint8)
imgTotal += 255 # white background
imgTotal[preLine: preLine + frameVectorRows, preCol: preCol + frameVectorCols] = inputImg
# colorbar image due to drawSpectrogram(..) picture has been normalised from 255 to 0,
# so here colorbar has values from 255 to 0
colorArrSize = 256
imgColorBar = np.zeros((colorArrSize, colColor, 1), np.uint8)
for i in range(colorArrSize):
imgColorBar[i] += colorArrSize - 1 - i
imgColorBar = cv.applyColorMap(imgColorBar, cv.COLORMAP_INFERNO)
imgColorBar = cv.resize(imgColorBar, (colColor, frameVectorRows), interpolation=cv.INTER_AREA) #
imgTotal[preLine: preLine + frameVectorRows,
preCol + frameVectorCols + ind_col:
preCol + frameVectorCols + ind_col + colColor] = imgColorBar
# calculating values on x axis
if xmin is None:
xmin = 0
if xmax is None:
xmax = len(inputAudio) / samplingRate
if xmax > self.xmarkup:
xList = np.linspace(xmin, xmax, self.xmarkup).astype(int)
else:
# this case is used to display a dynamic update
tmpXList = np.arange(xmin, xmax, 1).astype(int) + 1
xList = np.concatenate((np.zeros(self.xmarkup - len(tmpXList)), tmpXList[:]), axis=None)
# calculating values on y axis
# according to the Nyquist sampling theorem,
# signal should posses frequencies equal to half of sampling rate
ymin = 0
ymax = int(samplingRate / 2.)
yList = np.linspace(ymin, ymax, self.ymarkup).astype(int)
# calculating values on z axis
zList = np.linspace(np.min(stft), np.max(stft), self.zmarkup)
# parameters for layout drawing
textThickness = 1
textColor = (0, 0, 0)
gridThickness = 1
gridColor = (0, 0, 0)
font = cv.FONT_HERSHEY_SIMPLEX
fontScale = 0.5
serifSize = 10
indentDownX = serifSize * 2
indentDownY = serifSize // 2
indentLeftX = serifSize
indentLeftY = 2 * preCol // 3
# horizontal axis
cv.line(imgTotal, (preCol, totalRows - aftLine), (preCol + frameVectorCols, totalRows - aftLine),
gridColor, gridThickness)
# vertical axis
cv.line(imgTotal, (preCol, preLine), (preCol, preLine + frameVectorRows),
gridColor, gridThickness)
# drawing layout for x axis
numX = frameVectorCols // (self.xmarkup - 1)
for i in range(len(xList)):
a1 = preCol + i * numX
a2 = frameVectorRows + preLine
b1 = a1
b2 = a2 + serifSize
cv.line(imgTotal, (a1, a2), (b1, b2), gridColor, gridThickness)
cv.putText(imgTotal, str(int(xList[i])), (b1 - indentLeftX, b2 + indentDownX),
font, fontScale, textColor, textThickness)
# drawing layout for y axis
numY = frameVectorRows // (self.ymarkup - 1)
for i in range(len(yList)):
a1 = preCol
a2 = totalRows - aftLine - i * numY
b1 = preCol - serifSize
b2 = a2
cv.line(imgTotal, (a1, a2), (b1, b2), gridColor, gridThickness)
cv.putText(imgTotal, str(int(yList[i])), (b1 - indentLeftY, b2 + indentDownY),
font, fontScale, textColor, textThickness)
# drawing layout for z axis
numZ = frameVectorRows // (self.zmarkup - 1)
for i in range(len(zList)):
a1 = preCol + frameVectorCols + ind_col + colColor
a2 = totalRows - aftLine - i * numZ
b1 = a1 + serifSize
b2 = a2
cv.line(imgTotal, (a1, a2), (b1, b2), gridColor, gridThickness)
cv.putText(imgTotal, str(int(zList[i])), (b1 + 10, b2 + indentDownY),
font, fontScale, textColor, textThickness)
imgTotal = cv.resize(imgTotal, (self.cols, self.rows), interpolation=cv.INTER_AREA)
return imgTotal
def concatenateImages(self, img1, img2):
# first image will be under the second image
totalRows = img1.shape[0] + img2.shape[0]
totalCols = max(img1.shape[1], img2.shape[1])
# if images columns do not match, the difference is filled in white
imgTotal = np.zeros((totalRows, totalCols, 3), np.uint8)
imgTotal += 255
imgTotal[:img1.shape[0], :img1.shape[1]] = img1
imgTotal[img2.shape[0]:, :img2.shape[1]] = img2
return imgTotal
def dynamicFile(self, file):
cap = cv.VideoCapture(file)
params = [cv.CAP_PROP_AUDIO_STREAM, self.audioStream,
cv.CAP_PROP_VIDEO_STREAM, -1,
cv.CAP_PROP_AUDIO_DATA_DEPTH, cv.CV_16S]
params = np.asarray(params)
cap.open(file, cv.CAP_ANY, params)
if cap.isOpened() == False:
print("ERROR! Can't to open file")
return
audioBaseIndex = int(cap.get(cv.CAP_PROP_AUDIO_BASE_INDEX))
numberOfChannels = int(cap.get(cv.CAP_PROP_AUDIO_TOTAL_CHANNELS))
samplingRate = int(cap.get(cv.CAP_PROP_AUDIO_SAMPLES_PER_SECOND))
print("CAP_PROP_AUDIO_DATA_DEPTH: ", str((int(cap.get(cv.CAP_PROP_AUDIO_DATA_DEPTH)))))
print("CAP_PROP_AUDIO_SAMPLES_PER_SECOND: ", cap.get(cv.CAP_PROP_AUDIO_SAMPLES_PER_SECOND))
print("CAP_PROP_AUDIO_TOTAL_CHANNELS: ", numberOfChannels)
print("CAP_PROP_AUDIO_TOTAL_STREAMS: ", cap.get(cv.CAP_PROP_AUDIO_TOTAL_STREAMS))
step = int(self.updateTime * samplingRate)
frameSize = int(self.frameSizeTime * samplingRate)
# since the dimensional grid is counted in integer seconds,
# if duration of audio frame is less than xmarkup, to avoid an incorrect display,
# xmarkup will be taken equal to duration
if self.frameSizeTime <= self.xmarkup:
self.xmarkup = self.frameSizeTime
buffer = []
section = np.zeros(frameSize, dtype=np.int16)
currentSamples = 0
while (1):
if (cap.grab()):
frame = []
frame = np.asarray(frame)
frame = cap.retrieve(frame, audioBaseIndex)
for i in range(len(frame[1][0])):
buffer.append(frame[1][0][i])
buffer_size = len(buffer)
if (buffer_size >= step):
section = list(section)
currentSamples += step
del section[0:step]
section.extend(buffer[0:step])
del buffer[0:step]
section = np.asarray(section)
if currentSamples < frameSize:
xmin = 0
xmax = (currentSamples) / samplingRate
else:
xmin = (currentSamples - frameSize) / samplingRate + 1
xmax = (currentSamples) / samplingRate
if self.graph == "ampl":
imgAmplitude = self.drawAmplitude(section)
imgAmplitude = self.drawAmplitudeScale(imgAmplitude, section, samplingRate, xmin, xmax)
cv.imshow("Display amplitude graph", imgAmplitude)
cv.waitKey(self.waitTime)
elif self.graph == "spec":
stft = self.STFT(section)
imgSpec = self.drawSpectrogram(stft)
imgSpec = self.drawSpectrogramColorbar(imgSpec, section, samplingRate, stft, xmin, xmax)
cv.imshow("Display spectrogram", imgSpec)
cv.waitKey(self.waitTime)
elif self.graph == "ampl_and_spec":
imgAmplitude = self.drawAmplitude(section)
stft = self.STFT(section)
imgSpec = self.drawSpectrogram(stft)
imgAmplitude = self.drawAmplitudeScale(imgAmplitude, section, samplingRate, xmin, xmax)
imgSpec = self.drawSpectrogramColorbar(imgSpec, section, samplingRate, stft, xmin, xmax)
imgTotal = self.concatenateImages(imgAmplitude, imgSpec)
cv.imshow("Display amplitude graph and spectrogram", imgTotal)
cv.waitKey(self.waitTime)
else:
break
def dynamicMicrophone(self):
cap = cv.VideoCapture()
params = [cv.CAP_PROP_AUDIO_STREAM, 0, cv.CAP_PROP_VIDEO_STREAM, -1]
params = np.asarray(params)
cap.open(0, cv.CAP_ANY, params)
if cap.isOpened() == False:
print("ERROR! Can't to open file")
return
audioBaseIndex = int(cap.get(cv.CAP_PROP_AUDIO_BASE_INDEX))
numberOfChannels = int(cap.get(cv.CAP_PROP_AUDIO_TOTAL_CHANNELS))
print("CAP_PROP_AUDIO_DATA_DEPTH: ", str((int(cap.get(cv.CAP_PROP_AUDIO_DATA_DEPTH)))))
print("CAP_PROP_AUDIO_SAMPLES_PER_SECOND: ", cap.get(cv.CAP_PROP_AUDIO_SAMPLES_PER_SECOND))
print("CAP_PROP_AUDIO_TOTAL_CHANNELS: ", numberOfChannels)
print("CAP_PROP_AUDIO_TOTAL_STREAMS: ", cap.get(cv.CAP_PROP_AUDIO_TOTAL_STREAMS))
frame = []
frame = np.asarray(frame)
samplingRate = int(cap.get(cv.CAP_PROP_AUDIO_SAMPLES_PER_SECOND))
step = int(self.updateTime * samplingRate)
frameSize = int(self.frameSizeTime * samplingRate)
self.xmarkup = self.frameSizeTime
currentSamples = 0
buffer = []
section = np.zeros(frameSize, dtype=np.int16)
cvTickFreq = cv.getTickFrequency()
sysTimeCurr = cv.getTickCount()
sysTimePrev = sysTimeCurr
self.waitTime = self.updateTime * 1000
while ((sysTimeCurr - sysTimePrev) / cvTickFreq < self.microTime):
if (cap.grab()):
frame = []
frame = np.asarray(frame)
frame = cap.retrieve(frame, audioBaseIndex)
for i in range(len(frame[1][0])):
buffer.append(frame[1][0][i])
sysTimeCurr = cv.getTickCount()
buffer_size = len(buffer)
if (buffer_size >= step):
section = list(section)
currentSamples += step
del section[0:step]
section.extend(buffer[0:step])
del buffer[0:step]
section = np.asarray(section)
if currentSamples < frameSize:
xmin = 0
xmax = (currentSamples) / samplingRate
else:
xmin = (currentSamples - frameSize) / samplingRate + 1
xmax = (currentSamples) / samplingRate
if self.graph == "ampl":
imgAmplitude = self.drawAmplitude(section)
imgAmplitude = self.drawAmplitudeScale(imgAmplitude, section, samplingRate, xmin, xmax)
cv.imshow("Display amplitude graph", imgAmplitude)
cv.waitKey(self.waitTime)
elif self.graph == "spec":
stft = self.STFT(section)
imgSpec = self.drawSpectrogram(stft)
imgSpec = self.drawSpectrogramColorbar(imgSpec, section, samplingRate, stft, xmin, xmax)
cv.imshow("Display spectrogram", imgSpec)
cv.waitKey(self.waitTime)
elif self.graph == "ampl_and_spec":
imgAmplitude = self.drawAmplitude(section)
stft = self.STFT(section)
imgSpec = self.drawSpectrogram(stft)
imgAmplitude = self.drawAmplitudeScale(imgAmplitude, section, samplingRate, xmin, xmax)
imgSpec = self.drawSpectrogramColorbar(imgSpec, section, samplingRate, stft, xmin, xmax)
imgTotal = self.concatenateImages(imgAmplitude, imgSpec)
cv.imshow("Display amplitude graph and spectrogram", imgTotal)
cv.waitKey(self.waitTime)
else:
break
def initAndCheckArgs(self, args):
if args.inputType != "file" and args.inputType != "microphone":
print("Error: ", args.inputType, " input method doesnt exist")
return False
if args.draw != "static" and args.draw != "dynamic":
print("Error: ", args.draw, " draw type doesnt exist")
return False
if args.graph != "ampl" and args.graph != "spec" and args.graph != "ampl_and_spec":
print("Error: ", args.graph, " type of graph doesnt exist")
return False
if args.windowType != "Rect" and args.windowType != "Hann" and args.windowType != "Hamming":
print("Error: ", args.windowType, " type of window doesnt exist")
return False
if args.windLen <= 0:
print("Error: windLen = ", args.windLen, " - incorrect value. Must be > 0")
return False
if args.overlap <= 0:
print("Error: overlap = ", args.overlap, " - incorrect value. Must be > 0")
return False
if args.rows <= 0:
print("Error: rows = ", args.rows, " - incorrect value. Must be > 0")
return False
if args.cols <= 0:
print("Error: cols = ", args.cols, " - incorrect value. Must be > 0")
return False
if args.xmarkup < 2:
print("Error: xmarkup = ", args.xmarkup, " - incorrect value. Must be >= 2")
return False
if args.ymarkup < 2:
print("Error: ymarkup = ", args.ymarkup, " - incorrect value. Must be >= 2")
return False
if args.zmarkup < 2:
print("Error: zmarkup = ", args.zmarkup, " - incorrect value. Must be >= 2")
return False
if args.microTime <= 0:
print("Error: microTime = ", args.microTime, " - incorrect value. Must be > 0")
return False
if args.frameSizeTime <= 0:
print("Error: frameSizeTime = ", args.frameSizeTime, " - incorrect value. Must be > 0")
return False
if args.updateTime <= 0:
print("Error: updateTime = ", args.updateTime, " - incorrect value. Must be > 0")
return False
if args.waitTime < 0:
print("Error: waitTime = ", args.waitTime, " - incorrect value. Must be >= 0")
return False
return True
if __name__ == "__main__":
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
description='''this sample draws a volume graph and/or spectrogram of audio/video files and microphone\nDefault usage: ./Spectrogram.exe''')
parser.add_argument("-i", "--inputType", dest="inputType", type=str, default="file", help="file or microphone")
parser.add_argument("-d", "--draw", dest="draw", type=str, default="static",
help="type of drawing: static - for plotting graph(s) across the entire input audio; dynamic - for plotting graph(s) in a time-updating window")
parser.add_argument("-g", "--graph", dest="graph", type=str, default="ampl_and_spec",
help="type of graph: amplitude graph or/and spectrogram. Please use tags below : ampl - draw the amplitude graph; spec - draw the spectrogram; ampl_and_spec - draw the amplitude graph and spectrogram on one image under each other")
parser.add_argument("-a", "--audio", dest="audio", type=str, default='Megamind.avi',
help="name and path to file")
parser.add_argument("-s", "--audioStream", dest="audioStream", type=int, default=1,
help=" CAP_PROP_AUDIO_STREAM value")
parser.add_argument("-t", '--windowType', dest="windowType", type=str, default="Rect",
help="type of window for STFT. Please use tags below : Rect/Hann/Hamming")
parser.add_argument("-l", '--windLen', dest="windLen", type=int, default=256, help="size of window for STFT")
parser.add_argument("-o", '--overlap', dest="overlap", type=int, default=128, help="overlap of windows for STFT")
parser.add_argument("-gd", '--grid', dest="enableGrid", type=bool, default=False, help="grid on amplitude graph(on/off)")
parser.add_argument("-r", '--rows', dest="rows", type=int, default=400, help="rows of output image")
parser.add_argument("-c", '--cols', dest="cols", type=int, default=900, help="cols of output image")
parser.add_argument("-x", '--xmarkup', dest="xmarkup", type=int, default=5,
help="number of x axis divisions (time asix)")
parser.add_argument("-y", '--ymarkup', dest="ymarkup", type=int, default=5,
help="number of y axis divisions (frequency or/and amplitude axis)") # ?
parser.add_argument("-z", '--zmarkup', dest="zmarkup", type=int, default=5,
help="number of z axis divisions (colorbar)") # ?
parser.add_argument("-m", '--microTime', dest="microTime", type=int, default=20,
help="time of recording audio with microphone in seconds")
parser.add_argument("-f", '--frameSizeTime', dest="frameSizeTime", type=int, default=5,
help="size of sliding window in seconds")
parser.add_argument("-u", '--updateTime', dest="updateTime", type=int, default=1,
help="update time of sliding window in seconds")
parser.add_argument("-w", '--waitTime', dest="waitTime", type=int, default=10,
help="parameter to cv.waitKey() for dynamic update, takes values in milliseconds")
args = parser.parse_args()
AudioDrawing(args).Draw()
+1
View File
@@ -86,6 +86,7 @@ def explore_match(win, img1, img2, kp_pairs, status = None, H = None):
if status is None:
status = np.ones(len(kp_pairs), np.bool_)
status = status.reshape((len(kp_pairs), 1))
p1, p2 = [], [] # python 2 / python 3 change of zip unpacking
for kpp in kp_pairs:
p1.append(np.int32(kpp[0].pt))
+2 -2
View File
@@ -36,7 +36,7 @@ except (AttributeError, cv.error) as e:
# if SURF not available, ORB is default
FEATURES_FIND_CHOICES['orb'] = cv.ORB.create
try:
FEATURES_FIND_CHOICES['sift'] = cv.xfeatures2d_SIFT.create
FEATURES_FIND_CHOICES['sift'] = cv.SIFT_create
except AttributeError:
print("SIFT not available")
try:
@@ -436,7 +436,7 @@ def main():
sizes = []
blender = None
timelapser = None
# https://github.com/opencv/opencv/blob/master/samples/cpp/stitching_detailed.cpp#L725 ?
# https://github.com/opencv/opencv/blob/5.x/samples/cpp/stitching_detailed.cpp#L725 ?
for idx, name in enumerate(img_names):
full_img = cv.imread(name)
if not is_compose_scale_set:
@@ -24,7 +24,7 @@ mask = cv.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
roi_hist = cv.calcHist([hsv_roi],[0],mask,[180],[0,180])
cv.normalize(roi_hist,roi_hist,0,255,cv.NORM_MINMAX)
# Setup the termination criteria, either 10 iteration or move by atleast 1 pt
# Setup the termination criteria, either 10 iteration or move by at least 1 pt
term_crit = ( cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1 )
while(1):
@@ -24,7 +24,7 @@ mask = cv.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
roi_hist = cv.calcHist([hsv_roi],[0],mask,[180],[0,180])
cv.normalize(roi_hist,roi_hist,0,255,cv.NORM_MINMAX)
# Setup the termination criteria, either 10 iteration or move by atleast 1 pt
# Setup the termination criteria, either 10 iteration or move by at least 1 pt
term_crit = ( cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1 )
while(1):
@@ -17,12 +17,12 @@ feature_params = dict( maxCorners = 100,
blockSize = 7 )
# Parameters for lucas kanade optical flow
lk_params = dict( winSize = (15,15),
lk_params = dict( winSize = (15, 15),
maxLevel = 2,
criteria = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 0.03))
# Create some random colors
color = np.random.randint(0,255,(100,3))
color = np.random.randint(0, 255, (100, 3))
# Take first frame and find corners in it
ret, old_frame = cap.read()
@@ -33,7 +33,11 @@ p0 = cv.goodFeaturesToTrack(old_gray, mask = None, **feature_params)
mask = np.zeros_like(old_frame)
while(1):
ret,frame = cap.read()
ret, frame = cap.read()
if not ret:
print('No frames grabbed!')
break
frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# calculate optical flow
@@ -45,18 +49,20 @@ while(1):
good_old = p0[st==1]
# draw the tracks
for i,(new,old) in enumerate(zip(good_new, good_old)):
a,b = new.ravel()
c,d = old.ravel()
mask = cv.line(mask, (int(a),int(b)),(int(c),int(d)), color[i].tolist(), 2)
frame = cv.circle(frame,(int(a),int(b)),5,color[i].tolist(),-1)
img = cv.add(frame,mask)
for i, (new, old) in enumerate(zip(good_new, good_old)):
a, b = new.ravel()
c, d = old.ravel()
mask = cv.line(mask, (int(a), int(b)), (int(c), int(d)), color[i].tolist(), 2)
frame = cv.circle(frame, (int(a), int(b)), 5, color[i].tolist(), -1)
img = cv.add(frame, mask)
cv.imshow('frame',img)
cv.imshow('frame', img)
k = cv.waitKey(30) & 0xff
if k == 27:
break
# Now update the previous frame and previous points
old_gray = frame_gray.copy()
p0 = good_new.reshape(-1,1,2)
p0 = good_new.reshape(-1, 1, 2)
cv.destroyAllWindows()
@@ -2,22 +2,28 @@ import numpy as np
import cv2 as cv
cap = cv.VideoCapture(cv.samples.findFile("vtest.avi"))
ret, frame1 = cap.read()
prvs = cv.cvtColor(frame1,cv.COLOR_BGR2GRAY)
prvs = cv.cvtColor(frame1, cv.COLOR_BGR2GRAY)
hsv = np.zeros_like(frame1)
hsv[...,1] = 255
hsv[..., 1] = 255
while(1):
ret, frame2 = cap.read()
next = cv.cvtColor(frame2,cv.COLOR_BGR2GRAY)
flow = cv.calcOpticalFlowFarneback(prvs,next, None, 0.5, 3, 15, 3, 5, 1.2, 0)
mag, ang = cv.cartToPolar(flow[...,0], flow[...,1])
hsv[...,0] = ang*180/np.pi/2
hsv[...,2] = cv.normalize(mag,None,0,255,cv.NORM_MINMAX)
bgr = cv.cvtColor(hsv,cv.COLOR_HSV2BGR)
cv.imshow('frame2',bgr)
if not ret:
print('No frames grabbed!')
break
next = cv.cvtColor(frame2, cv.COLOR_BGR2GRAY)
flow = cv.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)
mag, ang = cv.cartToPolar(flow[..., 0], flow[..., 1])
hsv[..., 0] = ang*180/np.pi/2
hsv[..., 2] = cv.normalize(mag, None, 0, 255, cv.NORM_MINMAX)
bgr = cv.cvtColor(hsv, cv.COLOR_HSV2BGR)
cv.imshow('frame2', bgr)
k = cv.waitKey(30) & 0xff
if k == 27:
break
elif k == ord('s'):
cv.imwrite('opticalfb.png',frame2)
cv.imwrite('opticalhsv.png',bgr)
cv.imwrite('opticalfb.png', frame2)
cv.imwrite('opticalhsv.png', bgr)
prvs = next
cv.destroyAllWindows()
+1 -1
View File
@@ -20,7 +20,7 @@ int main(void)
// Number of experiment runs
int no_runs = 2;
// https://docs.opencv.org/master/d3/d63/classcv_1_1Mat.html
// https://docs.opencv.org/5.x/d3/d63/classcv_1_1Mat.html
cv::Mat src_new(IMG_ROWS, IMG_COLS, CV_8UC1, (void *)raw_pixels);
// Set parameters
+1 -1
View File
@@ -20,7 +20,7 @@ int main(void)
// Number of experiment runs
int no_runs = 2;
// https://docs.opencv.org/master/d3/d63/classcv_1_1Mat.html
// https://docs.opencv.org/5.x/d3/d63/classcv_1_1Mat.html
cv::Mat src(IMG_ROWS, IMG_COLS, CV_8UC1, (void *)raw_pixels);
// Run calc Hist