mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 07:43:03 +04:00
JavaScript bindings for dnn module
This commit is contained in:
@@ -15,7 +15,7 @@ set(the_description "Deep neural network module. It allows to load models from d
|
||||
|
||||
ocv_add_dispatched_file("layers/layers_common" AVX AVX2)
|
||||
|
||||
ocv_add_module(dnn opencv_core opencv_imgproc WRAP python matlab java)
|
||||
ocv_add_module(dnn opencv_core opencv_imgproc WRAP python matlab java js)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-shadow -Wno-parentheses -Wmaybe-uninitialized -Wsign-promo
|
||||
-Wmissing-declarations -Wmissing-prototypes
|
||||
)
|
||||
|
||||
@@ -221,11 +221,6 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
|
||||
class CV_EXPORTS LRNLayer : public Layer
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
CHANNEL_NRM,
|
||||
SPATIAL_NRM
|
||||
};
|
||||
int type;
|
||||
|
||||
int size;
|
||||
@@ -238,14 +233,6 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
|
||||
class CV_EXPORTS PoolingLayer : public Layer
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
MAX,
|
||||
AVE,
|
||||
STOCHASTIC,
|
||||
ROI
|
||||
};
|
||||
|
||||
int type;
|
||||
Size kernel, stride, pad;
|
||||
bool globalPooling;
|
||||
@@ -474,13 +461,6 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
|
||||
class CV_EXPORTS EltwiseLayer : public Layer
|
||||
{
|
||||
public:
|
||||
enum EltwiseOp
|
||||
{
|
||||
PROD = 0,
|
||||
SUM = 1,
|
||||
MAX = 2,
|
||||
};
|
||||
|
||||
static Ptr<EltwiseLayer> create(const LayerParams ¶ms);
|
||||
};
|
||||
|
||||
|
||||
@@ -423,8 +423,8 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
|
||||
* @param outputBlobs contains all output blobs for each layer specified in @p outBlobNames.
|
||||
* @param outBlobNames names for layers which outputs are needed to get
|
||||
*/
|
||||
CV_WRAP void forward(std::vector<std::vector<Mat> >& outputBlobs,
|
||||
const std::vector<String>& outBlobNames);
|
||||
void forward(std::vector<std::vector<Mat> >& outputBlobs,
|
||||
const std::vector<String>& outBlobNames);
|
||||
|
||||
//TODO:
|
||||
/** @brief Optimized forward.
|
||||
@@ -467,7 +467,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
|
||||
* @note If updating blob is not empty then @p blob must have the same shape,
|
||||
* because network reshaping is not implemented yet.
|
||||
*/
|
||||
CV_WRAP void setInput(const Mat &blob, const String& name = "");
|
||||
CV_WRAP void setInput(InputArray blob, const String& name = "");
|
||||
|
||||
/** @brief Sets the new value for the learned param of the layer.
|
||||
* @param layer name or id of the layer.
|
||||
@@ -733,7 +733,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
|
||||
* If @p crop is false, direct resize without cropping and preserving aspect ratio is performed.
|
||||
* @returns 4-dimansional Mat with NCHW dimensions order.
|
||||
*/
|
||||
CV_EXPORTS_W Mat blobFromImage(const Mat& image, double scalefactor=1.0, const Size& size = Size(),
|
||||
CV_EXPORTS_W Mat blobFromImage(InputArray image, double scalefactor=1.0, const Size& size = Size(),
|
||||
const Scalar& mean = Scalar(), bool swapRB=true, bool crop=true);
|
||||
/** @brief Creates 4-dimensional blob from series of images. Optionally resizes and
|
||||
* crops @p images from center, subtract @p mean values, scales values by @p scalefactor,
|
||||
|
||||
@@ -84,11 +84,11 @@ static String toString(const T &v)
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
Mat blobFromImage(const Mat& image, double scalefactor, const Size& size,
|
||||
Mat blobFromImage(InputArray image, double scalefactor, const Size& size,
|
||||
const Scalar& mean, bool swapRB, bool crop)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
std::vector<Mat> images(1, image);
|
||||
std::vector<Mat> images(1, image.getMat());
|
||||
return blobFromImages(images, scalefactor, size, mean, swapRB, crop);
|
||||
}
|
||||
|
||||
@@ -1910,7 +1910,7 @@ void Net::setInputsNames(const std::vector<String> &inputBlobNames)
|
||||
impl->netInputLayer->setNames(inputBlobNames);
|
||||
}
|
||||
|
||||
void Net::setInput(const Mat &blob_, const String& name)
|
||||
void Net::setInput(InputArray blob, const String& name)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
CV_TRACE_ARG_VALUE(name, "name", name.c_str());
|
||||
@@ -1930,6 +1930,7 @@ void Net::setInput(const Mat &blob_, const String& name)
|
||||
ld.umat_outputBlobs.resize( std::max(pin.oid+1, (int)ld.requiredOutputs.size()) );
|
||||
ld.outputBlobsWrappers.resize(ld.outputBlobs.size());
|
||||
MatShape prevShape = shape(ld.outputBlobs[pin.oid]);
|
||||
Mat blob_ = blob.getMat();
|
||||
bool oldShape = prevShape == shape(blob_);
|
||||
if (oldShape)
|
||||
{
|
||||
|
||||
@@ -52,22 +52,27 @@ namespace dnn
|
||||
class EltwiseLayerImpl : public EltwiseLayer
|
||||
{
|
||||
public:
|
||||
EltwiseOp op;
|
||||
enum EltwiseOp
|
||||
{
|
||||
PROD = 0,
|
||||
SUM = 1,
|
||||
MAX = 2,
|
||||
} op;
|
||||
std::vector<float> coeffs;
|
||||
|
||||
EltwiseLayerImpl(const LayerParams& params)
|
||||
{
|
||||
setParamsFrom(params);
|
||||
op = EltwiseLayer::SUM;
|
||||
op = SUM;
|
||||
if (params.has("operation"))
|
||||
{
|
||||
String operation = params.get<String>("operation").toLowerCase();
|
||||
if (operation == "prod")
|
||||
op = EltwiseLayer::PROD;
|
||||
op = PROD;
|
||||
else if (operation == "sum")
|
||||
op = EltwiseLayer::SUM;
|
||||
op = SUM;
|
||||
else if (operation == "max")
|
||||
op = EltwiseLayer::MAX;
|
||||
op = MAX;
|
||||
else
|
||||
CV_Error(cv::Error::StsBadArg, "Unknown operaticon type \"" + operation + "\"");
|
||||
}
|
||||
@@ -122,7 +127,7 @@ public:
|
||||
int channels;
|
||||
size_t planeSize;
|
||||
|
||||
EltwiseInvoker() : srcs(0), nsrcs(0), dst(0), coeffs(0), op(EltwiseLayer::PROD), nstripes(0), activ(0), channels(0), planeSize(0) {}
|
||||
EltwiseInvoker() : srcs(0), nsrcs(0), dst(0), coeffs(0), op(PROD), nstripes(0), activ(0), channels(0), planeSize(0) {}
|
||||
|
||||
static void run(const Mat** srcs, int nsrcs, Mat& dst,
|
||||
const std::vector<float>& coeffs, EltwiseOp op,
|
||||
@@ -150,7 +155,7 @@ public:
|
||||
CV_Assert(dst.total() == dst.size[0] * p.channels * p.planeSize);
|
||||
|
||||
bool simpleCoeffs = true;
|
||||
if( op == EltwiseLayer::SUM && !coeffs.empty() )
|
||||
if( op == SUM && !coeffs.empty() )
|
||||
{
|
||||
CV_Assert( coeffs.size() == (size_t)nsrcs );
|
||||
|
||||
@@ -192,7 +197,7 @@ public:
|
||||
const float* srcptr0 = srcs[0]->ptr<float>() + globalDelta;
|
||||
float* dstptr = dstptr0 + globalDelta;
|
||||
|
||||
if( op == EltwiseLayer::PROD )
|
||||
if( op == PROD )
|
||||
{
|
||||
for( k = 1; k < n; k++ )
|
||||
{
|
||||
@@ -204,7 +209,7 @@ public:
|
||||
srcptr0 = (const float*)dstptr;
|
||||
}
|
||||
}
|
||||
else if( op == EltwiseLayer::MAX )
|
||||
else if( op == MAX )
|
||||
{
|
||||
for( k = 1; k < n; k++ )
|
||||
{
|
||||
|
||||
@@ -67,9 +67,9 @@ public:
|
||||
type = -1;
|
||||
String nrmType = params.get<String>("norm_region", "ACROSS_CHANNELS");
|
||||
if (nrmType == "ACROSS_CHANNELS")
|
||||
type = LRNLayer::CHANNEL_NRM;
|
||||
type = CHANNEL_NRM;
|
||||
else if (nrmType == "WITHIN_CHANNEL")
|
||||
type = LRNLayer::SPATIAL_NRM;
|
||||
type = SPATIAL_NRM;
|
||||
else
|
||||
CV_Error(Error::StsBadArg, "Unknown region type \"" + nrmType + "\"");
|
||||
|
||||
@@ -397,6 +397,13 @@ public:
|
||||
}
|
||||
return flops;
|
||||
}
|
||||
|
||||
private:
|
||||
enum Type
|
||||
{
|
||||
CHANNEL_NRM,
|
||||
SPATIAL_NRM
|
||||
};
|
||||
};
|
||||
|
||||
Ptr<LRNLayer> LRNLayer::create(const LayerParams& params)
|
||||
|
||||
@@ -63,7 +63,7 @@ class PoolingLayerImpl : public PoolingLayer
|
||||
public:
|
||||
PoolingLayerImpl(const LayerParams& params)
|
||||
{
|
||||
type = PoolingLayer::MAX;
|
||||
type = MAX;
|
||||
computeMaxIdx = true;
|
||||
globalPooling = false;
|
||||
|
||||
@@ -71,11 +71,11 @@ public:
|
||||
{
|
||||
String pool = params.get<String>("pool").toLowerCase();
|
||||
if (pool == "max")
|
||||
type = PoolingLayer::MAX;
|
||||
type = MAX;
|
||||
else if (pool == "ave")
|
||||
type = PoolingLayer::AVE;
|
||||
type = AVE;
|
||||
else if (pool == "stochastic")
|
||||
type = PoolingLayer::STOCHASTIC;
|
||||
type = STOCHASTIC;
|
||||
else
|
||||
CV_Error(Error::StsBadArg, "Unknown pooling type \"" + pool + "\"");
|
||||
getPoolingKernelParams(params, kernel.height, kernel.width, globalPooling,
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
}
|
||||
else if (params.has("pooled_w") || params.has("pooled_h") || params.has("spatial_scale"))
|
||||
{
|
||||
type = PoolingLayer::ROI;
|
||||
type = ROI;
|
||||
}
|
||||
setParamsFrom(params);
|
||||
ceilMode = params.get<bool>("ceil_mode", true);
|
||||
@@ -115,8 +115,7 @@ public:
|
||||
{
|
||||
return backendId == DNN_BACKEND_DEFAULT ||
|
||||
backendId == DNN_BACKEND_HALIDE && haveHalide() &&
|
||||
(type == PoolingLayer::MAX ||
|
||||
type == PoolingLayer::AVE && !pad.width && !pad.height);
|
||||
(type == MAX || type == AVE && !pad.width && !pad.height);
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
@@ -200,9 +199,9 @@ public:
|
||||
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &inputs)
|
||||
{
|
||||
if (type == PoolingLayer::MAX)
|
||||
if (type == MAX)
|
||||
return initMaxPoolingHalide(inputs);
|
||||
else if (type == PoolingLayer::AVE)
|
||||
else if (type == AVE)
|
||||
return initAvePoolingHalide(inputs);
|
||||
else
|
||||
return Ptr<BackendNode>();
|
||||
@@ -221,7 +220,7 @@ public:
|
||||
float spatialScale;
|
||||
|
||||
PoolingInvoker() : src(0), rois(0), dst(0), mask(0), nstripes(0),
|
||||
computeMaxIdx(0), poolingType(PoolingLayer::MAX), spatialScale(0) {}
|
||||
computeMaxIdx(0), poolingType(MAX), spatialScale(0) {}
|
||||
|
||||
static void run(const Mat& src, const Mat& rois, Mat& dst, Mat& mask, Size kernel,
|
||||
Size stride, Size pad, int poolingType, float spatialScale,
|
||||
@@ -698,7 +697,7 @@ public:
|
||||
out.height = 1;
|
||||
out.width = 1;
|
||||
}
|
||||
else if (type == PoolingLayer::ROI)
|
||||
else if (type == ROI)
|
||||
{
|
||||
out.height = pooledSize.height;
|
||||
out.width = pooledSize.width;
|
||||
@@ -757,6 +756,14 @@ public:
|
||||
}
|
||||
return flops;
|
||||
}
|
||||
private:
|
||||
enum Type
|
||||
{
|
||||
MAX,
|
||||
AVE,
|
||||
STOCHASTIC,
|
||||
ROI
|
||||
};
|
||||
};
|
||||
|
||||
Ptr<PoolingLayer> PoolingLayer::create(const LayerParams& params)
|
||||
|
||||
@@ -73,11 +73,13 @@
|
||||
#include "opencv2/video/tracking.hpp"
|
||||
#include "opencv2/video/background_segm.hpp"
|
||||
#include "opencv2/objdetect.hpp"
|
||||
#include "opencv2/dnn.hpp"
|
||||
|
||||
#include <emscripten/bind.h>
|
||||
|
||||
using namespace emscripten;
|
||||
using namespace cv;
|
||||
using namespace dnn;
|
||||
|
||||
namespace binding_utils
|
||||
{
|
||||
@@ -339,12 +341,12 @@ EMSCRIPTEN_BINDINGS(binding_utils)
|
||||
.constructor<int, int, int, const Scalar&>()
|
||||
.constructor(&binding_utils::createMat, allow_raw_pointers())
|
||||
|
||||
.class_function("eye", select_overload<Mat(int, int, int)>(&binding_utils::matEye))
|
||||
.class_function("eye", select_overload<Mat(Size, int)>(&binding_utils::matEye))
|
||||
.class_function("ones", select_overload<Mat(int, int, int)>(&binding_utils::matOnes))
|
||||
.class_function("eye", select_overload<Mat(int, int, int)>(&binding_utils::matEye))
|
||||
.class_function("ones", select_overload<Mat(Size, int)>(&binding_utils::matOnes))
|
||||
.class_function("zeros", select_overload<Mat(int, int, int)>(&binding_utils::matZeros))
|
||||
.class_function("ones", select_overload<Mat(int, int, int)>(&binding_utils::matOnes))
|
||||
.class_function("zeros", select_overload<Mat(Size, int)>(&binding_utils::matZeros))
|
||||
.class_function("zeros", select_overload<Mat(int, int, int)>(&binding_utils::matZeros))
|
||||
|
||||
.property("rows", &cv::Mat::rows)
|
||||
.property("cols", &cv::Mat::cols)
|
||||
|
||||
@@ -125,6 +125,9 @@ video = {'': ['CamShift', 'calcOpticalFlowFarneback', 'calcOpticalFlowPyrLK', 'c
|
||||
'BackgroundSubtractorMOG2': ['BackgroundSubtractorMOG2', 'apply'],
|
||||
'BackgroundSubtractor': ['apply', 'getBackgroundImage']}
|
||||
|
||||
dnn = {'dnn_Net': ['setInput', 'forward'],
|
||||
'': ['readNetFromCaffe', 'readNetFromTensorflow', 'readNetFromTorch', 'readNetFromDarknet', 'blobFromImage']}
|
||||
|
||||
def makeWhiteList(module_list):
|
||||
wl = {}
|
||||
for m in module_list:
|
||||
@@ -135,7 +138,7 @@ def makeWhiteList(module_list):
|
||||
wl[k] = m[k]
|
||||
return wl
|
||||
|
||||
white_list = makeWhiteList([core, imgproc, objdetect, video])
|
||||
white_list = makeWhiteList([core, imgproc, objdetect, video, dnn])
|
||||
|
||||
# Features to be exported
|
||||
export_enums = False
|
||||
|
||||
Reference in New Issue
Block a user