Merge remote-tracking branch 'upstream/3.4' into merge-3.4

This commit is contained in:
Alexander Alekhin 2020-04-24 18:32:18 +00:00
commit 152e6476d9
30 changed files with 1658 additions and 44 deletions

View File

@ -620,7 +620,7 @@
volume = {1},
publisher = {IEEE}
}
@article{Lowe:2004:DIF:993451.996342,
@article{Lowe04,
author = {Lowe, David G.},
title = {Distinctive Image Features from Scale-Invariant Keypoints},
journal = {Int. J. Comput. Vision},

View File

@ -44,7 +44,7 @@ img1 = cv.imread('box.png',0) # queryImage
img2 = cv.imread('box_in_scene.png',0) # trainImage
# Initiate SIFT detector
sift = cv.xfeatures2d.SIFT_create()
sift = cv.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)

View File

@ -110,7 +110,7 @@ img1 = cv.imread('box.png',cv.IMREAD_GRAYSCALE) # queryImage
img2 = cv.imread('box_in_scene.png',cv.IMREAD_GRAYSCALE) # trainImage
# Initiate SIFT detector
sift = cv.xfeatures2d.SIFT_create()
sift = cv.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)
@ -174,7 +174,7 @@ img1 = cv.imread('box.png',cv.IMREAD_GRAYSCALE) # queryImage
img2 = cv.imread('box_in_scene.png',cv.IMREAD_GRAYSCALE) # trainImage
# Initiate SIFT detector
sift = cv.xfeatures2d.SIFT_create()
sift = cv.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)

View File

@ -119,7 +119,7 @@ import cv2 as cv
img = cv.imread('home.jpg')
gray= cv.cvtColor(img,cv.COLOR_BGR2GRAY)
sift = cv.xfeatures2d.SIFT_create()
sift = cv.SIFT_create()
kp = sift.detect(gray,None)
img=cv.drawKeypoints(gray,kp,img)
@ -151,7 +151,7 @@ Now to calculate the descriptor, OpenCV provides two methods.
We will see the second method:
@code{.py}
sift = cv.xfeatures2d.SIFT_create()
sift = cv.SIFT_create()
kp, des = sift.detectAndCompute(gray,None)
@endcode
Here kp will be a list of keypoints and des is a numpy array of shape

View File

@ -27,7 +27,7 @@ Binary descriptors (ORB, BRISK, ...) are matched using the <a href="https://en.w
This distance is equivalent to count the number of different elements for binary strings (population count after applying a XOR operation):
\f[ d_{hamming} \left ( a,b \right ) = \sum_{i=0}^{n-1} \left ( a_i \oplus b_i \right ) \f]
To filter the matches, Lowe proposed in @cite Lowe:2004:DIF:993451.996342 to use a distance ratio test to try to eliminate false matches.
To filter the matches, Lowe proposed in @cite Lowe04 to use a distance ratio test to try to eliminate false matches.
The distance ratio between the two nearest matches of a considered keypoint is computed and it is a good match when this value is below
a threshold. Indeed, this ratio allows helping to discriminate between ambiguous matches (distance ratio between the two nearest neighbors
is close to one) and well discriminated matches. The figure below from the SIFT paper illustrates the probability that a match is correct

View File

@ -159,6 +159,7 @@ struct v_uint8x32
(char)v22, (char)v23, (char)v24, (char)v25, (char)v26, (char)v27,
(char)v28, (char)v29, (char)v30, (char)v31);
}
/* coverity[uninit_ctor]: suppress warning */
v_uint8x32() {}
uchar get0() const { return (uchar)_v_cvtsi256_si32(val); }
@ -184,6 +185,7 @@ struct v_int8x32
v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20,
v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31);
}
/* coverity[uninit_ctor]: suppress warning */
v_int8x32() {}
schar get0() const { return (schar)_v_cvtsi256_si32(val); }
@ -205,6 +207,7 @@ struct v_uint16x16
(short)v4, (short)v5, (short)v6, (short)v7, (short)v8, (short)v9,
(short)v10, (short)v11, (short)v12, (short)v13, (short)v14, (short)v15);
}
/* coverity[uninit_ctor]: suppress warning */
v_uint16x16() {}
ushort get0() const { return (ushort)_v_cvtsi256_si32(val); }
@ -225,6 +228,7 @@ struct v_int16x16
val = _mm256_setr_epi16(v0, v1, v2, v3, v4, v5, v6, v7,
v8, v9, v10, v11, v12, v13, v14, v15);
}
/* coverity[uninit_ctor]: suppress warning */
v_int16x16() {}
short get0() const { return (short)_v_cvtsi256_si32(val); }
@ -243,6 +247,7 @@ struct v_uint32x8
val = _mm256_setr_epi32((unsigned)v0, (unsigned)v1, (unsigned)v2,
(unsigned)v3, (unsigned)v4, (unsigned)v5, (unsigned)v6, (unsigned)v7);
}
/* coverity[uninit_ctor]: suppress warning */
v_uint32x8() {}
unsigned get0() const { return (unsigned)_v_cvtsi256_si32(val); }
@ -260,6 +265,7 @@ struct v_int32x8
{
val = _mm256_setr_epi32(v0, v1, v2, v3, v4, v5, v6, v7);
}
/* coverity[uninit_ctor]: suppress warning */
v_int32x8() {}
int get0() const { return _v_cvtsi256_si32(val); }
@ -277,6 +283,7 @@ struct v_float32x8
{
val = _mm256_setr_ps(v0, v1, v2, v3, v4, v5, v6, v7);
}
/* coverity[uninit_ctor]: suppress warning */
v_float32x8() {}
float get0() const { return _mm_cvtss_f32(_mm256_castps256_ps128(val)); }
@ -291,7 +298,9 @@ struct v_uint64x4
explicit v_uint64x4(__m256i v) : val(v) {}
v_uint64x4(uint64 v0, uint64 v1, uint64 v2, uint64 v3)
{ val = _mm256_setr_epi64x((int64)v0, (int64)v1, (int64)v2, (int64)v3); }
/* coverity[uninit_ctor]: suppress warning */
v_uint64x4() {}
uint64 get0() const
{
#if defined __x86_64__ || defined _M_X64
@ -313,6 +322,7 @@ struct v_int64x4
explicit v_int64x4(__m256i v) : val(v) {}
v_int64x4(int64 v0, int64 v1, int64 v2, int64 v3)
{ val = _mm256_setr_epi64x(v0, v1, v2, v3); }
/* coverity[uninit_ctor]: suppress warning */
v_int64x4() {}
int64 get0() const
@ -336,6 +346,7 @@ struct v_float64x4
explicit v_float64x4(__m256d v) : val(v) {}
v_float64x4(double v0, double v1, double v2, double v3)
{ val = _mm256_setr_pd(v0, v1, v2, v3); }
/* coverity[uninit_ctor]: suppress warning */
v_float64x4() {}
double get0() const { return _mm_cvtsd_f64(_mm256_castpd256_pd128(val)); }

View File

@ -75,6 +75,7 @@ struct v_uint8x16
typedef __m128i vector_type;
enum { nlanes = 16 };
/* coverity[uninit_ctor]: suppress warning */
v_uint8x16() {}
explicit v_uint8x16(__m128i v) : val(v) {}
v_uint8x16(uchar v0, uchar v1, uchar v2, uchar v3, uchar v4, uchar v5, uchar v6, uchar v7,
@ -100,6 +101,7 @@ struct v_int8x16
typedef __m128i vector_type;
enum { nlanes = 16 };
/* coverity[uninit_ctor]: suppress warning */
v_int8x16() {}
explicit v_int8x16(__m128i v) : val(v) {}
v_int8x16(schar v0, schar v1, schar v2, schar v3, schar v4, schar v5, schar v6, schar v7,
@ -125,6 +127,7 @@ struct v_uint16x8
typedef __m128i vector_type;
enum { nlanes = 8 };
/* coverity[uninit_ctor]: suppress warning */
v_uint16x8() {}
explicit v_uint16x8(__m128i v) : val(v) {}
v_uint16x8(ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5, ushort v6, ushort v7)
@ -147,6 +150,7 @@ struct v_int16x8
typedef __m128i vector_type;
enum { nlanes = 8 };
/* coverity[uninit_ctor]: suppress warning */
v_int16x8() {}
explicit v_int16x8(__m128i v) : val(v) {}
v_int16x8(short v0, short v1, short v2, short v3, short v4, short v5, short v6, short v7)
@ -169,6 +173,7 @@ struct v_uint32x4
typedef __m128i vector_type;
enum { nlanes = 4 };
/* coverity[uninit_ctor]: suppress warning */
v_uint32x4() {}
explicit v_uint32x4(__m128i v) : val(v) {}
v_uint32x4(unsigned v0, unsigned v1, unsigned v2, unsigned v3)
@ -190,6 +195,7 @@ struct v_int32x4
typedef __m128i vector_type;
enum { nlanes = 4 };
/* coverity[uninit_ctor]: suppress warning */
v_int32x4() {}
explicit v_int32x4(__m128i v) : val(v) {}
v_int32x4(int v0, int v1, int v2, int v3)
@ -211,6 +217,7 @@ struct v_float32x4
typedef __m128 vector_type;
enum { nlanes = 4 };
/* coverity[uninit_ctor]: suppress warning */
v_float32x4() {}
explicit v_float32x4(__m128 v) : val(v) {}
v_float32x4(float v0, float v1, float v2, float v3)
@ -232,6 +239,7 @@ struct v_uint64x2
typedef __m128i vector_type;
enum { nlanes = 2 };
/* coverity[uninit_ctor]: suppress warning */
v_uint64x2() {}
explicit v_uint64x2(__m128i v) : val(v) {}
v_uint64x2(uint64 v0, uint64 v1)
@ -259,6 +267,7 @@ struct v_int64x2
typedef __m128i vector_type;
enum { nlanes = 2 };
/* coverity[uninit_ctor]: suppress warning */
v_int64x2() {}
explicit v_int64x2(__m128i v) : val(v) {}
v_int64x2(int64 v0, int64 v1)
@ -286,6 +295,7 @@ struct v_float64x2
typedef __m128d vector_type;
enum { nlanes = 2 };
/* coverity[uninit_ctor]: suppress warning */
v_float64x2() {}
explicit v_float64x2(__m128d v) : val(v) {}
v_float64x2(double v0, double v1)

View File

@ -2230,7 +2230,7 @@ struct Net::Impl
auto ieInpNode = inputNodes[i].dynamicCast<InfEngineNgraphNode>();
CV_Assert(oid < ieInpNode->node->get_output_size());
#if INF_ENGINE_VER_MAJOR_GT(2020020000)
#if INF_ENGINE_VER_MAJOR_GT(2020030000)
inputNodes[i] = Ptr<BackendNode>(new InfEngineNgraphNode(ieInpNode->node->get_output_as_single_output_node(oid)));
#else
inputNodes[i] = Ptr<BackendNode>(new InfEngineNgraphNode(ieInpNode->node->get_output_as_single_output_node(oid, false)));
@ -3450,6 +3450,8 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
{
CV_TRACE_FUNCTION();
CV_TRACE_REGION("register_inputs");
std::vector<String> inputsNames;
std::vector<MatShape> inp_shapes;
for (auto& it : ieNet.getInputsInfo())
@ -3468,6 +3470,8 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
cvNet.setInputShape(inputsNames[inp_id], inp_shapes[inp_id]);
}
CV_TRACE_REGION_NEXT("backendNode");
Ptr<BackendNode> backendNode;
#ifdef HAVE_DNN_NGRAPH
if (DNN_BACKEND_INFERENCE_ENGINE_NGRAPH == getInferenceEngineBackendTypeParam())
@ -3489,8 +3493,25 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
#endif
}
CV_TRACE_REGION_NEXT("register_outputs");
#ifdef HAVE_DNN_NGRAPH
auto ngraphFunction = ieNet.getFunction();
#if INF_ENGINE_VER_MAJOR_LT(INF_ENGINE_RELEASE_2020_2)
std::list< std::shared_ptr<ngraph::Node> > ngraphOperations;
#else
std::vector< std::shared_ptr<ngraph::Node> > ngraphOperations;
#endif
if (ngraphFunction)
{
ngraphOperations = ngraphFunction->get_ops();
}
#endif
for (auto& it : ieNet.getOutputsInfo())
{
CV_TRACE_REGION("output");
LayerParams lp;
int lid = cvNet.addLayer(it.first, "", lp);
@ -3499,15 +3520,38 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
#ifdef HAVE_DNN_NGRAPH
if (DNN_BACKEND_INFERENCE_ENGINE_NGRAPH == getInferenceEngineBackendTypeParam())
{
const auto& outputName = it.first;
Ptr<Layer> cvLayer(new NgraphBackendLayer(ieNet));
cvLayer->name = outputName;
cvLayer->type = "_unknown_";
InferenceEngine::CNNLayerPtr ieLayer = ieNet.getLayerByName(it.first.c_str());
CV_Assert(ieLayer);
if (ngraphFunction)
{
CV_TRACE_REGION("ngraph_function");
bool found = false;
for (const auto& op : ngraphOperations)
{
CV_Assert(op);
if (op->get_friendly_name() == outputName)
{
const std::string typeName = op->get_type_info().name;
cvLayer->type = typeName;
found = true;
break;
}
}
if (!found)
CV_LOG_WARNING(NULL, "DNN/IE: Can't determine output layer type: '" << outputName << "'");
}
else
{
CV_TRACE_REGION("legacy_cnn_layer");
InferenceEngine::CNNLayerPtr ieLayer = ieNet.getLayerByName(it.first.c_str());
CV_Assert(ieLayer);
cvLayer->name = it.first;
cvLayer->type = ieLayer->type;
cvLayer->type = ieLayer->type;
}
ld.layerInstance = cvLayer;
ld.backendNodes[DNN_BACKEND_INFERENCE_ENGINE_NGRAPH] = backendNode;
}
else
@ -3532,6 +3576,9 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
for (int i = 0; i < inputsNames.size(); ++i)
cvNet.connect(0, i, lid, i);
}
CV_TRACE_REGION_NEXT("finalize");
cvNet.setPreferableBackend(getInferenceEngineBackendTypeParam());
cvNet.impl->skipInfEngineInit = true;

View File

@ -382,6 +382,36 @@ public:
}
};
class BatchNormalizationSubgraph : public Subgraph
{
public:
BatchNormalizationSubgraph()
{
int input = addNodeToMatch("");
int data1 = addNodeToMatch("Constant");
int data2 = addNodeToMatch("Constant");
int data3 = addNodeToMatch("Constant");
int data4 = addNodeToMatch("Constant");
int shape1 = addNodeToMatch("Constant");
int reshape1 = addNodeToMatch("Reshape", data1, shape1);
int shape2 = addNodeToMatch("Constant");
int reshape2 = addNodeToMatch("Reshape", data2, shape2);
int shape3 = addNodeToMatch("Constant");
int reshape3 = addNodeToMatch("Reshape", data3, shape3);
int shape4 = addNodeToMatch("Constant");
int reshape4 = addNodeToMatch("Reshape", data4, shape4);
int sqrtNode = addNodeToMatch("Sqrt", reshape3);
int A = addNodeToMatch("Constant");
int divNode = addNodeToMatch("Div", A, sqrtNode);
int mul1 = addNodeToMatch("Mul", reshape1, divNode);
int mul2 = addNodeToMatch("Mul", reshape4, mul1);
int sub = addNodeToMatch("Sub", reshape2, mul2);
int mul3 = addNodeToMatch("Mul", input, mul1);
addNodeToMatch("Add", mul3, sub);
setFusedNode("BatchNormalization", input, data1, data2, data4 ,data3);
}
};
void simplifySubgraphs(opencv_onnx::GraphProto& net)
{
std::vector<Ptr<Subgraph> > subgraphs;
@ -394,6 +424,7 @@ void simplifySubgraphs(opencv_onnx::GraphProto& net)
subgraphs.push_back(makePtr<NormalizeSubgraph1>());
subgraphs.push_back(makePtr<NormalizeSubgraph2>());
subgraphs.push_back(makePtr<NormalizeSubgraph3>());
subgraphs.push_back(makePtr<BatchNormalizationSubgraph>());
simplifySubgraphs(Ptr<ImportGraphWrapper>(new ONNXGraphWrapper(net)), subgraphs);
}

View File

@ -309,11 +309,30 @@ static void addConstant(const std::string& name,
outShapes.insert(std::make_pair(name, shape(blob)));
}
void addConstantNodesForInitializers(opencv_onnx::GraphProto& graph_proto)
{
int num_initializers = graph_proto.initializer_size();
for (int id = 0; id < num_initializers; id++)
{
opencv_onnx::TensorProto initializer = graph_proto.initializer(id);
opencv_onnx::NodeProto* constant_node = graph_proto.add_node();
constant_node->set_op_type("Constant");
constant_node->set_name(initializer.name());
constant_node->add_output(initializer.name());
opencv_onnx::AttributeProto* value = constant_node->add_attribute();
opencv_onnx::TensorProto* tensor = initializer.New();
tensor->CopyFrom(initializer);
releaseONNXTensor(initializer);
value->set_allocated_t(tensor);
}
}
void ONNXImporter::populateNet(Net dstNet)
{
CV_Assert(model_proto.has_graph());
opencv_onnx::GraphProto graph_proto = model_proto.graph();
addConstantNodesForInitializers(graph_proto);
simplifySubgraphs(graph_proto);
std::map<std::string, Mat> constBlobs = getGraphTensors(graph_proto);

View File

@ -570,6 +570,10 @@ TEST_P(Test_Darknet_layers, reorg)
TEST_P(Test_Darknet_layers, maxpool)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
testDarknetLayer("maxpool");
}

View File

@ -357,6 +357,11 @@ TEST_P(MaxPooling, Accuracy)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && targetId == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
LayerParams lp;
lp.set("pool", "max");
lp.set("kernel_w", kernel.width);

View File

@ -134,6 +134,8 @@ static inline void genData(const InferenceEngine::TensorDesc& desc, Mat& m, Blob
void runIE(Target target, const std::string& xmlPath, const std::string& binPath,
std::map<std::string, cv::Mat>& inputsMap, std::map<std::string, cv::Mat>& outputsMap)
{
SCOPED_TRACE("runIE");
CNNNetReader reader;
reader.ReadNetwork(xmlPath);
reader.ReadWeights(binPath);
@ -247,6 +249,8 @@ void runCV(Backend backendId, Target targetId, const std::string& xmlPath, const
const std::map<std::string, cv::Mat>& inputsMap,
std::map<std::string, cv::Mat>& outputsMap)
{
SCOPED_TRACE("runOCV");
Net net = readNet(xmlPath, binPath);
for (auto& it : inputsMap)
net.setInput(it.second, it.first);
@ -273,9 +277,18 @@ TEST_P(DNNTestOpenVINO, models)
const Backend backendId = get<0>(get<0>(GetParam()));
const Target targetId = get<1>(get<0>(GetParam()));
std::string modelName = get<1>(GetParam());
if (backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
throw SkipTestException("No support for async forward");
ASSERT_FALSE(backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) <<
"Inference Engine backend is required";
#if INF_ENGINE_VER_MAJOR_GE(2020020000)
if (targetId == DNN_TARGET_MYRIAD && backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
{
if (modelName == "person-detection-retail-0013") // IRv10
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
}
#endif
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API);
@ -284,7 +297,6 @@ TEST_P(DNNTestOpenVINO, models)
else
FAIL() << "Unknown backendId";
std::string modelName = get<1>(GetParam());
bool isFP16 = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD);
const std::map<std::string, OpenVINOModelTestCaseInfo>& models = getOpenVINOTestModels();
@ -301,8 +313,8 @@ TEST_P(DNNTestOpenVINO, models)
// Single Myriad device cannot be shared across multiple processes.
if (targetId == DNN_TARGET_MYRIAD)
resetMyriadDevice();
runIE(targetId, xmlPath, binPath, inputsMap, ieOutputsMap);
runCV(backendId, targetId, xmlPath, binPath, inputsMap, cvOutputsMap);
EXPECT_NO_THROW(runIE(targetId, xmlPath, binPath, inputsMap, ieOutputsMap)) << "runIE";
EXPECT_NO_THROW(runCV(backendId, targetId, xmlPath, binPath, inputsMap, cvOutputsMap)) << "runCV";
double eps = 0;
#if INF_ENGINE_VER_MAJOR_GE(2020010000)

View File

@ -98,7 +98,14 @@ TEST_P(Test_ONNX_layers, InstanceNorm)
TEST_P(Test_ONNX_layers, MaxPooling)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
testONNXModels("maxpooling", npy, 0, 0, false, false);
}
TEST_P(Test_ONNX_layers, MaxPooling_2)
{
testONNXModels("two_maxpooling", npy, 0, 0, false, false);
}
@ -314,6 +321,15 @@ TEST_P(Test_ONNX_layers, BatchNormalization3D)
testONNXModels("batch_norm_3d");
}
TEST_P(Test_ONNX_layers, BatchNormalizationUnfused)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
testONNXModels("frozenBatchNorm2d");
}
TEST_P(Test_ONNX_layers, Transpose)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
@ -396,6 +412,16 @@ TEST_P(Test_ONNX_layers, ResizeUnfused)
testONNXModels("resize_bilinear_unfused_opset11_torch1.4");
}
TEST_P(Test_ONNX_layers, ResizeUnfusedTwoInputs)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
testONNXModels("upsample_unfused_two_inputs_opset9_torch1.4", npy, 0, 0, false, true, 2);
testONNXModels("upsample_unfused_two_inputs_opset11_torch1.4", npy, 0, 0, false, true, 2);
}
TEST_P(Test_ONNX_layers, MultyInputs)
{
testONNXModels("multy_inputs", npy, 0, 0, false, true, 2);

View File

@ -128,13 +128,32 @@ TEST_P(Test_TensorFlow_layers, reduce_mean)
runTensorFlowNet("global_pool_by_axis");
}
TEST_P(Test_TensorFlow_layers, conv)
TEST_P(Test_TensorFlow_layers, conv_single_conv)
{
runTensorFlowNet("single_conv");
}
TEST_P(Test_TensorFlow_layers, conv_atrous_conv2d_valid)
{
runTensorFlowNet("atrous_conv2d_valid");
}
TEST_P(Test_TensorFlow_layers, conv_atrous_conv2d_same)
{
runTensorFlowNet("atrous_conv2d_same");
}
TEST_P(Test_TensorFlow_layers, conv_depthwise_conv2d)
{
runTensorFlowNet("depthwise_conv2d");
}
TEST_P(Test_TensorFlow_layers, conv_keras_atrous_conv2d_same)
{
runTensorFlowNet("keras_atrous_conv2d_same");
}
TEST_P(Test_TensorFlow_layers, conv_pool_nchw)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
runTensorFlowNet("conv_pool_nchw");
}
@ -291,11 +310,32 @@ TEST_P(Test_TensorFlow_layers, slim_batch_norm)
runTensorFlowNet("slim_batch_norm", false, l1, lInf);
}
TEST_P(Test_TensorFlow_layers, pooling)
TEST_P(Test_TensorFlow_layers, pooling_max_pool_even)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
runTensorFlowNet("max_pool_even");
}
TEST_P(Test_TensorFlow_layers, pooling_max_pool_odd_valid)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
runTensorFlowNet("max_pool_odd_valid");
}
TEST_P(Test_TensorFlow_layers, pooling_max_pool_odd_same)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
runTensorFlowNet("max_pool_odd_same");
}
TEST_P(Test_TensorFlow_layers, pooling_reduce_mean)
{
runTensorFlowNet("reduce_mean"); // an average pooling over all spatial dimensions.
}
@ -815,24 +855,67 @@ TEST_P(Test_TensorFlow_nets, EAST_text_detection)
INSTANTIATE_TEST_CASE_P(/**/, Test_TensorFlow_nets, dnnBackendsAndTargets());
TEST_P(Test_TensorFlow_layers, fp16_weights)
TEST_P(Test_TensorFlow_layers, fp16_weights_fp16_single_conv)
{
float l1 = 0.00078;
float lInf = 0.012;
float l1 = 0.00078, lInf = 0.012;
runTensorFlowNet("fp16_single_conv", false, l1, lInf);
}
TEST_P(Test_TensorFlow_layers, fp16_weights_fp16_max_pool_odd_same)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
float l1 = 0.00078, lInf = 0.012;
runTensorFlowNet("fp16_max_pool_odd_same", false, l1, lInf);
}
TEST_P(Test_TensorFlow_layers, fp16_weights_fp16_eltwise_add_mul)
{
float l1 = 0.00078, lInf = 0.012;
runTensorFlowNet("fp16_eltwise_add_mul", false, l1, lInf);
}
TEST_P(Test_TensorFlow_layers, fp16_weights_fp16_pad_and_concat)
{
float l1 = 0.00078, lInf = 0.012;
runTensorFlowNet("fp16_pad_and_concat", false, l1, lInf);
}
TEST_P(Test_TensorFlow_layers, fp16_weights_fp16_padding_valid)
{
float l1 = 0.00078, lInf = 0.012;
runTensorFlowNet("fp16_padding_valid", false, l1, lInf);
}
TEST_P(Test_TensorFlow_layers, fp16_weights_fp16_max_pool_even)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
float l1 = 0.00078, lInf = 0.012;
// Reference output values are in range [0.0889, 1.651]
runTensorFlowNet("fp16_max_pool_even", false, (target == DNN_TARGET_MYRIAD) ? 0.003 : l1, lInf);
if (target == DNN_TARGET_MYRIAD)
{
}
TEST_P(Test_TensorFlow_layers, fp16_weights_fp16_deconvolution)
{
float l1 = 0.00078, lInf = 0.012;
if (target == DNN_TARGET_MYRIAD) {
l1 = 0.0041;
lInf = 0.024;
}
// Reference output values are in range [0, 10.75]
runTensorFlowNet("fp16_deconvolution", false, l1, lInf);
}
TEST_P(Test_TensorFlow_layers, fp16_weights_fp16_max_pool_odd_valid)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
float l1 = 0.00078, lInf = 0.012;
if (target == DNN_TARGET_MYRIAD) {
l1 = 0.0041;
lInf = 0.024;
}
// Reference output values are in range [0.418, 2.297]
runTensorFlowNet("fp16_max_pool_odd_valid", false, l1, lInf);
}

View File

@ -244,6 +244,39 @@ typedef Feature2D DescriptorExtractor;
//! @addtogroup features2d_main
//! @{
/** @brief Class for extracting keypoints and computing descriptors using the Scale Invariant Feature Transform
(SIFT) algorithm by D. Lowe @cite Lowe04 .
*/
class CV_EXPORTS_W SIFT : public Feature2D
{
public:
/**
@param nfeatures The number of best features to retain. The features are ranked by their scores
(measured in SIFT algorithm as the local contrast)
@param nOctaveLayers The number of layers in each octave. 3 is the value used in D. Lowe paper. The
number of octaves is computed automatically from the image resolution.
@param contrastThreshold The contrast threshold used to filter out weak features in semi-uniform
(low-contrast) regions. The larger the threshold, the less features are produced by the detector.
@param edgeThreshold The threshold used to filter out edge-like features. Note that the its meaning
is different from the contrastThreshold, i.e. the larger the edgeThreshold, the less features are
filtered out (more features are retained).
@param sigma The sigma of the Gaussian applied to the input image at the octave \#0. If your image
is captured with a weak camera with soft lenses, you might want to reduce the number.
*/
CV_WRAP static Ptr<SIFT> create(int nfeatures = 0, int nOctaveLayers = 3,
double contrastThreshold = 0.04, double edgeThreshold = 10,
double sigma = 1.6);
};
typedef SIFT SiftFeatureDetector;
typedef SIFT SiftDescriptorExtractor;
/** @brief Class implementing the BRISK keypoint detector and descriptor extractor, described in @cite LCS11 .
*/
class CV_EXPORTS_W BRISK : public Feature2D

View File

@ -6,6 +6,7 @@ import org.opencv.core.MatOfKeyPoint;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.KeyPoint;
import org.opencv.features2d.SIFT;
import org.opencv.test.OpenCVTestCase;
import org.opencv.test.OpenCVTestRunner;
import org.opencv.imgproc.Imgproc;
@ -29,7 +30,7 @@ public class SIFTDescriptorExtractorTest extends OpenCVTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
extractor = createClassInstance(XFEATURES2D+"SIFT", DEFAULT_FACTORY, null, null);
extractor = SIFT.create();
keypoint = new KeyPoint(55.775577545166016f, 44.224422454833984f, 16, 9.754629f, 8617.863f, 1, -1);
matSize = 100;
truth = new Mat(1, 128, CvType.CV_32FC1) {

View File

@ -0,0 +1,85 @@
// 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 "perf_precomp.hpp"
namespace opencv_test { namespace {
typedef perf::TestBaseWithParam<std::string> SIFT_detect;
typedef perf::TestBaseWithParam<std::string> SIFT_extract;
typedef perf::TestBaseWithParam<std::string> SIFT_full;
#define SIFT_IMAGES \
"cv/detectors_descriptors_evaluation/images_datasets/leuven/img1.png",\
"stitching/a3.png"
PERF_TEST_P_(SIFT_detect, SIFT)
{
string filename = getDataPath(GetParam());
Mat frame = imread(filename, IMREAD_GRAYSCALE);
ASSERT_FALSE(frame.empty()) << "Unable to load source image " << filename;
Mat mask;
declare.in(frame).time(90);
Ptr<SIFT> detector = SIFT::create();
vector<KeyPoint> points;
PERF_SAMPLE_BEGIN();
detector->detect(frame, points, mask);
PERF_SAMPLE_END();
SANITY_CHECK_NOTHING();
}
PERF_TEST_P_(SIFT_extract, SIFT)
{
string filename = getDataPath(GetParam());
Mat frame = imread(filename, IMREAD_GRAYSCALE);
ASSERT_FALSE(frame.empty()) << "Unable to load source image " << filename;
Mat mask;
declare.in(frame).time(90);
Ptr<SIFT> detector = SIFT::create();
vector<KeyPoint> points;
Mat descriptors;
detector->detect(frame, points, mask);
PERF_SAMPLE_BEGIN();
detector->compute(frame, points, descriptors);
PERF_SAMPLE_END();
SANITY_CHECK_NOTHING();
}
PERF_TEST_P_(SIFT_full, SIFT)
{
string filename = getDataPath(GetParam());
Mat frame = imread(filename, IMREAD_GRAYSCALE);
ASSERT_FALSE(frame.empty()) << "Unable to load source image " << filename;
Mat mask;
declare.in(frame).time(90);
Ptr<SIFT> detector = SIFT::create();
vector<KeyPoint> points;
Mat descriptors;
PERF_SAMPLE_BEGIN();
detector->detectAndCompute(frame, mask, points, descriptors, false);
PERF_SAMPLE_END();
SANITY_CHECK_NOTHING();
}
INSTANTIATE_TEST_CASE_P(/*nothing*/, SIFT_detect,
testing::Values(SIFT_IMAGES)
);
INSTANTIATE_TEST_CASE_P(/*nothing*/, SIFT_extract,
testing::Values(SIFT_IMAGES)
);
INSTANTIATE_TEST_CASE_P(/*nothing*/, SIFT_full,
testing::Values(SIFT_IMAGES)
);
}} // namespace

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,9 @@ const static std::string IMAGE_BIKES = "detectors_descriptors_evaluation/images_
* Descriptors's rotation invariance check
*/
INSTANTIATE_TEST_CASE_P(SIFT, DescriptorRotationInvariance,
Value(IMAGE_TSUKUBA, SIFT::create(), SIFT::create(), 0.98f));
INSTANTIATE_TEST_CASE_P(BRISK, DescriptorRotationInvariance,
Value(IMAGE_TSUKUBA, BRISK::create(), BRISK::create(), 0.99f));
@ -33,6 +36,10 @@ INSTANTIATE_TEST_CASE_P(AKAZE_DESCRIPTOR_KAZE, DescriptorRotationInvariance,
* Descriptor's scale invariance check
*/
// TODO: Expected: (descInliersRatio) >= (minInliersRatio), actual: 0.330378 vs 0.78
INSTANTIATE_TEST_CASE_P(DISABLED_SIFT, DescriptorScaleInvariance,
Value(IMAGE_BIKES, SIFT::create(), SIFT::create(), 0.78f));
INSTANTIATE_TEST_CASE_P(AKAZE, DescriptorScaleInvariance,
Value(IMAGE_BIKES, AKAZE::create(), AKAZE::create(), 0.6f));

View File

@ -18,6 +18,13 @@ namespace opencv_test { namespace {
* Tests registrations *
\****************************************************************************************/
TEST( Features2d_DescriptorExtractor_SIFT, regression )
{
CV_DescriptorExtractorTest<L1<float> > test( "descriptor-sift", 1.0f,
SIFT::create() );
test.safe_run();
}
TEST( Features2d_DescriptorExtractor_BRISK, regression )
{
CV_DescriptorExtractorTest<Hamming> test( "descriptor-brisk",
@ -64,7 +71,7 @@ TEST( Features2d_DescriptorExtractor_AKAZE_DESCRIPTOR_KAZE, regression )
test.safe_run();
}
TEST( Features2d_DescriptorExtractor, batch )
TEST( Features2d_DescriptorExtractor, batch_ORB )
{
string path = string(cvtest::TS::ptr()->get_data_path() + "detectors_descriptors_evaluation/images_datasets/graf");
vector<Mat> imgs, descriptors;
@ -92,6 +99,35 @@ TEST( Features2d_DescriptorExtractor, batch )
}
}
TEST( Features2d_DescriptorExtractor, batch_SIFT )
{
string path = string(cvtest::TS::ptr()->get_data_path() + "detectors_descriptors_evaluation/images_datasets/graf");
vector<Mat> imgs, descriptors;
vector<vector<KeyPoint> > keypoints;
int i, n = 6;
Ptr<SIFT> sift = SIFT::create();
for( i = 0; i < n; i++ )
{
string imgname = format("%s/img%d.png", path.c_str(), i+1);
Mat img = imread(imgname, 0);
imgs.push_back(img);
}
sift->detect(imgs, keypoints);
sift->compute(imgs, keypoints, descriptors);
ASSERT_EQ((int)keypoints.size(), n);
ASSERT_EQ((int)descriptors.size(), n);
for( i = 0; i < n; i++ )
{
EXPECT_GT((int)keypoints[i].size(), 100);
EXPECT_GT(descriptors[i].rows, 100);
}
}
class DescriptorImage : public TestWithParam<std::string>
{
protected:

View File

@ -17,6 +17,9 @@ const static std::string IMAGE_BIKES = "detectors_descriptors_evaluation/images_
* Detector's rotation invariance check
*/
INSTANTIATE_TEST_CASE_P(SIFT, DetectorRotationInvariance,
Value(IMAGE_TSUKUBA, SIFT::create(), 0.45f, 0.70f));
INSTANTIATE_TEST_CASE_P(BRISK, DetectorRotationInvariance,
Value(IMAGE_TSUKUBA, BRISK::create(), 0.45f, 0.76f));
@ -33,6 +36,10 @@ INSTANTIATE_TEST_CASE_P(AKAZE_DESCRIPTOR_KAZE, DetectorRotationInvariance,
* Detector's scale invariance check
*/
// TODO: Expected: (keyPointMatchesRatio) >= (minKeyPointMatchesRatio), actual: 0.596752 vs 0.69
INSTANTIATE_TEST_CASE_P(DISABLED_SIFT, DetectorScaleInvariance,
Value(IMAGE_BIKES, SIFT::create(), 0.69f, 0.98f));
INSTANTIATE_TEST_CASE_P(BRISK, DetectorScaleInvariance,
Value(IMAGE_BIKES, BRISK::create(), 0.08f, 0.49f));

View File

@ -18,6 +18,12 @@ namespace opencv_test { namespace {
* Tests registrations *
\****************************************************************************************/
TEST( Features2d_Detector_SIFT, regression )
{
CV_FeatureDetectorTest test( "detector-sift", SIFT::create() );
test.safe_run();
}
TEST( Features2d_Detector_BRISK, regression )
{
CV_FeatureDetectorTest test( "detector-brisk", BRISK::create() );

View File

@ -177,4 +177,11 @@ TEST(Features2d_Detector_Keypoints_AKAZE, validation)
test_mldb.safe_run();
}
TEST(Features2d_Detector_Keypoints_SIFT, validation)
{
CV_FeatureDetectorKeypointsTest test(SIFT::create());
test.safe_run();
}
}} // namespace

View File

@ -39,10 +39,10 @@ For example to grab from default camera using Direct Show as backend
```cpp
//declare a capture object
cv::VideoCapture cap(0 + cv::CAP_DSHOW);
cv::VideoCapture cap(0, cv::CAP_DSHOW);
//or specify the apiPreference with open
cap.open(0 + cv::CAP_DSHOW);
cap.open(0, cv::CAP_DSHOW);
```
If you want to grab from a file using the Direct Show as backend:

View File

@ -59,7 +59,7 @@
// Please obvserve, that jumbo frames are required when high fps & 16bit data is selected.
// (camera, switches/routers and the computer this software is running on)
//
// Basic usage: VideoCapture cap(CAP_ARAVIS + <camera id>);
// Basic usage: VideoCapture cap(<camera id>, CAP_ARAVIS);
//
// Supported properties:
// read/write

View File

@ -431,10 +431,11 @@ int main(int argc, char* argv[])
{
finder = xfeatures2d::SURF::create();
}
else if (features_type == "sift") {
finder = xfeatures2d::SIFT::create();
}
#endif
else if (features_type == "sift")
{
finder = SIFT::create();
}
else
{
cout << "Unknown 2D features type: '" << features_type << "'.\n";

View File

@ -323,15 +323,8 @@ void createFeatures(const std::string &featureName, int numKeypoints, cv::Ptr<cv
}
else if (featureName == "SIFT")
{
#if defined (OPENCV_ENABLE_NONFREE) && defined (HAVE_OPENCV_XFEATURES2D)
detector = cv::xfeatures2d::SIFT::create();
descriptor = cv::xfeatures2d::SIFT::create();
#else
std::cout << "xfeatures2d module is not available or nonfree is not enabled." << std::endl;
std::cout << "Default to ORB." << std::endl;
detector = cv::ORB::create(numKeypoints);
descriptor = cv::ORB::create(numKeypoints);
#endif
detector = cv::SIFT::create();
descriptor = cv::SIFT::create();
}
else if (featureName == "SURF")
{

View File

@ -25,7 +25,7 @@ int main(int, char**)
int deviceID = 0; // 0 = open default camera
int apiID = cv::CAP_ANY; // 0 = autodetect default API
// open selected camera using selected API
cap.open(deviceID + apiID);
cap.open(deviceID, apiID);
// check if we succeeded
if (!cap.isOpened()) {
cerr << "ERROR! Unable to open camera\n";

View File

@ -29,7 +29,7 @@ FLANN_INDEX_LSH = 6
def init_feature(name):
chunks = name.split('-')
if chunks[0] == 'sift':
detector = cv.xfeatures2d.SIFT_create()
detector = cv.SIFT_create()
norm = cv.NORM_L2
elif chunks[0] == 'surf':
detector = cv.xfeatures2d.SURF_create(800)