From b95d71af2bb86ac9b4699edf81d2332f2c52ea60 Mon Sep 17 00:00:00 2001 From: Maxim Pashchenkov Date: Fri, 26 Nov 2021 14:31:15 +0300 Subject: [PATCH] Merge pull request #21106 from mpashchenkov:mp/ocv-gapi-clean-samples G-API: Cleaning samples * parseSSD + removed render details from gcpukernel * self-rev * Applying comment * Added operators * warnings --- .../gapi/include/opencv2/gapi/cpu/gcpukernel.hpp | 9 --- modules/gapi/samples/gaze_estimation.cpp | 85 +------------------ modules/gapi/samples/infer_ie_onnx_hybrid.cpp | 8 +- modules/gapi/samples/infer_single_roi.cpp | 94 +++------------------- modules/gapi/samples/infer_ssd_onnx.cpp | 78 +++--------------- modules/gapi/samples/onevpl_infer_single_roi.cpp | 74 ++--------------- modules/gapi/samples/privacy_masking_camera.cpp | 63 ++------------- modules/gapi/samples/semantic_segmentation.cpp | 18 +++-- 8 files changed, 61 insertions(+), 368 deletions(-) diff --git a/modules/gapi/include/opencv2/gapi/cpu/gcpukernel.hpp b/modules/gapi/include/opencv2/gapi/cpu/gcpukernel.hpp index 009c196..48909a8 100644 --- a/modules/gapi/include/opencv2/gapi/cpu/gcpukernel.hpp +++ b/modules/gapi/include/opencv2/gapi/cpu/gcpukernel.hpp @@ -28,14 +28,6 @@ namespace gimpl { // Forward-declare an internal class class GCPUExecutable; - - namespace render - { - namespace ocv - { - class GRenderExecutable; - } - } } // namespace gimpl namespace gapi @@ -133,7 +125,6 @@ protected: std::unordered_map m_results; friend class gimpl::GCPUExecutable; - friend class gimpl::render::ocv::GRenderExecutable; }; class GAPI_EXPORTS GCPUKernel diff --git a/modules/gapi/samples/gaze_estimation.cpp b/modules/gapi/samples/gaze_estimation.cpp index 96b2ebf..8ccaccd 100644 --- a/modules/gapi/samples/gaze_estimation.cpp +++ b/modules/gapi/samples/gaze_estimation.cpp @@ -9,6 +9,7 @@ #include #include #include // CommandLineParser +#include const std::string about = "This is an OpenCV-based version of Gaze Estimation example"; @@ -58,16 +59,6 @@ G_API_OP(Size, , "custom.gapi.size") { } }; -G_API_OP(ParseSSD, - , - "custom.gaze_estimation.parseSSD") { - static cv::GArrayDesc outMeta( const cv::GMatDesc & - , const cv::GOpaqueDesc & - , bool) { - return cv::empty_array_desc(); - } -}; - // Left/Right eye per every face G_API_OP(ParseEyes, (GMats, GRects, GSize)>, @@ -91,27 +82,6 @@ G_API_OP(ProcessPoses, } }; -void adjustBoundingBox(cv::Rect& boundingBox) { - auto w = boundingBox.width; - auto h = boundingBox.height; - - boundingBox.x -= static_cast(0.067 * w); - boundingBox.y -= static_cast(0.028 * h); - - boundingBox.width += static_cast(0.15 * w); - boundingBox.height += static_cast(0.13 * h); - - if (boundingBox.width < boundingBox.height) { - auto dx = (boundingBox.height - boundingBox.width); - boundingBox.x -= dx / 2; - boundingBox.width += dx; - } else { - auto dy = (boundingBox.width - boundingBox.height); - boundingBox.y -= dy / 2; - boundingBox.height += dy; - } -} - void gazeVectorToGazeAngles(const cv::Point3f& gazeVector, cv::Point2f& gazeAngles) { auto r = cv::norm(gazeVector); @@ -130,55 +100,6 @@ GAPI_OCV_KERNEL(OCVSize, Size) { } }; -GAPI_OCV_KERNEL(OCVParseSSD, ParseSSD) { - static void run(const cv::Mat &in_ssd_result, - const cv::Size &upscale, - const bool filter_out_of_bounds, - std::vector &out_objects) { - const auto &in_ssd_dims = in_ssd_result.size; - CV_Assert(in_ssd_dims.dims() == 4u); - - const int MAX_PROPOSALS = in_ssd_dims[2]; - const int OBJECT_SIZE = in_ssd_dims[3]; - CV_Assert(OBJECT_SIZE == 7); // fixed SSD object size - - const cv::Rect surface({0,0}, upscale); - out_objects.clear(); - - const float *data = in_ssd_result.ptr(); - for (int i = 0; i < MAX_PROPOSALS; i++) { - const float image_id = data[i * OBJECT_SIZE + 0]; - const float label = data[i * OBJECT_SIZE + 1]; - const float confidence = data[i * OBJECT_SIZE + 2]; - const float rc_left = data[i * OBJECT_SIZE + 3]; - const float rc_top = data[i * OBJECT_SIZE + 4]; - const float rc_right = data[i * OBJECT_SIZE + 5]; - const float rc_bottom = data[i * OBJECT_SIZE + 6]; - (void) label; - if (image_id < 0.f) { - break; // marks end-of-detections - } - if (confidence < 0.5f) { - continue; // skip objects with low confidence - } - cv::Rect rc; // map relative coordinates to the original image scale - rc.x = static_cast(rc_left * upscale.width); - rc.y = static_cast(rc_top * upscale.height); - rc.width = static_cast(rc_right * upscale.width) - rc.x; - rc.height = static_cast(rc_bottom * upscale.height) - rc.y; - adjustBoundingBox(rc); // TODO: new option? - - const auto clipped_rc = rc & surface; // TODO: new option? - if (filter_out_of_bounds) { - if (clipped_rc.area() != rc.area()) { - continue; - } - } - out_objects.emplace_back(clipped_rc); - } - } -}; - cv::Rect eyeBox(const cv::Rect &face_rc, float p1_x, float p1_y, float p2_x, float p2_y, float scale = 1.8f) { @@ -335,11 +256,10 @@ int main(int argc, char *argv[]) cmd.printMessage(); return 0; } - cv::GMat in; cv::GMat faces = cv::gapi::infer(in); cv::GOpaque sz = cv::gapi::streaming::size(in); - cv::GArray faces_rc = custom::ParseSSD::on(faces, sz, true); + cv::GArray faces_rc = cv::gapi::parseSSD(faces, sz, 0.5f, true, true); cv::GArray angles_y, angles_p, angles_r; std::tie(angles_y, angles_p, angles_r) = cv::gapi::infer(faces_rc, in); cv::GArray heads_pos = custom::ProcessPoses::on(angles_y, angles_p, angles_r); @@ -386,7 +306,6 @@ int main(int argc, char *argv[]) }.cfgInputLayers({"left_eye_image", "right_eye_image", "head_pose_angles"}); auto kernels = cv::gapi::kernels< custom::OCVSize - , custom::OCVParseSSD , custom::OCVParseEyes , custom::OCVProcessPoses>(); auto networks = cv::gapi::networks(face_net, head_net, landmarks_net, gaze_net); diff --git a/modules/gapi/samples/infer_ie_onnx_hybrid.cpp b/modules/gapi/samples/infer_ie_onnx_hybrid.cpp index b8612a2..594c592 100644 --- a/modules/gapi/samples/infer_ie_onnx_hybrid.cpp +++ b/modules/gapi/samples/infer_ie_onnx_hybrid.cpp @@ -156,7 +156,6 @@ int main(int argc, char *argv[]) auto in_src = cv::gapi::wip::make_src(input); pipeline.setSource(cv::gin(in_src)); - pipeline.start(); cv::util::optional out_frame; cv::util::optional> out_faces; @@ -167,8 +166,13 @@ int main(int argc, char *argv[]) std::vector last_emotions; cv::VideoWriter writer; + cv::TickMeter tm; + std::size_t frames = 0u; + tm.start(); + pipeline.start(); while (pipeline.pull(cv::gout(out_frame, out_faces, out_emotions))) { + ++frames; if (out_faces && out_emotions) { last_faces = *out_faces; last_emotions = *out_emotions; @@ -191,5 +195,7 @@ int main(int argc, char *argv[]) cv::waitKey(1); } } + tm.stop(); + std::cout << "Processed " << frames << " frames" << " (" << frames / tm.getTimeSec() << " FPS)" << std::endl; return 0; } diff --git a/modules/gapi/samples/infer_single_roi.cpp b/modules/gapi/samples/infer_single_roi.cpp index 6f02770..e9c26a9 100644 --- a/modules/gapi/samples/infer_single_roi.cpp +++ b/modules/gapi/samples/infer_single_roi.cpp @@ -13,6 +13,7 @@ #include #include #include +#include const std::string keys = "{ h help | | Print this help message }" @@ -69,36 +70,18 @@ using GRect = cv::GOpaque; using GSize = cv::GOpaque; using GPrims = cv::GArray; -G_API_OP(GetSize, , "sample.custom.get-size") { - static cv::GOpaqueDesc outMeta(const cv::GMatDesc &) { - return cv::empty_gopaque_desc(); - } -}; - G_API_OP(LocateROI, , "sample.custom.locate-roi") { static cv::GOpaqueDesc outMeta(const cv::GMatDesc &) { return cv::empty_gopaque_desc(); } }; -G_API_OP(ParseSSD, , "sample.custom.parse-ssd") { - static cv::GArrayDesc outMeta(const cv::GMatDesc &, const cv::GOpaqueDesc &, const cv::GOpaqueDesc &) { - return cv::empty_array_desc(); - } -}; - G_API_OP(BBoxes, , "sample.custom.b-boxes") { static cv::GArrayDesc outMeta(const cv::GArrayDesc &, const cv::GOpaqueDesc &) { return cv::empty_array_desc(); } }; -GAPI_OCV_KERNEL(OCVGetSize, GetSize) { - static void run(const cv::Mat &in, cv::Size &out) { - out = {in.cols, in.rows}; - } -}; - GAPI_OCV_KERNEL(OCVLocateROI, LocateROI) { // This is the place where we can run extra analytics // on the input image frame and select the ROI (region @@ -124,55 +107,6 @@ GAPI_OCV_KERNEL(OCVLocateROI, LocateROI) { } }; -GAPI_OCV_KERNEL(OCVParseSSD, ParseSSD) { - static void run(const cv::Mat &in_ssd_result, - const cv::Rect &in_roi, - const cv::Size &in_parent_size, - std::vector &out_objects) { - const auto &in_ssd_dims = in_ssd_result.size; - CV_Assert(in_ssd_dims.dims() == 4u); - - const int MAX_PROPOSALS = in_ssd_dims[2]; - const int OBJECT_SIZE = in_ssd_dims[3]; - CV_Assert(OBJECT_SIZE == 7); // fixed SSD object size - - const cv::Size up_roi = in_roi.size(); - const cv::Rect surface({0,0}, in_parent_size); - - out_objects.clear(); - - const float *data = in_ssd_result.ptr(); - for (int i = 0; i < MAX_PROPOSALS; i++) { - const float image_id = data[i * OBJECT_SIZE + 0]; - const float label = data[i * OBJECT_SIZE + 1]; - const float confidence = data[i * OBJECT_SIZE + 2]; - const float rc_left = data[i * OBJECT_SIZE + 3]; - const float rc_top = data[i * OBJECT_SIZE + 4]; - const float rc_right = data[i * OBJECT_SIZE + 5]; - const float rc_bottom = data[i * OBJECT_SIZE + 6]; - (void) label; // unused - - if (image_id < 0.f) { - break; // marks end-of-detections - } - if (confidence < 0.5f) { - continue; // skip objects with low confidence - } - - // map relative coordinates to the original image scale - // taking the ROI into account - cv::Rect rc; - rc.x = static_cast(rc_left * up_roi.width); - rc.y = static_cast(rc_top * up_roi.height); - rc.width = static_cast(rc_right * up_roi.width) - rc.x; - rc.height = static_cast(rc_bottom * up_roi.height) - rc.y; - rc.x += in_roi.x; - rc.y += in_roi.y; - out_objects.emplace_back(rc & surface); - } - } -}; - GAPI_OCV_KERNEL(OCVBBoxes, BBoxes) { // This kernel converts the rectangles into G-API's // rendering primitives @@ -211,9 +145,7 @@ int main(int argc, char *argv[]) cmd.get("faced"), // device specifier }; auto kernels = cv::gapi::kernels - < custom::OCVGetSize - , custom::OCVLocateROI - , custom::OCVParseSSD + (); auto networks = cv::gapi::networks(face_net); @@ -222,16 +154,17 @@ int main(int argc, char *argv[]) cv::GStreamingCompiled pipeline; auto inputs = cv::gin(cv::gapi::wip::make_src(input)); + cv::GMat in; + cv::GOpaque sz = cv::gapi::streaming::size(in); if (opt_roi.has_value()) { // Use the value provided by user std::cout << "Will run inference for static region " << opt_roi.value() << " only" << std::endl; - cv::GMat in; cv::GOpaque in_roi; auto blob = cv::gapi::infer(in_roi, in); - auto rcs = custom::ParseSSD::on(blob, in_roi, custom::GetSize::on(in)); + cv::GArray rcs = cv::gapi::parseSSD(blob, sz, 0.5f, true, true); auto out = cv::gapi::wip::draw::render3ch(in, custom::BBoxes::on(rcs, in_roi)); pipeline = cv::GComputation(cv::GIn(in, in_roi), cv::GOut(out)) .compileStreaming(cv::compile_args(kernels, networks)); @@ -242,10 +175,9 @@ int main(int argc, char *argv[]) // Automatically detect ROI to infer. Make it output parameter std::cout << "ROI is not set or invalid. Locating it automatically" << std::endl; - cv::GMat in; cv::GOpaque roi = custom::LocateROI::on(in); auto blob = cv::gapi::infer(roi, in); - auto rcs = custom::ParseSSD::on(blob, roi, custom::GetSize::on(in)); + cv::GArray rcs = cv::gapi::parseSSD(blob, sz, 0.5f, true, true); auto out = cv::gapi::wip::draw::render3ch(in, custom::BBoxes::on(rcs, roi)); pipeline = cv::GComputation(cv::GIn(in), cv::GOut(out)) .compileStreaming(cv::compile_args(kernels, networks)); @@ -256,17 +188,15 @@ int main(int argc, char *argv[]) pipeline.start(); cv::Mat out; - int framesCount = 0; - cv::TickMeter t; - t.start(); + size_t frames = 0u; + cv::TickMeter tm; + tm.start(); while (pipeline.pull(cv::gout(out))) { cv::imshow("Out", out); cv::waitKey(1); - framesCount++; + ++frames; } - t.stop(); - std::cout << "Elapsed time: " << t.getTimeSec() << std::endl; - std::cout << "FPS: " << framesCount / (t.getTimeSec() ? t.getTimeSec() : 1) << std::endl; - std::cout << "framesCount: " << framesCount << std::endl; + tm.stop(); + std::cout << "Processed " << frames << " frames" << " (" << frames / tm.getTimeSec() << " FPS)" << std::endl; return 0; } diff --git a/modules/gapi/samples/infer_ssd_onnx.cpp b/modules/gapi/samples/infer_ssd_onnx.cpp index fc26ca1..c6073a2 100644 --- a/modules/gapi/samples/infer_ssd_onnx.cpp +++ b/modules/gapi/samples/infer_ssd_onnx.cpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace custom { @@ -23,71 +24,12 @@ using GDetections = cv::GArray; using GSize = cv::GOpaque; using GPrims = cv::GArray; -G_API_OP(GetSize, , "sample.custom.get-size") { - static cv::GOpaqueDesc outMeta(const cv::GMatDesc &) { - return cv::empty_gopaque_desc(); - } -}; -G_API_OP(ParseSSD, , "sample.custom.parse-ssd") { - static cv::GArrayDesc outMeta(const cv::GMatDesc &, const cv::GOpaqueDesc &) { - return cv::empty_array_desc(); - } -}; G_API_OP(BBoxes, , "sample.custom.b-boxes") { static cv::GArrayDesc outMeta(const cv::GArrayDesc &) { return cv::empty_array_desc(); } }; -GAPI_OCV_KERNEL(OCVGetSize, GetSize) { - static void run(const cv::Mat &in, cv::Size &out) { - out = {in.cols, in.rows}; - } -}; -GAPI_OCV_KERNEL(OCVParseSSD, ParseSSD) { - static void run(const cv::Mat &in_ssd_result, - const cv::Size &in_parent_size, - std::vector &out_objects) { - const auto &in_ssd_dims = in_ssd_result.size; - CV_Assert(in_ssd_dims.dims() == 4u); - - const int MAX_PROPOSALS = in_ssd_dims[2]; - const int OBJECT_SIZE = in_ssd_dims[3]; - - CV_Assert(OBJECT_SIZE == 7); // fixed SSD object size - - const cv::Rect surface({0,0}, in_parent_size); - - out_objects.clear(); - - const float *data = in_ssd_result.ptr(); - for (int i = 0; i < MAX_PROPOSALS; i++) { - const float image_id = data[i * OBJECT_SIZE + 0]; - const float label = data[i * OBJECT_SIZE + 1]; - const float confidence = data[i * OBJECT_SIZE + 2]; - const float rc_left = data[i * OBJECT_SIZE + 3]; - const float rc_top = data[i * OBJECT_SIZE + 4]; - const float rc_right = data[i * OBJECT_SIZE + 5]; - const float rc_bottom = data[i * OBJECT_SIZE + 6]; - (void) label; // unused - - if (image_id < 0.f) { - break; // marks end-of-detections - } - if (confidence < 0.5f) { - continue; // skip objects with low confidence - } - - // map relative coordinates to the original image scale - cv::Rect rc; - rc.x = static_cast(rc_left * in_parent_size.width); - rc.y = static_cast(rc_top * in_parent_size.height); - rc.width = static_cast(rc_right * in_parent_size.width) - rc.x; - rc.height = static_cast(rc_bottom * in_parent_size.height) - rc.y; - out_objects.emplace_back(rc & surface); - } - } -}; GAPI_OCV_KERNEL(OCVBBoxes, BBoxes) { // This kernel converts the rectangles into G-API's // rendering primitives @@ -151,7 +93,6 @@ void remap_ssd_ports(const std::unordered_map &onnx, } } // anonymous namespace - const std::string keys = "{ h help | | Print this help message }" "{ input | | Path to the input video file }" @@ -175,15 +116,14 @@ int main(int argc, char *argv[]) auto obj_net = cv::gapi::onnx::Params{obj_model_path} .cfgOutputLayers({"detection_output"}) .cfgPostProc({cv::GMatDesc{CV_32F, {1,1,200,7}}}, remap_ssd_ports); - auto kernels = cv::gapi::kernels< custom::OCVGetSize - , custom::OCVParseSSD - , custom::OCVBBoxes>(); + auto kernels = cv::gapi::kernels(); auto networks = cv::gapi::networks(obj_net); // Now build the graph cv::GMat in; auto blob = cv::gapi::infer(in); - auto rcs = custom::ParseSSD::on(blob, custom::GetSize::on(in)); + cv::GArray rcs = + cv::gapi::parseSSD(blob, cv::gapi::streaming::size(in), 0.5f, true, true); auto out = cv::gapi::wip::draw::render3ch(in, custom::BBoxes::on(rcs)); cv::GStreamingCompiled pipeline = cv::GComputation(cv::GIn(in), cv::GOut(out)) .compileStreaming(cv::compile_args(kernels, networks)); @@ -192,12 +132,16 @@ int main(int argc, char *argv[]) // The execution part pipeline.setSource(std::move(inputs)); - pipeline.start(); + cv::TickMeter tm; cv::VideoWriter writer; - + size_t frames = 0u; cv::Mat outMat; + + tm.start(); + pipeline.start(); while (pipeline.pull(cv::gout(outMat))) { + ++frames; cv::imshow("Out", outMat); cv::waitKey(1); if (!output.empty()) { @@ -209,5 +153,7 @@ int main(int argc, char *argv[]) writer << outMat; } } + tm.stop(); + std::cout << "Processed " << frames << " frames" << " (" << frames / tm.getTimeSec() << " FPS)" << std::endl; return 0; } diff --git a/modules/gapi/samples/onevpl_infer_single_roi.cpp b/modules/gapi/samples/onevpl_infer_single_roi.cpp index 9da64c9..fec0f0d 100644 --- a/modules/gapi/samples/onevpl_infer_single_roi.cpp +++ b/modules/gapi/samples/onevpl_infer_single_roi.cpp @@ -13,6 +13,7 @@ #include #include #include // CommandLineParser +#include #ifdef HAVE_INF_ENGINE #include // ParamMap @@ -126,12 +127,6 @@ G_API_OP(LocateROI, , "sample.custom.locate-roi") { } }; -G_API_OP(ParseSSD, , "sample.custom.parse-ssd") { - static cv::GArrayDesc outMeta(const cv::GMatDesc &, const cv::GOpaqueDesc &, const cv::GOpaqueDesc &) { - return cv::empty_array_desc(); - } -}; - G_API_OP(BBoxes, , "sample.custom.b-boxes") { static cv::GArrayDesc outMeta(const cv::GArrayDesc &, const cv::GOpaqueDesc &) { return cv::empty_array_desc(); @@ -163,55 +158,6 @@ GAPI_OCV_KERNEL(OCVLocateROI, LocateROI) { } }; -GAPI_OCV_KERNEL(OCVParseSSD, ParseSSD) { - static void run(const cv::Mat &in_ssd_result, - const cv::Rect &in_roi, - const cv::Size &in_parent_size, - std::vector &out_objects) { - const auto &in_ssd_dims = in_ssd_result.size; - CV_Assert(in_ssd_dims.dims() == 4u); - - const int MAX_PROPOSALS = in_ssd_dims[2]; - const int OBJECT_SIZE = in_ssd_dims[3]; - CV_Assert(OBJECT_SIZE == 7); // fixed SSD object size - - const cv::Size up_roi = in_roi.size(); - const cv::Rect surface({0,0}, in_parent_size); - - out_objects.clear(); - - const float *data = in_ssd_result.ptr(); - for (int i = 0; i < MAX_PROPOSALS; i++) { - const float image_id = data[i * OBJECT_SIZE + 0]; - const float label = data[i * OBJECT_SIZE + 1]; - const float confidence = data[i * OBJECT_SIZE + 2]; - const float rc_left = data[i * OBJECT_SIZE + 3]; - const float rc_top = data[i * OBJECT_SIZE + 4]; - const float rc_right = data[i * OBJECT_SIZE + 5]; - const float rc_bottom = data[i * OBJECT_SIZE + 6]; - (void) label; // unused - - if (image_id < 0.f) { - break; // marks end-of-detections - } - if (confidence < 0.5f) { - continue; // skip objects with low confidence - } - - // map relative coordinates to the original image scale - // taking the ROI into account - cv::Rect rc; - rc.x = static_cast(rc_left * up_roi.width); - rc.y = static_cast(rc_top * up_roi.height); - rc.width = static_cast(rc_right * up_roi.width) - rc.x; - rc.height = static_cast(rc_bottom * up_roi.height) - rc.y; - rc.x += in_roi.x; - rc.y += in_roi.y; - out_objects.emplace_back(rc & surface); - } - } -}; - GAPI_OCV_KERNEL(OCVBBoxes, BBoxes) { // This kernel converts the rectangles into G-API's // rendering primitives @@ -350,7 +296,6 @@ int main(int argc, char *argv[]) { auto kernels = cv::gapi::kernels < custom::OCVLocateROI - , custom::OCVParseSSD , custom::OCVBBoxes>(); auto networks = cv::gapi::networks(face_net); @@ -379,7 +324,7 @@ int main(int argc, char *argv[]) { auto size = cv::gapi::streaming::size(in); auto roi = custom::LocateROI::on(size); auto blob = cv::gapi::infer(roi, in); - auto rcs = custom::ParseSSD::on(blob, roi, size); + cv::GArray rcs = cv::gapi::parseSSD(blob, size, 0.5f, true, true); auto out_frame = cv::gapi::wip::draw::renderFrame(in, custom::BBoxes::on(rcs, roi)); auto out = cv::gapi::streaming::BGR(out_frame); @@ -398,8 +343,8 @@ int main(int argc, char *argv[]) { pipeline.setSource(std::move(cap)); pipeline.start(); - int framesCount = 0; - cv::TickMeter t; + size_t frames = 0u; + cv::TickMeter tm; cv::VideoWriter writer; if (!output.empty() && !writer.isOpened()) { const auto sz = cv::Size{frame_descr.size.width, frame_descr.size.height}; @@ -408,20 +353,17 @@ int main(int argc, char *argv[]) { } cv::Mat outMat; - t.start(); + tm.start(); while (pipeline.pull(cv::gout(outMat))) { cv::imshow("Out", outMat); cv::waitKey(1); if (!output.empty()) { writer << outMat; } - framesCount++; + ++frames; } - t.stop(); - std::cout << "Elapsed time: " << t.getTimeSec() << std::endl; - std::cout << "FPS: " << framesCount / t.getTimeSec() << std::endl; - std::cout << "framesCount: " << framesCount << std::endl; - + tm.stop(); + std::cout << "Processed " << frames << " frames" << " (" << frames / tm.getTimeSec() << " FPS)" << std::endl; return 0; } diff --git a/modules/gapi/samples/privacy_masking_camera.cpp b/modules/gapi/samples/privacy_masking_camera.cpp index 6e8411c..e7c0a53 100644 --- a/modules/gapi/samples/privacy_masking_camera.cpp +++ b/modules/gapi/samples/privacy_masking_camera.cpp @@ -13,6 +13,7 @@ #include #include #include +#include const std::string about = "This is an OpenCV-based version of Privacy Masking Camera example"; @@ -49,12 +50,6 @@ G_API_NET(FaceDetector, , "face-detector" using GDetections = cv::GArray; -G_API_OP(ParseSSD, , "custom.privacy_masking.postproc") { - static cv::GArrayDesc outMeta(const cv::GMatDesc &, const cv::GMatDesc &, int) { - return cv::empty_array_desc(); - } -}; - using GPrims = cv::GArray; G_API_OP(ToMosaic, , "custom.privacy_masking.to_mosaic") { @@ -63,53 +58,6 @@ G_API_OP(ToMosaic, , "custom.privacy_masking.t } }; -GAPI_OCV_KERNEL(OCVParseSSD, ParseSSD) { - static void run(const cv::Mat &in_ssd_result, - const cv::Mat &in_frame, - const int filter_label, - std::vector &out_objects) { - const auto &in_ssd_dims = in_ssd_result.size; - CV_Assert(in_ssd_dims.dims() == 4u); - - const int MAX_PROPOSALS = in_ssd_dims[2]; - const int OBJECT_SIZE = in_ssd_dims[3]; - CV_Assert(OBJECT_SIZE == 7); // fixed SSD object size - - const cv::Size upscale = in_frame.size(); - const cv::Rect surface({0,0}, upscale); - - out_objects.clear(); - - const float *data = in_ssd_result.ptr(); - for (int i = 0; i < MAX_PROPOSALS; i++) { - const float image_id = data[i * OBJECT_SIZE + 0]; - const float label = data[i * OBJECT_SIZE + 1]; - const float confidence = data[i * OBJECT_SIZE + 2]; - const float rc_left = data[i * OBJECT_SIZE + 3]; - const float rc_top = data[i * OBJECT_SIZE + 4]; - const float rc_right = data[i * OBJECT_SIZE + 5]; - const float rc_bottom = data[i * OBJECT_SIZE + 6]; - - if (image_id < 0.f) { - break; // marks end-of-detections - } - if (confidence < 0.5f) { - continue; // skip objects with low confidence - } - if (filter_label != -1 && static_cast(label) != filter_label) { - continue; // filter out object classes if filter is specified - } - - cv::Rect rc; // map relative coordinates to the original image scale - rc.x = static_cast(rc_left * upscale.width); - rc.y = static_cast(rc_top * upscale.height); - rc.width = static_cast(rc_right * upscale.width) - rc.x; - rc.height = static_cast(rc_bottom * upscale.height) - rc.y; - out_objects.emplace_back(rc & surface); - } - } -}; - GAPI_OCV_KERNEL(OCVToMosaic, ToMosaic) { static void run(const std::vector &in_plate_rcs, const std::vector &in_face_rcs, @@ -150,10 +98,13 @@ int main(int argc, char *argv[]) cv::GMat blob_faces = cv::gapi::infer(in); // VehLicDetector from Open Model Zoo marks vehicles with label "1" and // license plates with label "2", filter out license plates only. - cv::GArray rc_plates = custom::ParseSSD::on(blob_plates, in, 2); + cv::GOpaque sz = cv::gapi::streaming::size(in); + cv::GArray rc_plates, rc_faces; + cv::GArray labels; + std::tie(rc_plates, labels) = cv::gapi::parseSSD(blob_plates, sz, 0.5f, 2); // Face detector produces faces only so there's no need to filter by label, // pass "-1". - cv::GArray rc_faces = custom::ParseSSD::on(blob_faces, in, -1); + std::tie(rc_faces, labels) = cv::gapi::parseSSD(blob_faces, sz, 0.5f, -1); cv::GMat out = cv::gapi::wip::draw::render3ch(in, custom::ToMosaic::on(rc_plates, rc_faces)); cv::GComputation graph(in, out); @@ -169,7 +120,7 @@ int main(int argc, char *argv[]) weights_path(face_model_path), // path to weights cmd.get("faced"), // device specifier }; - auto kernels = cv::gapi::kernels(); + auto kernels = cv::gapi::kernels(); auto networks = cv::gapi::networks(plate_net, face_net); cv::TickMeter tm; diff --git a/modules/gapi/samples/semantic_segmentation.cpp b/modules/gapi/samples/semantic_segmentation.cpp index 4cdb14c..fd3ec27 100644 --- a/modules/gapi/samples/semantic_segmentation.cpp +++ b/modules/gapi/samples/semantic_segmentation.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include const std::string keys = @@ -117,10 +118,7 @@ GAPI_OCV_KERNEL(OCVPostProcessing, PostProcessing) { cv::Mat mask_img; classesToColors(classes, mask_img); - cv::resize(mask_img, out, in.size()); - const float blending = 0.3f; - out = in * blending + out * (1 - blending); } }; } // namespace custom @@ -148,7 +146,10 @@ int main(int argc, char *argv[]) { // Now build the graph cv::GMat in; cv::GMat out_blob = cv::gapi::infer(in); - cv::GMat out = custom::PostProcessing::on(in, out_blob); + cv::GMat post_proc_out = custom::PostProcessing::on(in, out_blob); + cv::GMat blending_in = in * 0.3f; + cv::GMat blending_out = post_proc_out * 0.7f; + cv::GMat out = blending_in + blending_out; cv::GStreamingCompiled pipeline = cv::GComputation(cv::GIn(in), cv::GOut(out)) .compileStreaming(cv::compile_args(kernels, networks)); @@ -156,11 +157,16 @@ int main(int argc, char *argv[]) { // The execution part pipeline.setSource(std::move(inputs)); - pipeline.start(); cv::VideoWriter writer; + cv::TickMeter tm; cv::Mat outMat; + + std::size_t frames = 0u; + tm.start(); + pipeline.start(); while (pipeline.pull(cv::gout(outMat))) { + ++frames; cv::imshow("Out", outMat); cv::waitKey(1); if (!output.empty()) { @@ -172,5 +178,7 @@ int main(int argc, char *argv[]) { writer << outMat; } } + tm.stop(); + std::cout << "Processed " << frames << " frames" << " (" << frames / tm.getTimeSec() << " FPS)" << std::endl; return 0; } -- 2.7.4