14
14
#include " utils/common.hpp"
15
15
#include " utils/shared_blob_allocator.h"
16
16
17
+ #include " openvino/openvino.hpp"
17
18
18
- /* *
19
- * @brief Get cv::Mat value in the correct format.
20
- */
19
+
20
+ /* *
21
+ * @brief Get cv::Mat value in the correct format.
22
+ */
21
23
template <typename T>
22
24
static const T getMatValue (const cv::Mat& mat, size_t h, size_t w, size_t c) {
23
25
switch (mat.type ()) {
@@ -48,9 +50,11 @@ static UNUSED void matToBlob(const cv::Mat& mat, const InferenceEngine::Blob::Pt
48
50
}
49
51
int batchOffset = batchIndex * width * height * channels;
50
52
51
- cv::Mat resizedMat (mat) ;
53
+ cv::Mat resizedMat;
52
54
if (static_cast <int >(width) != mat.size ().width || static_cast <int >(height) != mat.size ().height ) {
53
55
cv::resize (mat, resizedMat, cv::Size (width, height));
56
+ } else {
57
+ resizedMat = mat;
54
58
}
55
59
56
60
InferenceEngine::LockedMemory<void > blobMapped = InferenceEngine::as<InferenceEngine::MemoryBlob>(blob)->wmap ();
@@ -61,10 +65,9 @@ static UNUSED void matToBlob(const cv::Mat& mat, const InferenceEngine::Blob::Pt
61
65
for (size_t w = 0 ; w < width; w++)
62
66
blobData[batchOffset + c * width * height + h * width + w] =
63
67
getMatValue<float_t >(resizedMat, h, w, c);
64
- }
65
- else {
68
+ } else {
66
69
uint8_t * blobData = blobMapped.as <uint8_t *>();
67
- if (( resizedMat.type () & CV_MAT_DEPTH_MASK ) == CV_32F) {
70
+ if (resizedMat.depth ( ) == CV_32F) {
68
71
throw std::runtime_error (" Conversion of cv::Mat from float_t to uint8_t is forbidden" );
69
72
}
70
73
for (size_t c = 0 ; c < channels; c++)
@@ -75,14 +78,62 @@ static UNUSED void matToBlob(const cv::Mat& mat, const InferenceEngine::Blob::Pt
75
78
}
76
79
}
77
80
81
+ /* *
82
+ * @brief Resize and copy image data from cv::Mat object to a given Tensor object.
83
+ * @param mat - given cv::Mat object with an image data.
84
+ * @param tensor - Tensor object which to be filled by an image data.
85
+ * @param batchIndex - batch index of an image inside of the blob.
86
+ */
87
+ static UNUSED void matToTensor (const cv::Mat& mat, const ov::runtime::Tensor& tensor, int batchIndex = 0 ) {
88
+ ov::Shape tensorShape = tensor.get_shape ();
89
+ ov::Layout layout (" NCHW" );
90
+ const size_t width = tensorShape[ov::layout::width_idx (layout)];
91
+ const size_t height = tensorShape[ov::layout::height_idx (layout)];
92
+ const size_t channels = tensorShape[ov::layout::channels_idx (layout)];
93
+ if (static_cast <size_t >(mat.channels ()) != channels) {
94
+ throw std::runtime_error (" The number of channels for net input and image must match" );
95
+ }
96
+ if (channels != 1 && channels != 3 ) {
97
+ throw std::runtime_error (" Unsupported number of channels" );
98
+ }
99
+ int batchOffset = batchIndex * width * height * channels;
100
+
101
+ cv::Mat resizedMat;
102
+ if (static_cast <int >(width) != mat.size ().width || static_cast <int >(height) != mat.size ().height ) {
103
+ cv::resize (mat, resizedMat, cv::Size (width, height));
104
+ } else {
105
+ resizedMat = mat;
106
+ }
107
+
108
+ if (tensor.get_element_type () == ov::element::f32 ) {
109
+ float_t * tensorData = tensor.data <float_t >();
110
+ for (size_t c = 0 ; c < channels; c++)
111
+ for (size_t h = 0 ; h < height; h++)
112
+ for (size_t w = 0 ; w < width; w++)
113
+ tensorData[batchOffset + c * width * height + h * width + w] =
114
+ getMatValue<float_t >(resizedMat, h, w, c);
115
+ }
116
+ else {
117
+ uint8_t * tensorData = tensor.data <uint8_t >();
118
+ if (resizedMat.depth () == CV_32F) {
119
+ throw std::runtime_error (" Conversion of cv::Mat from float_t to uint8_t is forbidden" );
120
+ }
121
+ for (size_t c = 0 ; c < channels; c++)
122
+ for (size_t h = 0 ; h < height; h++)
123
+ for (size_t w = 0 ; w < width; w++)
124
+ tensorData[batchOffset + c * width * height + h * width + w] =
125
+ getMatValue<uint8_t >(resizedMat, h, w, c);
126
+ }
127
+ }
128
+
78
129
/* *
79
130
* @brief Wraps data stored inside of a passed cv::Mat object by new Blob pointer.
80
131
* @note: No memory allocation is happened. The blob just points to already existing
81
132
* cv::Mat data.
82
133
* @param mat - given cv::Mat object with an image data.
83
134
* @return resulting Blob pointer.
84
135
*/
85
- static UNUSED InferenceEngine::Blob::Ptr wrapMat2Blob (const cv::Mat & mat) {
136
+ static UNUSED InferenceEngine::Blob::Ptr wrapMat2Blob (const cv::Mat& mat) {
86
137
auto matType = mat.type () & CV_MAT_DEPTH_MASK;
87
138
if (matType != CV_8U && matType != CV_32F) {
88
139
throw std::runtime_error (" Unsupported mat type for wrapping" );
@@ -104,21 +155,34 @@ static UNUSED InferenceEngine::Blob::Ptr wrapMat2Blob(const cv::Mat &mat) {
104
155
InferenceEngine::Precision precision = isMatFloat ?
105
156
InferenceEngine::Precision::FP32 : InferenceEngine::Precision::U8;
106
157
InferenceEngine::TensorDesc tDesc (precision,
107
- { 1 , channels, height, width},
108
- InferenceEngine::Layout::NHWC);
158
+ { 1 , channels, height, width },
159
+ InferenceEngine::Layout::NHWC);
109
160
110
161
InferenceEngine::Blob::Ptr blob;
111
162
if (isMatFloat) {
112
163
blob = InferenceEngine::make_shared_blob<float >(tDesc, std::make_shared<SharedBlobAllocator>(mat));
113
- }
114
- else {
164
+ } else {
115
165
blob = InferenceEngine::make_shared_blob<uint8_t >(tDesc, std::make_shared<SharedBlobAllocator>(mat));
116
166
}
117
167
118
168
blob->allocate ();
119
169
return blob;
120
170
}
121
171
172
+ static UNUSED ov::runtime::Tensor wrapMat2Tensor (const cv::Mat& mat) {
173
+ const size_t channels = mat.channels ();
174
+ const size_t height = mat.size ().height ;
175
+ const size_t width = mat.size ().width ;
176
+
177
+ const size_t strideH = mat.step .buf [0 ];
178
+ const size_t strideW = mat.step .buf [1 ];
179
+
180
+ const bool is_dense = strideW == channels && strideH == channels * width;
181
+ OPENVINO_ASSERT (is_dense, " Doesn't support conversion from not dense cv::Mat" );
182
+
183
+ return ov::runtime::Tensor (ov::element::u8 , ov::Shape{ 1 , height, width, channels }, mat.data );
184
+ }
185
+
122
186
/* *
123
187
* @brief Puts text message on the frame, highlights the text with a white border to make it distinguishable from
124
188
* the background.
@@ -131,12 +195,12 @@ static UNUSED InferenceEngine::Blob::Ptr wrapMat2Blob(const cv::Mat &mat) {
131
195
* @param thickness - thickness of the lines used to draw a text.
132
196
*/
133
197
inline void putHighlightedText (const cv::Mat& frame,
134
- const std::string& message,
135
- cv::Point position,
136
- int fontFace,
137
- double fontScale,
138
- cv::Scalar color,
139
- int thickness) {
198
+ const std::string& message,
199
+ cv::Point position,
200
+ int fontFace,
201
+ double fontScale,
202
+ cv::Scalar color,
203
+ int thickness) {
140
204
cv::putText (frame, message, position, fontFace, fontScale, cv::Scalar (255 , 255 , 255 ), thickness + 1 );
141
205
cv::putText (frame, message, position, fontFace, fontScale, color, thickness);
142
206
}
@@ -153,7 +217,7 @@ class OutputTransform {
153
217
float inputWidth = static_cast <float >(inputSize.width );
154
218
float inputHeight = static_cast <float >(inputSize.height );
155
219
scaleFactor = std::min (outputResolution.height / inputHeight, outputResolution.width / inputWidth);
156
- newResolution = cv::Size{static_cast <int >(inputWidth * scaleFactor), static_cast <int >(inputHeight * scaleFactor)};
220
+ newResolution = cv::Size{ static_cast <int >(inputWidth * scaleFactor), static_cast <int >(inputHeight * scaleFactor) };
157
221
return newResolution;
158
222
}
159
223
@@ -197,20 +261,21 @@ class InputTransform {
197
261
public:
198
262
InputTransform () : reverseInputChannels(false ), isTrivial(true ) {}
199
263
200
- InputTransform (bool reverseInputChannels, const std::string & meanValues, const std::string & scaleValues) :
264
+ InputTransform (bool reverseInputChannels, const std::string& meanValues, const std::string& scaleValues) :
201
265
reverseInputChannels (reverseInputChannels),
202
266
isTrivial (!reverseInputChannels && meanValues.empty() && scaleValues.empty()),
203
267
means (meanValues.empty() ? cv::Scalar(0.0 , 0.0 , 0.0 ) : string2Vec(meanValues)),
204
268
stdScales (scaleValues.empty() ? cv::Scalar(1.0 , 1.0 , 1.0 ) : string2Vec(scaleValues)) {
205
269
}
206
270
207
- cv::Scalar string2Vec (const std::string & string) {
271
+ cv::Scalar string2Vec (const std::string& string) {
208
272
const auto & strValues = split (string, ' ' );
209
273
std::vector<float > values;
210
274
try {
211
275
for (auto & str : strValues)
212
276
values.push_back (std::stof (str));
213
- } catch (const std::invalid_argument&) {
277
+ }
278
+ catch (const std::invalid_argument&) {
214
279
throw std::runtime_error (" Invalid parameter --mean_values or --scale_values is provided." );
215
280
}
216
281
if (values.size () != 3 ) {
0 commit comments