JeVoisBase  1.21
JeVois Smart Embedded Machine Vision Toolkit Base Modules
Share this page:
Loading...
Searching...
No Matches
EdgeDetectionX4.C
Go to the documentation of this file.
1// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2//
3// JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2016 by Laurent Itti, the University of Southern
4// California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5//
6// This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7// redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8// Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10// License for more details. You should have received a copy of the GNU General Public License along with this program;
11// if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12//
13// Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14// Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16/*! \file */
17
18#include <jevois/Core/Module.H>
19#include <jevois/Debug/Log.H>
21
22#include <linux/videodev2.h>
23#include <opencv2/core/core.hpp>
24#include <opencv2/imgproc/imgproc.hpp>
25#include <future>
26
27// icon by Sergiu Bagrin in interface at flaticon
28
29static jevois::ParameterCategory const ParamCateg("Edge Detection Options");
30//! Parameter \relates EdgeDetectionX4
31JEVOIS_DECLARE_PARAMETER(thresh1, double, "First threshold for hysteresis", 20.0, ParamCateg);
32//! Parameter \relates EdgeDetectionX4
33JEVOIS_DECLARE_PARAMETER(thresh2, double, "Second threshold for hysteresis", 60.0, ParamCateg);
34//! Parameter \relates EdgeDetectionX4
35JEVOIS_DECLARE_PARAMETER(aperture, int, "Aperture size for the Sobel operator", 3, ParamCateg);
36//! Parameter \relates EdgeDetectionX4
37JEVOIS_DECLARE_PARAMETER(l2grad, bool, "Use more accurate L2 gradient norm if true, L1 if false", false, ParamCateg);
38//! Parameter \relates EdgeDetectionX4
39JEVOIS_DECLARE_PARAMETER(thresh1delta, double, "First threshold delta over threads", 50.0, ParamCateg);
40//! Parameter \relates EdgeDetectionX4
41JEVOIS_DECLARE_PARAMETER(thresh2delta, double, "Second threshold delta over threads", 50.0, ParamCateg);
42
43//! Simple module to detect edges, running 4 filters in parallel with 4 different settings
44/*! Compute 4 Canny edge detection filters with 4 different settings, in parallel.
45
46 This module is useful as a pre-processor, feeding edge maps at 4 different levels of details to further processing
47 that may happen on a host computer. The 4 different levels of detail can be leveraged to first detect the gross
48 outlines of objects, and then focus on finer textures within these objects.
49
50 This algorithm should easily run at 45 frames/s on the JeVois smart camera.
51
52
53 @author Laurent Itti
54
55 @displayname Edge Detection X4
56 @videomapping GREY 320 960 45.0 YUYV 320 240 45.0 JeVois EdgeDetectionX4
57 @email itti\@usc.edu
58 @address University of Southern California, HNB-07A, 3641 Watt Way, Los Angeles, CA 90089-2520, USA
59 @copyright Copyright (C) 2016 by Laurent Itti, iLab and the University of Southern California
60 @mainurl http://jevois.org
61 @supporturl http://jevois.org/doc
62 @otherurl http://iLab.usc.edu
63 @license GPL v3
64 @distribution Unrestricted
65 @restrictions None
66 \ingroup modules */
68 public jevois::Parameter<thresh1, thresh2, aperture, l2grad, thresh1delta, thresh2delta>
69{
70 public:
71 //! Default base class constructor ok
73
74 //! Virtual destructor for safe inheritance
75 virtual ~EdgeDetectionX4() { }
76
77 //! Processing function
78 virtual void process(jevois::InputFrame && inframe, jevois::OutputFrame && outframe) override
79 {
80 // Wait for next available camera image:
81 jevois::RawImage inimg = inframe.get();
82
83 // Convert to grayscale:
84 cv::Mat grayimg = jevois::rawimage::convertToCvGray(inimg);
85
86 // Let camera know we are done processing the input image:
87 inframe.done();
88
89 // Wait for an image from our gadget driver into which we will put our results:
90 jevois::RawImage outimg = outframe.get();
91 outimg.require("output", inimg.width, inimg.height * 4, V4L2_PIX_FMT_GREY);
92
93 // Launch 4 Canny filters in parallel. We launch 3 threads and will do the fourth in the current thread:
94 std::vector<std::future<void> > fut;
95
96 for (int i = 0; i < 3; ++i)
97 fut.push_back(jevois::async([&](int i) {
98 // Compute Canny edges directly into the output image, offset by i images down. The last argument of the
99 // cv::Mat constructor below is the address of an already-allocated pixel buffer for the cv::Mat:
100 cv::Mat edges(grayimg.rows, grayimg.cols, CV_8UC1, outimg.pixelsw<unsigned char>() + i * grayimg.total());
101
102 cv::Canny(grayimg, edges, thresh1::get() + i * thresh1delta::get(),
103 thresh2::get() + i * thresh2delta::get(), aperture::get(), l2grad::get());
104 }, i));
105
106 // Fourth one (same code as above except for the async, and for i=3):
107 cv::Mat edges(grayimg.rows, grayimg.cols, CV_8UC1, outimg.pixelsw<unsigned char>() + 3 * grayimg.total());
108 cv::Canny(grayimg, edges, thresh1::get() + 3 * thresh1delta::get(),
109 thresh2::get() + 3 * thresh2delta::get(), aperture::get(), l2grad::get());
110
111 // The fourth one is done now, wait for all the threads to complete. Note: using async() is preferred to using
112 // std::thread, as get() below will throw if any exception was thrown by a thread, as opposed to std::thread
113 // violently terminating the program on exception. In case two or more threads threw, we can here avoid
114 // termination by catching the exceptions one by one. Here we just ignore (since we are done anyway) but could
115 // throw just once if any of the threads threw:
116 for (auto & f : fut) try { f.get(); } catch (...) { jevois::warnAndIgnoreException(); }
117
118 // Send the output image with our processing results to the host over USB:
119 outframe.send();
120 }
121};
122
123// Allow the module to be loaded as a shared object (.so) file:
JEVOIS_REGISTER_MODULE(ArUcoBlob)
Simple module to detect edges, running 4 filters in parallel with 4 different settings.
virtual ~EdgeDetectionX4()
Virtual destructor for safe inheritance.
JEVOIS_DECLARE_PARAMETER(thresh1, double, "First threshold for hysteresis", 20.0, ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER(thresh1delta, double, "First threshold delta over threads", 50.0, ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER(thresh2delta, double, "Second threshold delta over threads", 50.0, ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER(l2grad, bool, "Use more accurate L2 gradient norm if true, L1 if false", false, ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER(aperture, int, "Aperture size for the Sobel operator", 3, ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER(thresh2, double, "Second threshold for hysteresis", 60.0, ParamCateg)
Parameter.
virtual void process(jevois::InputFrame &&inframe, jevois::OutputFrame &&outframe) override
Processing function.
friend friend class Module
unsigned int width
unsigned int height
void require(char const *info, unsigned int w, unsigned int h, unsigned int f) const
std::string warnAndIgnoreException(std::string const &prefix="")
cv::Mat convertToCvGray(RawImage const &src)
std::future< std::invoke_result_t< std::decay_t< Function >, std::decay_t< Args >... > > async(Function &&f, Args &&... args)