mirror of
https://github.com/opencv/opencv.git
synced 2025-01-18 22:44:02 +08:00
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
This commit is contained in:
commit
cd2b188c9a
@ -469,8 +469,9 @@ class TextFormat::Parser::ParserImpl {
|
||||
"\" has no field named \"" + field_name + "\".");
|
||||
return false;
|
||||
} else {
|
||||
ReportWarning("Message type \"" + descriptor->full_name() +
|
||||
"\" has no field named \"" + field_name + "\".");
|
||||
// No warnings to let user define custom layers (see https://github.com/opencv/opencv/pull/11129)
|
||||
// ReportWarning("Message type \"" + descriptor->full_name() +
|
||||
// "\" has no field named \"" + field_name + "\".");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -485,10 +486,13 @@ class TextFormat::Parser::ParserImpl {
|
||||
// start with "{" or "<" which indicates the beginning of a message body.
|
||||
// If there is no ":" or there is a "{" or "<" after ":", this field has
|
||||
// to be a message or the input is ill-formed.
|
||||
UnknownFieldSet* unknown_fields = reflection->MutableUnknownFields(message);
|
||||
if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
|
||||
return SkipFieldValue();
|
||||
UnknownFieldSet* unknown_field = unknown_fields->AddGroup(unknown_fields->field_count());
|
||||
unknown_field->AddLengthDelimited(0, field_name); // Add a field's name.
|
||||
return SkipFieldValue(unknown_field);
|
||||
} else {
|
||||
return SkipFieldMessage();
|
||||
return SkipFieldMessage(unknown_fields);
|
||||
}
|
||||
}
|
||||
|
||||
@ -571,7 +575,7 @@ label_skip_parsing:
|
||||
}
|
||||
|
||||
// Skips the next field including the field's name and value.
|
||||
bool SkipField() {
|
||||
bool SkipField(UnknownFieldSet* unknown_fields) {
|
||||
string field_name;
|
||||
if (TryConsume("[")) {
|
||||
// Extension name.
|
||||
@ -588,9 +592,11 @@ label_skip_parsing:
|
||||
// If there is no ":" or there is a "{" or "<" after ":", this field has
|
||||
// to be a message or the input is ill-formed.
|
||||
if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
|
||||
DO(SkipFieldValue());
|
||||
UnknownFieldSet* unknown_field = unknown_fields->AddGroup(unknown_fields->field_count());
|
||||
unknown_field->AddLengthDelimited(0, field_name); // Add a field's name.
|
||||
DO(SkipFieldValue(unknown_field));
|
||||
} else {
|
||||
DO(SkipFieldMessage());
|
||||
DO(SkipFieldMessage(unknown_fields));
|
||||
}
|
||||
// For historical reasons, fields may optionally be separated by commas or
|
||||
// semicolons.
|
||||
@ -625,11 +631,11 @@ label_skip_parsing:
|
||||
|
||||
// Skips the whole body of a message including the beginning delimiter and
|
||||
// the ending delimiter.
|
||||
bool SkipFieldMessage() {
|
||||
bool SkipFieldMessage(UnknownFieldSet* unknown_fields) {
|
||||
string delimiter;
|
||||
DO(ConsumeMessageDelimiter(&delimiter));
|
||||
while (!LookingAt(">") && !LookingAt("}")) {
|
||||
DO(SkipField());
|
||||
DO(SkipField(unknown_fields));
|
||||
}
|
||||
DO(Consume(delimiter));
|
||||
return true;
|
||||
@ -769,7 +775,7 @@ label_skip_parsing:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SkipFieldValue() {
|
||||
bool SkipFieldValue(UnknownFieldSet* unknown_field) {
|
||||
if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
|
||||
while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
|
||||
tokenizer_.Next();
|
||||
@ -779,9 +785,9 @@ label_skip_parsing:
|
||||
if (TryConsume("[")) {
|
||||
while (true) {
|
||||
if (!LookingAt("{") && !LookingAt("<")) {
|
||||
DO(SkipFieldValue());
|
||||
DO(SkipFieldValue(unknown_field));
|
||||
} else {
|
||||
DO(SkipFieldMessage());
|
||||
DO(SkipFieldMessage(unknown_field));
|
||||
}
|
||||
if (TryConsume("]")) {
|
||||
break;
|
||||
@ -833,6 +839,8 @@ label_skip_parsing:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Use a tag 1 because tag 0 is used for field's name.
|
||||
unknown_field->AddLengthDelimited(1, tokenizer_.current().text);
|
||||
tokenizer_.Next();
|
||||
return true;
|
||||
}
|
||||
@ -1298,13 +1306,13 @@ class TextFormat::Printer::TextGenerator
|
||||
TextFormat::Finder::~Finder() {
|
||||
}
|
||||
|
||||
TextFormat::Parser::Parser()
|
||||
TextFormat::Parser::Parser(bool allow_unknown_field)
|
||||
: error_collector_(NULL),
|
||||
finder_(NULL),
|
||||
parse_info_tree_(NULL),
|
||||
allow_partial_(false),
|
||||
allow_case_insensitive_field_(false),
|
||||
allow_unknown_field_(false),
|
||||
allow_unknown_field_(allow_unknown_field),
|
||||
allow_unknown_enum_(false),
|
||||
allow_field_number_(false),
|
||||
allow_relaxed_whitespace_(false),
|
||||
|
@ -457,7 +457,7 @@ class LIBPROTOBUF_EXPORT TextFormat {
|
||||
// For more control over parsing, use this class.
|
||||
class LIBPROTOBUF_EXPORT Parser {
|
||||
public:
|
||||
Parser();
|
||||
Parser(bool allow_unknown_field = false);
|
||||
~Parser();
|
||||
|
||||
// Like TextFormat::Parse().
|
||||
|
@ -258,7 +258,10 @@ if(X86 OR X86_64)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CPU_BASELINE)
|
||||
if(X86_64)
|
||||
if(APPLE)
|
||||
# MacOS X has limited set of possible supported H/W, so compiler is configured well
|
||||
set(CPU_BASELINE "DETECT" CACHE STRING "${HELP_CPU_BASELINE}")
|
||||
elseif(X86_64)
|
||||
set(CPU_BASELINE "SSE3" CACHE STRING "${HELP_CPU_BASELINE}")
|
||||
else()
|
||||
set(CPU_BASELINE "SSE2" CACHE STRING "${HELP_CPU_BASELINE}")
|
||||
|
@ -120,7 +120,9 @@ if(CV_GCC OR CV_CLANG)
|
||||
add_extra_compiler_option(-Wno-unnamed-type-template-args)
|
||||
add_extra_compiler_option(-Wno-comment)
|
||||
if(NOT OPENCV_SKIP_IMPLICIT_FALLTHROUGH
|
||||
AND NOT " ${CMAKE_CXX_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_CXX_FLAGS}" MATCHES "implicit-fallthrough")
|
||||
AND NOT " ${CMAKE_CXX_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_CXX_FLAGS}" MATCHES "implicit-fallthrough"
|
||||
AND (CV_GCC AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)
|
||||
)
|
||||
add_extra_compiler_option(-Wimplicit-fallthrough=3)
|
||||
endif()
|
||||
if(CV_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7.2.0)
|
||||
|
@ -4,12 +4,14 @@
|
||||
# define CV_POPCNT_U64 _mm_popcnt_u64
|
||||
# endif
|
||||
# define CV_POPCNT_U32 _mm_popcnt_u32
|
||||
#else
|
||||
#elif defined(__POPCNT__)
|
||||
# include <popcntintrin.h>
|
||||
# if defined(__x86_64__)
|
||||
# define CV_POPCNT_U64 __builtin_popcountll
|
||||
# endif
|
||||
# define CV_POPCNT_U32 __builtin_popcount
|
||||
#else
|
||||
# error "__POPCNT__ is not defined by compiler"
|
||||
#endif
|
||||
|
||||
int main()
|
||||
|
192
doc/tutorials/dnn/dnn_custom_layers/dnn_custom_layers.md
Normal file
192
doc/tutorials/dnn/dnn_custom_layers/dnn_custom_layers.md
Normal file
@ -0,0 +1,192 @@
|
||||
# Custom deep learning layers support {#tutorial_dnn_custom_layers}
|
||||
|
||||
## Introduction
|
||||
Deep learning is a fast growing area. The new approaches to build neural networks
|
||||
usually introduce new types of layers. They could be modifications of existing
|
||||
ones or implement outstanding researching ideas.
|
||||
|
||||
OpenCV gives an opportunity to import and run networks from different deep learning
|
||||
frameworks. There are a number of the most popular layers. However you can face
|
||||
a problem that your network cannot be imported using OpenCV because of unimplemented layers.
|
||||
|
||||
The first solution is to create a feature request at https://github.com/opencv/opencv/issues
|
||||
mentioning details such a source of model and type of new layer. A new layer could
|
||||
be implemented if OpenCV community shares this need.
|
||||
|
||||
The second way is to define a **custom layer** so OpenCV's deep learning engine
|
||||
will know how to use it. This tutorial is dedicated to show you a process of deep
|
||||
learning models import customization.
|
||||
|
||||
## Define a custom layer in C++
|
||||
Deep learning layer is a building block of network's pipeline.
|
||||
It has connections to **input blobs** and produces results to **output blobs**.
|
||||
There are trained **weights** and **hyper-parameters**.
|
||||
Layers' names, types, weights and hyper-parameters are stored in files are generated by
|
||||
native frameworks during training. If OpenCV mets unknown layer type it throws an
|
||||
exception trying to read a model:
|
||||
|
||||
```
|
||||
Unspecified error: Can't create layer "layer_name" of type "MyType" in function getLayerInstance
|
||||
```
|
||||
|
||||
To import the model correctly you have to derive a class from cv::dnn::Layer with
|
||||
the following methods:
|
||||
|
||||
@snippet dnn/custom_layers.cpp A custom layer interface
|
||||
|
||||
And register it before the import:
|
||||
|
||||
@snippet dnn/custom_layers.cpp Register a custom layer
|
||||
|
||||
@note `MyType` is a type of unimplemented layer from the thrown exception.
|
||||
|
||||
Let's see what all the methods do:
|
||||
|
||||
- Constructor
|
||||
|
||||
@snippet dnn/custom_layers.cpp MyLayer::MyLayer
|
||||
|
||||
Retrieves hyper-parameters from cv::dnn::LayerParams. If your layer has trainable
|
||||
weights they will be already stored in the Layer's member cv::dnn::Layer::blobs.
|
||||
|
||||
- A static method `create`
|
||||
|
||||
@snippet dnn/custom_layers.cpp MyLayer::create
|
||||
|
||||
This method should create an instance of you layer and return cv::Ptr with it.
|
||||
|
||||
- Output blobs' shape computation
|
||||
|
||||
@snippet dnn/custom_layers.cpp MyLayer::getMemoryShapes
|
||||
|
||||
Returns layer's output shapes depends on input shapes. You may request an extra
|
||||
memory using `internals`.
|
||||
|
||||
- Run a layer
|
||||
|
||||
@snippet dnn/custom_layers.cpp MyLayer::forward
|
||||
|
||||
Implement a layer's logic here. Compute outputs for given inputs.
|
||||
|
||||
@note OpenCV manages memory allocated for layers. In the most cases the same memory
|
||||
can be reused between layers. So your `forward` implementation should not rely that
|
||||
the second invocation of `forward` will has the same data at `outputs` and `internals`.
|
||||
|
||||
- Optional `finalize` method
|
||||
|
||||
@snippet dnn/custom_layers.cpp MyLayer::finalize
|
||||
|
||||
The chain of methods are the following: OpenCV deep learning engine calls `create`
|
||||
method once then it calls `getMemoryShapes` for an every created layer then you
|
||||
can make some preparations depends on known input dimensions at cv::dnn::Layer::finalize.
|
||||
After network was initialized only `forward` method is called for an every network's input.
|
||||
|
||||
@note Varying input blobs' sizes such height or width or batch size you make OpenCV
|
||||
reallocate all the internal memory. That leads efficiency gaps. Try to initialize
|
||||
and deploy models using a fixed batch size and image's dimensions.
|
||||
|
||||
## Example: custom layer from Caffe
|
||||
Let's create a custom layer `Interp` from https://github.com/cdmh/deeplab-public.
|
||||
It's just a simple resize that takes an input blob of size `N x C x Hi x Wi` and returns
|
||||
an output blob of size `N x C x Ho x Wo` where `N` is a batch size, `C` is a number of channels,
|
||||
`Hi x Wi` and `Ho x Wo` are input and output `height x width` correspondingly.
|
||||
This layer has no trainable weights but it has hyper-parameters to specify an output size.
|
||||
|
||||
In example,
|
||||
~~~~~~~~~~~~~
|
||||
layer {
|
||||
name: "output"
|
||||
type: "Interp"
|
||||
bottom: "input"
|
||||
top: "output"
|
||||
interp_param {
|
||||
height: 9
|
||||
width: 8
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
This way our implementation can look like:
|
||||
|
||||
@snippet dnn/custom_layers.cpp InterpLayer
|
||||
|
||||
Next we need to register a new layer type and try to import the model.
|
||||
|
||||
@snippet dnn/custom_layers.cpp Register InterpLayer
|
||||
|
||||
## Example: custom layer from TensorFlow
|
||||
This is an example of how to import a network with [tf.image.resize_bilinear](https://www.tensorflow.org/versions/master/api_docs/python/tf/image/resize_bilinear)
|
||||
operation. This is also a resize but with an implementation different from OpenCV's or `Interp` above.
|
||||
|
||||
Let's create a single layer network:
|
||||
~~~~~~~~~~~~~{.py}
|
||||
inp = tf.placeholder(tf.float32, [2, 3, 4, 5], 'input')
|
||||
resized = tf.image.resize_bilinear(inp, size=[9, 8], name='resize_bilinear')
|
||||
~~~~~~~~~~~~~
|
||||
OpenCV sees that TensorFlow's graph in the following way:
|
||||
|
||||
```
|
||||
node {
|
||||
name: "input"
|
||||
op: "Placeholder"
|
||||
attr {
|
||||
key: "dtype"
|
||||
value {
|
||||
type: DT_FLOAT
|
||||
}
|
||||
}
|
||||
}
|
||||
node {
|
||||
name: "resize_bilinear/size"
|
||||
op: "Const"
|
||||
attr {
|
||||
key: "dtype"
|
||||
value {
|
||||
type: DT_INT32
|
||||
}
|
||||
}
|
||||
attr {
|
||||
key: "value"
|
||||
value {
|
||||
tensor {
|
||||
dtype: DT_INT32
|
||||
tensor_shape {
|
||||
dim {
|
||||
size: 2
|
||||
}
|
||||
}
|
||||
tensor_content: "\t\000\000\000\010\000\000\000"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node {
|
||||
name: "resize_bilinear"
|
||||
op: "ResizeBilinear"
|
||||
input: "input:0"
|
||||
input: "resize_bilinear/size"
|
||||
attr {
|
||||
key: "T"
|
||||
value {
|
||||
type: DT_FLOAT
|
||||
}
|
||||
}
|
||||
attr {
|
||||
key: "align_corners"
|
||||
value {
|
||||
b: false
|
||||
}
|
||||
}
|
||||
}
|
||||
library {
|
||||
}
|
||||
```
|
||||
Custom layers import from TensorFlow is designed to put all layer's `attr` into
|
||||
cv::dnn::LayerParams but input `Const` blobs into cv::dnn::Layer::blobs.
|
||||
In our case resize's output shape will be stored in layer's `blobs[0]`.
|
||||
|
||||
@snippet dnn/custom_layers.cpp ResizeBilinearLayer
|
||||
|
||||
Next we register a layer and try to import the model.
|
||||
|
||||
@snippet dnn/custom_layers.cpp Register ResizeBilinearLayer
|
@ -48,3 +48,11 @@ Deep Neural Networks (dnn module) {#tutorial_table_of_content_dnn}
|
||||
*Author:* Dmitry Kurtaev
|
||||
|
||||
In this tutorial we'll run deep learning models in browser using OpenCV.js.
|
||||
|
||||
- @subpage tutorial_dnn_custom_layers
|
||||
|
||||
*Compatibility:* \> OpenCV 3.4.1
|
||||
|
||||
*Author:* Dmitry Kurtaev
|
||||
|
||||
How to define custom layers to import networks.
|
||||
|
@ -751,12 +751,8 @@ bool CirclesGridFinder::isDetectionCorrect()
|
||||
}
|
||||
return (vertices.size() == largeHeight * largeWidth + smallHeight * smallWidth);
|
||||
}
|
||||
|
||||
default:
|
||||
CV_Error(0, "Unknown pattern type");
|
||||
}
|
||||
|
||||
return false;
|
||||
CV_Error(Error::StsBadArg, "Unknown pattern type");
|
||||
}
|
||||
|
||||
void CirclesGridFinder::findMCS(const std::vector<Point2f> &basis, std::vector<Graph> &basisGraphs)
|
||||
|
@ -371,7 +371,7 @@ It is possible to alternate error processing by using redirectError().
|
||||
@param _func - function name. Available only when the compiler supports getting it
|
||||
@param _file - source file name where the error has occurred
|
||||
@param _line - line number in the source file where the error has occurred
|
||||
@see CV_Error, CV_Error_, CV_ErrorNoReturn, CV_ErrorNoReturn_, CV_Assert, CV_DbgAssert
|
||||
@see CV_Error, CV_Error_, CV_Assert, CV_DbgAssert
|
||||
*/
|
||||
CV_EXPORTS void error(int _code, const String& _err, const char* _func, const char* _file, int _line);
|
||||
|
||||
@ -414,8 +414,6 @@ CV_INLINE CV_NORETURN void errorNoReturn(int _code, const String& _err, const ch
|
||||
// We need to use simplified definition for them.
|
||||
#define CV_Error(...) do { abort(); } while (0)
|
||||
#define CV_Error_( code, args ) do { cv::format args; abort(); } while (0)
|
||||
#define CV_ErrorNoReturn(...) do { abort(); } while (0)
|
||||
#define CV_ErrorNoReturn_(...) do { abort(); } while (0)
|
||||
#define CV_Assert_1( expr ) do { if (!(expr)) abort(); } while (0)
|
||||
|
||||
#else // CV_STATIC_ANALYSIS
|
||||
@ -446,22 +444,22 @@ for example:
|
||||
*/
|
||||
#define CV_Error_( code, args ) cv::error( code, cv::format args, CV_Func, __FILE__, __LINE__ )
|
||||
|
||||
/** same as CV_Error(code,msg), but does not return */
|
||||
#define CV_ErrorNoReturn( code, msg ) cv::errorNoReturn( code, msg, CV_Func, __FILE__, __LINE__ )
|
||||
|
||||
/** same as CV_Error_(code,args), but does not return */
|
||||
#define CV_ErrorNoReturn_( code, args ) cv::errorNoReturn( code, cv::format args, CV_Func, __FILE__, __LINE__ )
|
||||
|
||||
#define CV_Assert_1( expr ) if(!!(expr)) ; else cv::error( cv::Error::StsAssert, #expr, CV_Func, __FILE__, __LINE__ )
|
||||
|
||||
//! @cond IGNORED
|
||||
#define CV__ErrorNoReturn( code, msg ) cv::errorNoReturn( code, msg, CV_Func, __FILE__, __LINE__ )
|
||||
#define CV__ErrorNoReturn_( code, args ) cv::errorNoReturn( code, cv::format args, CV_Func, __FILE__, __LINE__ )
|
||||
#ifdef __OPENCV_BUILD
|
||||
#undef CV_Error
|
||||
#define CV_Error CV_ErrorNoReturn
|
||||
#define CV_Error CV__ErrorNoReturn
|
||||
#undef CV_Error_
|
||||
#define CV_Error_ CV_ErrorNoReturn_
|
||||
#define CV_Error_ CV__ErrorNoReturn_
|
||||
#undef CV_Assert_1
|
||||
#define CV_Assert_1( expr ) if(!!(expr)) ; else cv::errorNoReturn( cv::Error::StsAssert, #expr, CV_Func, __FILE__, __LINE__ )
|
||||
#else
|
||||
// backward compatibility
|
||||
#define CV_ErrorNoReturn CV__ErrorNoReturn
|
||||
#define CV_ErrorNoReturn_ CV__ErrorNoReturn_
|
||||
#endif
|
||||
//! @endcond
|
||||
|
||||
|
@ -1042,13 +1042,16 @@ template<typename _Tp, int n> inline bool v_check_any(const v_reg<_Tp, n>& a)
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @brief Bitwise select
|
||||
/** @brief Per-element select (blend operation)
|
||||
|
||||
Return value will be built by combining values a and b using the following scheme:
|
||||
If the i-th bit in _mask_ is 1
|
||||
select i-th bit from _a_
|
||||
else
|
||||
select i-th bit from _b_ */
|
||||
Return value will be built by combining values _a_ and _b_ using the following scheme:
|
||||
result[i] = mask[i] ? a[i] : b[i];
|
||||
|
||||
@note: _mask_ element values are restricted to these values:
|
||||
- 0: select element from _b_
|
||||
- 0xff/0xffff/etc: select element from _a_
|
||||
(fully compatible with bitwise-based operator)
|
||||
*/
|
||||
template<typename _Tp, int n> inline v_reg<_Tp, n> v_select(const v_reg<_Tp, n>& mask,
|
||||
const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b)
|
||||
{
|
||||
@ -1058,8 +1061,8 @@ template<typename _Tp, int n> inline v_reg<_Tp, n> v_select(const v_reg<_Tp, n>&
|
||||
for( int i = 0; i < n; i++ )
|
||||
{
|
||||
int_type m = Traits::reinterpret_int(mask.s[i]);
|
||||
c.s[i] = Traits::reinterpret_from_int((Traits::reinterpret_int(a.s[i]) & m)
|
||||
| (Traits::reinterpret_int(b.s[i]) & ~m));
|
||||
CV_DbgAssert(m == 0 || m == (~(int_type)0)); // restrict mask values: 0 or 0xff/0xffff/etc
|
||||
c.s[i] = m ? a.s[i] : b.s[i];
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
@ -438,10 +438,14 @@ void v_rshr_pack_store(schar* ptr, const v_int16x8& a)
|
||||
}
|
||||
|
||||
|
||||
// bit-wise "mask ? a : b"
|
||||
// byte-wise "mask ? a : b"
|
||||
inline __m128i v_select_si128(__m128i mask, __m128i a, __m128i b)
|
||||
{
|
||||
#if CV_SSE4_1
|
||||
return _mm_blendv_epi8(b, a, mask);
|
||||
#else
|
||||
return _mm_xor_si128(b, _mm_and_si128(_mm_xor_si128(a, b), mask));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline v_uint16x8 v_pack(const v_uint32x4& a, const v_uint32x4& b)
|
||||
@ -1403,6 +1407,26 @@ OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_int32x4, epi8, v_packq_epi32, OPENCV_HAL_AND,
|
||||
OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_float32x4, ps, OPENCV_HAL_NOP, OPENCV_HAL_1ST, 15, 15)
|
||||
OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_float64x2, pd, OPENCV_HAL_NOP, OPENCV_HAL_1ST, 3, 3)
|
||||
|
||||
#if CV_SSE4_1
|
||||
#define OPENCV_HAL_IMPL_SSE_SELECT(_Tpvec, cast_ret, cast, suffix) \
|
||||
inline _Tpvec v_select(const _Tpvec& mask, const _Tpvec& a, const _Tpvec& b) \
|
||||
{ \
|
||||
return _Tpvec(cast_ret(_mm_blendv_##suffix(cast(b.val), cast(a.val), cast(mask.val)))); \
|
||||
}
|
||||
|
||||
OPENCV_HAL_IMPL_SSE_SELECT(v_uint8x16, OPENCV_HAL_NOP, OPENCV_HAL_NOP, epi8)
|
||||
OPENCV_HAL_IMPL_SSE_SELECT(v_int8x16, OPENCV_HAL_NOP, OPENCV_HAL_NOP, epi8)
|
||||
OPENCV_HAL_IMPL_SSE_SELECT(v_uint16x8, OPENCV_HAL_NOP, OPENCV_HAL_NOP, epi8)
|
||||
OPENCV_HAL_IMPL_SSE_SELECT(v_int16x8, OPENCV_HAL_NOP, OPENCV_HAL_NOP, epi8)
|
||||
OPENCV_HAL_IMPL_SSE_SELECT(v_uint32x4, _mm_castps_si128, _mm_castsi128_ps, ps)
|
||||
OPENCV_HAL_IMPL_SSE_SELECT(v_int32x4, _mm_castps_si128, _mm_castsi128_ps, ps)
|
||||
// OPENCV_HAL_IMPL_SSE_SELECT(v_uint64x2, TBD, TBD, pd)
|
||||
// OPENCV_HAL_IMPL_SSE_SELECT(v_int64x2, TBD, TBD, ps)
|
||||
OPENCV_HAL_IMPL_SSE_SELECT(v_float32x4, OPENCV_HAL_NOP, OPENCV_HAL_NOP, ps)
|
||||
OPENCV_HAL_IMPL_SSE_SELECT(v_float64x2, OPENCV_HAL_NOP, OPENCV_HAL_NOP, pd)
|
||||
|
||||
#else // CV_SSE4_1
|
||||
|
||||
#define OPENCV_HAL_IMPL_SSE_SELECT(_Tpvec, suffix) \
|
||||
inline _Tpvec v_select(const _Tpvec& mask, const _Tpvec& a, const _Tpvec& b) \
|
||||
{ \
|
||||
@ -1419,6 +1443,7 @@ OPENCV_HAL_IMPL_SSE_SELECT(v_int32x4, si128)
|
||||
// OPENCV_HAL_IMPL_SSE_SELECT(v_int64x2, si128)
|
||||
OPENCV_HAL_IMPL_SSE_SELECT(v_float32x4, ps)
|
||||
OPENCV_HAL_IMPL_SSE_SELECT(v_float64x2, pd)
|
||||
#endif
|
||||
|
||||
#define OPENCV_HAL_IMPL_SSE_EXPAND(_Tpuvec, _Tpwuvec, _Tpu, _Tpsvec, _Tpwsvec, _Tps, suffix, wsuffix, shift) \
|
||||
inline void v_expand(const _Tpuvec& a, _Tpwuvec& b0, _Tpwuvec& b1) \
|
||||
@ -1607,6 +1632,28 @@ inline void v_load_deinterleave(const uchar* ptr, v_uint8x16& a, v_uint8x16& b)
|
||||
|
||||
inline void v_load_deinterleave(const uchar* ptr, v_uint8x16& a, v_uint8x16& b, v_uint8x16& c)
|
||||
{
|
||||
#if CV_SSSE3
|
||||
static const __m128i m0 = _mm_setr_epi8(0, 3, 6, 9, 12, 15, 1, 4, 7, 10, 13, 2, 5, 8, 11, 14);
|
||||
static const __m128i m1 = _mm_alignr_epi8(m0, m0, 11);
|
||||
static const __m128i m2 = _mm_alignr_epi8(m0, m0, 6);
|
||||
|
||||
__m128i t0 = _mm_loadu_si128((const __m128i*)ptr);
|
||||
__m128i t1 = _mm_loadu_si128((const __m128i*)(ptr + 16));
|
||||
__m128i t2 = _mm_loadu_si128((const __m128i*)(ptr + 32));
|
||||
|
||||
__m128i s0 = _mm_shuffle_epi8(t0, m0);
|
||||
__m128i s1 = _mm_shuffle_epi8(t1, m1);
|
||||
__m128i s2 = _mm_shuffle_epi8(t2, m2);
|
||||
|
||||
t0 = _mm_alignr_epi8(s1, _mm_slli_si128(s0, 10), 5);
|
||||
a.val = _mm_alignr_epi8(s2, t0, 5);
|
||||
|
||||
t1 = _mm_alignr_epi8(_mm_srli_si128(s1, 5), _mm_slli_si128(s0, 5), 6);
|
||||
b.val = _mm_alignr_epi8(_mm_srli_si128(s2, 5), t1, 5);
|
||||
|
||||
t2 = _mm_alignr_epi8(_mm_srli_si128(s2, 10), s1, 11);
|
||||
c.val = _mm_alignr_epi8(t2, s0, 11);
|
||||
#else
|
||||
__m128i t00 = _mm_loadu_si128((const __m128i*)ptr);
|
||||
__m128i t01 = _mm_loadu_si128((const __m128i*)(ptr + 16));
|
||||
__m128i t02 = _mm_loadu_si128((const __m128i*)(ptr + 32));
|
||||
@ -1626,6 +1673,7 @@ inline void v_load_deinterleave(const uchar* ptr, v_uint8x16& a, v_uint8x16& b,
|
||||
a.val = _mm_unpacklo_epi8(t30, _mm_unpackhi_epi64(t31, t31));
|
||||
b.val = _mm_unpacklo_epi8(_mm_unpackhi_epi64(t30, t30), t32);
|
||||
c.val = _mm_unpacklo_epi8(t31, _mm_unpackhi_epi64(t32, t32));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void v_load_deinterleave(const uchar* ptr, v_uint8x16& a, v_uint8x16& b, v_uint8x16& c, v_uint8x16& d)
|
||||
@ -1840,6 +1888,27 @@ inline void v_store_interleave( uchar* ptr, const v_uint8x16& a, const v_uint8x1
|
||||
inline void v_store_interleave( uchar* ptr, const v_uint8x16& a, const v_uint8x16& b,
|
||||
const v_uint8x16& c )
|
||||
{
|
||||
#if CV_SSSE3
|
||||
static const __m128i m0 = _mm_setr_epi8(0, 6, 11, 1, 7, 12, 2, 8, 13, 3, 9, 14, 4, 10, 15, 5);
|
||||
static const __m128i m1 = _mm_setr_epi8(5, 11, 0, 6, 12, 1, 7, 13, 2, 8, 14, 3, 9, 15, 4, 10);
|
||||
static const __m128i m2 = _mm_setr_epi8(10, 0, 5, 11, 1, 6, 12, 2, 7, 13, 3, 8, 14, 4, 9, 15);
|
||||
|
||||
__m128i t0 = _mm_alignr_epi8(b.val, _mm_slli_si128(a.val, 10), 5);
|
||||
t0 = _mm_alignr_epi8(c.val, t0, 5);
|
||||
__m128i s0 = _mm_shuffle_epi8(t0, m0);
|
||||
|
||||
__m128i t1 = _mm_alignr_epi8(_mm_srli_si128(b.val, 5), _mm_slli_si128(a.val, 5), 6);
|
||||
t1 = _mm_alignr_epi8(_mm_srli_si128(c.val, 5), t1, 5);
|
||||
__m128i s1 = _mm_shuffle_epi8(t1, m1);
|
||||
|
||||
__m128i t2 = _mm_alignr_epi8(_mm_srli_si128(c.val, 10), b.val, 11);
|
||||
t2 = _mm_alignr_epi8(t2, a.val, 11);
|
||||
__m128i s2 = _mm_shuffle_epi8(t2, m2);
|
||||
|
||||
_mm_storeu_si128((__m128i*)ptr, s0);
|
||||
_mm_storeu_si128((__m128i*)(ptr + 16), s1);
|
||||
_mm_storeu_si128((__m128i*)(ptr + 32), s2);
|
||||
#else
|
||||
__m128i z = _mm_setzero_si128();
|
||||
__m128i ab0 = _mm_unpacklo_epi8(a.val, b.val);
|
||||
__m128i ab1 = _mm_unpackhi_epi8(a.val, b.val);
|
||||
@ -1881,6 +1950,7 @@ inline void v_store_interleave( uchar* ptr, const v_uint8x16& a, const v_uint8x1
|
||||
_mm_storeu_si128((__m128i*)(ptr), v0);
|
||||
_mm_storeu_si128((__m128i*)(ptr + 16), v1);
|
||||
_mm_storeu_si128((__m128i*)(ptr + 32), v2);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void v_store_interleave( uchar* ptr, const v_uint8x16& a, const v_uint8x16& b,
|
||||
|
@ -93,7 +93,7 @@ static void dumpOpenCLInformation()
|
||||
|
||||
const Device& device = Device::getDefault();
|
||||
if (!device.available())
|
||||
CV_ErrorNoReturn(Error::OpenCLInitError, "OpenCL device is not available");
|
||||
CV_Error(Error::OpenCLInitError, "OpenCL device is not available");
|
||||
|
||||
DUMP_MESSAGE_STDOUT("Current OpenCL device: ");
|
||||
|
||||
|
@ -76,7 +76,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef CL_VERSION_1_2
|
||||
#define CV_REQUIRE_OPENCL_1_2_ERROR CV_ErrorNoReturn(cv::Error::OpenCLApiCallError, "OpenCV compiled without OpenCL v1.2 support, so we can't use functionality from OpenCL v1.2")
|
||||
#define CV_REQUIRE_OPENCL_1_2_ERROR CV_Error(cv::Error::OpenCLApiCallError, "OpenCV compiled without OpenCL v1.2 support, so we can't use functionality from OpenCL v1.2")
|
||||
#endif
|
||||
|
||||
#endif // HAVE_OPENCL
|
||||
|
@ -96,8 +96,8 @@ PERF_TEST_P(Size_MatType, Mat_Clone_Roi,
|
||||
}
|
||||
|
||||
PERF_TEST_P(Size_MatType, Mat_CopyToWithMask,
|
||||
testing::Combine(testing::Values(TYPICAL_MAT_SIZES),
|
||||
testing::Values(CV_8UC1, CV_8UC2))
|
||||
testing::Combine(testing::Values(::perf::sz1080p, ::perf::szODD),
|
||||
testing::Values(CV_8UC1, CV_8UC2, CV_8UC3, CV_16UC1, CV_32SC1, CV_32FC4))
|
||||
)
|
||||
{
|
||||
const Size_MatType_t params = GetParam();
|
||||
|
@ -53,7 +53,6 @@ namespace cv {
|
||||
static void* OutOfMemoryError(size_t size)
|
||||
{
|
||||
CV_Error_(CV_StsNoMem, ("Failed to allocate %llu bytes", (unsigned long long)size));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,3 +1,6 @@
|
||||
// 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 "precomp.hpp"
|
||||
#include <sstream>
|
||||
|
||||
@ -364,7 +367,6 @@ bool CommandLineParser::has(const String& name) const
|
||||
}
|
||||
|
||||
CV_Error_(Error::StsBadArg, ("undeclared key '%s' requested", name.c_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CommandLineParser::check() const
|
||||
|
@ -91,11 +91,7 @@ copyMask_<uchar>(const uchar* _src, size_t sstep, const uchar* mask, size_t mste
|
||||
uchar* dst = (uchar*)_dst;
|
||||
int x = 0;
|
||||
#if CV_SIMD128
|
||||
if( hasSIMD128()
|
||||
#if CV_SSE4_2
|
||||
&& USE_SSE4_2
|
||||
#endif
|
||||
) {
|
||||
{
|
||||
v_uint8x16 v_zero = v_setzero_u8();
|
||||
|
||||
for( ; x <= size.width - 16; x += 16 )
|
||||
@ -104,11 +100,7 @@ copyMask_<uchar>(const uchar* _src, size_t sstep, const uchar* mask, size_t mste
|
||||
v_dst = v_load(dst + x),
|
||||
v_nmask = v_load(mask + x) == v_zero;
|
||||
|
||||
#if CV_SSE4_2
|
||||
v_dst = v_uint8x16(_mm_blendv_epi8(v_src.val, v_dst.val, v_nmask.val));
|
||||
#else
|
||||
v_dst = v_select(v_nmask, v_dst, v_src);
|
||||
#endif
|
||||
v_store(dst + x, v_dst);
|
||||
}
|
||||
}
|
||||
@ -130,11 +122,7 @@ copyMask_<ushort>(const uchar* _src, size_t sstep, const uchar* mask, size_t mst
|
||||
ushort* dst = (ushort*)_dst;
|
||||
int x = 0;
|
||||
#if CV_SIMD128
|
||||
if( hasSIMD128()
|
||||
#if CV_SSE4_2
|
||||
&& USE_SSE4_2
|
||||
#endif
|
||||
) {
|
||||
{
|
||||
v_uint8x16 v_zero = v_setzero_u8();
|
||||
|
||||
for( ; x <= size.width - 16; x += 16 )
|
||||
@ -146,13 +134,8 @@ copyMask_<ushort>(const uchar* _src, size_t sstep, const uchar* mask, size_t mst
|
||||
v_uint8x16 v_nmask = v_load(mask + x) == v_zero;
|
||||
v_zip(v_nmask, v_nmask, v_nmask1, v_nmask2);
|
||||
|
||||
#if CV_SSE4_2
|
||||
v_dst1 = v_uint16x8(_mm_blendv_epi8(v_src1.val, v_dst1.val, v_nmask1.val));
|
||||
v_dst2 = v_uint16x8(_mm_blendv_epi8(v_src2.val, v_dst2.val, v_nmask2.val));
|
||||
#else
|
||||
v_dst1 = v_select(v_reinterpret_as_u16(v_nmask1), v_dst1, v_src1);
|
||||
v_dst2 = v_select(v_reinterpret_as_u16(v_nmask2), v_dst2, v_src2);
|
||||
#endif
|
||||
v_store(dst + x, v_dst1);
|
||||
v_store(dst + x + 8, v_dst2);
|
||||
}
|
||||
|
@ -50,11 +50,11 @@
|
||||
#include <vector>
|
||||
# include "directx.inc.hpp"
|
||||
#else // HAVE_DIRECTX
|
||||
#define NO_DIRECTX_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without DirectX support")
|
||||
#define NO_DIRECTX_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without DirectX support")
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_OPENCL
|
||||
# define NO_OPENCL_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
|
||||
# define NO_OPENCL_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
|
||||
#endif // HAVE_OPENCL
|
||||
|
||||
namespace cv { namespace directx {
|
||||
|
@ -143,6 +143,9 @@
|
||||
return func;
|
||||
}
|
||||
#else
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable : 4702) // unreachable code
|
||||
#endif
|
||||
static void* IntGetProcAddress(const char*)
|
||||
{
|
||||
CV_Error(cv::Error::OpenGlNotSupported, "The library is compiled without OpenGL support");
|
||||
|
@ -912,7 +912,6 @@ Mat Mat::reshape(int _cn, int _newndims, const int* _newsz) const
|
||||
|
||||
CV_Error(CV_StsNotImplemented, "Reshaping of n-dimensional non-continuous matrices is not supported yet");
|
||||
// TBD
|
||||
return Mat();
|
||||
}
|
||||
|
||||
Mat Mat::reshape(int _cn, const std::vector<int>& _newshape) const
|
||||
|
@ -179,7 +179,6 @@ Mat cvarrToMat(const CvArr* arr, bool copyData,
|
||||
return buf;
|
||||
}
|
||||
CV_Error(CV_StsBadArg, "Unknown array type");
|
||||
return Mat();
|
||||
}
|
||||
|
||||
void extractImageCOI(const CvArr* arr, OutputArray _ch, int coi)
|
||||
|
@ -110,14 +110,12 @@ Mat _InputArray::getMat_(int i) const
|
||||
{
|
||||
CV_Assert( i < 0 );
|
||||
CV_Error(cv::Error::StsNotImplemented, "You should explicitly call mapHost/unmapHost methods for ogl::Buffer object");
|
||||
return Mat();
|
||||
}
|
||||
|
||||
if( k == CUDA_GPU_MAT )
|
||||
{
|
||||
CV_Assert( i < 0 );
|
||||
CV_Error(cv::Error::StsNotImplemented, "You should explicitly call download method for cuda::GpuMat object");
|
||||
return Mat();
|
||||
}
|
||||
|
||||
if( k == CUDA_HOST_MEM )
|
||||
@ -130,7 +128,6 @@ Mat _InputArray::getMat_(int i) const
|
||||
}
|
||||
|
||||
CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
|
||||
return Mat();
|
||||
}
|
||||
|
||||
UMat _InputArray::getUMat(int i) const
|
||||
@ -354,14 +351,12 @@ cuda::GpuMat _InputArray::getGpuMat() const
|
||||
if (k == OPENGL_BUFFER)
|
||||
{
|
||||
CV_Error(cv::Error::StsNotImplemented, "You should explicitly call mapDevice/unmapDevice methods for ogl::Buffer object");
|
||||
return cuda::GpuMat();
|
||||
}
|
||||
|
||||
if (k == NONE)
|
||||
return cuda::GpuMat();
|
||||
|
||||
CV_Error(cv::Error::StsNotImplemented, "getGpuMat is available only for cuda::GpuMat and cuda::HostMem");
|
||||
return cuda::GpuMat();
|
||||
}
|
||||
void _InputArray::getGpuMatVector(std::vector<cuda::GpuMat>& gpumv) const
|
||||
{
|
||||
@ -516,7 +511,6 @@ Size _InputArray::size(int i) const
|
||||
}
|
||||
|
||||
CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
|
||||
return Size();
|
||||
}
|
||||
|
||||
int _InputArray::sizend(int* arrsz, int i) const
|
||||
@ -716,7 +710,6 @@ int _InputArray::dims(int i) const
|
||||
}
|
||||
|
||||
CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t _InputArray::total(int i) const
|
||||
@ -845,7 +838,6 @@ int _InputArray::type(int i) const
|
||||
return ((const cuda::HostMem*)obj)->type();
|
||||
|
||||
CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _InputArray::depth(int i) const
|
||||
@ -928,7 +920,6 @@ bool _InputArray::empty() const
|
||||
return ((const cuda::HostMem*)obj)->empty();
|
||||
|
||||
CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _InputArray::isContinuous(int i) const
|
||||
@ -970,7 +961,6 @@ bool _InputArray::isContinuous(int i) const
|
||||
return i < 0 ? ((const cuda::GpuMat*)obj)->isContinuous() : true;
|
||||
|
||||
CV_Error(CV_StsNotImplemented, "Unknown/unsupported array type");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool _InputArray::isSubmatrix(int i) const
|
||||
@ -1009,7 +999,6 @@ bool _InputArray::isSubmatrix(int i) const
|
||||
}
|
||||
|
||||
CV_Error(CV_StsNotImplemented, "");
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t _InputArray::offset(int i) const
|
||||
@ -1074,7 +1063,6 @@ size_t _InputArray::offset(int i) const
|
||||
}
|
||||
|
||||
CV_Error(Error::StsNotImplemented, "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t _InputArray::step(int i) const
|
||||
@ -1135,7 +1123,6 @@ size_t _InputArray::step(int i) const
|
||||
}
|
||||
|
||||
CV_Error(Error::StsNotImplemented, "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _InputArray::copyTo(const _OutputArray& arr) const
|
||||
@ -1459,7 +1446,6 @@ void _OutputArray::create(int d, const int* sizes, int mtype, int i,
|
||||
if( k == NONE )
|
||||
{
|
||||
CV_Error(CV_StsNullPtr, "create() called for the missing output array" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( k == STD_VECTOR_MAT )
|
||||
|
@ -133,7 +133,7 @@ namespace cv { namespace ocl {
|
||||
int refcount
|
||||
|
||||
#ifndef HAVE_OPENCL
|
||||
#define CV_OPENCL_NO_SUPPORT() CV_ErrorNoReturn(cv::Error::OpenCLApiCallError, "OpenCV build without OpenCL support")
|
||||
#define CV_OPENCL_NO_SUPPORT() CV_Error(cv::Error::OpenCLApiCallError, "OpenCV build without OpenCL support")
|
||||
namespace {
|
||||
struct DummyImpl
|
||||
{
|
||||
@ -2177,7 +2177,7 @@ struct Context::Impl
|
||||
if (!ptr)
|
||||
{
|
||||
CV_OPENCL_SVM_TRACE_ERROR_P("clSVMAlloc returned NULL...\n");
|
||||
CV_ErrorNoReturn(Error::StsBadArg, "clSVMAlloc returned NULL");
|
||||
CV_Error(Error::StsBadArg, "clSVMAlloc returned NULL");
|
||||
}
|
||||
try
|
||||
{
|
||||
@ -2186,7 +2186,7 @@ struct Context::Impl
|
||||
if (CL_SUCCESS != clEnqueueSVMMap(q, CL_TRUE, CL_MAP_WRITE, ptr, 100, 0, NULL, NULL))
|
||||
{
|
||||
CV_OPENCL_SVM_TRACE_ERROR_P("clEnqueueSVMMap failed...\n");
|
||||
CV_ErrorNoReturn(Error::StsBadArg, "clEnqueueSVMMap FAILED");
|
||||
CV_Error(Error::StsBadArg, "clEnqueueSVMMap FAILED");
|
||||
}
|
||||
clFinish(q);
|
||||
try
|
||||
@ -2201,12 +2201,12 @@ struct Context::Impl
|
||||
if (CL_SUCCESS != clEnqueueSVMUnmap(q, ptr, 0, NULL, NULL))
|
||||
{
|
||||
CV_OPENCL_SVM_TRACE_ERROR_P("clEnqueueSVMUnmap failed...\n");
|
||||
CV_ErrorNoReturn(Error::StsBadArg, "clEnqueueSVMUnmap FAILED");
|
||||
CV_Error(Error::StsBadArg, "clEnqueueSVMUnmap FAILED");
|
||||
}
|
||||
clFinish(q);
|
||||
if (error)
|
||||
{
|
||||
CV_ErrorNoReturn(Error::StsBadArg, "OpenCL SVM buffer access test was FAILED");
|
||||
CV_Error(Error::StsBadArg, "OpenCL SVM buffer access test was FAILED");
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
@ -2412,7 +2412,7 @@ void Context::setUseSVM(bool enabled)
|
||||
i->svmInit();
|
||||
if (enabled && !i->svmAvailable)
|
||||
{
|
||||
CV_ErrorNoReturn(Error::StsError, "OpenCL Shared Virtual Memory (SVM) is not supported by OpenCL device");
|
||||
CV_Error(Error::StsError, "OpenCL Shared Virtual Memory (SVM) is not supported by OpenCL device");
|
||||
}
|
||||
i->svmEnabled = enabled;
|
||||
}
|
||||
@ -2483,7 +2483,7 @@ void attachContext(const String& platformName, void* platformID, void* context,
|
||||
CV_OCL_CHECK(clGetPlatformIDs(0, 0, &cnt));
|
||||
|
||||
if (cnt == 0)
|
||||
CV_ErrorNoReturn(cv::Error::OpenCLApiCallError, "no OpenCL platform available!");
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "no OpenCL platform available!");
|
||||
|
||||
std::vector<cl_platform_id> platforms(cnt);
|
||||
|
||||
@ -2505,13 +2505,13 @@ void attachContext(const String& platformName, void* platformID, void* context,
|
||||
}
|
||||
|
||||
if (!platformAvailable)
|
||||
CV_ErrorNoReturn(cv::Error::OpenCLApiCallError, "No matched platforms available!");
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "No matched platforms available!");
|
||||
|
||||
// check if platformID corresponds to platformName
|
||||
String actualPlatformName;
|
||||
get_platform_name((cl_platform_id)platformID, actualPlatformName);
|
||||
if (platformName != actualPlatformName)
|
||||
CV_ErrorNoReturn(cv::Error::OpenCLApiCallError, "No matched platforms available!");
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "No matched platforms available!");
|
||||
|
||||
// do not initialize OpenCL context
|
||||
Context ctx = Context::getDefault(false);
|
||||
@ -3305,7 +3305,7 @@ struct ProgramSource::Impl
|
||||
hash = crc64(sourceAddr_, sourceSize_);
|
||||
break;
|
||||
default:
|
||||
CV_ErrorNoReturn(Error::StsInternal, "Internal error");
|
||||
CV_Error(Error::StsInternal, "Internal error");
|
||||
}
|
||||
sourceHash_ = cv::format("%08llx", hash);
|
||||
isHashUpdated = true;
|
||||
@ -3427,7 +3427,7 @@ const String& ProgramSource::source() const
|
||||
|
||||
ProgramSource::hash_t ProgramSource::hash() const
|
||||
{
|
||||
CV_ErrorNoReturn(Error::StsNotImplemented, "Removed method: ProgramSource::hash()");
|
||||
CV_Error(Error::StsNotImplemented, "Removed method: ProgramSource::hash()");
|
||||
}
|
||||
|
||||
ProgramSource ProgramSource::fromBinary(const String& module, const String& name,
|
||||
@ -3597,11 +3597,11 @@ struct Program::Impl
|
||||
}
|
||||
else if (src_->kind_ == ProgramSource::Impl::PROGRAM_SPIRV)
|
||||
{
|
||||
CV_ErrorNoReturn(Error::StsNotImplemented, "OpenCL: SPIR-V is not supported");
|
||||
CV_Error(Error::StsNotImplemented, "OpenCL: SPIR-V is not supported");
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_ErrorNoReturn(Error::StsInternal, "Internal error");
|
||||
CV_Error(Error::StsInternal, "Internal error");
|
||||
}
|
||||
CV_Assert(handle != NULL);
|
||||
#if OPENCV_HAVE_FILESYSTEM_SUPPORT
|
||||
@ -3948,19 +3948,19 @@ void* Program::ptr() const
|
||||
#ifndef OPENCV_REMOVE_DEPRECATED_API
|
||||
const ProgramSource& Program::source() const
|
||||
{
|
||||
CV_ErrorNoReturn(Error::StsNotImplemented, "Removed API");
|
||||
CV_Error(Error::StsNotImplemented, "Removed API");
|
||||
}
|
||||
|
||||
bool Program::read(const String& bin, const String& buildflags)
|
||||
{
|
||||
CV_UNUSED(bin); CV_UNUSED(buildflags);
|
||||
CV_ErrorNoReturn(Error::StsNotImplemented, "Removed API");
|
||||
CV_Error(Error::StsNotImplemented, "Removed API");
|
||||
}
|
||||
|
||||
bool Program::write(String& bin) const
|
||||
{
|
||||
CV_UNUSED(bin);
|
||||
CV_ErrorNoReturn(Error::StsNotImplemented, "Removed API");
|
||||
CV_Error(Error::StsNotImplemented, "Removed API");
|
||||
}
|
||||
|
||||
String Program::getPrefix() const
|
||||
@ -5627,7 +5627,7 @@ public:
|
||||
}
|
||||
if (id != NULL && strcmp(id, "OCL") != 0)
|
||||
{
|
||||
CV_ErrorNoReturn(cv::Error::StsBadArg, "getBufferPoolController(): unknown BufferPool ID\n");
|
||||
CV_Error(cv::Error::StsBadArg, "getBufferPoolController(): unknown BufferPool ID\n");
|
||||
}
|
||||
return &bufferPool;
|
||||
}
|
||||
|
@ -316,7 +316,7 @@ static void* opencl_check_fn(int ID)
|
||||
#endif
|
||||
else
|
||||
{
|
||||
CV_ErrorNoReturn(cv::Error::StsBadArg, "Invalid function ID");
|
||||
CV_Error(cv::Error::StsBadArg, "Invalid function ID");
|
||||
}
|
||||
void* func = CV_CL_GET_PROC_ADDRESS(e->fnName);
|
||||
if (!func)
|
||||
|
@ -48,7 +48,7 @@
|
||||
# include <cuda_gl_interop.h>
|
||||
# endif
|
||||
#else // HAVE_OPENGL
|
||||
# define NO_OPENGL_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without OpenGL support")
|
||||
# define NO_OPENGL_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without OpenGL support")
|
||||
#endif // HAVE_OPENGL
|
||||
|
||||
using namespace cv;
|
||||
@ -1304,10 +1304,15 @@ void cv::ogl::Arrays::release()
|
||||
|
||||
void cv::ogl::Arrays::setAutoRelease(bool flag)
|
||||
{
|
||||
#ifndef HAVE_OPENGL
|
||||
CV_UNUSED(flag);
|
||||
throw_no_ogl();
|
||||
#else
|
||||
vertex_.setAutoRelease(flag);
|
||||
color_.setAutoRelease(flag);
|
||||
normal_.setAutoRelease(flag);
|
||||
texCoord_.setAutoRelease(flag);
|
||||
#endif
|
||||
}
|
||||
|
||||
void cv::ogl::Arrays::bind() const
|
||||
@ -1563,10 +1568,10 @@ void cv::ogl::render(const ogl::Arrays& arr, InputArray indices, int mode, Scala
|
||||
# ifdef cl_khr_gl_sharing
|
||||
# define HAVE_OPENCL_OPENGL_SHARING
|
||||
# else
|
||||
# define NO_OPENCL_SHARING_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without OpenCL/OpenGL sharing support")
|
||||
# define NO_OPENCL_SHARING_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without OpenCL/OpenGL sharing support")
|
||||
# endif
|
||||
#else // HAVE_OPENCL
|
||||
# define NO_OPENCL_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
|
||||
# define NO_OPENCL_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
|
||||
#endif // HAVE_OPENCL
|
||||
|
||||
#if defined(HAVE_OPENGL)
|
||||
|
@ -233,7 +233,7 @@ namespace
|
||||
#if CV__EXCEPTION_PTR
|
||||
std::rethrow_exception(pException);
|
||||
#else
|
||||
CV_ErrorNoReturn(Error::StsError, "Exception in parallel_for() body: " + exception_message);
|
||||
CV_Error(Error::StsError, "Exception in parallel_for() body: " + exception_message);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ char* icvGets( CvFileStorage* fs, char* str, int maxCount )
|
||||
return ptr;
|
||||
}
|
||||
#endif
|
||||
CV_ErrorNoReturn(CV_StsError, "The storage is not opened");
|
||||
CV_Error(CV_StsError, "The storage is not opened");
|
||||
}
|
||||
|
||||
int icvEof( CvFileStorage* fs )
|
||||
|
@ -532,7 +532,7 @@ struct HWFeatures
|
||||
"******************************************************************\n");
|
||||
fprintf(stderr, "\nRequired baseline features:\n");
|
||||
checkFeatures(baseline_features, sizeof(baseline_features) / sizeof(baseline_features[0]), true);
|
||||
CV_ErrorNoReturn(cv::Error::StsAssert, "Missing support for required CPU baseline features. Check OpenCV build configuration and required CPU/HW setup.");
|
||||
CV_Error(cv::Error::StsAssert, "Missing support for required CPU baseline features. Check OpenCV build configuration and required CPU/HW setup.");
|
||||
}
|
||||
|
||||
readSettings(baseline_features, sizeof(baseline_features) / sizeof(baseline_features[0]));
|
||||
@ -1567,7 +1567,7 @@ bool utils::getConfigurationParameterBool(const char* name, bool defaultValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
CV_ErrorNoReturn(cv::Error::StsBadArg, cv::format("Invalid value for %s parameter: %s", name, value.c_str()));
|
||||
CV_Error(cv::Error::StsBadArg, cv::format("Invalid value for %s parameter: %s", name, value.c_str()));
|
||||
}
|
||||
|
||||
|
||||
@ -1598,7 +1598,7 @@ size_t utils::getConfigurationParameterSizeT(const char* name, size_t defaultVal
|
||||
return v * 1024 * 1024;
|
||||
else if (suffixStr == "KB" || suffixStr == "Kb" || suffixStr == "kb")
|
||||
return v * 1024;
|
||||
CV_ErrorNoReturn(cv::Error::StsBadArg, cv::format("Invalid value for %s parameter: %s", name, value.c_str()));
|
||||
CV_Error(cv::Error::StsBadArg, cv::format("Invalid value for %s parameter: %s", name, value.c_str()));
|
||||
}
|
||||
|
||||
cv::String utils::getConfigurationParameterString(const char* name, const char* defaultValue)
|
||||
|
@ -837,8 +837,6 @@ UMat UMat::reshape(int _cn, int _newndims, const int* _newsz) const
|
||||
}
|
||||
|
||||
CV_Error(CV_StsNotImplemented, "Reshaping of n-dimensional non-continuous matrices is not supported yet");
|
||||
// TBD
|
||||
return UMat();
|
||||
}
|
||||
|
||||
Mat UMat::getMat(int accessFlags) const
|
||||
|
@ -265,7 +265,7 @@ struct FileLock::Impl
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_ErrorNoReturn_(Error::StsAssert, ("Can't open lock file: %s", fname));
|
||||
CV_Error_(Error::StsAssert, ("Can't open lock file: %s", fname));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -517,7 +517,7 @@ cv::String getCacheDirectory(const char* sub_directory_name, const char* configu
|
||||
}
|
||||
|
||||
#else
|
||||
#define NOT_IMPLEMENTED CV_ErrorNoReturn(Error::StsNotImplemented, "");
|
||||
#define NOT_IMPLEMENTED CV_Error(Error::StsNotImplemented, "");
|
||||
CV_EXPORTS bool exists(const cv::String& /*path*/) { NOT_IMPLEMENTED }
|
||||
CV_EXPORTS void remove_all(const cv::String& /*path*/) { NOT_IMPLEMENTED }
|
||||
CV_EXPORTS bool createDirectory(const cv::String& /*path*/) { NOT_IMPLEMENTED }
|
||||
|
@ -10,7 +10,7 @@
|
||||
#ifdef HAVE_VA
|
||||
# include <va/va.h>
|
||||
#else // HAVE_VA
|
||||
# define NO_VA_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without VA support (libva)")
|
||||
# define NO_VA_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without VA support (libva)")
|
||||
#endif // HAVE_VA
|
||||
|
||||
using namespace cv;
|
||||
|
@ -174,7 +174,6 @@ bool Core_EigenTest::check_pair_count(const cv::Mat& src, const cv::Mat& evalues
|
||||
std::cout << "Number of rows: " << evalues.rows << " Number of cols: " << evalues.cols << endl;
|
||||
std::cout << "Size of src symmetric matrix: " << src.rows << " * " << src.cols << endl; std::cout << endl;
|
||||
CV_Error(CORE_EIGEN_ERROR_COUNT, MESSAGE_ERROR_COUNT);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -190,7 +189,6 @@ bool Core_EigenTest::check_pair_count(const cv::Mat& src, const cv::Mat& evalues
|
||||
std::cout << "Number of rows: " << evectors.rows << " Number of cols: " << evectors.cols << endl;
|
||||
std:: cout << "Size of src symmetric matrix: " << src.rows << " * " << src.cols << endl; std::cout << endl;
|
||||
CV_Error (CORE_EIGEN_ERROR_SIZE, MESSAGE_ERROR_SIZE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(evalues.rows == right_eigen_pair_count && evalues.cols == 1))
|
||||
@ -199,7 +197,6 @@ bool Core_EigenTest::check_pair_count(const cv::Mat& src, const cv::Mat& evalues
|
||||
std::cout << "Number of rows: " << evalues.rows << " Number of cols: " << evalues.cols << endl;
|
||||
std:: cout << "Size of src symmetric matrix: " << src.rows << " * " << src.cols << endl; std::cout << endl;
|
||||
CV_Error (CORE_EIGEN_ERROR_COUNT, MESSAGE_ERROR_COUNT);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -237,7 +234,6 @@ bool Core_EigenTest::check_orthogonality(const cv::Mat& U)
|
||||
std::cout << endl; std::cout << "Checking orthogonality of matrix " << U << ": ";
|
||||
print_information(i, U, diff, eps_vec);
|
||||
CV_Error(CORE_EIGEN_ERROR_ORTHO, MESSAGE_ERROR_ORTHO);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,7 +253,6 @@ bool Core_EigenTest::check_pairs_order(const cv::Mat& eigen_values)
|
||||
std::cout << "Pair of indexes with non descending of eigen values: (" << i << ", " << i+1 << ")." << endl;
|
||||
std::cout << endl;
|
||||
CV_Error(CORE_EIGEN_ERROR_ORDER, MESSAGE_ERROR_ORDER);
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -272,7 +267,6 @@ bool Core_EigenTest::check_pairs_order(const cv::Mat& eigen_values)
|
||||
std::cout << "Pair of indexes with non descending of eigen values: (" << i << ", " << i+1 << ")." << endl;
|
||||
std::cout << endl;
|
||||
CV_Error(CORE_EIGEN_ERROR_ORDER, "Eigen values are not sorted in descending order.");
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -331,7 +325,6 @@ bool Core_EigenTest::test_pairs(const cv::Mat& src)
|
||||
std::cout << endl; std::cout << "Checking accuracy of eigen vectors computing for matrix " << src << ": ";
|
||||
print_information(i, src, diff, eps_vec);
|
||||
CV_Error(CORE_EIGEN_ERROR_DIFF, MESSAGE_ERROR_DIFF_2);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -360,7 +353,6 @@ bool Core_EigenTest::test_values(const cv::Mat& src)
|
||||
std::cout << endl; std::cout << "Checking accuracy of eigen values computing for matrix " << src << ": ";
|
||||
print_information(i, src, diff, eps_val);
|
||||
CV_Error(CORE_EIGEN_ERROR_DIFF, MESSAGE_ERROR_DIFF_1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -657,8 +657,15 @@ template<typename R> struct TheTest
|
||||
|
||||
TheTest & test_mask()
|
||||
{
|
||||
Data<R> dataA, dataB, dataC, dataD(1), dataE(2);
|
||||
typedef V_TypeTraits<LaneType> Traits;
|
||||
typedef typename Traits::int_type int_type;
|
||||
|
||||
Data<R> dataA, dataB(0), dataC, dataD(1), dataE(2);
|
||||
dataA[1] *= (LaneType)-1;
|
||||
const LaneType mask_one = Traits::reinterpret_from_int(~(typename Traits::uint_type)(0));
|
||||
dataB[1] = mask_one;
|
||||
dataB[R::nlanes / 2] = mask_one;
|
||||
dataB[R::nlanes - 1] = mask_one;
|
||||
dataC *= (LaneType)-1;
|
||||
R a = dataA, b = dataB, c = dataC, d = dataD, e = dataE;
|
||||
|
||||
@ -670,12 +677,9 @@ template<typename R> struct TheTest
|
||||
EXPECT_EQ(true, v_check_all(c));
|
||||
|
||||
EXPECT_EQ(true, v_check_any(a));
|
||||
EXPECT_EQ(false, v_check_any(b));
|
||||
EXPECT_EQ(true, v_check_any(b));
|
||||
EXPECT_EQ(true, v_check_any(c));
|
||||
|
||||
typedef V_TypeTraits<LaneType> Traits;
|
||||
typedef typename Traits::int_type int_type;
|
||||
|
||||
R f = v_select(b, d, e);
|
||||
Data<R> resF = f;
|
||||
for (int i = 0; i < R::nlanes; ++i)
|
||||
|
@ -555,7 +555,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
|
||||
* An every sample in the batch is normalized separately. Optionally,
|
||||
* output is scaled by the trained parameters.
|
||||
*/
|
||||
class NormalizeBBoxLayer : public Layer
|
||||
class CV_EXPORTS NormalizeBBoxLayer : public Layer
|
||||
{
|
||||
public:
|
||||
float pnorm, epsilon;
|
||||
|
@ -142,6 +142,10 @@ public:
|
||||
const T &set(const String &key, const T &value);
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &stream, const Dict &dict);
|
||||
|
||||
std::map<String, DictValue>::const_iterator begin() const;
|
||||
|
||||
std::map<String, DictValue>::const_iterator end() const;
|
||||
};
|
||||
|
||||
//! @}
|
||||
|
@ -102,9 +102,13 @@ inline int64 DictValue::get<int64>(int idx) const
|
||||
|
||||
return (int64)doubleValue;
|
||||
}
|
||||
else if (type == Param::STRING)
|
||||
{
|
||||
return std::atoi((*ps)[idx].c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Assert(isInt() || isReal());
|
||||
CV_Assert(isInt() || isReal() || isString());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -146,9 +150,13 @@ inline double DictValue::get<double>(int idx) const
|
||||
{
|
||||
return (double)(*pi)[idx];
|
||||
}
|
||||
else if (type == Param::STRING)
|
||||
{
|
||||
return std::atof((*ps)[idx].c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Assert(isReal() || isInt());
|
||||
CV_Assert(isReal() || isInt() || isString());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -261,17 +269,16 @@ inline int DictValue::size() const
|
||||
{
|
||||
case Param::INT:
|
||||
return (int)pi->size();
|
||||
break;
|
||||
case Param::STRING:
|
||||
return (int)ps->size();
|
||||
break;
|
||||
case Param::REAL:
|
||||
return (int)pd->size();
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsInternal, "");
|
||||
return -1;
|
||||
}
|
||||
#ifdef __OPENCV_BUILD
|
||||
CV_Error(Error::StsInternal, "");
|
||||
#else
|
||||
CV_ErrorNoReturn(Error::StsInternal, "");
|
||||
#endif
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &stream, const DictValue &dictv)
|
||||
@ -366,6 +373,16 @@ inline std::ostream &operator<<(std::ostream &stream, const Dict &dict)
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline std::map<String, DictValue>::const_iterator Dict::begin() const
|
||||
{
|
||||
return dict.begin();
|
||||
}
|
||||
|
||||
inline std::map<String, DictValue>::const_iterator Dict::end() const
|
||||
{
|
||||
return dict.end();
|
||||
}
|
||||
|
||||
CV__DNN_EXPERIMENTAL_NS_END
|
||||
}
|
||||
}
|
||||
|
@ -13,11 +13,11 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
|
||||
|
||||
/** @brief Registers layer constructor in runtime.
|
||||
* @param type string, containing type name of the layer.
|
||||
* @param constuctorFunc pointer to the function of type LayerRegister::Constuctor, which creates the layer.
|
||||
* @param constructorFunc pointer to the function of type LayerRegister::Constructor, which creates the layer.
|
||||
* @details This macros must be placed inside the function code.
|
||||
*/
|
||||
#define CV_DNN_REGISTER_LAYER_FUNC(type, constuctorFunc) \
|
||||
cv::dnn::LayerFactory::registerLayer(#type, constuctorFunc);
|
||||
#define CV_DNN_REGISTER_LAYER_FUNC(type, constructorFunc) \
|
||||
cv::dnn::LayerFactory::registerLayer(#type, constructorFunc);
|
||||
|
||||
/** @brief Registers layer class in runtime.
|
||||
* @param type string, containing type name of the layer.
|
||||
@ -29,11 +29,11 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
|
||||
|
||||
/** @brief Registers layer constructor on module load time.
|
||||
* @param type string, containing type name of the layer.
|
||||
* @param constuctorFunc pointer to the function of type LayerRegister::Constuctor, which creates the layer.
|
||||
* @param constructorFunc pointer to the function of type LayerRegister::Constructor, which creates the layer.
|
||||
* @details This macros must be placed outside the function code.
|
||||
*/
|
||||
#define CV_DNN_REGISTER_LAYER_FUNC_STATIC(type, constuctorFunc) \
|
||||
static cv::dnn::details::_LayerStaticRegisterer __LayerStaticRegisterer_##type(#type, constuctorFunc);
|
||||
#define CV_DNN_REGISTER_LAYER_FUNC_STATIC(type, constructorFunc) \
|
||||
static cv::dnn::details::_LayerStaticRegisterer __LayerStaticRegisterer_##type(#type, constructorFunc);
|
||||
|
||||
/** @brief Registers layer class on module load time.
|
||||
* @param type string, containing type name of the layer.
|
||||
@ -59,10 +59,10 @@ class _LayerStaticRegisterer
|
||||
String type;
|
||||
public:
|
||||
|
||||
_LayerStaticRegisterer(const String &layerType, LayerFactory::Constuctor layerConstuctor)
|
||||
_LayerStaticRegisterer(const String &layerType, LayerFactory::Constructor layerConstructor)
|
||||
{
|
||||
this->type = layerType;
|
||||
LayerFactory::registerLayer(layerType, layerConstuctor);
|
||||
LayerFactory::registerLayer(layerType, layerConstructor);
|
||||
}
|
||||
|
||||
~_LayerStaticRegisterer()
|
||||
|
@ -58,10 +58,10 @@ class CV_EXPORTS LayerFactory
|
||||
public:
|
||||
|
||||
//! Each Layer class must provide this function to the factory
|
||||
typedef Ptr<Layer>(*Constuctor)(LayerParams ¶ms);
|
||||
typedef Ptr<Layer>(*Constructor)(LayerParams ¶ms);
|
||||
|
||||
//! Registers the layer class with typename @p type and specified @p constructor. Thread-safe.
|
||||
static void registerLayer(const String &type, Constuctor constructor);
|
||||
static void registerLayer(const String &type, Constructor constructor);
|
||||
|
||||
//! Unregisters registered layer with specified type name. Thread-safe.
|
||||
static void unregisterLayer(const String &type);
|
||||
|
@ -103,6 +103,19 @@ public:
|
||||
ReadNetParamsFromBinaryBufferOrDie(dataModel, lenModel, &netBinary);
|
||||
}
|
||||
|
||||
void extractCustomParams(const google::protobuf::UnknownFieldSet& unknownFields, cv::dnn::LayerParams ¶ms)
|
||||
{
|
||||
const int numFields = unknownFields.field_count();
|
||||
for (int i = 0; i < numFields; ++i)
|
||||
{
|
||||
const google::protobuf::UnknownField& field = unknownFields.field(i);
|
||||
CV_Assert(field.type() == google::protobuf::UnknownField::TYPE_GROUP);
|
||||
std::string fieldName = field.group().field(0).length_delimited();
|
||||
std::string fieldValue = field.group().field(1).length_delimited();
|
||||
params.set(fieldName, fieldValue);
|
||||
}
|
||||
}
|
||||
|
||||
void addParam(const Message &msg, const FieldDescriptor *field, cv::dnn::LayerParams ¶ms)
|
||||
{
|
||||
const Reflection *refl = msg.GetReflection();
|
||||
@ -187,12 +200,15 @@ public:
|
||||
if (!isInternal && !ends_with_param(fd->name()))
|
||||
continue;
|
||||
|
||||
const google::protobuf::UnknownFieldSet& unknownFields = msgRefl->GetUnknownFields(msg);
|
||||
bool hasData = fd->is_required() ||
|
||||
(fd->is_optional() && msgRefl->HasField(msg, fd)) ||
|
||||
(fd->is_repeated() && msgRefl->FieldSize(msg, fd) > 0);
|
||||
(fd->is_repeated() && msgRefl->FieldSize(msg, fd) > 0) ||
|
||||
!unknownFields.empty();
|
||||
if (!hasData)
|
||||
continue;
|
||||
|
||||
extractCustomParams(unknownFields, params);
|
||||
if (fd->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE)
|
||||
{
|
||||
if (fd->is_repeated()) //Extract only first item!
|
||||
@ -258,7 +274,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void extractBinaryLayerParms(const caffe::LayerParameter& layer, LayerParams& layerParams)
|
||||
void extractBinaryLayerParams(const caffe::LayerParameter& layer, LayerParams& layerParams)
|
||||
{
|
||||
const std::string &name = layer.name();
|
||||
|
||||
@ -319,7 +335,7 @@ public:
|
||||
LayerParams layerParams;
|
||||
|
||||
extractLayerParams(layer, layerParams);
|
||||
extractBinaryLayerParms(layer, layerParams);
|
||||
extractBinaryLayerParams(layer, layerParams);
|
||||
|
||||
int repetitions = layerCounter[name]++;
|
||||
if (repetitions)
|
||||
|
@ -1120,7 +1120,7 @@ bool ReadProtoFromTextFile(const char* filename, Message* proto) {
|
||||
std::ifstream fs(filename, std::ifstream::in);
|
||||
CHECK(fs.is_open()) << "Can't open \"" << filename << "\"";
|
||||
IstreamInputStream input(&fs);
|
||||
return google::protobuf::TextFormat::Parse(&input, proto);
|
||||
return google::protobuf::TextFormat::Parser(true).Parse(&input, proto);
|
||||
}
|
||||
|
||||
bool ReadProtoFromBinaryFile(const char* filename, Message* proto) {
|
||||
|
@ -1941,7 +1941,7 @@ Net::Net() : impl(new Net::Impl)
|
||||
Net Net::readFromModelOptimizer(const String& xml, const String& bin)
|
||||
{
|
||||
#ifndef HAVE_INF_ENGINE
|
||||
CV_ErrorNoReturn(Error::StsError, "Build OpenCV with Inference Engine to enable loading models from Model Optimizer.");
|
||||
CV_Error(Error::StsError, "Build OpenCV with Inference Engine to enable loading models from Model Optimizer.");
|
||||
#else
|
||||
InferenceEngine::CNNNetReader reader;
|
||||
reader.ReadNetwork(xml);
|
||||
@ -2790,7 +2790,7 @@ static Mutex& getLayerFactoryMutex()
|
||||
return *instance;
|
||||
}
|
||||
|
||||
typedef std::map<String, LayerFactory::Constuctor> LayerFactory_Impl;
|
||||
typedef std::map<String, std::vector<LayerFactory::Constructor> > LayerFactory_Impl;
|
||||
|
||||
static LayerFactory_Impl& getLayerFactoryImpl_()
|
||||
{
|
||||
@ -2813,21 +2813,22 @@ static LayerFactory_Impl& getLayerFactoryImpl()
|
||||
return *instance;
|
||||
}
|
||||
|
||||
void LayerFactory::registerLayer(const String &type, Constuctor constructor)
|
||||
void LayerFactory::registerLayer(const String &type, Constructor constructor)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
CV_TRACE_ARG_VALUE(type, "type", type.c_str());
|
||||
|
||||
cv::AutoLock lock(getLayerFactoryMutex());
|
||||
String type_ = type.toLowerCase();
|
||||
LayerFactory_Impl::const_iterator it = getLayerFactoryImpl().find(type_);
|
||||
LayerFactory_Impl::iterator it = getLayerFactoryImpl().find(type_);
|
||||
|
||||
if (it != getLayerFactoryImpl().end() && it->second != constructor)
|
||||
if (it != getLayerFactoryImpl().end())
|
||||
{
|
||||
CV_Error(cv::Error::StsBadArg, "Layer \"" + type_ + "\" already was registered");
|
||||
if (it->second.back() == constructor)
|
||||
CV_Error(cv::Error::StsBadArg, "Layer \"" + type_ + "\" already was registered");
|
||||
it->second.push_back(constructor);
|
||||
}
|
||||
|
||||
getLayerFactoryImpl().insert(std::make_pair(type_, constructor));
|
||||
getLayerFactoryImpl().insert(std::make_pair(type_, std::vector<Constructor>(1, constructor)));
|
||||
}
|
||||
|
||||
void LayerFactory::unregisterLayer(const String &type)
|
||||
@ -2837,7 +2838,15 @@ void LayerFactory::unregisterLayer(const String &type)
|
||||
|
||||
cv::AutoLock lock(getLayerFactoryMutex());
|
||||
String type_ = type.toLowerCase();
|
||||
getLayerFactoryImpl().erase(type_);
|
||||
|
||||
LayerFactory_Impl::iterator it = getLayerFactoryImpl().find(type_);
|
||||
if (it != getLayerFactoryImpl().end())
|
||||
{
|
||||
if (it->second.size() > 1)
|
||||
it->second.pop_back();
|
||||
else
|
||||
getLayerFactoryImpl().erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<Layer> LayerFactory::createLayerInstance(const String &type, LayerParams& params)
|
||||
@ -2851,7 +2860,8 @@ Ptr<Layer> LayerFactory::createLayerInstance(const String &type, LayerParams& pa
|
||||
|
||||
if (it != getLayerFactoryImpl().end())
|
||||
{
|
||||
return it->second(params);
|
||||
CV_Assert(!it->second.empty());
|
||||
return it->second.back()(params);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2920,7 +2930,7 @@ Net readNet(const String& _model, const String& _config, const String& _framewor
|
||||
std::swap(model, config);
|
||||
return readNetFromModelOptimizer(config, model);
|
||||
}
|
||||
CV_ErrorNoReturn(Error::StsError, "Cannot determine an origin framework of files: " +
|
||||
CV_Error(Error::StsError, "Cannot determine an origin framework of files: " +
|
||||
model + (config.empty() ? "" : ", " + config));
|
||||
}
|
||||
|
||||
|
@ -151,7 +151,7 @@ public:
|
||||
message += " layer parameter does not contain ";
|
||||
message += parameterName;
|
||||
message += " parameter.";
|
||||
CV_ErrorNoReturn(Error::StsBadArg, message);
|
||||
CV_Error(Error::StsBadArg, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -471,12 +471,12 @@ public:
|
||||
{
|
||||
int label = it->first;
|
||||
if (confidenceScores.rows <= label)
|
||||
CV_ErrorNoReturn_(cv::Error::StsError, ("Could not find confidence predictions for label %d", label));
|
||||
CV_Error_(cv::Error::StsError, ("Could not find confidence predictions for label %d", label));
|
||||
const std::vector<float>& scores = confidenceScores.row(label);
|
||||
int locLabel = _shareLocation ? -1 : label;
|
||||
LabelBBox::const_iterator label_bboxes = decodeBBoxes.find(locLabel);
|
||||
if (label_bboxes == decodeBBoxes.end())
|
||||
CV_ErrorNoReturn_(cv::Error::StsError, ("Could not find location predictions for label %d", locLabel));
|
||||
CV_Error_(cv::Error::StsError, ("Could not find location predictions for label %d", locLabel));
|
||||
const std::vector<int>& indices = it->second;
|
||||
|
||||
for (size_t j = 0; j < indices.size(); ++j, ++count)
|
||||
@ -507,14 +507,14 @@ public:
|
||||
if (c == _backgroundLabelId)
|
||||
continue; // Ignore background class.
|
||||
if (c >= confidenceScores.rows)
|
||||
CV_ErrorNoReturn_(cv::Error::StsError, ("Could not find confidence predictions for label %d", c));
|
||||
CV_Error_(cv::Error::StsError, ("Could not find confidence predictions for label %d", c));
|
||||
|
||||
const std::vector<float> scores = confidenceScores.row(c);
|
||||
int label = _shareLocation ? -1 : c;
|
||||
|
||||
LabelBBox::const_iterator label_bboxes = decodeBBoxes.find(label);
|
||||
if (label_bboxes == decodeBBoxes.end())
|
||||
CV_ErrorNoReturn_(cv::Error::StsError, ("Could not find location predictions for label %d", label));
|
||||
CV_Error_(cv::Error::StsError, ("Could not find location predictions for label %d", label));
|
||||
if (_bboxesNormalized)
|
||||
NMSFast_(label_bboxes->second, scores, _confidenceThreshold, _nmsThreshold, 1.0, _topK,
|
||||
indices[c], util::caffe_norm_box_overlap);
|
||||
@ -532,7 +532,7 @@ public:
|
||||
int label = it->first;
|
||||
const std::vector<int>& labelIndices = it->second;
|
||||
if (label >= confidenceScores.rows)
|
||||
CV_ErrorNoReturn_(cv::Error::StsError, ("Could not find location predictions for label %d", label));
|
||||
CV_Error_(cv::Error::StsError, ("Could not find location predictions for label %d", label));
|
||||
const std::vector<float>& scores = confidenceScores.row(label);
|
||||
for (size_t j = 0; j < labelIndices.size(); ++j)
|
||||
{
|
||||
@ -645,7 +645,7 @@ public:
|
||||
decode_bbox.ymax = decode_bbox_center_y + decode_bbox_height * .5;
|
||||
}
|
||||
else
|
||||
CV_ErrorNoReturn(Error::StsBadArg, "Unknown type.");
|
||||
CV_Error(Error::StsBadArg, "Unknown type.");
|
||||
|
||||
if (clip_bbox)
|
||||
{
|
||||
@ -714,7 +714,7 @@ public:
|
||||
continue; // Ignore background class.
|
||||
LabelBBox::const_iterator label_loc_preds = loc_preds.find(label);
|
||||
if (label_loc_preds == loc_preds.end())
|
||||
CV_ErrorNoReturn_(cv::Error::StsError, ("Could not find location predictions for label %d", label));
|
||||
CV_Error_(cv::Error::StsError, ("Could not find location predictions for label %d", label));
|
||||
DecodeBBoxes(prior_bboxes, prior_variances,
|
||||
code_type, variance_encoded_in_target, clip, clip_bounds,
|
||||
normalized_bbox, label_loc_preds->second, decode_bboxes[label]);
|
||||
|
@ -89,7 +89,7 @@ public:
|
||||
if (net.node(i).name() == name)
|
||||
return net.node(i);
|
||||
}
|
||||
CV_ErrorNoReturn(Error::StsParseError, "Input node with name " + name + " not found");
|
||||
CV_Error(Error::StsParseError, "Input node with name " + name + " not found");
|
||||
}
|
||||
|
||||
// Match TensorFlow subgraph starting from <nodeId> with a set of nodes to be fused.
|
||||
|
@ -1564,8 +1564,44 @@ void TFImporter::populateNet(Net dstNet)
|
||||
}
|
||||
else
|
||||
{
|
||||
printLayerAttr(layer);
|
||||
CV_Error_(Error::StsError, ("Unknown layer type %s in op %s", type.c_str(), name.c_str()));
|
||||
// Importer does not know how to map this TensorFlow's operation onto OpenCV's layer.
|
||||
// However we create a layer with the same type and rely that user defined a custom layer.
|
||||
|
||||
// All the attributes are added to LayerParams.
|
||||
google::protobuf::Map<std::string, tensorflow::AttrValue> attr = layer.attr();
|
||||
for (google::protobuf::Map<std::string, tensorflow::AttrValue>::const_iterator ai = attr.begin();
|
||||
ai != attr.end(); ++ai)
|
||||
{
|
||||
if (ai->second.value_case() == tensorflow::AttrValue::kS) // string
|
||||
layerParams.set(ai->first, ai->second.s());
|
||||
if (ai->second.value_case() == tensorflow::AttrValue::kI) // int64
|
||||
layerParams.set(ai->first, ai->second.i());
|
||||
if (ai->second.value_case() == tensorflow::AttrValue::kF) // float
|
||||
layerParams.set(ai->first, ai->second.f());
|
||||
if (ai->second.value_case() == tensorflow::AttrValue::kB) // bool
|
||||
layerParams.set(ai->first, ai->second.b());
|
||||
}
|
||||
|
||||
// All the Const input nodes are added to layer's blobs.
|
||||
std::vector<std::string> inputsNames;
|
||||
for (int i = 0; i < layer.input_size(); ++i)
|
||||
{
|
||||
// Check if input is a Const node.
|
||||
if (value_id.find(layer.input(i)) != value_id.end())
|
||||
{
|
||||
Mat blob = getTensorContent(getConstBlob(layer, value_id, i));
|
||||
layerParams.blobs.push_back(blob);
|
||||
}
|
||||
else
|
||||
inputsNames.push_back(layer.input(i));
|
||||
}
|
||||
int id = dstNet.addLayer(name, type, layerParams);
|
||||
layer_id[name] = id;
|
||||
|
||||
for (int i = 0; i < inputsNames.size(); ++i)
|
||||
{
|
||||
connect(layer_id, dstNet, parsePin(inputsNames[i]), id, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -940,7 +940,21 @@ struct TorchImporter
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "Unknown nn class \"" + className + "\"");
|
||||
// Importer does not know how to map Torch's layer type to an OpenCV's one.
|
||||
// However we parse all the parameters to let user create a custom layer.
|
||||
readTorchTable(scalarParams, tensorParams);
|
||||
for (std::map<String, DictValue>::const_iterator it = scalarParams.begin();
|
||||
it != scalarParams.end(); ++it)
|
||||
{
|
||||
layerParams.set(it->first, it->second);
|
||||
}
|
||||
for (std::map<String, std::pair<int, Mat> >::iterator it = tensorParams.begin();
|
||||
it != tensorParams.end(); ++it)
|
||||
{
|
||||
layerParams.blobs.push_back(it->second.second);
|
||||
}
|
||||
newModule->apiType = nnName;
|
||||
curModule->modules.push_back(newModule);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -44,7 +44,7 @@
|
||||
#include "npy_blob.hpp"
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
#include <opencv2/dnn/all_layers.hpp>
|
||||
#include <opencv2/ts/ocl_test.hpp>
|
||||
#include <opencv2/dnn/layer.details.hpp> // CV_DNN_REGISTER_LAYER_CLASS
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
@ -117,94 +117,50 @@ void testLayerUsingCaffeModels(String basename, int targetId = DNN_TARGET_CPU,
|
||||
normAssert(ref, out);
|
||||
}
|
||||
|
||||
TEST(Layer_Test_Softmax, Accuracy)
|
||||
typedef testing::TestWithParam<DNNTarget> Test_Caffe_layers;
|
||||
TEST_P(Test_Caffe_layers, Softmax)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_softmax");
|
||||
testLayerUsingCaffeModels("layer_softmax", GetParam());
|
||||
}
|
||||
|
||||
OCL_TEST(Layer_Test_Softmax, Accuracy)
|
||||
TEST_P(Test_Caffe_layers, LRN_spatial)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_softmax", DNN_TARGET_OPENCL);
|
||||
testLayerUsingCaffeModels("layer_lrn_spatial", GetParam());
|
||||
}
|
||||
|
||||
TEST(Layer_Test_LRN_spatial, Accuracy)
|
||||
TEST_P(Test_Caffe_layers, LRN_channels)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_lrn_spatial");
|
||||
testLayerUsingCaffeModels("layer_lrn_channels", GetParam());
|
||||
}
|
||||
|
||||
OCL_TEST(Layer_Test_LRN_spatial, Accuracy)
|
||||
TEST_P(Test_Caffe_layers, Convolution)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_lrn_spatial", DNN_TARGET_OPENCL);
|
||||
testLayerUsingCaffeModels("layer_convolution", GetParam(), true);
|
||||
}
|
||||
|
||||
TEST(Layer_Test_LRN_channels, Accuracy)
|
||||
TEST_P(Test_Caffe_layers, DeConvolution)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_lrn_channels");
|
||||
testLayerUsingCaffeModels("layer_deconvolution", GetParam(), true, false);
|
||||
}
|
||||
|
||||
OCL_TEST(Layer_Test_LRN_channels, Accuracy)
|
||||
TEST_P(Test_Caffe_layers, InnerProduct)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_lrn_channels", DNN_TARGET_OPENCL);
|
||||
testLayerUsingCaffeModels("layer_inner_product", GetParam(), true);
|
||||
}
|
||||
|
||||
TEST(Layer_Test_Convolution, Accuracy)
|
||||
TEST_P(Test_Caffe_layers, Pooling_max)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_convolution", DNN_TARGET_CPU, true);
|
||||
testLayerUsingCaffeModels("layer_pooling_max", GetParam());
|
||||
}
|
||||
|
||||
OCL_TEST(Layer_Test_Convolution, Accuracy)
|
||||
TEST_P(Test_Caffe_layers, Pooling_ave)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_convolution", DNN_TARGET_OPENCL, true);
|
||||
testLayerUsingCaffeModels("layer_pooling_ave", GetParam());
|
||||
}
|
||||
|
||||
TEST(Layer_Test_DeConvolution, Accuracy)
|
||||
TEST_P(Test_Caffe_layers, MVN)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_deconvolution", DNN_TARGET_CPU, true, false);
|
||||
}
|
||||
|
||||
OCL_TEST(Layer_Test_DeConvolution, Accuracy)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_deconvolution", DNN_TARGET_OPENCL, true, false);
|
||||
}
|
||||
|
||||
TEST(Layer_Test_InnerProduct, Accuracy)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_inner_product", DNN_TARGET_CPU, true);
|
||||
}
|
||||
|
||||
OCL_TEST(Layer_Test_InnerProduct, Accuracy)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_inner_product", DNN_TARGET_OPENCL, true);
|
||||
}
|
||||
|
||||
TEST(Layer_Test_Pooling_max, Accuracy)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_pooling_max");
|
||||
}
|
||||
|
||||
OCL_TEST(Layer_Test_Pooling_max, Accuracy)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_pooling_max", DNN_TARGET_OPENCL);
|
||||
}
|
||||
|
||||
TEST(Layer_Test_Pooling_ave, Accuracy)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_pooling_ave");
|
||||
}
|
||||
|
||||
OCL_TEST(Layer_Test_Pooling_ave, Accuracy)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_pooling_ave", DNN_TARGET_OPENCL);
|
||||
}
|
||||
|
||||
TEST(Layer_Test_MVN, Accuracy)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_mvn");
|
||||
}
|
||||
|
||||
OCL_TEST(Layer_Test_MVN, Accuracy)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_mvn", DNN_TARGET_OPENCL);
|
||||
testLayerUsingCaffeModels("layer_mvn", GetParam());
|
||||
}
|
||||
|
||||
void testReshape(const MatShape& inputShape, const MatShape& targetShape,
|
||||
@ -257,14 +213,9 @@ TEST(Layer_Test_BatchNorm, local_stats)
|
||||
testLayerUsingCaffeModels("layer_batch_norm_local_stats", DNN_TARGET_CPU, true, false);
|
||||
}
|
||||
|
||||
TEST(Layer_Test_ReLU, Accuracy)
|
||||
TEST_P(Test_Caffe_layers, ReLU)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_relu");
|
||||
}
|
||||
|
||||
OCL_TEST(Layer_Test_ReLU, Accuracy)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_relu", DNN_TARGET_OPENCL);
|
||||
testLayerUsingCaffeModels("layer_relu", GetParam());
|
||||
}
|
||||
|
||||
TEST(Layer_Test_Dropout, Accuracy)
|
||||
@ -272,14 +223,9 @@ TEST(Layer_Test_Dropout, Accuracy)
|
||||
testLayerUsingCaffeModels("layer_dropout");
|
||||
}
|
||||
|
||||
TEST(Layer_Test_Concat, Accuracy)
|
||||
TEST_P(Test_Caffe_layers, Concat)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_concat");
|
||||
}
|
||||
|
||||
OCL_TEST(Layer_Test_Concat, Accuracy)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_concat", DNN_TARGET_OPENCL);
|
||||
testLayerUsingCaffeModels("layer_concat", GetParam());
|
||||
}
|
||||
|
||||
TEST(Layer_Test_Fused_Concat, Accuracy)
|
||||
@ -325,26 +271,16 @@ TEST(Layer_Test_Fused_Concat, Accuracy)
|
||||
testLayerUsingCaffeModels("layer_concat_shared_input", DNN_TARGET_CPU, true, false);
|
||||
}
|
||||
|
||||
TEST(Layer_Test_Eltwise, Accuracy)
|
||||
TEST_P(Test_Caffe_layers, Eltwise)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_eltwise");
|
||||
testLayerUsingCaffeModels("layer_eltwise", GetParam());
|
||||
}
|
||||
|
||||
OCL_TEST(Layer_Test_Eltwise, Accuracy)
|
||||
TEST_P(Test_Caffe_layers, PReLU)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_eltwise", DNN_TARGET_OPENCL);
|
||||
}
|
||||
|
||||
TEST(Layer_Test_PReLU, Accuracy)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_prelu", DNN_TARGET_CPU, true);
|
||||
testLayerUsingCaffeModels("layer_prelu_fc", DNN_TARGET_CPU, true, false);
|
||||
}
|
||||
|
||||
OCL_TEST(Layer_Test_PReLU, Accuracy)
|
||||
{
|
||||
testLayerUsingCaffeModels("layer_prelu", DNN_TARGET_OPENCL, true);
|
||||
testLayerUsingCaffeModels("layer_prelu_fc", DNN_TARGET_OPENCL, true, false);
|
||||
int targetId = GetParam();
|
||||
testLayerUsingCaffeModels("layer_prelu", targetId, true);
|
||||
testLayerUsingCaffeModels("layer_prelu_fc", targetId, true, false);
|
||||
}
|
||||
|
||||
//template<typename XMat>
|
||||
@ -385,14 +321,9 @@ static void test_Reshape_Split_Slice_layers(int targetId)
|
||||
normAssert(input, output);
|
||||
}
|
||||
|
||||
TEST(Layer_Test_Reshape_Split_Slice, Accuracy)
|
||||
TEST_P(Test_Caffe_layers, Reshape_Split_Slice)
|
||||
{
|
||||
test_Reshape_Split_Slice_layers(DNN_TARGET_CPU);
|
||||
}
|
||||
|
||||
OCL_TEST(Layer_Test_Reshape_Split_Slice, Accuracy)
|
||||
{
|
||||
test_Reshape_Split_Slice_layers(DNN_TARGET_OPENCL);
|
||||
test_Reshape_Split_Slice_layers(GetParam());
|
||||
}
|
||||
|
||||
TEST(Layer_Conv_Elu, Accuracy)
|
||||
@ -602,7 +533,6 @@ TEST(Layer_Test_ROIPooling, Accuracy)
|
||||
normAssert(out, ref);
|
||||
}
|
||||
|
||||
typedef testing::TestWithParam<DNNTarget> Test_Caffe_layers;
|
||||
TEST_P(Test_Caffe_layers, FasterRCNN_Proposal)
|
||||
{
|
||||
Net net = readNetFromCaffe(_tf("net_faster_rcnn_proposal.prototxt"));
|
||||
@ -906,4 +836,104 @@ TEST(Test_DLDT, two_inputs)
|
||||
}
|
||||
#endif // HAVE_INF_ENGINE
|
||||
|
||||
// Test a custom layer.
|
||||
class InterpLayer CV_FINAL : public Layer
|
||||
{
|
||||
public:
|
||||
InterpLayer(const LayerParams ¶ms) : Layer(params)
|
||||
{
|
||||
zoomFactor = params.get<int>("zoom_factor", 0);
|
||||
outWidth = params.get<int>("width", 0);
|
||||
outHeight = params.get<int>("height", 0);
|
||||
}
|
||||
|
||||
static Ptr<InterpLayer> create(LayerParams& params)
|
||||
{
|
||||
return Ptr<InterpLayer>(new InterpLayer(params));
|
||||
}
|
||||
|
||||
virtual bool getMemoryShapes(const std::vector<std::vector<int> > &inputs,
|
||||
const int requiredOutputs,
|
||||
std::vector<std::vector<int> > &outputs,
|
||||
std::vector<std::vector<int> > &internals) const CV_OVERRIDE
|
||||
{
|
||||
const int batchSize = inputs[0][0];
|
||||
const int numChannels = inputs[0][1];
|
||||
const int inpHeight = inputs[0][2];
|
||||
const int inpWidth = inputs[0][3];
|
||||
|
||||
std::vector<int> outShape(4);
|
||||
outShape[0] = batchSize;
|
||||
outShape[1] = numChannels;
|
||||
outShape[2] = outHeight != 0 ? outHeight : (inpHeight + (inpHeight - 1) * (zoomFactor - 1));
|
||||
outShape[3] = outWidth != 0 ? outWidth : (inpWidth + (inpWidth - 1) * (zoomFactor - 1));
|
||||
outputs.assign(1, outShape);
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void finalize(const std::vector<Mat*>& inputs, std::vector<Mat> &outputs) CV_OVERRIDE
|
||||
{
|
||||
if (!outWidth && !outHeight)
|
||||
{
|
||||
outHeight = outputs[0].size[2];
|
||||
outWidth = outputs[0].size[3];
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation of this custom layer is based on https://github.com/cdmh/deeplab-public/blob/master/src/caffe/layers/interp_layer.cpp
|
||||
virtual void forward(std::vector<Mat*> &inputs, std::vector<Mat> &outputs, std::vector<Mat>& internals) CV_OVERRIDE
|
||||
{
|
||||
Mat& inp = *inputs[0];
|
||||
Mat& out = outputs[0];
|
||||
const float* inpData = (float*)inp.data;
|
||||
float* outData = (float*)out.data;
|
||||
|
||||
const int batchSize = inp.size[0];
|
||||
const int numChannels = inp.size[1];
|
||||
const int inpHeight = inp.size[2];
|
||||
const int inpWidth = inp.size[3];
|
||||
|
||||
const float rheight = (outHeight > 1) ? static_cast<float>(inpHeight - 1) / (outHeight - 1) : 0.f;
|
||||
const float rwidth = (outWidth > 1) ? static_cast<float>(inpWidth - 1) / (outWidth - 1) : 0.f;
|
||||
for (int h2 = 0; h2 < outHeight; ++h2)
|
||||
{
|
||||
const float h1r = rheight * h2;
|
||||
const int h1 = h1r;
|
||||
const int h1p = (h1 < inpHeight - 1) ? 1 : 0;
|
||||
const float h1lambda = h1r - h1;
|
||||
const float h0lambda = 1.f - h1lambda;
|
||||
for (int w2 = 0; w2 < outWidth; ++w2)
|
||||
{
|
||||
const float w1r = rwidth * w2;
|
||||
const int w1 = w1r;
|
||||
const int w1p = (w1 < inpWidth - 1) ? 1 : 0;
|
||||
const float w1lambda = w1r - w1;
|
||||
const float w0lambda = 1.f - w1lambda;
|
||||
const float* pos1 = inpData + h1 * inpWidth + w1;
|
||||
float* pos2 = outData + h2 * outWidth + w2;
|
||||
for (int c = 0; c < batchSize * numChannels; ++c)
|
||||
{
|
||||
pos2[0] =
|
||||
h0lambda * (w0lambda * pos1[0] + w1lambda * pos1[w1p]) +
|
||||
h1lambda * (w0lambda * pos1[h1p * inpWidth] + w1lambda * pos1[h1p * inpWidth + w1p]);
|
||||
pos1 += inpWidth * inpHeight;
|
||||
pos2 += outWidth * outHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void forward(InputArrayOfArrays, OutputArrayOfArrays, OutputArrayOfArrays) CV_OVERRIDE {}
|
||||
|
||||
private:
|
||||
int outWidth, outHeight, zoomFactor;
|
||||
};
|
||||
|
||||
TEST(Layer_Test_Interp, Accuracy)
|
||||
{
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Interp, InterpLayer);
|
||||
testLayerUsingCaffeModels("layer_interp", DNN_TARGET_CPU, false, false);
|
||||
LayerFactory::unregisterLayer("Interp");
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
#include <opencv2/dnn/layer.details.hpp> // CV_DNN_REGISTER_LAYER_CLASS
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
TEST(blobFromImage_4ch, Regression)
|
||||
@ -75,4 +77,64 @@ TEST(readNet, Regression)
|
||||
EXPECT_FALSE(net.empty());
|
||||
}
|
||||
|
||||
class FirstCustomLayer CV_FINAL : public Layer
|
||||
{
|
||||
public:
|
||||
FirstCustomLayer(const LayerParams ¶ms) : Layer(params) {}
|
||||
|
||||
static Ptr<Layer> create(LayerParams& params)
|
||||
{
|
||||
return Ptr<Layer>(new FirstCustomLayer(params));
|
||||
}
|
||||
|
||||
virtual void forward(InputArrayOfArrays, OutputArrayOfArrays, OutputArrayOfArrays) CV_OVERRIDE {}
|
||||
virtual void forward(std::vector<Mat*> &inputs, std::vector<Mat> &outputs, std::vector<Mat>& internals) CV_OVERRIDE
|
||||
{
|
||||
outputs[0].setTo(1);
|
||||
}
|
||||
};
|
||||
|
||||
class SecondCustomLayer CV_FINAL : public Layer
|
||||
{
|
||||
public:
|
||||
SecondCustomLayer(const LayerParams ¶ms) : Layer(params) {}
|
||||
|
||||
static Ptr<Layer> create(LayerParams& params)
|
||||
{
|
||||
return Ptr<Layer>(new SecondCustomLayer(params));
|
||||
}
|
||||
|
||||
virtual void forward(InputArrayOfArrays, OutputArrayOfArrays, OutputArrayOfArrays) CV_OVERRIDE {}
|
||||
virtual void forward(std::vector<Mat*> &inputs, std::vector<Mat> &outputs, std::vector<Mat>& internals) CV_OVERRIDE
|
||||
{
|
||||
outputs[0].setTo(2);
|
||||
}
|
||||
};
|
||||
|
||||
TEST(LayerFactory, custom_layers)
|
||||
{
|
||||
LayerParams lp;
|
||||
lp.name = "name";
|
||||
lp.type = "CustomType";
|
||||
|
||||
Mat inp(1, 1, CV_32FC1);
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
if (i == 0) { CV_DNN_REGISTER_LAYER_CLASS(CustomType, FirstCustomLayer); }
|
||||
else if (i == 1) { CV_DNN_REGISTER_LAYER_CLASS(CustomType, SecondCustomLayer); }
|
||||
else if (i == 2) { LayerFactory::unregisterLayer("CustomType"); }
|
||||
|
||||
Net net;
|
||||
net.addLayerToPrev(lp.name, lp.type, lp);
|
||||
|
||||
net.setInput(inp);
|
||||
Mat output = net.forward();
|
||||
|
||||
if (i == 0) EXPECT_EQ(output.at<float>(0), 1);
|
||||
else if (i == 1) EXPECT_EQ(output.at<float>(0), 2);
|
||||
else if (i == 2) EXPECT_EQ(output.at<float>(0), 1);
|
||||
}
|
||||
LayerFactory::unregisterLayer("CustomType");
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
@ -12,6 +12,8 @@ Test for Tensorflow models loading
|
||||
#include "test_precomp.hpp"
|
||||
#include "npy_blob.hpp"
|
||||
|
||||
#include <opencv2/dnn/layer.details.hpp> // CV_DNN_REGISTER_LAYER_CLASS
|
||||
|
||||
namespace opencv_test
|
||||
{
|
||||
|
||||
@ -364,4 +366,95 @@ TEST(Test_TensorFlow, memory_read)
|
||||
runTensorFlowNet("batch_norm_text", DNN_TARGET_CPU, true, l1, lInf, true);
|
||||
}
|
||||
|
||||
// Test a custom layer.
|
||||
class ResizeBilinearLayer CV_FINAL : public Layer
|
||||
{
|
||||
public:
|
||||
ResizeBilinearLayer(const LayerParams ¶ms) : Layer(params)
|
||||
{
|
||||
CV_Assert(!params.get<bool>("align_corners", false));
|
||||
CV_Assert(blobs.size() == 1, blobs[0].type() == CV_32SC1);
|
||||
outHeight = blobs[0].at<int>(0, 0);
|
||||
outWidth = blobs[0].at<int>(0, 1);
|
||||
}
|
||||
|
||||
static Ptr<Layer> create(LayerParams& params)
|
||||
{
|
||||
return Ptr<Layer>(new ResizeBilinearLayer(params));
|
||||
}
|
||||
|
||||
virtual bool getMemoryShapes(const std::vector<std::vector<int> > &inputs,
|
||||
const int requiredOutputs,
|
||||
std::vector<std::vector<int> > &outputs,
|
||||
std::vector<std::vector<int> > &internals) const CV_OVERRIDE
|
||||
{
|
||||
std::vector<int> outShape(4);
|
||||
outShape[0] = inputs[0][0]; // batch size
|
||||
outShape[1] = inputs[0][1]; // number of channels
|
||||
outShape[2] = outHeight;
|
||||
outShape[3] = outWidth;
|
||||
outputs.assign(1, outShape);
|
||||
return false;
|
||||
}
|
||||
|
||||
// This implementation is based on a reference implementation from
|
||||
// https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/kernels/internal/reference/reference_ops.h
|
||||
virtual void forward(std::vector<Mat*> &inputs, std::vector<Mat> &outputs, std::vector<Mat> &internals) CV_OVERRIDE
|
||||
{
|
||||
Mat& inp = *inputs[0];
|
||||
Mat& out = outputs[0];
|
||||
const float* inpData = (float*)inp.data;
|
||||
float* outData = (float*)out.data;
|
||||
|
||||
const int batchSize = inp.size[0];
|
||||
const int numChannels = inp.size[1];
|
||||
const int inpHeight = inp.size[2];
|
||||
const int inpWidth = inp.size[3];
|
||||
|
||||
float heightScale = static_cast<float>(inpHeight) / outHeight;
|
||||
float widthScale = static_cast<float>(inpWidth) / outWidth;
|
||||
for (int b = 0; b < batchSize; ++b)
|
||||
{
|
||||
for (int y = 0; y < outHeight; ++y)
|
||||
{
|
||||
float input_y = y * heightScale;
|
||||
int y0 = static_cast<int>(std::floor(input_y));
|
||||
int y1 = std::min(y0 + 1, inpHeight - 1);
|
||||
for (int x = 0; x < outWidth; ++x)
|
||||
{
|
||||
float input_x = x * widthScale;
|
||||
int x0 = static_cast<int>(std::floor(input_x));
|
||||
int x1 = std::min(x0 + 1, inpWidth - 1);
|
||||
for (int c = 0; c < numChannels; ++c)
|
||||
{
|
||||
float interpolation =
|
||||
inpData[offset(inp.size, c, x0, y0, b)] * (1 - (input_y - y0)) * (1 - (input_x - x0)) +
|
||||
inpData[offset(inp.size, c, x0, y1, b)] * (input_y - y0) * (1 - (input_x - x0)) +
|
||||
inpData[offset(inp.size, c, x1, y0, b)] * (1 - (input_y - y0)) * (input_x - x0) +
|
||||
inpData[offset(inp.size, c, x1, y1, b)] * (input_y - y0) * (input_x - x0);
|
||||
outData[offset(out.size, c, x, y, b)] = interpolation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void forward(InputArrayOfArrays, OutputArrayOfArrays, OutputArrayOfArrays) CV_OVERRIDE {}
|
||||
|
||||
private:
|
||||
static inline int offset(const MatSize& size, int c, int x, int y, int b)
|
||||
{
|
||||
return x + size[3] * (y + size[2] * (c + size[1] * b));
|
||||
}
|
||||
|
||||
int outWidth, outHeight;
|
||||
};
|
||||
|
||||
TEST(Test_TensorFlow, resize_bilinear)
|
||||
{
|
||||
CV_DNN_REGISTER_LAYER_CLASS(ResizeBilinear, ResizeBilinearLayer);
|
||||
runTensorFlowNet("resize_bilinear");
|
||||
LayerFactory::unregisterLayer("ResizeBilinear");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "test_precomp.hpp"
|
||||
#include "npy_blob.hpp"
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
#include <opencv2/dnn/layer.details.hpp> // CV_DNN_REGISTER_LAYER_CLASS
|
||||
|
||||
namespace opencv_test
|
||||
{
|
||||
@ -325,4 +326,62 @@ TEST(Torch_Importer, net_residual)
|
||||
runTorchNet("net_residual", DNN_TARGET_CPU, "", false, true);
|
||||
}
|
||||
|
||||
// Test a custom layer
|
||||
// https://github.com/torch/nn/blob/master/doc/convolution.md#nn.SpatialUpSamplingNearest
|
||||
class SpatialUpSamplingNearestLayer CV_FINAL : public Layer
|
||||
{
|
||||
public:
|
||||
SpatialUpSamplingNearestLayer(const LayerParams ¶ms) : Layer(params)
|
||||
{
|
||||
scale = params.get<int>("scale_factor");
|
||||
}
|
||||
|
||||
static Ptr<Layer> create(LayerParams& params)
|
||||
{
|
||||
return Ptr<Layer>(new SpatialUpSamplingNearestLayer(params));
|
||||
}
|
||||
|
||||
virtual bool getMemoryShapes(const std::vector<std::vector<int> > &inputs,
|
||||
const int requiredOutputs,
|
||||
std::vector<std::vector<int> > &outputs,
|
||||
std::vector<std::vector<int> > &internals) const CV_OVERRIDE
|
||||
{
|
||||
std::vector<int> outShape(4);
|
||||
outShape[0] = inputs[0][0]; // batch size
|
||||
outShape[1] = inputs[0][1]; // number of channels
|
||||
outShape[2] = scale * inputs[0][2];
|
||||
outShape[3] = scale * inputs[0][3];
|
||||
outputs.assign(1, outShape);
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void forward(std::vector<Mat*> &inputs, std::vector<Mat> &outputs, std::vector<Mat> &internals) CV_OVERRIDE
|
||||
{
|
||||
Mat& inp = *inputs[0];
|
||||
Mat& out = outputs[0];
|
||||
const int outHeight = out.size[2];
|
||||
const int outWidth = out.size[3];
|
||||
for (size_t n = 0; n < inputs[0]->size[0]; ++n)
|
||||
{
|
||||
for (size_t ch = 0; ch < inputs[0]->size[1]; ++ch)
|
||||
{
|
||||
resize(getPlane(inp, n, ch), getPlane(out, n, ch),
|
||||
Size(outWidth, outHeight), 0, 0, INTER_NEAREST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void forward(InputArrayOfArrays, OutputArrayOfArrays, OutputArrayOfArrays) CV_OVERRIDE {}
|
||||
|
||||
private:
|
||||
int scale;
|
||||
};
|
||||
|
||||
TEST(Torch_Importer, upsampling_nearest)
|
||||
{
|
||||
CV_DNN_REGISTER_LAYER_CLASS(SpatialUpSamplingNearest, SpatialUpSamplingNearestLayer);
|
||||
runTorchNet("net_spatial_upsampling_nearest", DNN_TARGET_CPU, "", false, true);
|
||||
LayerFactory::unregisterLayer("SpatialUpSamplingNearest");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1360,11 +1360,13 @@ Ptr<DescriptorMatcher> FlannBasedMatcher::clone( bool emptyTrainData ) const
|
||||
{
|
||||
CV_Error( Error::StsNotImplemented, "deep clone functionality is not implemented, because "
|
||||
"Flann::Index has not copy constructor or clone method ");
|
||||
#if 0
|
||||
//matcher->flannIndex;
|
||||
matcher->addedDescCount = addedDescCount;
|
||||
matcher->mergedDescriptors = DescriptorCollection( mergedDescriptors );
|
||||
std::transform( trainDescCollection.begin(), trainDescCollection.end(),
|
||||
matcher->trainDescCollection.begin(), clone_op );
|
||||
#endif
|
||||
}
|
||||
return matcher;
|
||||
}
|
||||
|
@ -530,7 +530,6 @@ static const char* NO_QT_ERR_MSG = "The library is compiled without QT support";
|
||||
cv::QtFont cv::fontQt(const String&, int, Scalar, int, int, int)
|
||||
{
|
||||
CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG);
|
||||
return QtFont();
|
||||
}
|
||||
|
||||
void cv::addText( const Mat&, const String&, Point, const QtFont&)
|
||||
@ -556,7 +555,6 @@ void cv::displayOverlay(const String&, const String&, int )
|
||||
int cv::startLoop(int (*)(int argc, char *argv[]), int , char**)
|
||||
{
|
||||
CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cv::stopLoop()
|
||||
@ -577,7 +575,6 @@ void cv::loadWindowParameters(const String&)
|
||||
int cv::createButton(const String&, ButtonCallback, void*, int , bool )
|
||||
{
|
||||
CV_Error(CV_StsNotImplemented, NO_QT_ERR_MSG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -606,17 +603,16 @@ void cv::setWindowTitle(const String&, const String&)
|
||||
}
|
||||
|
||||
#define CV_NO_GUI_ERROR(funcname) \
|
||||
cvError( CV_StsError, funcname, \
|
||||
cv::errorNoReturn(cv::Error::StsError, \
|
||||
"The function is not implemented. " \
|
||||
"Rebuild the library with Windows, GTK+ 2.x or Carbon support. "\
|
||||
"If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script", \
|
||||
__FILE__, __LINE__ )
|
||||
funcname, __FILE__, __LINE__)
|
||||
|
||||
|
||||
CV_IMPL int cvNamedWindow( const char*, int )
|
||||
{
|
||||
CV_NO_GUI_ERROR("cvNamedWindow");
|
||||
return -1;
|
||||
}
|
||||
|
||||
CV_IMPL void cvDestroyWindow( const char* )
|
||||
@ -651,7 +647,6 @@ cvCreateTrackbar( const char*, const char*,
|
||||
int*, int, CvTrackbarCallback )
|
||||
{
|
||||
CV_NO_GUI_ERROR( "cvCreateTrackbar" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
CV_IMPL int
|
||||
@ -660,7 +655,6 @@ cvCreateTrackbar2( const char* /*trackbar_name*/, const char* /*window_name*/,
|
||||
void* /*userdata*/ )
|
||||
{
|
||||
CV_NO_GUI_ERROR( "cvCreateTrackbar2" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
CV_IMPL void
|
||||
@ -672,7 +666,6 @@ cvSetMouseCallback( const char*, CvMouseCallback, void* )
|
||||
CV_IMPL int cvGetTrackbarPos( const char*, const char* )
|
||||
{
|
||||
CV_NO_GUI_ERROR( "cvGetTrackbarPos" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
CV_IMPL void cvSetTrackbarPos( const char*, const char*, int )
|
||||
@ -693,33 +686,28 @@ CV_IMPL void cvSetTrackbarMin(const char*, const char*, int)
|
||||
CV_IMPL void* cvGetWindowHandle( const char* )
|
||||
{
|
||||
CV_NO_GUI_ERROR( "cvGetWindowHandle" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
CV_IMPL const char* cvGetWindowName( void* )
|
||||
{
|
||||
CV_NO_GUI_ERROR( "cvGetWindowName" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
CV_IMPL int cvWaitKey( int )
|
||||
{
|
||||
CV_NO_GUI_ERROR( "cvWaitKey" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
CV_IMPL int cvInitSystem( int , char** )
|
||||
{
|
||||
|
||||
CV_NO_GUI_ERROR( "cvInitSystem" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
CV_IMPL int cvStartWindowThread()
|
||||
{
|
||||
|
||||
CV_NO_GUI_ERROR( "cvStartWindowThread" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-------- Qt ---------
|
||||
@ -742,7 +730,6 @@ CV_IMPL int cvStartLoop(int (*)(int argc, char *argv[]), int , char* argv[])
|
||||
{
|
||||
(void)argv;
|
||||
CV_NO_GUI_ERROR("cvStartLoop");
|
||||
return -1;
|
||||
}
|
||||
|
||||
CV_IMPL void cvStopLoop()
|
||||
@ -763,7 +750,6 @@ CV_IMPL void cvSaveWindowParameters(const char* )
|
||||
CV_IMPL int cvCreateButton(const char*, void (*)(int, void*), void*, int, int)
|
||||
{
|
||||
CV_NO_GUI_ERROR("cvCreateButton");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -490,7 +490,7 @@ decode_rle8_bad: ;
|
||||
result = true;
|
||||
break;
|
||||
default:
|
||||
CV_ErrorNoReturn(cv::Error::StsError, "Invalid/unsupported mode");
|
||||
CV_Error(cv::Error::StsError, "Invalid/unsupported mode");
|
||||
}
|
||||
}
|
||||
CV_CATCH_ALL
|
||||
|
@ -409,7 +409,7 @@ bool GdalDecoder::readData( Mat& img ){
|
||||
color = 3;
|
||||
break;
|
||||
default:
|
||||
CV_ErrorNoReturn(cv::Error::StsError, "Invalid/unsupported mode");
|
||||
CV_Error(cv::Error::StsError, "Invalid/unsupported mode");
|
||||
}
|
||||
|
||||
// make sure the image band has the same dimensions as the image
|
||||
|
@ -77,7 +77,7 @@ static int ReadNumber(RLByteStream& strm, int maxdigits = 0)
|
||||
else
|
||||
{
|
||||
#if 1
|
||||
CV_ErrorNoReturn_(Error::StsError, ("PXM: Unexpected code in ReadNumber(): 0x%x (%d)", code, code));
|
||||
CV_Error_(Error::StsError, ("PXM: Unexpected code in ReadNumber(): 0x%x (%d)", code, code));
|
||||
#else
|
||||
code = strm.getByte();
|
||||
#endif
|
||||
@ -354,7 +354,7 @@ bool PxMDecoder::readData( Mat& img )
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CV_ErrorNoReturn(Error::StsError, "m_bpp is not supported");
|
||||
CV_Error(Error::StsError, "m_bpp is not supported");
|
||||
}
|
||||
}
|
||||
CV_CATCH (cv::Exception, e)
|
||||
|
@ -722,7 +722,7 @@ bool imwrite( const String& filename, InputArray _img,
|
||||
else if (_img.isMatVector() || _img.isUMatVector())
|
||||
_img.getMatVector(img_vec);
|
||||
else
|
||||
CV_ErrorNoReturn(Error::StsBadArg, "Unknown/unsupported input encountered");
|
||||
CV_Error(Error::StsBadArg, "Unknown/unsupported input encountered");
|
||||
|
||||
CV_Assert(!img_vec.empty());
|
||||
return imwrite_(filename, img_vec, params, false);
|
||||
|
@ -99,7 +99,6 @@ static int rgbe_error(int rgbe_error_code, const char *msg)
|
||||
CV_Error(cv::Error::StsError, cv::String("RGBE error: \n") +
|
||||
cv::String(msg));
|
||||
}
|
||||
return RGBE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
/* standard conversion from float pixels to rgbe pixels */
|
||||
|
@ -126,9 +126,8 @@ static Mat interp1(InputArray _x, InputArray _Y, InputArray _xi)
|
||||
case CV_32SC1: return interp1_<int>(x,Y,xi); break;
|
||||
case CV_32FC1: return interp1_<float>(x,Y,xi); break;
|
||||
case CV_64FC1: return interp1_<double>(x,Y,xi); break;
|
||||
default: CV_Error(Error::StsUnsupportedFormat, ""); break;
|
||||
}
|
||||
return Mat();
|
||||
CV_Error(Error::StsUnsupportedFormat, "");
|
||||
}
|
||||
|
||||
namespace colormap
|
||||
|
@ -3980,7 +3980,6 @@ namespace cv{
|
||||
}
|
||||
|
||||
CV_Error(CV_StsUnsupportedFormat, "unsupported label/image type");
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
@ -4003,7 +4002,6 @@ int cv::connectedComponents(InputArray img_, OutputArray _labels, int connectivi
|
||||
}
|
||||
else{
|
||||
CV_Error(CV_StsUnsupportedFormat, "the type of labels must be 16u or 32s");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3642,8 +3642,6 @@ cv::Ptr<cv::BaseRowFilter> cv::getLinearRowFilter( int srcType, int bufType,
|
||||
CV_Error_( CV_StsNotImplemented,
|
||||
("Unsupported combination of source format (=%d), and buffer format (=%d)",
|
||||
srcType, bufType));
|
||||
|
||||
return Ptr<BaseRowFilter>();
|
||||
}
|
||||
|
||||
|
||||
@ -3739,8 +3737,6 @@ cv::Ptr<cv::BaseColumnFilter> cv::getLinearColumnFilter( int bufType, int dstTyp
|
||||
CV_Error_( CV_StsNotImplemented,
|
||||
("Unsupported combination of buffer format (=%d), and destination format (=%d)",
|
||||
bufType, dstType));
|
||||
|
||||
return Ptr<BaseColumnFilter>();
|
||||
}
|
||||
|
||||
|
||||
@ -4491,8 +4487,6 @@ cv::Ptr<cv::BaseFilter> cv::getLinearFilter(int srcType, int dstType,
|
||||
CV_Error_( CV_StsNotImplemented,
|
||||
("Unsupported combination of source format (=%d), and destination format (=%d)",
|
||||
srcType, dstType));
|
||||
|
||||
return Ptr<BaseFilter>();
|
||||
}
|
||||
|
||||
|
||||
|
@ -888,7 +888,6 @@ cv::Ptr<cv::BaseRowFilter> cv::getMorphologyRowFilter(int op, int type, int ksiz
|
||||
}
|
||||
|
||||
CV_Error_( CV_StsNotImplemented, ("Unsupported data type (=%d)", type));
|
||||
return Ptr<BaseRowFilter>();
|
||||
}
|
||||
|
||||
cv::Ptr<cv::BaseColumnFilter> cv::getMorphologyColumnFilter(int op, int type, int ksize, int anchor)
|
||||
@ -935,7 +934,6 @@ cv::Ptr<cv::BaseColumnFilter> cv::getMorphologyColumnFilter(int op, int type, in
|
||||
}
|
||||
|
||||
CV_Error_( CV_StsNotImplemented, ("Unsupported data type (=%d)", type));
|
||||
return Ptr<BaseColumnFilter>();
|
||||
}
|
||||
|
||||
|
||||
@ -973,7 +971,6 @@ cv::Ptr<cv::BaseFilter> cv::getMorphologyFilter(int op, int type, InputArray _ke
|
||||
}
|
||||
|
||||
CV_Error_( CV_StsNotImplemented, ("Unsupported data type (=%d)", type));
|
||||
return Ptr<BaseFilter>();
|
||||
}
|
||||
|
||||
|
||||
|
@ -113,9 +113,7 @@ inline bool isStorageOrMat(void * arr)
|
||||
return true;
|
||||
else if (CV_IS_MAT( arr ))
|
||||
return false;
|
||||
else
|
||||
CV_Error( CV_StsBadArg, "Destination is not CvMemStorage* nor CvMat*" );
|
||||
return false;
|
||||
CV_Error( CV_StsBadArg, "Destination is not CvMemStorage* nor CvMat*" );
|
||||
}
|
||||
|
||||
#endif /*__OPENCV_CV_INTERNAL_H_*/
|
||||
|
@ -1332,8 +1332,6 @@ cv::Ptr<cv::BaseRowFilter> cv::getRowSumFilter(int srcType, int sumType, int ksi
|
||||
CV_Error_( CV_StsNotImplemented,
|
||||
("Unsupported combination of source format (=%d), and buffer format (=%d)",
|
||||
srcType, sumType));
|
||||
|
||||
return Ptr<BaseRowFilter>();
|
||||
}
|
||||
|
||||
|
||||
@ -1374,8 +1372,6 @@ cv::Ptr<cv::BaseColumnFilter> cv::getColumnSumFilter(int sumType, int dstType, i
|
||||
CV_Error_( CV_StsNotImplemented,
|
||||
("Unsupported combination of sum format (=%d), and destination format (=%d)",
|
||||
sumType, dstType));
|
||||
|
||||
return Ptr<BaseColumnFilter>();
|
||||
}
|
||||
|
||||
|
||||
@ -1656,8 +1652,6 @@ static Ptr<BaseRowFilter> getSqrRowSumFilter(int srcType, int sumType, int ksize
|
||||
CV_Error_( CV_StsNotImplemented,
|
||||
("Unsupported combination of source format (=%d), and buffer format (=%d)",
|
||||
srcType, sumType));
|
||||
|
||||
return Ptr<BaseRowFilter>();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -613,7 +613,6 @@ static Point2f mapPointSpherical(const Point2f& p, float alpha, Vec4d* J, int pr
|
||||
return Point2f((float)asin(x1), (float)asin(y1));
|
||||
}
|
||||
CV_Error(CV_StsBadArg, "Unknown projection type");
|
||||
return Point2f();
|
||||
}
|
||||
|
||||
|
||||
|
@ -125,7 +125,6 @@ template <typename T> bool CV_BoundingRectTest::checking_function_work(vector <P
|
||||
cout << "Result rect (x, y, w, h): [" << rect[i].x << ", " << rect[i].y << ", " << rect[i].width << ", " << rect[i].height << "]" << endl;
|
||||
cout << endl;
|
||||
CV_Error(IMGPROC_BOUNDINGRECT_ERROR_DIFF, MESSAGE_ERROR_DIFF);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -58,7 +58,6 @@ int str_to_svm_type(String& str)
|
||||
if( !str.compare("NU_SVR") )
|
||||
return SVM::NU_SVR;
|
||||
CV_Error( CV_StsBadArg, "incorrect svm type string" );
|
||||
return -1;
|
||||
}
|
||||
int str_to_svm_kernel_type( String& str )
|
||||
{
|
||||
@ -71,7 +70,6 @@ int str_to_svm_kernel_type( String& str )
|
||||
if( !str.compare("SIGMOID") )
|
||||
return SVM::SIGMOID;
|
||||
CV_Error( CV_StsBadArg, "incorrect svm type string" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 4. em
|
||||
@ -85,7 +83,6 @@ int str_to_ann_train_method( String& str )
|
||||
if (!str.compare("ANNEAL"))
|
||||
return ANN_MLP::ANNEAL;
|
||||
CV_Error( CV_StsBadArg, "incorrect ann train method string" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -102,7 +99,6 @@ int str_to_ann_activation_function(String& str)
|
||||
if (!str.compare("LEAKYRELU"))
|
||||
return ANN_MLP::LEAKYRELU;
|
||||
CV_Error(CV_StsBadArg, "incorrect ann activation function string");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -374,7 +370,6 @@ int str_to_boost_type( String& str )
|
||||
if ( !str.compare("GENTLE") )
|
||||
return Boost::GENTLE;
|
||||
CV_Error( CV_StsBadArg, "incorrect boost type string" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 8. rtrees
|
||||
@ -387,7 +382,6 @@ int str_to_svmsgd_type( String& str )
|
||||
if ( !str.compare("ASGD") )
|
||||
return SVMSGD::ASGD;
|
||||
CV_Error( CV_StsBadArg, "incorrect svmsgd type string" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
int str_to_margin_type( String& str )
|
||||
@ -397,7 +391,6 @@ int str_to_margin_type( String& str )
|
||||
if ( !str.compare("HARD_MARGIN") )
|
||||
return SVMSGD::HARD_MARGIN;
|
||||
CV_Error( CV_StsBadArg, "incorrect svmsgd margin type string" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -54,7 +54,6 @@ Ptr<ExposureCompensator> ExposureCompensator::createDefault(int type)
|
||||
if (type == GAIN_BLOCKS)
|
||||
return makePtr<BlocksGainCompensator>();
|
||||
CV_Error(Error::StsBadArg, "unsupported exposure compensation method");
|
||||
return Ptr<ExposureCompensator>();
|
||||
}
|
||||
|
||||
|
||||
|
@ -836,7 +836,7 @@ std::string findDataFile(const std::string& relative_path, bool required)
|
||||
#endif
|
||||
#endif
|
||||
if (required)
|
||||
CV_ErrorNoReturn(cv::Error::StsError, cv::format("OpenCV tests: Can't find required data file: %s", relative_path.c_str()));
|
||||
CV_Error(cv::Error::StsError, cv::format("OpenCV tests: Can't find required data file: %s", relative_path.c_str()));
|
||||
throw SkipTestException(cv::format("OpenCV tests: Can't find data file: %s", relative_path.c_str()));
|
||||
}
|
||||
|
||||
|
@ -404,7 +404,7 @@ double cv::findTransformECC(InputArray templateImage,
|
||||
Mat templateFloat = Mat(hs, ws, CV_32F);// to store the (smoothed) template
|
||||
Mat imageFloat = Mat(hd, wd, CV_32F);// to store the (smoothed) input image
|
||||
Mat imageWarped = Mat(hs, ws, CV_32F);// to store the warped zero-mean input image
|
||||
Mat imageMask = Mat(hs, ws, CV_8U); //to store the final mask
|
||||
Mat imageMask = Mat(hs, ws, CV_8U); // to store the final mask
|
||||
|
||||
Mat inputMaskMat = inputMask.getMat();
|
||||
//to use it for mask warping
|
||||
|
@ -106,7 +106,8 @@ protected:
|
||||
bool parseMovi(frame_list& in_frame_list)
|
||||
{
|
||||
//not implemented
|
||||
in_frame_list.empty();
|
||||
CV_UNUSED(in_frame_list);
|
||||
// FIXIT: in_frame_list.empty();
|
||||
return true;
|
||||
}
|
||||
bool parseStrl(char stream_id, Codecs codec_);
|
||||
|
@ -40,6 +40,8 @@
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include "cap_intelperc.hpp"
|
||||
#include "cap_dshow.hpp"
|
||||
|
||||
@ -63,7 +65,7 @@
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#endif
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__GNUC__) && __GNUC__ >= 7
|
||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#endif
|
||||
|
||||
@ -200,12 +202,6 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
|
||||
TRY_OPEN(capture, cvCreateCameraCapture_V4L(index))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
TRY_OPEN(capture, cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L2, reinterpret_cast<char *>(index)))
|
||||
|
||||
TRY_OPEN(capture, cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L, reinterpret_cast<char *>(index)))
|
||||
#endif
|
||||
|
||||
if (pref) break; // CAP_VFW or CAP_V4L or CAP_V4L2
|
||||
|
||||
case CAP_FIREWIRE:
|
||||
@ -221,11 +217,6 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
|
||||
TRY_OPEN(capture, cvCreateCameraCapture_CMU(index))
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_GSTREAMER) && 0
|
||||
// Re-enable again when gstreamer 1394 support will land in the backend code
|
||||
TRY_OPEN(capture, cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_1394, 0))
|
||||
#endif
|
||||
|
||||
if (pref) break; // CAP_FIREWIRE
|
||||
|
||||
#ifdef HAVE_MIL
|
||||
@ -330,12 +321,6 @@ CV_IMPL CvCapture * cvCreateFileCaptureWithPreference (const char * filename, in
|
||||
if (apiPreference) break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
case CAP_GSTREAMER:
|
||||
TRY_OPEN(result, cvCreateCapture_GStreamer (CV_CAP_GSTREAMER_FILE, filename))
|
||||
if (apiPreference) break;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT)
|
||||
case CAP_QT:
|
||||
TRY_OPEN(result, cvCreateFileCapture_QT (filename))
|
||||
@ -463,6 +448,9 @@ static Ptr<IVideoCapture> IVideoCapture_create(int index)
|
||||
{
|
||||
int domains[] =
|
||||
{
|
||||
#ifdef HAVE_GSTREAMER
|
||||
CAP_GSTREAMER,
|
||||
#endif
|
||||
#ifdef HAVE_DSHOW
|
||||
CAP_DSHOW,
|
||||
#endif
|
||||
@ -490,7 +478,8 @@ static Ptr<IVideoCapture> IVideoCapture_create(int index)
|
||||
// try every possibly installed camera API
|
||||
for (int i = 0; domains[i] >= 0; i++)
|
||||
{
|
||||
#if defined(HAVE_DSHOW) || \
|
||||
#if defined(HAVE_GSTREAMER) || \
|
||||
defined(HAVE_DSHOW) || \
|
||||
defined(HAVE_INTELPERC) || \
|
||||
defined(WINRT_VIDEO) || \
|
||||
defined(HAVE_GPHOTO2) || \
|
||||
@ -499,6 +488,11 @@ static Ptr<IVideoCapture> IVideoCapture_create(int index)
|
||||
|
||||
switch (domains[i])
|
||||
{
|
||||
#ifdef HAVE_GSTREAMER
|
||||
case CAP_GSTREAMER:
|
||||
capture = createGStreamerCapture(index);
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_DSHOW
|
||||
case CAP_DSHOW:
|
||||
capture = makePtr<VideoCapture_DShow>(index);
|
||||
@ -536,6 +530,14 @@ static Ptr<IVideoCapture> IVideoCapture_create(const String& filename, int apiPr
|
||||
{
|
||||
bool useAny = (apiPreference == CAP_ANY);
|
||||
Ptr<IVideoCapture> capture;
|
||||
#ifdef HAVE_GSTREAMER
|
||||
if (useAny || apiPreference == CAP_GSTREAMER)
|
||||
{
|
||||
capture = createGStreamerCapture(filename);
|
||||
if (capture && capture->isOpened())
|
||||
return capture;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_XINE
|
||||
if (useAny || apiPreference == CAP_XINE)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -96,7 +96,6 @@ static bool createEncodeHuffmanTable( const int* src, unsigned* table, int max_s
|
||||
if( size > max_size )
|
||||
{
|
||||
CV_Error(CV_StsOutOfRange, "too big maximum Huffman code size");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset( table, 0, size*sizeof(table[0]));
|
||||
|
@ -139,7 +139,6 @@ CvVideoWriter* cvCreateVideoWriter_Images(const char* filename);
|
||||
#define CV_CAP_GSTREAMER_V4L2 2
|
||||
#define CV_CAP_GSTREAMER_FILE 3
|
||||
|
||||
CvCapture* cvCreateCapture_GStreamer(int type, const char *filename);
|
||||
CvCapture* cvCreateFileCapture_FFMPEG_proxy(const char* filename);
|
||||
|
||||
|
||||
@ -194,7 +193,11 @@ namespace cv
|
||||
Ptr<IVideoCapture> createGPhoto2Capture(int index);
|
||||
Ptr<IVideoCapture> createGPhoto2Capture(const String& deviceName);
|
||||
|
||||
|
||||
Ptr<IVideoCapture> createXINECapture(const char* filename);
|
||||
|
||||
Ptr<IVideoCapture> createGStreamerCapture(const String& filename);
|
||||
Ptr<IVideoCapture> createGStreamerCapture(int index);
|
||||
}
|
||||
|
||||
#endif /* __VIDEOIO_H_ */
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
namespace opencv_test
|
||||
{
|
||||
|
||||
typedef tuple< string, Size, Size, int > Param;
|
||||
typedef testing::TestWithParam< Param > Videoio_Gstreamer_Test;
|
||||
|
||||
@ -19,8 +20,9 @@ TEST_P(Videoio_Gstreamer_Test, test_object_structure)
|
||||
int count_frames = 10;
|
||||
std::ostringstream pipeline;
|
||||
pipeline << "videotestsrc pattern=ball num-buffers=" << count_frames << " ! " << format;
|
||||
pipeline << ", framerate=1/1, width=" << frame_size.width << ", height=" << frame_size.height << " ! appsink";
|
||||
VideoCapture cap(pipeline.str(), CAP_GSTREAMER);
|
||||
pipeline << ", width=" << frame_size.width << ", height=" << frame_size.height << " ! appsink";
|
||||
VideoCapture cap;
|
||||
ASSERT_NO_THROW(cap.open(pipeline.str(), CAP_GSTREAMER));
|
||||
ASSERT_TRUE(cap.isOpened());
|
||||
|
||||
Mat buffer, decode_frame, gray_frame, rgb_frame;
|
||||
|
@ -46,12 +46,62 @@
|
||||
namespace opencv_test
|
||||
{
|
||||
|
||||
struct VideoCaptureAPI
|
||||
{
|
||||
VideoCaptureAPIs api;
|
||||
|
||||
inline const char * toString() const
|
||||
{
|
||||
switch (api)
|
||||
{
|
||||
case CAP_ANY: return "CAP_ANY";
|
||||
#ifdef __linux__
|
||||
case CAP_V4L2: return "CAP_V4L/CAP_V4L2";
|
||||
#else
|
||||
case CAP_VFW: return "CAP_VFW";
|
||||
#endif
|
||||
case CAP_FIREWIRE: return "CAP_FIREWIRE";
|
||||
case CAP_QT: return "CAP_QT";
|
||||
case CAP_UNICAP: return "CAP_UNICAP";
|
||||
case CAP_DSHOW: return "CAP_DSHOW";
|
||||
case CAP_PVAPI: return "CAP_PVAPI";
|
||||
case CAP_OPENNI: return "CAP_OPENNI";
|
||||
case CAP_OPENNI_ASUS: return "CAP_OPENNI_ASUS";
|
||||
case CAP_ANDROID: return "CAP_ANDROID";
|
||||
case CAP_XIAPI: return "CAP_XIAPI";
|
||||
case CAP_AVFOUNDATION: return "CAP_AVFOUNDATION";
|
||||
case CAP_GIGANETIX: return "CAP_GIGANETIX";
|
||||
case CAP_MSMF: return "CAP_MSMF";
|
||||
case CAP_WINRT: return "CAP_WINRT";
|
||||
case CAP_INTELPERC: return "CAP_INTELPERC";
|
||||
case CAP_OPENNI2: return "CAP_OPENNI2";
|
||||
case CAP_OPENNI2_ASUS: return "CAP_OPENNI2_ASUS";
|
||||
case CAP_GPHOTO2: return "CAP_GPHOTO2";
|
||||
case CAP_GSTREAMER: return "CAP_GSTREAMER";
|
||||
case CAP_FFMPEG: return "CAP_FFMPEG";
|
||||
case CAP_IMAGES: return "CAP_IMAGES";
|
||||
case CAP_ARAVIS: return "CAP_ARAVIS";
|
||||
case CAP_OPENCV_MJPEG: return "CAP_OPENCV_MJPEG";
|
||||
case CAP_INTEL_MFX: return "CAP_INTEL_MFX";
|
||||
case CAP_XINE: return "CAP_XINE";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
VideoCaptureAPI(int api_ = CAP_ANY) : api((VideoCaptureAPIs)api_) {}
|
||||
operator int() { return api; }
|
||||
};
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &out, const VideoCaptureAPI & api)
|
||||
{
|
||||
out << api.toString(); return out;
|
||||
}
|
||||
|
||||
class Videoio_Test_Base
|
||||
{
|
||||
protected:
|
||||
string ext;
|
||||
string video_file;
|
||||
int apiPref;
|
||||
VideoCaptureAPI apiPref;
|
||||
protected:
|
||||
Videoio_Test_Base() {}
|
||||
virtual ~Videoio_Test_Base() {}
|
||||
@ -60,14 +110,16 @@ protected:
|
||||
void checkFrameRead(int idx, VideoCapture & cap)
|
||||
{
|
||||
//int frameID = (int)cap.get(CAP_PROP_POS_FRAMES);
|
||||
Mat img; cap >> img;
|
||||
Mat img;
|
||||
ASSERT_NO_THROW(cap >> img);
|
||||
//std::cout << "idx=" << idx << " img=" << img.size() << " frameID=" << frameID << std::endl;
|
||||
ASSERT_FALSE(img.empty()) << "idx=" << idx;
|
||||
checkFrameContent(img, idx);
|
||||
}
|
||||
void checkFrameSeek(int idx, VideoCapture & cap)
|
||||
{
|
||||
bool canSeek = cap.set(CAP_PROP_POS_FRAMES, idx);
|
||||
bool canSeek = false;
|
||||
ASSERT_NO_THROW(canSeek = cap.set(CAP_PROP_POS_FRAMES, idx));
|
||||
if (!canSeek)
|
||||
{
|
||||
std::cout << "Seek to frame '" << idx << "' is not supported. SKIP." << std::endl;
|
||||
@ -79,26 +131,15 @@ protected:
|
||||
public:
|
||||
void doTest()
|
||||
{
|
||||
if (apiPref == CAP_AVFOUNDATION)
|
||||
{
|
||||
// TODO: fix this backend
|
||||
std::cout << "SKIP test: AVFoundation backend returns invalid frame count" << std::endl;
|
||||
return;
|
||||
}
|
||||
else if (apiPref == CAP_VFW)
|
||||
{
|
||||
// TODO: fix this backend
|
||||
std::cout << "SKIP test: Video for Windows backend not open files" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
VideoCapture cap(video_file, apiPref);
|
||||
VideoCapture cap;
|
||||
ASSERT_NO_THROW(cap.open(video_file, apiPref));
|
||||
if (!cap.isOpened())
|
||||
{
|
||||
std::cout << "SKIP test: backend " << apiPref << " can't open the video: " << video_file << std::endl;
|
||||
return;
|
||||
}
|
||||
int n_frames = (int)cap.get(CAP_PROP_FRAME_COUNT);
|
||||
int n_frames = -1;
|
||||
EXPECT_NO_THROW(n_frames = (int)cap.get(CAP_PROP_FRAME_COUNT));
|
||||
if (n_frames > 0)
|
||||
{
|
||||
ASSERT_GT(n_frames, 0);
|
||||
@ -124,7 +165,8 @@ public:
|
||||
checkFrameRead(k, cap);
|
||||
}
|
||||
}
|
||||
bool canSeek = cap.set(CAP_PROP_POS_FRAMES, 0);
|
||||
bool canSeek = false;
|
||||
EXPECT_NO_THROW(canSeek = cap.set(CAP_PROP_POS_FRAMES, 0));
|
||||
if (!canSeek)
|
||||
{
|
||||
std::cout << "Seek to frame '0' is not supported. SKIP all 'seek' tests." << std::endl;
|
||||
@ -134,7 +176,9 @@ public:
|
||||
if (ext != "wmv" && ext != "h264" && ext != "h265")
|
||||
{
|
||||
SCOPED_TRACE("progressive seek");
|
||||
ASSERT_TRUE(cap.set(CAP_PROP_POS_FRAMES, 0));
|
||||
bool res = false;
|
||||
EXPECT_NO_THROW(res = cap.set(CAP_PROP_POS_FRAMES, 0));
|
||||
ASSERT_TRUE(res);
|
||||
for (int k = 0; k < n_frames; k += 20)
|
||||
{
|
||||
checkFrameSeek(k, cap);
|
||||
@ -144,7 +188,9 @@ public:
|
||||
if (ext != "mpg" && ext != "wmv" && ext != "h264" && ext != "h265")
|
||||
{
|
||||
SCOPED_TRACE("random seek");
|
||||
ASSERT_TRUE(cap.set(CAP_PROP_POS_FRAMES, 0));
|
||||
bool res = false;
|
||||
EXPECT_NO_THROW(res = cap.set(CAP_PROP_POS_FRAMES, 0));
|
||||
ASSERT_TRUE(res);
|
||||
for (int k = 0; k < 10; ++k)
|
||||
{
|
||||
checkFrameSeek(cvtest::TS::ptr()->get_rng().uniform(0, n_frames), cap);
|
||||
@ -154,7 +200,7 @@ public:
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
typedef tuple<string, int> Backend_Type_Params;
|
||||
typedef tuple<string, VideoCaptureAPI> Backend_Type_Params;
|
||||
|
||||
class Videoio_Bunny : public Videoio_Test_Base, public testing::TestWithParam<Backend_Type_Params>
|
||||
{
|
||||
@ -168,37 +214,29 @@ public:
|
||||
}
|
||||
void doFrameCountTest()
|
||||
{
|
||||
if (apiPref == CAP_AVFOUNDATION)
|
||||
{
|
||||
// TODO: fix this backend
|
||||
std::cout << "SKIP test: AVFoundation backend returns invalid frame count" << std::endl;
|
||||
return;
|
||||
}
|
||||
else if (apiPref == CAP_VFW)
|
||||
{
|
||||
// TODO: fix this backend
|
||||
std::cout << "SKIP test: Video for Windows backend not open files" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
VideoCapture cap(video_file, apiPref);
|
||||
VideoCapture cap;
|
||||
EXPECT_NO_THROW(cap.open(video_file, apiPref));
|
||||
if (!cap.isOpened())
|
||||
{
|
||||
std::cout << "SKIP test: backend " << apiPref << " can't open the video: " << video_file << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
EXPECT_EQ(bunny_param.getWidth() , cap.get(CAP_PROP_FRAME_WIDTH));
|
||||
EXPECT_EQ(bunny_param.getHeight(), cap.get(CAP_PROP_FRAME_HEIGHT));
|
||||
Size actual;
|
||||
EXPECT_NO_THROW(actual = Size((int)cap.get(CAP_PROP_FRAME_WIDTH),
|
||||
(int)cap.get(CAP_PROP_FRAME_HEIGHT)));
|
||||
EXPECT_EQ(bunny_param.getWidth(), actual.width);
|
||||
EXPECT_EQ(bunny_param.getHeight(), actual.height);
|
||||
|
||||
double fps_prop = cap.get(CAP_PROP_FPS);
|
||||
double fps_prop = 0;
|
||||
EXPECT_NO_THROW(fps_prop = cap.get(CAP_PROP_FPS));
|
||||
if (fps_prop > 0)
|
||||
EXPECT_NEAR(fps_prop, bunny_param.getFps(), 1);
|
||||
else
|
||||
std::cout << "FPS is not available. SKIP check." << std::endl;
|
||||
|
||||
int count_prop = 0;
|
||||
count_prop = (int)cap.get(CAP_PROP_FRAME_COUNT);
|
||||
EXPECT_NO_THROW(count_prop = (int)cap.get(CAP_PROP_FRAME_COUNT));
|
||||
// mpg file reports 5.08 sec * 24 fps => property returns 122 frames
|
||||
// but actual number of frames returned is 125
|
||||
if (ext != "mpg")
|
||||
@ -213,7 +251,7 @@ public:
|
||||
while (cap.isOpened())
|
||||
{
|
||||
Mat frame;
|
||||
cap >> frame;
|
||||
EXPECT_NO_THROW(cap >> frame);
|
||||
if (frame.empty())
|
||||
break;
|
||||
EXPECT_EQ(bunny_param.getWidth(), frame.cols);
|
||||
@ -229,7 +267,15 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef tuple<string, string, float, int> Ext_Fourcc_PSNR;
|
||||
//==================================================================================================
|
||||
|
||||
struct Ext_Fourcc_PSNR
|
||||
{
|
||||
string ext;
|
||||
string fourcc;
|
||||
float PSNR;
|
||||
VideoCaptureAPI api;
|
||||
};
|
||||
typedef tuple<Size, Ext_Fourcc_PSNR> Size_Ext_Fourcc_PSNR;
|
||||
|
||||
class Videoio_Synthetic : public Videoio_Test_Base, public testing::TestWithParam<Size_Ext_Fourcc_PSNR>
|
||||
@ -243,39 +289,27 @@ public:
|
||||
Videoio_Synthetic()
|
||||
{
|
||||
frame_size = get<0>(GetParam());
|
||||
const Ext_Fourcc_PSNR ¶m = get<1>(GetParam());
|
||||
ext = get<0>(param);
|
||||
fourcc = fourccFromString(get<1>(param));
|
||||
PSNR_GT = get<2>(param);
|
||||
const Ext_Fourcc_PSNR p = get<1>(GetParam());
|
||||
ext = p.ext;
|
||||
fourcc = fourccFromString(p.fourcc);
|
||||
PSNR_GT = p.PSNR;
|
||||
video_file = cv::tempfile((fourccToString(fourcc) + "." + ext).c_str());
|
||||
frame_count = 100;
|
||||
fps = 25.;
|
||||
apiPref = get<3>(param);
|
||||
apiPref = p.api;
|
||||
}
|
||||
void SetUp()
|
||||
{
|
||||
|
||||
if (apiPref == CAP_AVFOUNDATION)
|
||||
{
|
||||
// TODO: fix this backend
|
||||
std::cout << "SKIP test: AVFoundation backend can not write video" << std::endl;
|
||||
return;
|
||||
}
|
||||
else if (apiPref == CAP_VFW)
|
||||
{
|
||||
// TODO: fix this backend
|
||||
std::cout << "SKIP test: Video for Windows backend not open files" << std::endl;
|
||||
return;
|
||||
}
|
||||
Mat img(frame_size, CV_8UC3);
|
||||
VideoWriter writer(video_file, apiPref, fourcc, fps, frame_size, true);
|
||||
VideoWriter writer;
|
||||
EXPECT_NO_THROW(writer.open(video_file, apiPref, fourcc, fps, frame_size, true));
|
||||
ASSERT_TRUE(writer.isOpened());
|
||||
for(int i = 0; i < frame_count; ++i )
|
||||
{
|
||||
generateFrame(i, frame_count, img);
|
||||
writer << img;
|
||||
EXPECT_NO_THROW(writer << img);
|
||||
}
|
||||
writer.release();
|
||||
EXPECT_NO_THROW(writer.release());
|
||||
}
|
||||
void TearDown()
|
||||
{
|
||||
@ -301,6 +335,10 @@ public:
|
||||
if (fourcc == VideoWriter::fourcc('M', 'P', 'E', 'G') && ext == "mkv")
|
||||
expected_frame_count.end += 1;
|
||||
|
||||
// Workaround for some gstreamer pipelines
|
||||
if (apiPref == CAP_GSTREAMER)
|
||||
expected_frame_count.start -= 1;
|
||||
|
||||
ASSERT_LE(expected_frame_count.start, actual);
|
||||
ASSERT_GE(expected_frame_count.end, actual);
|
||||
|
||||
@ -310,22 +348,24 @@ public:
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
int backend_params[] = {
|
||||
static VideoCaptureAPI backend_params[] = {
|
||||
#ifdef HAVE_QUICKTIME
|
||||
CAP_QT,
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_AVFOUNDATION
|
||||
CAP_AVFOUNDATION,
|
||||
#endif
|
||||
// TODO: Broken?
|
||||
//#ifdef HAVE_AVFOUNDATION
|
||||
// CAP_AVFOUNDATION,
|
||||
//#endif
|
||||
|
||||
#ifdef HAVE_MSMF
|
||||
CAP_MSMF,
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_VFW
|
||||
CAP_VFW,
|
||||
#endif
|
||||
// TODO: Broken?
|
||||
//#ifdef HAVE_VFW
|
||||
// CAP_VFW,
|
||||
//#endif
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
CAP_GSTREAMER,
|
||||
@ -343,7 +383,7 @@ int backend_params[] = {
|
||||
// CAP_INTEL_MFX
|
||||
};
|
||||
|
||||
string bunny_params[] = {
|
||||
static string bunny_params[] = {
|
||||
#ifdef HAVE_VIDEO_INPUT
|
||||
string("wmv"),
|
||||
string("mov"),
|
||||
@ -368,12 +408,22 @@ INSTANTIATE_TEST_CASE_P(videoio, Videoio_Bunny,
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
inline Ext_Fourcc_PSNR makeParam(const char * ext, const char * fourcc, float psnr, int apipref)
|
||||
inline Ext_Fourcc_PSNR makeParam(const char * ext, const char * fourcc, float psnr, VideoCaptureAPIs apipref)
|
||||
{
|
||||
return make_tuple(string(ext), string(fourcc), (float)psnr, (int)apipref);
|
||||
Ext_Fourcc_PSNR res;
|
||||
res.ext = ext;
|
||||
res.fourcc = fourcc;
|
||||
res.PSNR = psnr;
|
||||
res.api = apipref;
|
||||
return res;
|
||||
}
|
||||
|
||||
Ext_Fourcc_PSNR synthetic_params[] = {
|
||||
inline static std::ostream &operator<<(std::ostream &out, const Ext_Fourcc_PSNR &p)
|
||||
{
|
||||
out << "FOURCC(" << p.fourcc << "), ." << p.ext << ", " << p.api << ", " << p.PSNR << "dB"; return out;
|
||||
}
|
||||
|
||||
static Ext_Fourcc_PSNR synthetic_params[] = {
|
||||
|
||||
#ifdef HAVE_MSMF
|
||||
#if !defined(_M_ARM)
|
||||
@ -385,16 +435,17 @@ Ext_Fourcc_PSNR synthetic_params[] = {
|
||||
makeParam("mov", "H264", 30.f, CAP_MSMF),
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_VFW
|
||||
#if !defined(_M_ARM)
|
||||
makeParam("wmv", "WMV1", 30.f, CAP_VFW),
|
||||
makeParam("wmv", "WMV2", 30.f, CAP_VFW),
|
||||
#endif
|
||||
makeParam("wmv", "WMV3", 30.f, CAP_VFW),
|
||||
makeParam("wmv", "WVC1", 30.f, CAP_VFW),
|
||||
makeParam("avi", "H264", 30.f, CAP_VFW),
|
||||
makeParam("avi", "MJPG", 30.f, CAP_VFW),
|
||||
#endif
|
||||
// TODO: Broken?
|
||||
//#ifdef HAVE_VFW
|
||||
//#if !defined(_M_ARM)
|
||||
// makeParam("wmv", "WMV1", 30.f, CAP_VFW),
|
||||
// makeParam("wmv", "WMV2", 30.f, CAP_VFW),
|
||||
//#endif
|
||||
// makeParam("wmv", "WMV3", 30.f, CAP_VFW),
|
||||
// makeParam("wmv", "WVC1", 30.f, CAP_VFW),
|
||||
// makeParam("avi", "H264", 30.f, CAP_VFW),
|
||||
// makeParam("avi", "MJPG", 30.f, CAP_VFW),
|
||||
//#endif
|
||||
|
||||
#ifdef HAVE_QUICKTIME
|
||||
makeParam("mov", "mp4v", 30.f, CAP_QT),
|
||||
@ -408,17 +459,18 @@ Ext_Fourcc_PSNR synthetic_params[] = {
|
||||
makeParam("mkv", "MJPG", 30.f, CAP_QT),
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_AVFOUNDATION
|
||||
makeParam("mov", "mp4v", 30.f, CAP_AVFOUNDATION),
|
||||
makeParam("avi", "XVID", 30.f, CAP_AVFOUNDATION),
|
||||
makeParam("avi", "MPEG", 30.f, CAP_AVFOUNDATION),
|
||||
makeParam("avi", "IYUV", 30.f, CAP_AVFOUNDATION),
|
||||
makeParam("avi", "MJPG", 30.f, CAP_AVFOUNDATION),
|
||||
// TODO: Broken?
|
||||
//#ifdef HAVE_AVFOUNDATION
|
||||
// makeParam("mov", "mp4v", 30.f, CAP_AVFOUNDATION),
|
||||
// makeParam("avi", "XVID", 30.f, CAP_AVFOUNDATION),
|
||||
// makeParam("avi", "MPEG", 30.f, CAP_AVFOUNDATION),
|
||||
// makeParam("avi", "IYUV", 30.f, CAP_AVFOUNDATION),
|
||||
// makeParam("avi", "MJPG", 30.f, CAP_AVFOUNDATION),
|
||||
|
||||
makeParam("mkv", "XVID", 30.f, CAP_AVFOUNDATION),
|
||||
makeParam("mkv", "MPEG", 30.f, CAP_AVFOUNDATION),
|
||||
makeParam("mkv", "MJPG", 30.f, CAP_AVFOUNDATION),
|
||||
#endif
|
||||
// makeParam("mkv", "XVID", 30.f, CAP_AVFOUNDATION),
|
||||
// makeParam("mkv", "MPEG", 30.f, CAP_AVFOUNDATION),
|
||||
// makeParam("mkv", "MJPG", 30.f, CAP_AVFOUNDATION),
|
||||
//#endif
|
||||
|
||||
#ifdef HAVE_FFMPEG
|
||||
makeParam("avi", "XVID", 30.f, CAP_FFMPEG),
|
||||
@ -432,15 +484,13 @@ Ext_Fourcc_PSNR synthetic_params[] = {
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
// makeParam("avi", "XVID", 30.f, CAP_GSTREAMER), - corrupted frames, broken indexes
|
||||
makeParam("avi", "MPEG", 30.f, CAP_GSTREAMER),
|
||||
makeParam("avi", "IYUV", 30.f, CAP_GSTREAMER),
|
||||
makeParam("avi", "MJPG", 30.f, CAP_GSTREAMER),
|
||||
makeParam("avi", "H264", 30.f, CAP_GSTREAMER),
|
||||
|
||||
// makeParam("mkv", "XVID", 30.f, CAP_GSTREAMER),
|
||||
makeParam("mkv", "MPEG", 30.f, CAP_GSTREAMER),
|
||||
makeParam("mkv", "MJPG", 30.f, CAP_GSTREAMER),
|
||||
makeParam("mkv", "H264", 30.f, CAP_GSTREAMER),
|
||||
|
||||
#endif
|
||||
makeParam("avi", "MJPG", 30.f, CAP_OPENCV_MJPEG),
|
||||
|
@ -8,144 +8,430 @@
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
string getGstDemuxPlugin(string container);
|
||||
string getGstAvDecodePlugin(string codec);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
class GStreamerPipeline
|
||||
{
|
||||
const string keys =
|
||||
"{h help usage ? | | print help messages }"
|
||||
"{p pipeline |gst-default| pipeline name (supported: 'gst-default', 'gst-vaapi', 'gst-libav', 'ffmpeg') }"
|
||||
"{ct container |mp4 | container name (supported: 'mp4', 'mov', 'avi', 'mkv') }"
|
||||
"{cd codec |h264 | codec name (supported: 'h264', 'h265', 'mpeg2', 'mpeg4', 'mjpeg', 'vp8') }"
|
||||
"{f file path | | path to file }"
|
||||
"{fm fast | | fast measure fps }";
|
||||
|
||||
CommandLineParser parser(argc, argv, keys);
|
||||
|
||||
parser.about("This program shows how to read a video file with GStreamer pipeline with OpenCV.");
|
||||
|
||||
if (parser.has("help"))
|
||||
public:
|
||||
// Preprocessing arguments command line
|
||||
GStreamerPipeline(int argc, char *argv[])
|
||||
{
|
||||
parser.printMessage();
|
||||
return 0;
|
||||
const string keys =
|
||||
"{h help usage ? | | print help messages }"
|
||||
"{m mode | | coding mode (supported: encode, decode) }"
|
||||
"{p pipeline |default | pipeline name (supported: 'default', 'gst-basic', 'gst-vaapi', 'gst-libav', 'ffmpeg') }"
|
||||
"{ct container |mp4 | container name (supported: 'mp4', 'mov', 'avi', 'mkv') }"
|
||||
"{cd codec |h264 | codec name (supported: 'h264', 'h265', 'mpeg2', 'mpeg4', 'mjpeg', 'vp8') }"
|
||||
"{f file path | | path to file }"
|
||||
"{vr resolution |720p | video resolution for encoding (supported: '720p', '1080p', '4k') }"
|
||||
"{fps |30 | fix frame per second for encoding (supported: fps > 0) }"
|
||||
"{fm fast | | fast measure fps }";
|
||||
cmd_parser = new CommandLineParser(argc, argv, keys);
|
||||
cmd_parser->about("This program shows how to read a video file with GStreamer pipeline with OpenCV.");
|
||||
|
||||
if (cmd_parser->has("help"))
|
||||
{
|
||||
cmd_parser->printMessage();
|
||||
exit_code = -1;
|
||||
}
|
||||
|
||||
fast_measure = cmd_parser->has("fast"); // fast measure fps
|
||||
fix_fps = cmd_parser->get<int>("fps"); // fixed frame per second
|
||||
pipeline = cmd_parser->get<string>("pipeline"), // gstreamer pipeline type
|
||||
container = cmd_parser->get<string>("container"), // container type
|
||||
mode = cmd_parser->get<string>("mode"), // coding mode
|
||||
codec = cmd_parser->get<string>("codec"), // codec type
|
||||
file_name = cmd_parser->get<string>("file"), // path to videofile
|
||||
resolution = cmd_parser->get<string>("resolution"); // video resolution
|
||||
|
||||
if (!cmd_parser->check())
|
||||
{
|
||||
cmd_parser->printErrors();
|
||||
exit_code = -1;
|
||||
}
|
||||
exit_code = 0;
|
||||
}
|
||||
|
||||
bool arg_fast_measure = parser.has("fast"); // fast measure fps
|
||||
string arg_pipeline = parser.get<string>("pipeline"), // GStreamer pipeline type
|
||||
arg_container = parser.get<string>("container"), // container type
|
||||
arg_codec = parser.get<string>("codec"), // codec type
|
||||
arg_file_name = parser.get<string>("file"); // path to videofile
|
||||
VideoCapture cap;
|
||||
~GStreamerPipeline() { delete cmd_parser; }
|
||||
|
||||
if (!parser.check())
|
||||
// Start pipeline
|
||||
int run()
|
||||
{
|
||||
parser.printErrors();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Choose the constructed GStreamer pipeline
|
||||
if (arg_pipeline.find("gst") == 0)
|
||||
{
|
||||
ostringstream pipeline;
|
||||
pipeline << "filesrc location=\"" << arg_file_name << "\"";
|
||||
pipeline << " ! " << getGstDemuxPlugin(arg_container);
|
||||
|
||||
if (arg_pipeline.find("default") == 4) {
|
||||
pipeline << " ! decodebin";
|
||||
}
|
||||
else if (arg_pipeline.find("vaapi1710") == 4)
|
||||
if (exit_code < 0) { return exit_code; }
|
||||
if (mode == "decode") { if (createDecodePipeline() < 0) return -1; }
|
||||
else if (mode == "encode") { if (createEncodePipeline() < 0) return -1; }
|
||||
else
|
||||
{
|
||||
pipeline << " ! vaapidecodebin";
|
||||
if (arg_container == "mkv")
|
||||
{
|
||||
pipeline << " ! autovideoconvert";
|
||||
}
|
||||
else
|
||||
{
|
||||
pipeline << " ! video/x-raw, format=YV12";
|
||||
}
|
||||
cout << "Unsupported mode: " << mode << endl;
|
||||
cmd_parser->printErrors();
|
||||
return -1;
|
||||
}
|
||||
else if (arg_pipeline.find("libav") == 4)
|
||||
cout << "_____________________________________" << endl;
|
||||
cout << "Pipeline " << mode << ":" << endl;
|
||||
cout << stream_pipeline.str() << endl;
|
||||
// Choose a show video or only measure fps
|
||||
cout << "_____________________________________" << endl;
|
||||
cout << "Start measure frame per seconds (fps)" << endl;
|
||||
cout << "Loading ..." << endl;
|
||||
|
||||
vector<double> tick_counts;
|
||||
|
||||
cout << "Start " << mode << ": " << file_name;
|
||||
cout << " (" << pipeline << ")" << endl;
|
||||
|
||||
while(true)
|
||||
{
|
||||
pipeline << " ! " << getGstAvDecodePlugin(arg_codec);
|
||||
int64 temp_count_tick = 0;
|
||||
if (mode == "decode")
|
||||
{
|
||||
Mat frame;
|
||||
temp_count_tick = getTickCount();
|
||||
cap >> frame;
|
||||
temp_count_tick = getTickCount() - temp_count_tick;
|
||||
if (frame.empty()) { break; }
|
||||
}
|
||||
else if (mode == "encode")
|
||||
{
|
||||
Mat element;
|
||||
while(!cap.grab());
|
||||
cap.retrieve(element);
|
||||
temp_count_tick = getTickCount();
|
||||
wrt << element;
|
||||
temp_count_tick = getTickCount() - temp_count_tick;
|
||||
}
|
||||
|
||||
tick_counts.push_back(static_cast<double>(temp_count_tick));
|
||||
if (((mode == "decode") && fast_measure && (tick_counts.size() > 1e3)) ||
|
||||
((mode == "encode") && (tick_counts.size() > 3e3)) ||
|
||||
((mode == "encode") && fast_measure && (tick_counts.size() > 1e2)))
|
||||
{ break; }
|
||||
|
||||
}
|
||||
double time_fps = sum(tick_counts)[0] / getTickFrequency();
|
||||
|
||||
if (tick_counts.size() != 0)
|
||||
{
|
||||
cout << "Finished: " << tick_counts.size() << " in " << time_fps <<" sec ~ " ;
|
||||
cout << tick_counts.size() / time_fps <<" fps " << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
parser.printMessage();
|
||||
cout << "Unsupported pipeline: " << arg_pipeline << endl;
|
||||
return -4;
|
||||
cout << "Failed " << mode << ": " << file_name;
|
||||
cout << " (" << pipeline << ")" << endl;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Free video resource
|
||||
void close()
|
||||
{
|
||||
cap.release();
|
||||
wrt.release();
|
||||
}
|
||||
|
||||
private:
|
||||
// Choose the constructed GStreamer pipeline for decode
|
||||
int createDecodePipeline()
|
||||
{
|
||||
if (pipeline == "default") {
|
||||
cap = VideoCapture(file_name, CAP_GSTREAMER);
|
||||
}
|
||||
else if (pipeline.find("gst") == 0)
|
||||
{
|
||||
stream_pipeline << "filesrc location=\"" << file_name << "\"";
|
||||
stream_pipeline << " ! " << getGstMuxPlugin();
|
||||
|
||||
if (pipeline.find("basic") == 4)
|
||||
{
|
||||
stream_pipeline << getGstDefaultCodePlugin();
|
||||
}
|
||||
else if (pipeline.find("vaapi1710") == 4)
|
||||
{
|
||||
stream_pipeline << getGstVaapiCodePlugin();
|
||||
}
|
||||
else if (pipeline.find("libav") == 4)
|
||||
{
|
||||
stream_pipeline << getGstAvCodePlugin();
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Unsupported pipeline: " << pipeline << endl;
|
||||
cmd_parser->printErrors();
|
||||
return -1;
|
||||
}
|
||||
|
||||
stream_pipeline << " ! videoconvert n-threads=" << getNumThreads();
|
||||
stream_pipeline << " ! appsink sync=false";
|
||||
cap = VideoCapture(stream_pipeline.str(), CAP_GSTREAMER);
|
||||
}
|
||||
else if (pipeline == "ffmpeg")
|
||||
{
|
||||
cap = VideoCapture(file_name, CAP_FFMPEG);
|
||||
stream_pipeline << "default pipeline for ffmpeg" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Unsupported pipeline: " << pipeline << endl;
|
||||
cmd_parser->printErrors();
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Choose the constructed GStreamer pipeline for encode
|
||||
int createEncodePipeline()
|
||||
{
|
||||
if (checkConfiguration() < 0) return -1;
|
||||
ostringstream test_pipeline;
|
||||
test_pipeline << "videotestsrc pattern=smpte";
|
||||
test_pipeline << " ! video/x-raw, " << getVideoSettings();
|
||||
test_pipeline << " ! appsink sync=false";
|
||||
cap = VideoCapture(test_pipeline.str(), CAP_GSTREAMER);
|
||||
|
||||
if (pipeline == "default") {
|
||||
wrt = VideoWriter(file_name, CAP_GSTREAMER, getFourccCode(), fix_fps, fix_size, true);
|
||||
}
|
||||
else if (pipeline.find("gst") == 0)
|
||||
{
|
||||
stream_pipeline << "appsrc ! videoconvert n-threads=" << getNumThreads() << " ! ";
|
||||
|
||||
if (pipeline.find("basic") == 4)
|
||||
{
|
||||
stream_pipeline << getGstDefaultCodePlugin();
|
||||
}
|
||||
else if (pipeline.find("vaapi1710") == 4)
|
||||
{
|
||||
stream_pipeline << getGstVaapiCodePlugin();
|
||||
}
|
||||
else if (pipeline.find("libav") == 4)
|
||||
{
|
||||
stream_pipeline << getGstAvCodePlugin();
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Unsupported pipeline: " << pipeline << endl;
|
||||
cmd_parser->printErrors();
|
||||
return -1;
|
||||
}
|
||||
|
||||
stream_pipeline << " ! " << getGstMuxPlugin();
|
||||
stream_pipeline << " ! filesink location=\"" << file_name << "\"";
|
||||
wrt = VideoWriter(stream_pipeline.str(), CAP_GSTREAMER, 0, fix_fps, fix_size, true);
|
||||
}
|
||||
else if (pipeline == "ffmpeg")
|
||||
{
|
||||
wrt = VideoWriter(file_name, CAP_FFMPEG, getFourccCode(), fix_fps, fix_size, true);
|
||||
stream_pipeline << "default pipeline for ffmpeg" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Unsupported pipeline: " << pipeline << endl;
|
||||
cmd_parser->printErrors();
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Choose video resolution for encoding
|
||||
string getVideoSettings()
|
||||
{
|
||||
ostringstream video_size;
|
||||
if (fix_fps > 0) { video_size << "framerate=" << fix_fps << "/1, "; }
|
||||
else
|
||||
{
|
||||
cout << "Unsupported fps (< 0): " << fix_fps << endl;
|
||||
cmd_parser->printErrors();
|
||||
return string();
|
||||
}
|
||||
|
||||
pipeline << " ! videoconvert";
|
||||
pipeline << " n-threads=" << getNumThreads();
|
||||
pipeline << " ! appsink sync=false";
|
||||
cap = VideoCapture(pipeline.str(), CAP_GSTREAMER);
|
||||
if (resolution == "720p") { fix_size = Size(1280, 720); }
|
||||
else if (resolution == "1080p") { fix_size = Size(1920, 1080); }
|
||||
else if (resolution == "4k") { fix_size = Size(3840, 2160); }
|
||||
else
|
||||
{
|
||||
cout << "Unsupported video resolution: " << resolution << endl;
|
||||
cmd_parser->printErrors();
|
||||
return string();
|
||||
}
|
||||
|
||||
video_size << "width=" << fix_size.width << ", height=" << fix_size.height;
|
||||
return video_size.str();
|
||||
}
|
||||
else if (arg_pipeline == "ffmpeg")
|
||||
|
||||
// Choose a video container
|
||||
string getGstMuxPlugin()
|
||||
{
|
||||
cap = VideoCapture(arg_file_name, CAP_FFMPEG);
|
||||
ostringstream plugin;
|
||||
if (container == "avi") { plugin << "avi"; }
|
||||
else if (container == "mp4") { plugin << "qt"; }
|
||||
else if (container == "mov") { plugin << "qt"; }
|
||||
else if (container == "mkv") { plugin << "matroska"; }
|
||||
else
|
||||
{
|
||||
cout << "Unsupported container: " << container << endl;
|
||||
cmd_parser->printErrors();
|
||||
return string();
|
||||
}
|
||||
|
||||
if (mode == "decode") { plugin << "demux"; }
|
||||
else if (mode == "encode") { plugin << "mux"; }
|
||||
else
|
||||
{
|
||||
cout << "Unsupported mode: " << mode << endl;
|
||||
cmd_parser->printErrors();
|
||||
return string();
|
||||
}
|
||||
|
||||
return plugin.str();
|
||||
}
|
||||
else
|
||||
|
||||
// Choose a libav codec
|
||||
string getGstAvCodePlugin()
|
||||
{
|
||||
parser.printMessage();
|
||||
cout << "Unsupported pipeline: " << arg_pipeline << endl;
|
||||
return -4;
|
||||
ostringstream plugin;
|
||||
if (mode == "decode")
|
||||
{
|
||||
if (codec == "h264") { plugin << "h264parse ! "; }
|
||||
else if (codec == "h265") { plugin << "h265parse ! "; }
|
||||
plugin << "avdec_";
|
||||
}
|
||||
else if (mode == "encode") { plugin << "avenc_"; }
|
||||
else
|
||||
{
|
||||
cout << "Unsupported mode: " << mode << endl;
|
||||
cmd_parser->printErrors();
|
||||
return string();
|
||||
}
|
||||
|
||||
if (codec == "h264") { plugin << "h264"; }
|
||||
else if (codec == "h265") { plugin << "h265"; }
|
||||
else if (codec == "mpeg2") { plugin << "mpeg2video"; }
|
||||
else if (codec == "mpeg4") { plugin << "mpeg4"; }
|
||||
else if (codec == "mjpeg") { plugin << "mjpeg"; }
|
||||
else if (codec == "vp8") { plugin << "vp8"; }
|
||||
else
|
||||
{
|
||||
cout << "Unsupported libav codec: " << codec << endl;
|
||||
cmd_parser->printErrors();
|
||||
return string();
|
||||
}
|
||||
|
||||
return plugin.str();
|
||||
}
|
||||
|
||||
// Choose a show video or only measure fps
|
||||
cout << "_____________________________________" << '\n';
|
||||
cout << "Start measure frame per seconds (fps)" << '\n';
|
||||
cout << "Loading ..." << '\n';
|
||||
|
||||
Mat frame;
|
||||
vector<double> tick_counts;
|
||||
|
||||
cout << "Start decoding: " << arg_file_name;
|
||||
cout << " (" << arg_pipeline << ")" << endl;
|
||||
|
||||
while(true)
|
||||
// Choose a vaapi codec
|
||||
string getGstVaapiCodePlugin()
|
||||
{
|
||||
int64 temp_count_tick = getTickCount();
|
||||
cap >> frame;
|
||||
temp_count_tick = getTickCount() - temp_count_tick;
|
||||
if (frame.empty()) { break; }
|
||||
tick_counts.push_back(static_cast<double>(temp_count_tick));
|
||||
if (arg_fast_measure && (tick_counts.size() > 1000)) { break; }
|
||||
ostringstream plugin;
|
||||
if (mode == "decode")
|
||||
{
|
||||
plugin << "vaapidecodebin";
|
||||
if (container == "mkv") { plugin << " ! autovideoconvert"; }
|
||||
else { plugin << " ! video/x-raw, format=YV12"; }
|
||||
}
|
||||
else if (mode == "encode")
|
||||
{
|
||||
if (codec == "h264") { plugin << "vaapih264enc"; }
|
||||
else if (codec == "h265") { plugin << "vaapih265enc"; }
|
||||
else if (codec == "mpeg2") { plugin << "vaapimpeg2enc"; }
|
||||
else if (codec == "mjpeg") { plugin << "vaapijpegenc"; }
|
||||
else if (codec == "vp8") { plugin << "vaapivp8enc"; }
|
||||
else
|
||||
{
|
||||
cout << "Unsupported vaapi codec: " << codec << endl;
|
||||
cmd_parser->printErrors();
|
||||
return string();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Unsupported mode: " << resolution << endl;
|
||||
cmd_parser->printErrors();
|
||||
return string();
|
||||
}
|
||||
return plugin.str();
|
||||
}
|
||||
|
||||
// Choose a default codec
|
||||
string getGstDefaultCodePlugin()
|
||||
{
|
||||
ostringstream plugin;
|
||||
if (mode == "decode")
|
||||
{
|
||||
plugin << " ! decodebin";
|
||||
}
|
||||
else if (mode == "encode")
|
||||
{
|
||||
if (codec == "h264") { plugin << "x264enc"; }
|
||||
else if (codec == "h265") { plugin << "x265enc"; }
|
||||
else if (codec == "mpeg2") { plugin << "mpeg2enc"; }
|
||||
else if (codec == "mjpeg") { plugin << "jpegenc"; }
|
||||
else if (codec == "vp8") { plugin << "vp8enc"; }
|
||||
else
|
||||
{
|
||||
cout << "Unsupported default codec: " << codec << endl;
|
||||
cmd_parser->printErrors();
|
||||
return string();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Unsupported mode: " << resolution << endl;
|
||||
cmd_parser->printErrors();
|
||||
return string();
|
||||
}
|
||||
return plugin.str();
|
||||
}
|
||||
// Get fourcc for codec
|
||||
int getFourccCode()
|
||||
{
|
||||
if (codec == "h264") { return VideoWriter::fourcc('H','2','6','4'); }
|
||||
else if (codec == "h265") { return VideoWriter::fourcc('H','E','V','C'); }
|
||||
else if (codec == "mpeg2") { return VideoWriter::fourcc('M','P','E','G'); }
|
||||
else if (codec == "mpeg4") { return VideoWriter::fourcc('M','P','4','2'); }
|
||||
else if (codec == "mjpeg") { return VideoWriter::fourcc('M','J','P','G'); }
|
||||
else if (codec == "vp8") { return VideoWriter::fourcc('V','P','8','0'); }
|
||||
else
|
||||
{
|
||||
cout << "Unsupported ffmpeg codec: " << codec << endl;
|
||||
cmd_parser->printErrors();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
double time_fps = sum(tick_counts)[0] / getTickFrequency();
|
||||
|
||||
if (tick_counts.size() != 0)
|
||||
// Check bad configuration
|
||||
int checkConfiguration()
|
||||
{
|
||||
cout << "Finished: " << tick_counts.size() << " in " << time_fps <<" sec ~ " ;
|
||||
cout << tick_counts.size() / time_fps <<" fps " << endl;
|
||||
if ((codec == "mpeg2" && getGstMuxPlugin() == "qtmux") ||
|
||||
(codec == "h265" && getGstMuxPlugin() == "avimux") ||
|
||||
(pipeline == "gst-libav" && (codec == "h264" || codec == "h265")) ||
|
||||
(pipeline == "gst-vaapi1710" && codec=="mpeg2" && resolution=="4k") ||
|
||||
(pipeline == "gst-vaapi1710" && codec=="mpeg2" && resolution=="1080p" && fix_fps > 30))
|
||||
{
|
||||
cout << "Unsupported configuration" << endl;
|
||||
cmd_parser->printErrors();
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Failed decoding: " << arg_file_name;
|
||||
cout << " (" << arg_pipeline << ")" << endl;
|
||||
return -5;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Choose a video container
|
||||
string getGstDemuxPlugin(string container) {
|
||||
if (container == "avi") { return "avidemux"; }
|
||||
else if (container == "mp4") { return "qtdemux"; }
|
||||
else if (container == "mov") { return "qtdemux"; }
|
||||
else if (container == "mkv") { return "matroskademux"; }
|
||||
return string();
|
||||
}
|
||||
|
||||
// Choose a codec
|
||||
string getGstAvDecodePlugin(string codec) {
|
||||
if (codec == "h264") { return "h264parse ! avdec_h264"; }
|
||||
else if (codec == "h265") { return "h265parse ! avdec_h265"; }
|
||||
else if (codec == "mpeg2") { return "avdec_mpeg2video"; }
|
||||
else if (codec == "mpeg4") { return "avdec_mpeg4"; }
|
||||
else if (codec == "mjpeg") { return "avdec_mjpeg"; }
|
||||
else if (codec == "vp8") { return "avdec_vp8"; }
|
||||
return string();
|
||||
|
||||
bool fast_measure; // fast measure fps
|
||||
string pipeline, // gstreamer pipeline type
|
||||
container, // container type
|
||||
mode, // coding mode
|
||||
codec, // codec type
|
||||
file_name, // path to videofile
|
||||
resolution; // video resolution
|
||||
int fix_fps; // fixed frame per second
|
||||
Size fix_size; // fixed frame size
|
||||
int exit_code;
|
||||
VideoWriter wrt;
|
||||
VideoCapture cap;
|
||||
ostringstream stream_pipeline;
|
||||
CommandLineParser* cmd_parser;
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
GStreamerPipeline pipe(argc, argv);
|
||||
return pipe.run();
|
||||
}
|
||||
|
232
samples/cpp/tutorial_code/dnn/custom_layers.cpp
Normal file
232
samples/cpp/tutorial_code/dnn/custom_layers.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
#include <opencv2/dnn.hpp>
|
||||
|
||||
//! [A custom layer interface]
|
||||
class MyLayer : public cv::dnn::Layer
|
||||
{
|
||||
public:
|
||||
//! [MyLayer::MyLayer]
|
||||
MyLayer(const cv::dnn::LayerParams ¶ms);
|
||||
//! [MyLayer::MyLayer]
|
||||
|
||||
//! [MyLayer::create]
|
||||
static cv::Ptr<cv::dnn::Layer> create(cv::dnn::LayerParams& params);
|
||||
//! [MyLayer::create]
|
||||
|
||||
//! [MyLayer::getMemoryShapes]
|
||||
virtual bool getMemoryShapes(const std::vector<std::vector<int> > &inputs,
|
||||
const int requiredOutputs,
|
||||
std::vector<std::vector<int> > &outputs,
|
||||
std::vector<std::vector<int> > &internals) const;
|
||||
//! [MyLayer::getMemoryShapes]
|
||||
|
||||
//! [MyLayer::forward]
|
||||
virtual void forward(std::vector<cv::Mat*> &inputs, std::vector<cv::Mat> &outputs, std::vector<cv::Mat> &internals);
|
||||
//! [MyLayer::forward]
|
||||
|
||||
//! [MyLayer::finalize]
|
||||
virtual void finalize(const std::vector<cv::Mat*> &inputs, std::vector<cv::Mat> &outputs);
|
||||
//! [MyLayer::finalize]
|
||||
|
||||
virtual void forward(cv::InputArrayOfArrays inputs, cv::OutputArrayOfArrays outputs, cv::OutputArrayOfArrays internals);
|
||||
};
|
||||
//! [A custom layer interface]
|
||||
|
||||
//! [InterpLayer]
|
||||
class InterpLayer : public cv::dnn::Layer
|
||||
{
|
||||
public:
|
||||
InterpLayer(const cv::dnn::LayerParams ¶ms) : Layer(params)
|
||||
{
|
||||
outWidth = params.get<int>("width", 0);
|
||||
outHeight = params.get<int>("height", 0);
|
||||
}
|
||||
|
||||
static cv::Ptr<cv::dnn::Layer> create(cv::dnn::LayerParams& params)
|
||||
{
|
||||
return cv::Ptr<cv::dnn::Layer>(new InterpLayer(params));
|
||||
}
|
||||
|
||||
virtual bool getMemoryShapes(const std::vector<std::vector<int> > &inputs,
|
||||
const int requiredOutputs,
|
||||
std::vector<std::vector<int> > &outputs,
|
||||
std::vector<std::vector<int> > &internals) const
|
||||
{
|
||||
CV_UNUSED(requiredOutputs); CV_UNUSED(internals);
|
||||
std::vector<int> outShape(4);
|
||||
outShape[0] = inputs[0][0]; // batch size
|
||||
outShape[1] = inputs[0][1]; // number of channels
|
||||
outShape[2] = outHeight;
|
||||
outShape[3] = outWidth;
|
||||
outputs.assign(1, outShape);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Implementation of this custom layer is based on https://github.com/cdmh/deeplab-public/blob/master/src/caffe/layers/interp_layer.cpp
|
||||
virtual void forward(std::vector<cv::Mat*> &inputs, std::vector<cv::Mat> &outputs, std::vector<cv::Mat> &internals)
|
||||
{
|
||||
CV_UNUSED(internals);
|
||||
cv::Mat& inp = *inputs[0];
|
||||
cv::Mat& out = outputs[0];
|
||||
const float* inpData = (float*)inp.data;
|
||||
float* outData = (float*)out.data;
|
||||
|
||||
const int batchSize = inp.size[0];
|
||||
const int numChannels = inp.size[1];
|
||||
const int inpHeight = inp.size[2];
|
||||
const int inpWidth = inp.size[3];
|
||||
|
||||
const float rheight = (outHeight > 1) ? static_cast<float>(inpHeight - 1) / (outHeight - 1) : 0.f;
|
||||
const float rwidth = (outWidth > 1) ? static_cast<float>(inpWidth - 1) / (outWidth - 1) : 0.f;
|
||||
for (int h2 = 0; h2 < outHeight; ++h2)
|
||||
{
|
||||
const float h1r = rheight * h2;
|
||||
const int h1 = static_cast<int>(h1r);
|
||||
const int h1p = (h1 < inpHeight - 1) ? 1 : 0;
|
||||
const float h1lambda = h1r - h1;
|
||||
const float h0lambda = 1.f - h1lambda;
|
||||
for (int w2 = 0; w2 < outWidth; ++w2)
|
||||
{
|
||||
const float w1r = rwidth * w2;
|
||||
const int w1 = static_cast<int>(w1r);
|
||||
const int w1p = (w1 < inpWidth - 1) ? 1 : 0;
|
||||
const float w1lambda = w1r - w1;
|
||||
const float w0lambda = 1.f - w1lambda;
|
||||
const float* pos1 = inpData + h1 * inpWidth + w1;
|
||||
float* pos2 = outData + h2 * outWidth + w2;
|
||||
for (int c = 0; c < batchSize * numChannels; ++c)
|
||||
{
|
||||
pos2[0] =
|
||||
h0lambda * (w0lambda * pos1[0] + w1lambda * pos1[w1p]) +
|
||||
h1lambda * (w0lambda * pos1[h1p * inpWidth] + w1lambda * pos1[h1p * inpWidth + w1p]);
|
||||
pos1 += inpWidth * inpHeight;
|
||||
pos2 += outWidth * outHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void forward(cv::InputArrayOfArrays, cv::OutputArrayOfArrays, cv::OutputArrayOfArrays) {}
|
||||
|
||||
private:
|
||||
int outWidth, outHeight;
|
||||
};
|
||||
//! [InterpLayer]
|
||||
|
||||
//! [ResizeBilinearLayer]
|
||||
class ResizeBilinearLayer : public cv::dnn::Layer
|
||||
{
|
||||
public:
|
||||
ResizeBilinearLayer(const cv::dnn::LayerParams ¶ms) : Layer(params)
|
||||
{
|
||||
CV_Assert(!params.get<bool>("align_corners", false));
|
||||
CV_Assert(blobs.size() == 1, blobs[0].type() == CV_32SC1);
|
||||
outHeight = blobs[0].at<int>(0, 0);
|
||||
outWidth = blobs[0].at<int>(0, 1);
|
||||
}
|
||||
|
||||
static cv::Ptr<cv::dnn::Layer> create(cv::dnn::LayerParams& params)
|
||||
{
|
||||
return cv::Ptr<cv::dnn::Layer>(new ResizeBilinearLayer(params));
|
||||
}
|
||||
|
||||
virtual bool getMemoryShapes(const std::vector<std::vector<int> > &inputs,
|
||||
const int requiredOutputs,
|
||||
std::vector<std::vector<int> > &outputs,
|
||||
std::vector<std::vector<int> > &internals) const
|
||||
{
|
||||
CV_UNUSED(requiredOutputs); CV_UNUSED(internals);
|
||||
std::vector<int> outShape(4);
|
||||
outShape[0] = inputs[0][0]; // batch size
|
||||
outShape[1] = inputs[0][1]; // number of channels
|
||||
outShape[2] = outHeight;
|
||||
outShape[3] = outWidth;
|
||||
outputs.assign(1, outShape);
|
||||
return false;
|
||||
}
|
||||
|
||||
// This implementation is based on a reference implementation from
|
||||
// https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/kernels/internal/reference/reference_ops.h
|
||||
virtual void forward(std::vector<cv::Mat*> &inputs, std::vector<cv::Mat> &outputs, std::vector<cv::Mat> &internals)
|
||||
{
|
||||
CV_UNUSED(internals);
|
||||
cv::Mat& inp = *inputs[0];
|
||||
cv::Mat& out = outputs[0];
|
||||
const float* inpData = (float*)inp.data;
|
||||
float* outData = (float*)out.data;
|
||||
|
||||
const int batchSize = inp.size[0];
|
||||
const int numChannels = inp.size[1];
|
||||
const int inpHeight = inp.size[2];
|
||||
const int inpWidth = inp.size[3];
|
||||
|
||||
float heightScale = static_cast<float>(inpHeight) / outHeight;
|
||||
float widthScale = static_cast<float>(inpWidth) / outWidth;
|
||||
for (int b = 0; b < batchSize; ++b)
|
||||
{
|
||||
for (int y = 0; y < outHeight; ++y)
|
||||
{
|
||||
float input_y = y * heightScale;
|
||||
int y0 = static_cast<int>(std::floor(input_y));
|
||||
int y1 = std::min(y0 + 1, inpHeight - 1);
|
||||
for (int x = 0; x < outWidth; ++x)
|
||||
{
|
||||
float input_x = x * widthScale;
|
||||
int x0 = static_cast<int>(std::floor(input_x));
|
||||
int x1 = std::min(x0 + 1, inpWidth - 1);
|
||||
for (int c = 0; c < numChannels; ++c)
|
||||
{
|
||||
float interpolation =
|
||||
inpData[offset(inp.size, c, x0, y0, b)] * (1 - (input_y - y0)) * (1 - (input_x - x0)) +
|
||||
inpData[offset(inp.size, c, x0, y1, b)] * (input_y - y0) * (1 - (input_x - x0)) +
|
||||
inpData[offset(inp.size, c, x1, y0, b)] * (1 - (input_y - y0)) * (input_x - x0) +
|
||||
inpData[offset(inp.size, c, x1, y1, b)] * (input_y - y0) * (input_x - x0);
|
||||
outData[offset(out.size, c, x, y, b)] = interpolation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void forward(cv::InputArrayOfArrays, cv::OutputArrayOfArrays, cv::OutputArrayOfArrays) {}
|
||||
|
||||
private:
|
||||
static inline int offset(const cv::MatSize& size, int c, int x, int y, int b)
|
||||
{
|
||||
return x + size[3] * (y + size[2] * (c + size[1] * b));
|
||||
}
|
||||
|
||||
int outWidth, outHeight;
|
||||
};
|
||||
//! [ResizeBilinearLayer]
|
||||
|
||||
//! [Register a custom layer]
|
||||
#include <opencv2/dnn/layer.details.hpp> // CV_DNN_REGISTER_LAYER_CLASS macro
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
CV_DNN_REGISTER_LAYER_CLASS(MyType, MyLayer);
|
||||
// ...
|
||||
//! [Register a custom layer]
|
||||
CV_UNUSED(argc); CV_UNUSED(argv);
|
||||
//! [Register InterpLayer]
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Interp, InterpLayer);
|
||||
cv::dnn::Net caffeNet = cv::dnn::readNet("/path/to/config.prototxt", "/path/to/weights.caffemodel");
|
||||
//! [Register InterpLayer]
|
||||
|
||||
//! [Register ResizeBilinearLayer]
|
||||
CV_DNN_REGISTER_LAYER_CLASS(ResizeBilinear, ResizeBilinearLayer);
|
||||
cv::dnn::Net tfNet = cv::dnn::readNet("/path/to/graph.pb");
|
||||
//! [Register ResizeBilinearLayer]
|
||||
}
|
||||
|
||||
cv::Ptr<cv::dnn::Layer> MyLayer::create(cv::dnn::LayerParams& params)
|
||||
{
|
||||
return cv::Ptr<cv::dnn::Layer>(new MyLayer(params));
|
||||
}
|
||||
MyLayer::MyLayer(const cv::dnn::LayerParams&) {}
|
||||
bool MyLayer::getMemoryShapes(const std::vector<std::vector<int> >&, const int,
|
||||
std::vector<std::vector<int> >&,
|
||||
std::vector<std::vector<int> >&) const { return false; }
|
||||
void MyLayer::forward(std::vector<cv::Mat*>&, std::vector<cv::Mat>&, std::vector<cv::Mat>&) {}
|
||||
void MyLayer::finalize(const std::vector<cv::Mat*>&, std::vector<cv::Mat>&) {}
|
||||
void MyLayer::forward(cv::InputArrayOfArrays, cv::OutputArrayOfArrays, cv::OutputArrayOfArrays) {}
|
@ -214,7 +214,7 @@ void postprocess(Mat& frame, const std::vector<Mat>& outs, Net& net)
|
||||
}
|
||||
}
|
||||
std::vector<int> indices;
|
||||
NMSBoxes(boxes, confidences, confThreshold, 0.4, indices);
|
||||
NMSBoxes(boxes, confidences, confThreshold, 0.4f, indices);
|
||||
for (size_t i = 0; i < indices.size(); ++i)
|
||||
{
|
||||
int idx = indices[i];
|
||||
|
Loading…
Reference in New Issue
Block a user