From 5a6b23e8f3ccf9391558057f159e1b8937347c39 Mon Sep 17 00:00:00 2001 From: Lubov Batanina Date: Tue, 30 Jul 2019 17:23:47 +0300 Subject: [PATCH] Support for several min and max sizes in PriorBox layer (Merge pull request #15076) * Support for several min and max sizes in PriorBox layer * Fix minSize * Check size * Modify initInfEngine * Fix tests * Fix IE support * Add priorbox test * Remove inputs --- modules/dnn/misc/caffe/opencv-caffe.pb.cc | 213 +++++++++++---------- modules/dnn/misc/caffe/opencv-caffe.pb.h | 176 +++++++++-------- modules/dnn/src/caffe/opencv-caffe.proto | 4 +- modules/dnn/src/layers/prior_box_layer.cpp | 62 +++--- modules/dnn/test/test_layers.cpp | 16 ++ 5 files changed, 259 insertions(+), 212 deletions(-) diff --git a/modules/dnn/misc/caffe/opencv-caffe.pb.cc b/modules/dnn/misc/caffe/opencv-caffe.pb.cc index af84d72279..c46752dc73 100644 --- a/modules/dnn/misc/caffe/opencv-caffe.pb.cc +++ b/modules/dnn/misc/caffe/opencv-caffe.pb.cc @@ -2092,19 +2092,19 @@ const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUT GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::opencv_caffe::PriorBoxParameter, offset_w_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::opencv_caffe::PriorBoxParameter, width_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::opencv_caffe::PriorBoxParameter, height_), + ~0u, + ~0u, + ~0u, + 6, + 7, + ~0u, 0, 1, - ~0u, - 8, - 9, - ~0u, 2, 3, 4, 5, - 6, - 7, - 10, + 8, ~0u, ~0u, ~0u, @@ -3528,8 +3528,8 @@ void AddDescriptorsImpl() { "al\030\001 \001(\010:\004true\0223\n\014scale_filler\030\002 \001(\0132\035.o" "pencv_caffe.FillerParameter\022\034\n\016channel_s" "hared\030\003 \001(\010:\004true\022\022\n\003eps\030\004 \001(\002:\0051e-10\"\346\002" - "\n\021PriorBoxParameter\022\020\n\010min_size\030\001 \001(\002\022\020\n" - "\010max_size\030\002 \001(\002\022\024\n\014aspect_ratio\030\003 \003(\002\022\022\n" + "\n\021PriorBoxParameter\022\020\n\010min_size\030\001 \003(\002\022\020\n" + "\010max_size\030\002 \003(\002\022\024\n\014aspect_ratio\030\003 \003(\002\022\022\n" "\004flip\030\004 \001(\010:\004true\022\022\n\004clip\030\005 \001(\010:\004true\022\020\n" "\010variance\030\006 \003(\002\022\020\n\010img_size\030\007 \001(\r\022\r\n\005img" "_h\030\010 \001(\r\022\r\n\005img_w\030\t \001(\r\022\014\n\004step\030\n \001(\002\022\016\n" @@ -6600,6 +6600,8 @@ PriorBoxParameter::PriorBoxParameter(const PriorBoxParameter& from) _internal_metadata_(NULL), _has_bits_(from._has_bits_), _cached_size_(0), + min_size_(from.min_size_), + max_size_(from.max_size_), aspect_ratio_(from.aspect_ratio_), variance_(from.variance_), offset_h_(from.offset_h_), @@ -6607,17 +6609,17 @@ PriorBoxParameter::PriorBoxParameter(const PriorBoxParameter& from) width_(from.width_), height_(from.height_) { _internal_metadata_.MergeFrom(from._internal_metadata_); - ::memcpy(&min_size_, &from.min_size_, + ::memcpy(&img_size_, &from.img_size_, static_cast(reinterpret_cast(&offset_) - - reinterpret_cast(&min_size_)) + sizeof(offset_)); + reinterpret_cast(&img_size_)) + sizeof(offset_)); // @@protoc_insertion_point(copy_constructor:opencv_caffe.PriorBoxParameter) } void PriorBoxParameter::SharedCtor() { _cached_size_ = 0; - ::memset(&min_size_, 0, static_cast( + ::memset(&img_size_, 0, static_cast( reinterpret_cast(&step_w_) - - reinterpret_cast(&min_size_)) + sizeof(step_w_)); + reinterpret_cast(&img_size_)) + sizeof(step_w_)); flip_ = true; clip_ = true; offset_ = 0.5f; @@ -6660,6 +6662,8 @@ void PriorBoxParameter::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; + min_size_.Clear(); + max_size_.Clear(); aspect_ratio_.Clear(); variance_.Clear(); offset_h_.Clear(); @@ -6668,15 +6672,13 @@ void PriorBoxParameter::Clear() { height_.Clear(); cached_has_bits = _has_bits_[0]; if (cached_has_bits & 255u) { - ::memset(&min_size_, 0, static_cast( + ::memset(&img_size_, 0, static_cast( reinterpret_cast(&step_w_) - - reinterpret_cast(&min_size_)) + sizeof(step_w_)); - } - if (cached_has_bits & 1792u) { + reinterpret_cast(&img_size_)) + sizeof(step_w_)); flip_ = true; clip_ = true; - offset_ = 0.5f; } + offset_ = 0.5f; _has_bits_.Clear(); _internal_metadata_.Clear(); } @@ -6691,28 +6693,38 @@ bool PriorBoxParameter::MergePartialFromCodedStream( tag = p.first; if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional float min_size = 1; + // repeated float min_size = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(13u /* 13 & 0xFF */)) { - set_has_min_size(); - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive< float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( - input, &min_size_))); + 1, 13u, input, this->mutable_min_size()))); + } else if ( + static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, this->mutable_min_size()))); } else { goto handle_unusual; } break; } - // optional float max_size = 2; + // repeated float max_size = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(21u /* 21 & 0xFF */)) { - set_has_max_size(); - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive< float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( - input, &max_size_))); + 1, 21u, input, this->mutable_max_size()))); + } else if ( + static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, this->mutable_max_size()))); } else { goto handle_unusual; } @@ -6985,15 +6997,16 @@ void PriorBoxParameter::SerializeWithCachedSizes( ::google::protobuf::uint32 cached_has_bits = 0; (void) cached_has_bits; - cached_has_bits = _has_bits_[0]; - // optional float min_size = 1; - if (cached_has_bits & 0x00000001u) { - ::google::protobuf::internal::WireFormatLite::WriteFloat(1, this->min_size(), output); + // repeated float min_size = 1; + for (int i = 0, n = this->min_size_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteFloat( + 1, this->min_size(i), output); } - // optional float max_size = 2; - if (cached_has_bits & 0x00000002u) { - ::google::protobuf::internal::WireFormatLite::WriteFloat(2, this->max_size(), output); + // repeated float max_size = 2; + for (int i = 0, n = this->max_size_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteFloat( + 2, this->max_size(i), output); } // repeated float aspect_ratio = 3; @@ -7002,13 +7015,14 @@ void PriorBoxParameter::SerializeWithCachedSizes( 3, this->aspect_ratio(i), output); } + cached_has_bits = _has_bits_[0]; // optional bool flip = 4 [default = true]; - if (cached_has_bits & 0x00000100u) { + if (cached_has_bits & 0x00000040u) { ::google::protobuf::internal::WireFormatLite::WriteBool(4, this->flip(), output); } // optional bool clip = 5 [default = true]; - if (cached_has_bits & 0x00000200u) { + if (cached_has_bits & 0x00000080u) { ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->clip(), output); } @@ -7019,37 +7033,37 @@ void PriorBoxParameter::SerializeWithCachedSizes( } // optional uint32 img_size = 7; - if (cached_has_bits & 0x00000004u) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormatLite::WriteUInt32(7, this->img_size(), output); } // optional uint32 img_h = 8; - if (cached_has_bits & 0x00000008u) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteUInt32(8, this->img_h(), output); } // optional uint32 img_w = 9; - if (cached_has_bits & 0x00000010u) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormatLite::WriteUInt32(9, this->img_w(), output); } // optional float step = 10; - if (cached_has_bits & 0x00000020u) { + if (cached_has_bits & 0x00000008u) { ::google::protobuf::internal::WireFormatLite::WriteFloat(10, this->step(), output); } // optional float step_h = 11; - if (cached_has_bits & 0x00000040u) { + if (cached_has_bits & 0x00000010u) { ::google::protobuf::internal::WireFormatLite::WriteFloat(11, this->step_h(), output); } // optional float step_w = 12; - if (cached_has_bits & 0x00000080u) { + if (cached_has_bits & 0x00000020u) { ::google::protobuf::internal::WireFormatLite::WriteFloat(12, this->step_w(), output); } // optional float offset = 13 [default = 0.5]; - if (cached_has_bits & 0x00000400u) { + if (cached_has_bits & 0x00000100u) { ::google::protobuf::internal::WireFormatLite::WriteFloat(13, this->offset(), output); } @@ -7091,28 +7105,26 @@ void PriorBoxParameter::SerializeWithCachedSizes( ::google::protobuf::uint32 cached_has_bits = 0; (void) cached_has_bits; - cached_has_bits = _has_bits_[0]; - // optional float min_size = 1; - if (cached_has_bits & 0x00000001u) { - target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(1, this->min_size(), target); - } + // repeated float min_size = 1; + target = ::google::protobuf::internal::WireFormatLite:: + WriteFloatToArray(1, this->min_size_, target); - // optional float max_size = 2; - if (cached_has_bits & 0x00000002u) { - target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(2, this->max_size(), target); - } + // repeated float max_size = 2; + target = ::google::protobuf::internal::WireFormatLite:: + WriteFloatToArray(2, this->max_size_, target); // repeated float aspect_ratio = 3; target = ::google::protobuf::internal::WireFormatLite:: WriteFloatToArray(3, this->aspect_ratio_, target); + cached_has_bits = _has_bits_[0]; // optional bool flip = 4 [default = true]; - if (cached_has_bits & 0x00000100u) { + if (cached_has_bits & 0x00000040u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(4, this->flip(), target); } // optional bool clip = 5 [default = true]; - if (cached_has_bits & 0x00000200u) { + if (cached_has_bits & 0x00000080u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->clip(), target); } @@ -7121,37 +7133,37 @@ void PriorBoxParameter::SerializeWithCachedSizes( WriteFloatToArray(6, this->variance_, target); // optional uint32 img_size = 7; - if (cached_has_bits & 0x00000004u) { + if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(7, this->img_size(), target); } // optional uint32 img_h = 8; - if (cached_has_bits & 0x00000008u) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(8, this->img_h(), target); } // optional uint32 img_w = 9; - if (cached_has_bits & 0x00000010u) { + if (cached_has_bits & 0x00000004u) { target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(9, this->img_w(), target); } // optional float step = 10; - if (cached_has_bits & 0x00000020u) { + if (cached_has_bits & 0x00000008u) { target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(10, this->step(), target); } // optional float step_h = 11; - if (cached_has_bits & 0x00000040u) { + if (cached_has_bits & 0x00000010u) { target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(11, this->step_h(), target); } // optional float step_w = 12; - if (cached_has_bits & 0x00000080u) { + if (cached_has_bits & 0x00000020u) { target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(12, this->step_w(), target); } // optional float offset = 13 [default = 0.5]; - if (cached_has_bits & 0x00000400u) { + if (cached_has_bits & 0x00000100u) { target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(13, this->offset(), target); } @@ -7188,6 +7200,24 @@ size_t PriorBoxParameter::ByteSizeLong() const { ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( _internal_metadata_.unknown_fields()); } + // repeated float min_size = 1; + { + unsigned int count = static_cast(this->min_size_size()); + size_t data_size = 4UL * count; + total_size += 1 * + ::google::protobuf::internal::FromIntSize(this->min_size_size()); + total_size += data_size; + } + + // repeated float max_size = 2; + { + unsigned int count = static_cast(this->max_size_size()); + size_t data_size = 4UL * count; + total_size += 1 * + ::google::protobuf::internal::FromIntSize(this->max_size_size()); + total_size += data_size; + } + // repeated float aspect_ratio = 3; { unsigned int count = static_cast(this->aspect_ratio_size()); @@ -7243,16 +7273,6 @@ size_t PriorBoxParameter::ByteSizeLong() const { } if (_has_bits_[0 / 32] & 255u) { - // optional float min_size = 1; - if (has_min_size()) { - total_size += 1 + 4; - } - - // optional float max_size = 2; - if (has_max_size()) { - total_size += 1 + 4; - } - // optional uint32 img_size = 7; if (has_img_size()) { total_size += 1 + @@ -7289,8 +7309,6 @@ size_t PriorBoxParameter::ByteSizeLong() const { total_size += 1 + 4; } - } - if (_has_bits_[8 / 32] & 1792u) { // optional bool flip = 4 [default = true]; if (has_flip()) { total_size += 1 + 1; @@ -7301,12 +7319,12 @@ size_t PriorBoxParameter::ByteSizeLong() const { total_size += 1 + 1; } - // optional float offset = 13 [default = 0.5]; - if (has_offset()) { - total_size += 1 + 4; - } - } + // optional float offset = 13 [default = 0.5]; + if (has_offset()) { + total_size += 1 + 4; + } + int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = cached_size; @@ -7336,6 +7354,8 @@ void PriorBoxParameter::MergeFrom(const PriorBoxParameter& from) { ::google::protobuf::uint32 cached_has_bits = 0; (void) cached_has_bits; + min_size_.MergeFrom(from.min_size_); + max_size_.MergeFrom(from.max_size_); aspect_ratio_.MergeFrom(from.aspect_ratio_); variance_.MergeFrom(from.variance_); offset_h_.MergeFrom(from.offset_h_); @@ -7345,42 +7365,33 @@ void PriorBoxParameter::MergeFrom(const PriorBoxParameter& from) { cached_has_bits = from._has_bits_[0]; if (cached_has_bits & 255u) { if (cached_has_bits & 0x00000001u) { - min_size_ = from.min_size_; - } - if (cached_has_bits & 0x00000002u) { - max_size_ = from.max_size_; - } - if (cached_has_bits & 0x00000004u) { img_size_ = from.img_size_; } - if (cached_has_bits & 0x00000008u) { + if (cached_has_bits & 0x00000002u) { img_h_ = from.img_h_; } - if (cached_has_bits & 0x00000010u) { + if (cached_has_bits & 0x00000004u) { img_w_ = from.img_w_; } - if (cached_has_bits & 0x00000020u) { + if (cached_has_bits & 0x00000008u) { step_ = from.step_; } - if (cached_has_bits & 0x00000040u) { + if (cached_has_bits & 0x00000010u) { step_h_ = from.step_h_; } - if (cached_has_bits & 0x00000080u) { + if (cached_has_bits & 0x00000020u) { step_w_ = from.step_w_; } + if (cached_has_bits & 0x00000040u) { + flip_ = from.flip_; + } + if (cached_has_bits & 0x00000080u) { + clip_ = from.clip_; + } _has_bits_[0] |= cached_has_bits; } - if (cached_has_bits & 1792u) { - if (cached_has_bits & 0x00000100u) { - flip_ = from.flip_; - } - if (cached_has_bits & 0x00000200u) { - clip_ = from.clip_; - } - if (cached_has_bits & 0x00000400u) { - offset_ = from.offset_; - } - _has_bits_[0] |= cached_has_bits; + if (cached_has_bits & 0x00000100u) { + set_offset(from.offset()); } } @@ -7408,14 +7419,14 @@ void PriorBoxParameter::Swap(PriorBoxParameter* other) { } void PriorBoxParameter::InternalSwap(PriorBoxParameter* other) { using std::swap; + min_size_.InternalSwap(&other->min_size_); + max_size_.InternalSwap(&other->max_size_); aspect_ratio_.InternalSwap(&other->aspect_ratio_); variance_.InternalSwap(&other->variance_); offset_h_.InternalSwap(&other->offset_h_); offset_w_.InternalSwap(&other->offset_w_); width_.InternalSwap(&other->width_); height_.InternalSwap(&other->height_); - swap(min_size_, other->min_size_); - swap(max_size_, other->max_size_); swap(img_size_, other->img_size_); swap(img_h_, other->img_h_); swap(img_w_, other->img_w_); diff --git a/modules/dnn/misc/caffe/opencv-caffe.pb.h b/modules/dnn/misc/caffe/opencv-caffe.pb.h index 1920cf8e89..923ca7fb1f 100644 --- a/modules/dnn/misc/caffe/opencv-caffe.pb.h +++ b/modules/dnn/misc/caffe/opencv-caffe.pb.h @@ -1886,6 +1886,30 @@ class PriorBoxParameter : public ::google::protobuf::Message /* @@protoc_inserti // accessors ------------------------------------------------------- + // repeated float min_size = 1; + int min_size_size() const; + void clear_min_size(); + static const int kMinSizeFieldNumber = 1; + float min_size(int index) const; + void set_min_size(int index, float value); + void add_min_size(float value); + const ::google::protobuf::RepeatedField< float >& + min_size() const; + ::google::protobuf::RepeatedField< float >* + mutable_min_size(); + + // repeated float max_size = 2; + int max_size_size() const; + void clear_max_size(); + static const int kMaxSizeFieldNumber = 2; + float max_size(int index) const; + void set_max_size(int index, float value); + void add_max_size(float value); + const ::google::protobuf::RepeatedField< float >& + max_size() const; + ::google::protobuf::RepeatedField< float >* + mutable_max_size(); + // repeated float aspect_ratio = 3; int aspect_ratio_size() const; void clear_aspect_ratio(); @@ -1958,20 +1982,6 @@ class PriorBoxParameter : public ::google::protobuf::Message /* @@protoc_inserti ::google::protobuf::RepeatedField< float >* mutable_height(); - // optional float min_size = 1; - bool has_min_size() const; - void clear_min_size(); - static const int kMinSizeFieldNumber = 1; - float min_size() const; - void set_min_size(float value); - - // optional float max_size = 2; - bool has_max_size() const; - void clear_max_size(); - static const int kMaxSizeFieldNumber = 2; - float max_size() const; - void set_max_size(float value); - // optional uint32 img_size = 7; bool has_img_size() const; void clear_img_size(); @@ -2037,10 +2047,6 @@ class PriorBoxParameter : public ::google::protobuf::Message /* @@protoc_inserti // @@protoc_insertion_point(class_scope:opencv_caffe.PriorBoxParameter) private: - void set_has_min_size(); - void clear_has_min_size(); - void set_has_max_size(); - void clear_has_max_size(); void set_has_flip(); void clear_has_flip(); void set_has_clip(); @@ -2063,14 +2069,14 @@ class PriorBoxParameter : public ::google::protobuf::Message /* @@protoc_inserti ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; ::google::protobuf::internal::HasBits<1> _has_bits_; mutable int _cached_size_; + ::google::protobuf::RepeatedField< float > min_size_; + ::google::protobuf::RepeatedField< float > max_size_; ::google::protobuf::RepeatedField< float > aspect_ratio_; ::google::protobuf::RepeatedField< float > variance_; ::google::protobuf::RepeatedField< float > offset_h_; ::google::protobuf::RepeatedField< float > offset_w_; ::google::protobuf::RepeatedField< float > width_; ::google::protobuf::RepeatedField< float > height_; - float min_size_; - float max_size_; ::google::protobuf::uint32 img_size_; ::google::protobuf::uint32 img_h_; ::google::protobuf::uint32 img_w_; @@ -15271,52 +15277,64 @@ inline void NormalizeBBoxParameter::set_eps(float value) { // PriorBoxParameter -// optional float min_size = 1; -inline bool PriorBoxParameter::has_min_size() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void PriorBoxParameter::set_has_min_size() { - _has_bits_[0] |= 0x00000001u; -} -inline void PriorBoxParameter::clear_has_min_size() { - _has_bits_[0] &= ~0x00000001u; +// repeated float min_size = 1; +inline int PriorBoxParameter::min_size_size() const { + return min_size_.size(); } inline void PriorBoxParameter::clear_min_size() { - min_size_ = 0; - clear_has_min_size(); + min_size_.Clear(); } -inline float PriorBoxParameter::min_size() const { +inline float PriorBoxParameter::min_size(int index) const { // @@protoc_insertion_point(field_get:opencv_caffe.PriorBoxParameter.min_size) - return min_size_; + return min_size_.Get(index); } -inline void PriorBoxParameter::set_min_size(float value) { - set_has_min_size(); - min_size_ = value; +inline void PriorBoxParameter::set_min_size(int index, float value) { + min_size_.Set(index, value); // @@protoc_insertion_point(field_set:opencv_caffe.PriorBoxParameter.min_size) } +inline void PriorBoxParameter::add_min_size(float value) { + min_size_.Add(value); + // @@protoc_insertion_point(field_add:opencv_caffe.PriorBoxParameter.min_size) +} +inline const ::google::protobuf::RepeatedField< float >& +PriorBoxParameter::min_size() const { + // @@protoc_insertion_point(field_list:opencv_caffe.PriorBoxParameter.min_size) + return min_size_; +} +inline ::google::protobuf::RepeatedField< float >* +PriorBoxParameter::mutable_min_size() { + // @@protoc_insertion_point(field_mutable_list:opencv_caffe.PriorBoxParameter.min_size) + return &min_size_; +} -// optional float max_size = 2; -inline bool PriorBoxParameter::has_max_size() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void PriorBoxParameter::set_has_max_size() { - _has_bits_[0] |= 0x00000002u; -} -inline void PriorBoxParameter::clear_has_max_size() { - _has_bits_[0] &= ~0x00000002u; +// repeated float max_size = 2; +inline int PriorBoxParameter::max_size_size() const { + return max_size_.size(); } inline void PriorBoxParameter::clear_max_size() { - max_size_ = 0; - clear_has_max_size(); + max_size_.Clear(); } -inline float PriorBoxParameter::max_size() const { +inline float PriorBoxParameter::max_size(int index) const { // @@protoc_insertion_point(field_get:opencv_caffe.PriorBoxParameter.max_size) + return max_size_.Get(index); +} +inline void PriorBoxParameter::set_max_size(int index, float value) { + max_size_.Set(index, value); + // @@protoc_insertion_point(field_set:opencv_caffe.PriorBoxParameter.max_size) +} +inline void PriorBoxParameter::add_max_size(float value) { + max_size_.Add(value); + // @@protoc_insertion_point(field_add:opencv_caffe.PriorBoxParameter.max_size) +} +inline const ::google::protobuf::RepeatedField< float >& +PriorBoxParameter::max_size() const { + // @@protoc_insertion_point(field_list:opencv_caffe.PriorBoxParameter.max_size) return max_size_; } -inline void PriorBoxParameter::set_max_size(float value) { - set_has_max_size(); - max_size_ = value; - // @@protoc_insertion_point(field_set:opencv_caffe.PriorBoxParameter.max_size) +inline ::google::protobuf::RepeatedField< float >* +PriorBoxParameter::mutable_max_size() { + // @@protoc_insertion_point(field_mutable_list:opencv_caffe.PriorBoxParameter.max_size) + return &max_size_; } // repeated float aspect_ratio = 3; @@ -15351,13 +15369,13 @@ PriorBoxParameter::mutable_aspect_ratio() { // optional bool flip = 4 [default = true]; inline bool PriorBoxParameter::has_flip() const { - return (_has_bits_[0] & 0x00000100u) != 0; + return (_has_bits_[0] & 0x00000040u) != 0; } inline void PriorBoxParameter::set_has_flip() { - _has_bits_[0] |= 0x00000100u; + _has_bits_[0] |= 0x00000040u; } inline void PriorBoxParameter::clear_has_flip() { - _has_bits_[0] &= ~0x00000100u; + _has_bits_[0] &= ~0x00000040u; } inline void PriorBoxParameter::clear_flip() { flip_ = true; @@ -15375,13 +15393,13 @@ inline void PriorBoxParameter::set_flip(bool value) { // optional bool clip = 5 [default = true]; inline bool PriorBoxParameter::has_clip() const { - return (_has_bits_[0] & 0x00000200u) != 0; + return (_has_bits_[0] & 0x00000080u) != 0; } inline void PriorBoxParameter::set_has_clip() { - _has_bits_[0] |= 0x00000200u; + _has_bits_[0] |= 0x00000080u; } inline void PriorBoxParameter::clear_has_clip() { - _has_bits_[0] &= ~0x00000200u; + _has_bits_[0] &= ~0x00000080u; } inline void PriorBoxParameter::clear_clip() { clip_ = true; @@ -15429,13 +15447,13 @@ PriorBoxParameter::mutable_variance() { // optional uint32 img_size = 7; inline bool PriorBoxParameter::has_img_size() const { - return (_has_bits_[0] & 0x00000004u) != 0; + return (_has_bits_[0] & 0x00000001u) != 0; } inline void PriorBoxParameter::set_has_img_size() { - _has_bits_[0] |= 0x00000004u; + _has_bits_[0] |= 0x00000001u; } inline void PriorBoxParameter::clear_has_img_size() { - _has_bits_[0] &= ~0x00000004u; + _has_bits_[0] &= ~0x00000001u; } inline void PriorBoxParameter::clear_img_size() { img_size_ = 0u; @@ -15453,13 +15471,13 @@ inline void PriorBoxParameter::set_img_size(::google::protobuf::uint32 value) { // optional uint32 img_h = 8; inline bool PriorBoxParameter::has_img_h() const { - return (_has_bits_[0] & 0x00000008u) != 0; + return (_has_bits_[0] & 0x00000002u) != 0; } inline void PriorBoxParameter::set_has_img_h() { - _has_bits_[0] |= 0x00000008u; + _has_bits_[0] |= 0x00000002u; } inline void PriorBoxParameter::clear_has_img_h() { - _has_bits_[0] &= ~0x00000008u; + _has_bits_[0] &= ~0x00000002u; } inline void PriorBoxParameter::clear_img_h() { img_h_ = 0u; @@ -15477,13 +15495,13 @@ inline void PriorBoxParameter::set_img_h(::google::protobuf::uint32 value) { // optional uint32 img_w = 9; inline bool PriorBoxParameter::has_img_w() const { - return (_has_bits_[0] & 0x00000010u) != 0; + return (_has_bits_[0] & 0x00000004u) != 0; } inline void PriorBoxParameter::set_has_img_w() { - _has_bits_[0] |= 0x00000010u; + _has_bits_[0] |= 0x00000004u; } inline void PriorBoxParameter::clear_has_img_w() { - _has_bits_[0] &= ~0x00000010u; + _has_bits_[0] &= ~0x00000004u; } inline void PriorBoxParameter::clear_img_w() { img_w_ = 0u; @@ -15501,13 +15519,13 @@ inline void PriorBoxParameter::set_img_w(::google::protobuf::uint32 value) { // optional float step = 10; inline bool PriorBoxParameter::has_step() const { - return (_has_bits_[0] & 0x00000020u) != 0; + return (_has_bits_[0] & 0x00000008u) != 0; } inline void PriorBoxParameter::set_has_step() { - _has_bits_[0] |= 0x00000020u; + _has_bits_[0] |= 0x00000008u; } inline void PriorBoxParameter::clear_has_step() { - _has_bits_[0] &= ~0x00000020u; + _has_bits_[0] &= ~0x00000008u; } inline void PriorBoxParameter::clear_step() { step_ = 0; @@ -15525,13 +15543,13 @@ inline void PriorBoxParameter::set_step(float value) { // optional float step_h = 11; inline bool PriorBoxParameter::has_step_h() const { - return (_has_bits_[0] & 0x00000040u) != 0; + return (_has_bits_[0] & 0x00000010u) != 0; } inline void PriorBoxParameter::set_has_step_h() { - _has_bits_[0] |= 0x00000040u; + _has_bits_[0] |= 0x00000010u; } inline void PriorBoxParameter::clear_has_step_h() { - _has_bits_[0] &= ~0x00000040u; + _has_bits_[0] &= ~0x00000010u; } inline void PriorBoxParameter::clear_step_h() { step_h_ = 0; @@ -15549,13 +15567,13 @@ inline void PriorBoxParameter::set_step_h(float value) { // optional float step_w = 12; inline bool PriorBoxParameter::has_step_w() const { - return (_has_bits_[0] & 0x00000080u) != 0; + return (_has_bits_[0] & 0x00000020u) != 0; } inline void PriorBoxParameter::set_has_step_w() { - _has_bits_[0] |= 0x00000080u; + _has_bits_[0] |= 0x00000020u; } inline void PriorBoxParameter::clear_has_step_w() { - _has_bits_[0] &= ~0x00000080u; + _has_bits_[0] &= ~0x00000020u; } inline void PriorBoxParameter::clear_step_w() { step_w_ = 0; @@ -15573,13 +15591,13 @@ inline void PriorBoxParameter::set_step_w(float value) { // optional float offset = 13 [default = 0.5]; inline bool PriorBoxParameter::has_offset() const { - return (_has_bits_[0] & 0x00000400u) != 0; + return (_has_bits_[0] & 0x00000100u) != 0; } inline void PriorBoxParameter::set_has_offset() { - _has_bits_[0] |= 0x00000400u; + _has_bits_[0] |= 0x00000100u; } inline void PriorBoxParameter::clear_has_offset() { - _has_bits_[0] &= ~0x00000400u; + _has_bits_[0] &= ~0x00000100u; } inline void PriorBoxParameter::clear_offset() { offset_ = 0.5f; diff --git a/modules/dnn/src/caffe/opencv-caffe.proto b/modules/dnn/src/caffe/opencv-caffe.proto index 380b51f281..8ab35bac99 100644 --- a/modules/dnn/src/caffe/opencv-caffe.proto +++ b/modules/dnn/src/caffe/opencv-caffe.proto @@ -116,9 +116,9 @@ message PriorBoxParameter { CENTER_SIZE = 2; } // Minimum box size (in pixels). Required! - optional float min_size = 1; + repeated float min_size = 1; // Maximum box size (in pixels). Required! - optional float max_size = 2; + repeated float max_size = 2; // Various of aspect ratios. Duplicate ratios will be ignored. // If none is provided, we use default ratio 1. repeated float aspect_ratio = 3; diff --git a/modules/dnn/src/layers/prior_box_layer.cpp b/modules/dnn/src/layers/prior_box_layer.cpp index dc949d0fba..4e0a6e018f 100644 --- a/modules/dnn/src/layers/prior_box_layer.cpp +++ b/modules/dnn/src/layers/prior_box_layer.cpp @@ -180,21 +180,20 @@ public: PriorBoxLayerImpl(const LayerParams ¶ms) { setParamsFrom(params); - _minSize = getParameter(params, "min_size", 0, false, 0); _flip = getParameter(params, "flip", 0, false, true); _clip = getParameter(params, "clip", 0, false, true); _bboxesNormalized = getParameter(params, "normalized_bbox", 0, false, true); - _aspectRatios.clear(); - + getParams("min_size", params, &_minSize); getAspectRatios(params); getVariance(params); - _maxSize = -1; if (params.has("max_size")) { - _maxSize = params.get("max_size").get(0); - CV_Assert(_maxSize > _minSize); + getParams("max_size", params, &_maxSize); + CV_Assert(_minSize.size() == _maxSize.size()); + for (int i = 0; i < _maxSize.size(); i++) + CV_Assert(_minSize[i] < _maxSize[i]); } std::vector widths, heights; @@ -213,25 +212,28 @@ public: } else { - CV_Assert(_minSize > 0); - _boxWidths.resize(1 + (_maxSize > 0 ? 1 : 0) + _aspectRatios.size()); - _boxHeights.resize(_boxWidths.size()); - _boxWidths[0] = _boxHeights[0] = _minSize; - - int i = 1; - if (_maxSize > 0) + CV_Assert(!_minSize.empty()); + for (int i = 0; i < _minSize.size(); ++i) { - // second prior: aspect_ratio = 1, size = sqrt(min_size * max_size) - _boxWidths[i] = _boxHeights[i] = sqrt(_minSize * _maxSize); - i += 1; - } + float minSize = _minSize[i]; + CV_Assert(minSize > 0); + _boxWidths.push_back(minSize); + _boxHeights.push_back(minSize); - // rest of priors - for (size_t r = 0; r < _aspectRatios.size(); ++r) - { - float arSqrt = sqrt(_aspectRatios[r]); - _boxWidths[i + r] = _minSize * arSqrt; - _boxHeights[i + r] = _minSize / arSqrt; + if (_maxSize.size() > 0) + { + float size = sqrt(minSize * _maxSize[i]); + _boxWidths.push_back(size); + _boxHeights.push_back(size); + } + + // rest of priors + for (size_t r = 0; r < _aspectRatios.size(); ++r) + { + float arSqrt = sqrt(_aspectRatios[r]); + _boxWidths.push_back(minSize * arSqrt); + _boxHeights.push_back(minSize / arSqrt); + } } } CV_Assert(_boxWidths.size() == _boxHeights.size()); @@ -271,7 +273,8 @@ public: virtual bool supportBackend(int backendId) CV_OVERRIDE { return backendId == DNN_BACKEND_OPENCV || - (backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine()); + (backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine() && + ( _explicitSizes || (_minSize.size() == 1 && _maxSize.size() <= 1))); } bool getMemoryShapes(const std::vector &inputs, @@ -508,10 +511,9 @@ public: InferenceEngine::Builder::PriorBoxLayer ieLayer(name); CV_Assert(!_explicitSizes); - - ieLayer.setMinSize(_minSize); - if (_maxSize > 0) - ieLayer.setMaxSize(_maxSize); + ieLayer.setMinSize(_minSize[0]); + if (!_maxSize.empty()) + ieLayer.setMaxSize(_maxSize[0]); CV_CheckEQ(_offsetsX.size(), (size_t)1, ""); CV_CheckEQ(_offsetsY.size(), (size_t)1, ""); CV_CheckEQ(_offsetsX[0], _offsetsY[0], ""); ieLayer.setOffset(_offsetsX[0]); @@ -558,8 +560,8 @@ public: } private: - float _minSize; - float _maxSize; + std::vector _minSize; + std::vector _maxSize; float _stepX, _stepY; diff --git a/modules/dnn/test/test_layers.cpp b/modules/dnn/test/test_layers.cpp index 02d33b4c36..fabe4d4b89 100644 --- a/modules/dnn/test/test_layers.cpp +++ b/modules/dnn/test/test_layers.cpp @@ -742,6 +742,22 @@ TEST_P(Test_Caffe_layers, Average_pooling_kernel_area) normAssert(out, blobFromImage(ref)); } +TEST_P(Test_Caffe_layers, PriorBox_repeated) +{ + Net net = readNet(_tf("prior_box.prototxt")); + int inp_size[] = {1, 3, 10, 10}; + int shape_size[] = {1, 2, 3, 4}; + Mat inp(4, inp_size, CV_32F); + randu(inp, -1.0f, 1.0f); + Mat shape(4, shape_size, CV_32F); + randu(shape, -1.0f, 1.0f); + net.setInput(inp, "data"); + net.setInput(shape, "shape"); + Mat out = net.forward(); + Mat ref = blobFromNPY(_tf("priorbox_output.npy")); + normAssert(out, ref, ""); +} + // Test PriorBoxLayer in case of no aspect ratios (just squared proposals). TEST_P(Test_Caffe_layers, PriorBox_squares) {