Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
magicwindyyd
mindspore
提交
593ee1eb
M
mindspore
项目概览
magicwindyyd
/
mindspore
与 Fork 源项目一致
Fork自
MindSpore / mindspore
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
mindspore
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
593ee1eb
编写于
6月 29, 2020
作者:
I
islam_amin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
C++ UT common files for object detection tests
上级
9b439948
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
305 addition
and
0 deletion
+305
-0
tests/ut/cpp/dataset/CMakeLists.txt
tests/ut/cpp/dataset/CMakeLists.txt
+1
-0
tests/ut/cpp/dataset/common/bboxop_common.cc
tests/ut/cpp/dataset/common/bboxop_common.cc
+230
-0
tests/ut/cpp/dataset/common/bboxop_common.h
tests/ut/cpp/dataset/common/bboxop_common.h
+74
-0
未找到文件。
tests/ut/cpp/dataset/CMakeLists.txt
浏览文件 @
593ee1eb
...
...
@@ -3,6 +3,7 @@ include(GoogleTest)
SET
(
DE_UT_SRCS
common/common.cc
common/cvop_common.cc
common/bboxop_common.cc
batch_op_test.cc
bit_functions_test.cc
storage_container_test.cc
...
...
tests/ut/cpp/dataset/common/bboxop_common.cc
0 → 100644
浏览文件 @
593ee1eb
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bboxop_common.h"
#include <memory>
#include <string>
#include <vector>
#include <iostream>
#include <stdio.h>
#include "./tinyxml2.h"
#include "opencv2/opencv.hpp"
#include "common/utils.h"
#include "dataset/core/cv_tensor.h"
#include "dataset/util/path.h"
#include "dataset/core/constants.h"
#include "utils/log_adapter.h"
using
namespace
mindspore
::
dataset
;
using
namespace
UT
::
CVOP
::
BBOXOP
;
using
tinyxml2
::
XMLDocument
;
using
tinyxml2
::
XMLElement
;
using
tinyxml2
::
XMLError
;
const
char
kAnnotationsFolder
[]
=
"/Annotations/"
;
const
char
kImagesFolder
[]
=
"/JPEGImages/"
;
const
char
kExpectedName
[]
=
"Expected"
;
const
char
kActualName
[]
=
"Actual"
;
const
char
kAnnotExt
[]
=
".xml"
;
const
char
kImageExt
[]
=
".jpg"
;
BBoxOpCommon
::
BBoxOpCommon
()
{}
BBoxOpCommon
::~
BBoxOpCommon
()
{}
void
BBoxOpCommon
::
SetUp
()
{
MS_LOG
(
INFO
)
<<
"starting test."
;
image_folder_build_
=
"data/dataset/imagefolder/"
;
image_folder_src_
=
"../../../../../tests/ut/data/dataset/imagefolder/"
;
std
::
string
dir_path
=
"data/dataset/testVOC2012_2"
;
GetInputImagesAndAnnotations
(
dir_path
);
}
void
BBoxOpCommon
::
GetInputImagesAndAnnotations
(
const
std
::
string
&
dir
,
std
::
size_t
num_of_samples
)
{
std
::
string
images_path
=
dir
+
std
::
string
(
kImagesFolder
);
std
::
string
annots_path
=
dir
+
std
::
string
(
kAnnotationsFolder
);
Path
dir_path
(
images_path
);
std
::
shared_ptr
<
Path
::
DirIterator
>
image_dir_itr
=
Path
::
DirIterator
::
OpenDirectory
(
&
dir_path
);
std
::
vector
<
std
::
string
>
paths_to_fetch
;
if
(
!
dir_path
.
Exists
())
{
MS_LOG
(
ERROR
)
<<
"Images folder was not found : "
+
images_path
;
EXPECT_TRUE
(
dir_path
.
Exists
());
}
std
::
size_t
files_fetched
=
0
;
// get image file paths
while
(
image_dir_itr
->
hasNext
()
&&
files_fetched
<
num_of_samples
)
{
Path
image_path
=
image_dir_itr
->
next
();
if
(
image_path
.
Extension
()
==
std
::
string
(
kImageExt
))
{
paths_to_fetch
.
push_back
(
image_path
.
toString
());
files_fetched
++
;
}
}
// sort fetched files
std
::
sort
(
paths_to_fetch
.
begin
(),
paths_to_fetch
.
end
());
for
(
const
auto
&
image_file
:
paths_to_fetch
)
{
std
::
string
image_ext
=
std
::
string
(
kImageExt
);
std
::
string
annot_file
=
image_file
;
std
::
size_t
pos
=
0
;
// first replace the Image dir with the Annotation dir.
if
((
pos
=
image_file
.
find
(
std
::
string
(
kImagesFolder
),
0
))
!=
std
::
string
::
npos
)
{
annot_file
.
replace
(
pos
,
std
::
string
(
kImagesFolder
).
length
(),
std
::
string
(
kAnnotationsFolder
));
}
// then replace the extensions. the image extension to annotation extension
if
((
pos
=
annot_file
.
find
(
image_ext
,
0
))
!=
std
::
string
::
npos
)
{
annot_file
.
replace
(
pos
,
std
::
string
(
kAnnotExt
).
length
(),
std
::
string
(
kAnnotExt
));
}
std
::
shared_ptr
<
Tensor
>
annotation_tensor
;
// load annotations and log failure
if
(
!
LoadAnnotationFile
(
annot_file
,
&
annotation_tensor
))
{
MS_LOG
(
ERROR
)
<<
"Loading Annotations failed in GetInputImagesAndAnnotations"
;
EXPECT_EQ
(
0
,
1
);
}
// load image
GetInputImage
(
image_file
);
// add image and annotation to the tensor table
TensorRow
row_data
({
std
::
move
(
input_tensor_
),
std
::
move
(
annotation_tensor
)});
images_and_annotations_
.
push_back
(
row_data
);
}
}
void
BBoxOpCommon
::
SaveImagesWithAnnotations
(
BBoxOpCommon
::
FileType
type
,
const
std
::
string
&
op_name
,
const
TensorTable
&
table
)
{
int
i
=
0
;
for
(
auto
&
row
:
table
)
{
std
::
shared_ptr
<
Tensor
>
row_to_save
;
Status
swap_status
=
SwapRedAndBlue
(
row
[
0
],
&
row_to_save
);
if
(
!
swap_status
.
IsOk
())
{
MS_LOG
(
ERROR
)
<<
"Swaping red and blue channels failed in SaveImagesWithAnnotations."
;
EXPECT_TRUE
(
swap_status
.
IsOk
());
}
cv
::
Mat
image
=
std
::
static_pointer_cast
<
CVTensor
>
(
row_to_save
)
->
mat
();
uint32_t
num_of_boxes
=
row
[
1
]
->
shape
()[
0
];
bool
passing_data_fetch
=
true
;
// For each bounding box draw on the image.
for
(
uint32_t
i
=
0
;
i
<
num_of_boxes
;
i
++
)
{
uint32_t
x
=
0
;
uint32_t
y
=
0
;
uint32_t
w
=
0
;
uint32_t
h
=
0
;
passing_data_fetch
&=
row
[
1
]
->
GetUnsignedIntAt
(
&
x
,
{
i
,
0
}).
IsOk
();
passing_data_fetch
&=
row
[
1
]
->
GetUnsignedIntAt
(
&
y
,
{
i
,
1
}).
IsOk
();
passing_data_fetch
&=
row
[
1
]
->
GetUnsignedIntAt
(
&
w
,
{
i
,
2
}).
IsOk
();
passing_data_fetch
&=
row
[
1
]
->
GetUnsignedIntAt
(
&
h
,
{
i
,
3
}).
IsOk
();
if
(
!
passing_data_fetch
)
{
MS_LOG
(
ERROR
)
<<
"Fetching bbox coordinates failed in SaveImagesWithAnnotations."
;
EXPECT_TRUE
(
passing_data_fetch
);
}
cv
::
Rect
bbox
(
x
,
y
,
w
,
h
);
cv
::
rectangle
(
image
,
bbox
,
cv
::
Scalar
(
255
,
0
,
0
),
10
,
8
,
0
);
}
bool
im_write_success
=
false
;
// if user wants to save an expected image, use the path to the source folder.
if
(
type
==
FileType
::
kExpected
)
{
im_write_success
=
cv
::
imwrite
(
image_folder_src_
+
std
::
string
(
kExpectedName
)
+
op_name
+
std
::
to_string
(
i
)
+
std
::
string
(
kImageExt
),
image
);
}
else
{
// otherwise if we are saving actual images only for comparison, save in current working dir in build folders.
im_write_success
=
cv
::
imwrite
(
std
::
string
(
kActualName
)
+
op_name
+
std
::
to_string
(
i
)
+
std
::
string
(
kImageExt
),
image
);
}
if
(
!
im_write_success
)
{
MS_LOG
(
ERROR
)
<<
"Image write failed in SaveImagesWithAnnotations."
;
EXPECT_TRUE
(
im_write_success
);
}
i
+=
1
;
}
}
void
BBoxOpCommon
::
CompareActualAndExpected
(
const
std
::
string
&
op_name
)
{
size_t
num_of_images
=
images_and_annotations_
.
size
();
for
(
size_t
i
=
0
;
i
<
num_of_images
;
i
++
)
{
// load actual and expected images.
std
::
string
actual_path
=
std
::
string
(
kActualName
)
+
op_name
+
std
::
to_string
(
i
)
+
std
::
string
(
kImageExt
);
std
::
string
expected_path
=
image_folder_build_
+
std
::
string
(
kExpectedName
)
+
op_name
+
std
::
to_string
(
i
)
+
std
::
string
(
kImageExt
);
cv
::
Mat
expect_img
=
cv
::
imread
(
expected_path
,
cv
::
IMREAD_COLOR
);
cv
::
Mat
actual_img
=
cv
::
imread
(
actual_path
,
cv
::
IMREAD_COLOR
);
// after comparison is done remove temporary file
EXPECT_TRUE
(
remove
(
actual_path
.
c_str
())
==
0
);
// compare using ==operator by Tensor
if
(
actual_img
.
data
)
{
EXPECT_EQ
(
CVTensor
(
expect_img
)
==
CVTensor
(
actual_img
),
true
);
}
else
{
MS_LOG
(
ERROR
)
<<
"Not pass verification! Image data is null."
;
EXPECT_EQ
(
0
,
1
);
}
}
}
bool
BBoxOpCommon
::
LoadAnnotationFile
(
const
std
::
string
&
path
,
std
::
shared_ptr
<
Tensor
>
*
target_BBox
)
{
if
(
!
Path
(
path
).
Exists
())
{
MS_LOG
(
ERROR
)
<<
"File is not found : "
+
path
;
return
false
;
}
XMLDocument
doc
;
XMLError
e
=
doc
.
LoadFile
(
mindspore
::
common
::
SafeCStr
(
path
));
if
(
e
!=
XMLError
::
XML_SUCCESS
)
{
MS_LOG
(
ERROR
)
<<
"Xml load failed"
;
return
false
;
}
XMLElement
*
root
=
doc
.
RootElement
();
if
(
root
==
nullptr
)
{
MS_LOG
(
ERROR
)
<<
"Xml load root element error"
;
return
false
;
}
XMLElement
*
object
=
root
->
FirstChildElement
(
"object"
);
if
(
object
==
nullptr
)
{
MS_LOG
(
ERROR
)
<<
"No object find in "
+
path
;
return
false
;
}
std
::
vector
<
uint32_t
>
return_value_list
;
dsize_t
bbox_count
=
0
;
// keep track of number of bboxes in file
dsize_t
bbox_val_count
=
4
;
// creating bboxes of size 4 to test function
// FILE OK TO READ
while
(
object
!=
nullptr
)
{
bbox_count
+=
1
;
std
::
string
label_name
;
uint32_t
xmin
=
0
,
ymin
=
0
,
xmax
=
0
,
ymax
=
0
;
XMLElement
*
bbox_node
=
object
->
FirstChildElement
(
"bndbox"
);
if
(
bbox_node
!=
nullptr
)
{
XMLElement
*
xmin_node
=
bbox_node
->
FirstChildElement
(
"xmin"
);
if
(
xmin_node
!=
nullptr
)
xmin
=
xmin_node
->
UnsignedText
();
XMLElement
*
ymin_node
=
bbox_node
->
FirstChildElement
(
"ymin"
);
if
(
ymin_node
!=
nullptr
)
ymin
=
ymin_node
->
UnsignedText
();
XMLElement
*
xmax_node
=
bbox_node
->
FirstChildElement
(
"xmax"
);
if
(
xmax_node
!=
nullptr
)
xmax
=
xmax_node
->
UnsignedText
();
XMLElement
*
ymax_node
=
bbox_node
->
FirstChildElement
(
"ymax"
);
if
(
ymax_node
!=
nullptr
)
ymax
=
ymax_node
->
UnsignedText
();
}
else
{
MS_LOG
(
ERROR
)
<<
"bndbox dismatch in "
+
path
;
return
false
;
}
if
(
xmin
>
0
&&
ymin
>
0
&&
xmax
>
xmin
&&
ymax
>
ymin
)
{
for
(
auto
item
:
{
xmin
,
ymin
,
xmax
-
xmin
,
ymax
-
ymin
})
{
return_value_list
.
push_back
(
item
);
}
}
object
=
object
->
NextSiblingElement
(
"object"
);
// Read next BBox if exists
}
std
::
shared_ptr
<
Tensor
>
ret_value
;
Status
s
=
Tensor
::
CreateTensor
(
&
ret_value
,
return_value_list
,
TensorShape
({
bbox_count
,
bbox_val_count
}));
EXPECT_TRUE
(
s
.
IsOk
());
(
*
target_BBox
)
=
ret_value
;
// load bbox from file into return
return
true
;
}
tests/ut/cpp/dataset/common/bboxop_common.h
0 → 100644
浏览文件 @
593ee1eb
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TESTS_DATASET_UT_CORE_COMMON_DE_UT_BBOXOP_COMMON_H_
#define TESTS_DATASET_UT_CORE_COMMON_DE_UT_BBOXOP_COMMON_H_
#include "cvop_common.h"
#include "dataset/util/path.h"
namespace
UT
{
namespace
CVOP
{
namespace
BBOXOP
{
class
BBoxOpCommon
:
public
CVOpCommon
{
public:
enum
FileType
{
kExpected
,
kActual
};
BBoxOpCommon
();
~
BBoxOpCommon
();
/// \brief Sets up the class's variable, images_and_annotations
void
SetUp
()
override
;
/// \brief Get all images and annotations in images_and_annotations TensorTable from dir
/// \param[in] dir directory containing images and annotation folders
/// \param[in] num_of_samples number of rows to fetch (default = 1)
void
GetInputImagesAndAnnotations
(
const
std
::
string
&
dir
,
std
::
size_t
num_of_samples
=
1
);
/// \brief Save the given tensor table
/// \param[in] type type of images to be stored (e.g. Expected or Actual)
/// \param[in] op_name name of op being tested
/// \param[in] table rows of images and corresponding annotations
void
SaveImagesWithAnnotations
(
FileType
type
,
const
std
::
string
&
op_name
,
const
TensorTable
&
table
);
/// \brief Compare actual and expected results. The images will have the bounding boxes on them
/// Log if images don't match
/// \param[in] op_name name of op being tested
void
CompareActualAndExpected
(
const
std
::
string
&
op_name
);
/// \brief Load BBox data from an XML file into a Tensor
/// \param[in] path path to XML bbox data file
/// \param[inout] target_BBox pointer to a Tensor to load
/// \return True if file loaded successfully, false if error -> logged to STD out
bool
LoadAnnotationFile
(
const
std
::
string
&
path
,
std
::
shared_ptr
<
Tensor
>
*
target_BBox
);
TensorTable
images_and_annotations_
;
private:
// directory of image_folder when the dataset/data gets transferred to build
std
::
string
image_folder_build_
;
// directory of image_folder in the source project (used to store expected results)
std
::
string
image_folder_src_
;
};
}
// namespace BBOXOP
}
// namespace CVOP
}
// namespace UT
#endif // TESTS_DATASET_UT_CORE_COMMON_DE_UT_BBOXOP_COMMON_H_
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录