Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ModelZoo
ResNet50_migraphx
Commits
1eff8465
Commit
1eff8465
authored
Jun 14, 2023
by
liucong
Browse files
修改代码
parent
8a0838dd
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
443 additions
and
125 deletions
+443
-125
CMakeLists.txt
CMakeLists.txt
+1
-0
Doc/Tutorial_Cpp.md
Doc/Tutorial_Cpp.md
+42
-12
Doc/Tutorial_Python.md
Doc/Tutorial_Python.md
+39
-18
Python/Classifier.py
Python/Classifier.py
+33
-13
README.md
README.md
+38
-32
Resource/Configuration.xml
Resource/Configuration.xml
+1
-6
Src/Classifier.cpp
Src/Classifier.cpp
+72
-25
Src/Classifier.h
Src/Classifier.h
+0
-4
Src/Utility/CommonDefinition.h
Src/Utility/CommonDefinition.h
+1
-13
Src/Utility/CommonUtility.cpp
Src/Utility/CommonUtility.cpp
+157
-0
Src/Utility/CommonUtility.h
Src/Utility/CommonUtility.h
+57
-0
Src/main.cpp
Src/main.cpp
+2
-2
No files found.
CMakeLists.txt
View file @
1eff8465
...
@@ -37,6 +37,7 @@ link_libraries(${LIBRARY})
...
@@ -37,6 +37,7 @@ link_libraries(${LIBRARY})
# 添加源文件
# 添加源文件
set
(
SOURCE_FILES
${
CMAKE_CURRENT_SOURCE_DIR
}
/Src/main.cpp
set
(
SOURCE_FILES
${
CMAKE_CURRENT_SOURCE_DIR
}
/Src/main.cpp
${
CMAKE_CURRENT_SOURCE_DIR
}
/Src/Classifier.cpp
${
CMAKE_CURRENT_SOURCE_DIR
}
/Src/Classifier.cpp
${
CMAKE_CURRENT_SOURCE_DIR
}
/Src/Utility/CommonUtility.cpp
${
CMAKE_CURRENT_SOURCE_DIR
}
/Src/Utility/Filesystem.cpp
)
${
CMAKE_CURRENT_SOURCE_DIR
}
/Src/Utility/Filesystem.cpp
)
# 添加可执行目标
# 添加可执行目标
...
...
Doc/Tutorial_Cpp.md
View file @
1eff8465
...
@@ -16,13 +16,17 @@
...
@@ -16,13 +16,17 @@
在将数据输入到模型之前,需要对图像做如下预处理操作:
在将数据输入到模型之前,需要对图像做如下预处理操作:
-
resize到224x224
-
图像格式转换,BGR转换为RGB
-
将像素值归一化到[0.0, 1.0]
-
转换数据排布为NCHW
-
调整图像大小,并在中心窗口位置裁剪出224x224大小的图像
-
normalize操作,对图像减均值再除方差
-
转换数据排布为NCHW
本示例代码采用了OpenCV
的cv::dnn::blobFromImages()函数
实现了预处理操作:
本示例代码
主要
采用了OpenCV实现了预处理操作:
```
c++
```
c++
ErrorCode
Classifier
::
Classify
(
const
std
::
vector
<
cv
::
Mat
>
&
srcImages
,
std
::
vector
<
std
::
vector
<
ResultOfPrediction
>>
&
predictions
)
ErrorCode
Classifier
::
Classify
(
const
std
::
vector
<
cv
::
Mat
>
&
srcImages
,
std
::
vector
<
std
::
vector
<
ResultOfPrediction
>>
&
predictions
)
...
@@ -30,20 +34,46 @@ ErrorCode Classifier::Classify(const std::vector<cv::Mat> &srcImages,std::vector
...
@@ -30,20 +34,46 @@ ErrorCode Classifier::Classify(const std::vector<cv::Mat> &srcImages,std::vector
...
...
// 预处理
// 预处理
std
::
vector
<
cv
::
Mat
>
image
;
for
(
int
i
=
0
;
i
<
srcImages
.
size
();
++
i
)
{
//BGR转换为RGB
cv
::
Mat
imgRGB
;
cv
::
cvtColor
(
srcImages
[
i
],
imgRGB
,
cv
::
COLOR_BGR2RGB
);
// 调整大小,保持长宽比
cv
::
Mat
shrink
;
float
ratio
=
(
float
)
256
/
min
(
imgRGB
.
cols
,
imgRGB
.
rows
);
if
(
imgRGB
.
rows
>
imgRGB
.
cols
)
{
cv
::
resize
(
imgRGB
,
shrink
,
cv
::
Size
(
256
,
int
(
ratio
*
imgRGB
.
rows
)),
0
,
0
);
}
else
{
cv
::
resize
(
imgRGB
,
shrink
,
cv
::
Size
(
int
(
ratio
*
imgRGB
.
cols
),
256
),
0
,
0
);
}
// 裁剪中心窗口
int
start_x
=
shrink
.
cols
/
2
-
224
/
2
;
int
start_y
=
shrink
.
rows
/
2
-
224
/
2
;
cv
::
Rect
rect
(
start_x
,
start_y
,
224
,
224
);
cv
::
Mat
images
=
shrink
(
rect
);
image
.
push_back
(
images
);
}
// normalize并转换为NCHW
cv
::
Mat
inputBlob
;
cv
::
Mat
inputBlob
;
cv
::
dnn
::
blobFromImages
(
srcImages
,
// 输入数据,支持多张图像
Image2BlobParams
image2BlobParams
;
inputBlob
,
// 输出数据
image2BlobParams
.
scalefactor
=
cv
::
Scalar
(
1
/
58.395
,
1
/
57.12
,
1
/
57.375
);
scale
,
// 缩放系数,这里为1/255.0
image2BlobParams
.
mean
=
cv
::
Scalar
(
123.675
,
116.28
,
103.53
);
inputSize
,
// 模型输入大小,这里为28x28
image2BlobParams
.
swapRB
=
false
;
meanValue
,
// 均值,这里不需要减均值,所以设置为0.0
blobFromImagesWithParams
(
image
,
inputBlob
,
image2BlobParams
);
swapRB
,
// 多通道图像,这里设置为1
false
);
...
...
}
}
```
```
cv::dnn::
blobFromImages()函数支持多个输入图像,首先
将
输入图像
resize到inputSize,然后减去均值meanValue,最后乘以scale并
转换为NCHW,最终将转换好的数据保存到inputBlob中,然后就可以输入到模型中执行推理了。
blobFromImages
WithParams
()函数支持多个输入图像,首先
对
输入图像
各通道减对应的均值,然后乘以各通道对应的缩放系数,最后
转换为NCHW,最终将转换好的数据保存到inputBlob中,然后就可以输入到模型中执行推理了。
...
...
Doc/Tutorial_Python.md
View file @
1eff8465
...
@@ -14,27 +14,52 @@
...
@@ -14,27 +14,52 @@
在将数据输入到模型之前,需要对图像做如下预处理操作:
在将数据输入到模型之前,需要对图像做如下预处理操作:
-
转换数据排布为NCHW
-
图像格式转换,将BGR转换为RGB
-
将像素值归一化到[0.0, 1.0]
-
调整图像大小,使短边为 256,长边等比例缩放
-
裁剪图像,在中心窗口位置裁剪出224x224大小的图像
-
normalize操作,对图像减均值再除方差
-
调整输入数据的尺寸为(1, 3, 224, 224)
-
调整输入数据的尺寸为(1, 3, 224, 224)
本示例代码采用了OpenCV实现了预处理操作:
本示例代码采用了OpenCV实现了预处理操作:
```
```
def Preprocessing(pathOfImage):
def Preprocessing(pathOfImage):
image = cv2.imread(pathOfImage,cv2.IMREAD_COLOR)
image = cv2.imread(pathOfImage, cv2.IMREAD_COLOR)
# 转换为RGB格式
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 调整图像的尺寸
image = cv2.resize(image, (224,224))
# 调整大小,保持长宽比
# 维度转换HWC->CHW
ratio = float(256) / min(image.shape[0], image.shape[1])
if image.shape[0] > image.shape[1]:
new_size = [int(round(ratio * image.shape[0])), 256]
else:
new_size = [256, int(round(ratio * image.shape[1]))]
image = np.array(cv2.resize(image, (new_size[1],new_size[0]))) # w h 格式
# 裁剪中心窗口
h, w, c = image.shape
start_x = w//2 - 224//2
start_y = h//2 - 224//2
image = image[start_y:start_y+224, start_x:start_x+224, :]
# transpose
image = image.transpose(2, 0, 1)
image = image.transpose(2, 0, 1)
# 维度拓展,增加batch维度
image = np.expand_dims(image, 0)
# 将输入数据转换为float32
image = np.ascontiguousarray(image)
img_data = image.astype('float32')
image = image.astype(np.float32)
# 归一化
# normalize
input = image / 255
mean_vec = np.array([123.675, 116.28, 103.53])
return input
stddev_vec = np.array([58.395, 57.12, 57.375])
norm_img_data = np.zeros(img_data.shape).astype('float32')
for i in range(img_data.shape[0]):
norm_img_data[i,:,:] = (img_data[i,:,:] - mean_vec[i]) / stddev_vec[i]
# 调整输入数据的尺寸
norm_img_data = norm_img_data.reshape(1, 3, 224, 224).astype('float32')
return norm_img_data
```
```
...
@@ -61,12 +86,8 @@ if __name__ == '__main__':
...
@@ -61,12 +86,8 @@ if __name__ == '__main__':
numberOfOutput=outputShape.elements() # 输出节点元素的个数
numberOfOutput=outputShape.elements() # 输出节点元素的个数
# 获取分类结果
# 获取分类结果
result=results[0].tolist() # 将migraphx.argument转换为list
result=np.array(result)
result=np.array(result)
# 打印1000个类别的输出值
print(result)
```
```
-
Preprocessing()函数返回输入数据(numpy类型),然后通过{inputName: migraphx.argument(image)}构造一个字典输入模型执行推理,如果模型有多个输入,则在字典中需要添加多个输入数据。
-
Preprocessing()函数返回输入数据(numpy类型),然后通过{inputName: migraphx.argument(image)}构造一个字典输入模型执行推理,如果模型有多个输入,则在字典中需要添加多个输入数据。
-
model.run()返回模型的推理结果,返回结果是一个list类型,results[0]表示第一个输出节点的输出,是一个migraphx.argument类型,由于示例模型只有一个输出节点,所以results[0]对应resnetv24_dense0_fwd节点
,如果想将migraphx.argument类型转换为list类型,可以通过tolist()方法实现。最后,打印出1000个类别的输出值
。
-
model.run()返回模型的推理结果,返回结果是一个list类型,results[0]表示第一个输出节点的输出,是一个migraphx.argument类型,由于示例模型只有一个输出节点,所以results[0]对应resnetv24_dense0_fwd节点
。最后,通过np.array(result)获取分类结果
。
Python/Classifier.py
View file @
1eff8465
...
@@ -8,15 +8,40 @@ import numpy as np
...
@@ -8,15 +8,40 @@ import numpy as np
import
migraphx
import
migraphx
def
Preprocessing
(
pathOfImage
):
def
Preprocessing
(
pathOfImage
):
image
=
cv2
.
imread
(
pathOfImage
,
cv2
.
IMREAD_COLOR
)
# cv2.IMREAD_COLOR:彩色图,cv2.IMREAD_GRAYSCALE:灰度图
# 读取图像
image
=
cv2
.
imread
(
pathOfImage
,
cv2
.
IMREAD_COLOR
)
image
=
cv2
.
cvtColor
(
image
,
cv2
.
COLOR_BGR2RGB
)
image
=
cv2
.
cvtColor
(
image
,
cv2
.
COLOR_BGR2RGB
)
image
=
cv2
.
resize
(
image
,
(
224
,
224
))
# 调整大小,使短边为256,保持长宽比
ratio
=
float
(
256
)
/
min
(
image
.
shape
[
0
],
image
.
shape
[
1
])
if
image
.
shape
[
0
]
>
image
.
shape
[
1
]:
new_size
=
[
int
(
round
(
ratio
*
image
.
shape
[
0
])),
256
]
else
:
new_size
=
[
256
,
int
(
round
(
ratio
*
image
.
shape
[
1
]))]
image
=
np
.
array
(
cv2
.
resize
(
image
,
(
new_size
[
1
],
new_size
[
0
])))
# w h 格式
# 裁剪中心窗口为224*224
h
,
w
,
c
=
image
.
shape
start_x
=
w
//
2
-
224
//
2
start_y
=
h
//
2
-
224
//
2
image
=
image
[
start_y
:
start_y
+
224
,
start_x
:
start_x
+
224
,
:]
# transpose
image
=
image
.
transpose
(
2
,
0
,
1
)
image
=
image
.
transpose
(
2
,
0
,
1
)
image
=
np
.
expand_dims
(
image
,
0
)
image
=
np
.
ascontiguousarray
(
image
)
# 将输入数据转换为float32
image
=
image
.
astype
(
np
.
float32
)
img_data
=
image
.
astype
(
'float32'
)
input
=
image
/
255
return
input
# normalize
mean_vec
=
np
.
array
([
123.675
,
116.28
,
103.53
])
stddev_vec
=
np
.
array
([
58.395
,
57.12
,
57.375
])
norm_img_data
=
np
.
zeros
(
img_data
.
shape
).
astype
(
'float32'
)
for
i
in
range
(
img_data
.
shape
[
0
]):
norm_img_data
[
i
,:,:]
=
(
img_data
[
i
,:,:]
-
mean_vec
[
i
])
/
stddev_vec
[
i
]
# 调整尺寸
norm_img_data
=
norm_img_data
.
reshape
(
1
,
3
,
224
,
224
).
astype
(
'float32'
)
return
norm_img_data
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
# 加载模型
# 加载模型
...
@@ -25,9 +50,6 @@ if __name__ == '__main__':
...
@@ -25,9 +50,6 @@ if __name__ == '__main__':
inputShape
=
model
.
get_parameter_shapes
()[
inputName
].
lens
()
inputShape
=
model
.
get_parameter_shapes
()[
inputName
].
lens
()
print
(
"inputName:{0}
\n
inputShape:{1}"
.
format
(
inputName
,
inputShape
))
print
(
"inputName:{0}
\n
inputShape:{1}"
.
format
(
inputName
,
inputShape
))
# FP16
# migraphx.quantize_fp16(model)
# 编译
# 编译
model
.
compile
(
t
=
migraphx
.
get_target
(
"gpu"
),
device_id
=
0
)
# device_id: 设置GPU设备,默认为0号设备
model
.
compile
(
t
=
migraphx
.
get_target
(
"gpu"
),
device_id
=
0
)
# device_id: 设置GPU设备,默认为0号设备
...
@@ -45,8 +67,6 @@ if __name__ == '__main__':
...
@@ -45,8 +67,6 @@ if __name__ == '__main__':
numberOfOutput
=
outputShape
.
elements
()
# 输出节点元素的个数
numberOfOutput
=
outputShape
.
elements
()
# 输出节点元素的个数
# 获取分类结果
# 获取分类结果
result
=
results
[
0
].
tolist
()
# 将migraphx.argument转换为list
result
=
np
.
array
(
results
[
0
])
result
=
np
.
array
(
result
)
# 打印1000个类别的输出
print
(
result
)
print
(
result
)
\ No newline at end of file
README.md
View file @
1eff8465
...
@@ -8,21 +8,23 @@ ResNet50模型包含了49个卷积层、一个全连接层。
...
@@ -8,21 +8,23 @@ ResNet50模型包含了49个卷积层、一个全连接层。
## Python版本推理
## Python版本推理
下面介绍如何运行
p
ython代码示例,
具体推理代码解析,在Doc/
Tutorial_Python.md
中有详细说明
。
下面介绍如何运行
P
ython代码示例,
Python示例的详细说明见Doc目录下的
Tutorial_Python.md。
###
拉取
镜像
###
下载
镜像
在光源
可拉取推理的docker镜像,ResNet50模型推理的镜像如下
:
在光源
中下载MIGraphX镜像
:
```
python
```
python
docker
pull
image
.
sourcefind
.
cn
:
5000
/
dcu
/
admin
/
base
/
custom
:
ort1
.
14.0
_migraphx3
.
0.0
-
dtk22
.
10.1
docker
pull
image
.
sourcefind
.
cn
:
5000
/
dcu
/
admin
/
base
/
custom
:
ort1
.
14.0
_migraphx3
.
0.0
-
dtk22
.
10.1
```
```
###
推理示例
###
设置Python环境变量
1.
参考《MIGraphX教程》设置好PYTHONPATH
```
export PYTHONPATH=/opt/dtk/lib:$PYTHONPATH
```
2.
安装依赖
:
###
安装依赖
```
python
```
python
# 进入resnet50 migraphx工程根目录
# 进入resnet50 migraphx工程根目录
...
@@ -35,7 +37,9 @@ cd Python/
...
@@ -35,7 +37,9 @@ cd Python/
pip
install
-
r
requirements
.
txt
pip
install
-
r
requirements
.
txt
```
```
3.
在Python目录下执行如下命令运行该示例程序:
### 运行示例
在Python目录下执行如下命令运行该示例程序:
```
python
```
python
python
Classifier
.
py
python
Classifier
.
py
...
@@ -44,18 +48,24 @@ python Classifier.py
...
@@ -44,18 +48,24 @@ python Classifier.py
输出结果中,每个值分别对应每个label的输出值。
输出结果中,每个值分别对应每个label的输出值。
```
```
[
1.25075293e+00 1.78420877e+00 -2.56109548e+00 -3.44433069
e+00
[
-2.07137913e-02 2.25237548e-01 -1.98313940e+00 -2.97359991
e+00
-
2
.
6
611
356
7e+00
1.52841401e+00 7.93735325
e-01
-
1.2
6759931e-02
-
1
.611
0019
7e+00
4.24269080e-01 -9.02939081
e-01
1.2
1229446e+00
...
...
4.39746976e-02 3.43239784e-01 2.75328755e+00 1.70684290e+00
-2.69769251e-01 -4.28011447e-01 1.25102985e+00 9.06333506e-01
8.54880095
e-01
2
.1
2219620e+00 2.35758686e+00 -1.06204104e+00
]
-1.08657002
e-01
3
.1
5954179e-01 1.94901276e+00 -5.70572793e-01
]
```
```
## C++版本推理
## C++版本推理
下面介绍如何运行C++代码示例,具体推理代码解析,在Doc/Tutorial_Cpp.md目录中有详细说明。
下面介绍如何运行C++代码示例,C++示例的详细说明见Doc目录下的Tutorial_Cpp.md。
### 下载镜像
在光源中下载MIGraphX镜像:
参考Python版本推理中的构建安装,在光源中拉取推理的docker镜像。
```
docker pull image.sourcefind.cn:5000/dcu/admin/base/custom:ort1.14.0_migraphx3.0.0-dtk22.10.1
```
### 安装Opencv依赖
### 安装Opencv依赖
...
@@ -66,10 +76,8 @@ sh ./3rdParty/InstallOpenCVDependences.sh
...
@@ -66,10 +76,8 @@ sh ./3rdParty/InstallOpenCVDependences.sh
### 修改CMakeLists.txt
### 修改CMakeLists.txt
-
如果使用ubuntu系统,需要修改CMakeLists.txt中依赖库路径:
如果使用ubuntu系统,需要修改CMakeLists.txt中依赖库路径:
将"${CMAKE_CURRENT_SOURCE_DIR}/depend/lib64/"修改为"${CMAKE_CURRENT_SOURCE_DIR}/depend/lib/"
将"${CMAKE_CURRENT_SOURCE_DIR}/depend/lib64/"修改为"${CMAKE_CURRENT_SOURCE_DIR}/depend/lib/"
-
**MIGraphX2.3.0及以上版本需要c++17**
### 安装OpenCV并构建工程
### 安装OpenCV并构建工程
...
@@ -100,9 +108,7 @@ export LD_LIBRARY_PATH=<path_to_resnet50_migraphx>/depend/lib/:$LD_LIBRARY_PATH
...
@@ -100,9 +108,7 @@ export LD_LIBRARY_PATH=<path_to_resnet50_migraphx>/depend/lib/:$LD_LIBRARY_PATH
source ~/.bashrc
source ~/.bashrc
```
```
### 推理示例
### 运行示例
运行ResNet50示例程序,具体执行如下命令:
```
python
```
python
# 进入resnet50 migraphx工程根目录
# 进入resnet50 migraphx工程根目录
...
@@ -118,23 +124,23 @@ cd ./build/
...
@@ -118,23 +124,23 @@ cd ./build/
输出结果中,每个值分别对应每个label的输出值。
输出结果中,每个值分别对应每个label的输出值。
```
```
label:0,confidence:
1.250770
label:0,confidence:
-0.020714
label:1,confidence:
1.7840
38
label:1,confidence:
0.2252
38
label:2,confidence:-
2.561039
label:2,confidence:-
1.983140
label:3,confidence:-
3.44428
1
label:3,confidence:-
2.97360
1
label:4,confidence:-
2.661
02
6
label:4,confidence:-
1.6110
02
label:5,confidence:
1.528
26
0
label:5,confidence:
0.424
26
8
...
...
label:995,confidence:
1.706820
label:995,confidence:
0.906333
label:996,confidence:0.
854793
label:996,confidence:
-
0.
108658
label:997,confidence:
2.12198
5
label:997,confidence:
0.31595
5
label:998,confidence:
2.357481
label:998,confidence:
1.949013
label:999,confidence:-
1.062007
label:999,confidence:-
0.570573
```
```
## 历史版本
## 历史版本
https://developer.hpccube.com/codes/modelzoo/
classifier
_migraphx
https://developer.hpccube.com/codes/modelzoo/
resnet50
_migraphx
## 参考资料
## 参考资料
...
...
Resource/Configuration.xml
View file @
1eff8465
<?xml version="1.0" encoding="GB2312"?>
<?xml version="1.0" encoding="GB2312"?>
<opencv_storage>
<opencv_storage>
<!--分类器-->
<!--分类器-->
<Classifier>
<Classifier>
<ModelPath>
"../Resource/Models/resnet50-v2-7.onnx"
</ModelPath>
<ModelPath>
"../Resource/Models/resnet50-v2-7.onnx"
</ModelPath>
<Scale>
0.003922
</Scale>
<!--缩放尺度-->
<MeanValue1>
0.0
</MeanValue1>
<!--均值-->
<MeanValue2>
0.0
</MeanValue2>
<MeanValue3>
0.0
</MeanValue3>
<SwapRB>
1
</SwapRB>
<Crop>
0
</Crop>
<UseInt8>
0
</UseInt8>
<!--是否使用int8,不支持-->
<UseInt8>
0
</UseInt8>
<!--是否使用int8,不支持-->
<UseFP16>
0
</UseFP16>
<!--是否使用FP16-->
<UseFP16>
0
</UseFP16>
<!--是否使用FP16-->
</Classifier>
</Classifier>
...
...
Src/Classifier.cpp
View file @
1eff8465
...
@@ -6,6 +6,8 @@
...
@@ -6,6 +6,8 @@
#include <Filesystem.h>
#include <Filesystem.h>
#include <SimpleLog.h>
#include <SimpleLog.h>
#include <algorithm>
#include <CommonUtility.h>
namespace
migraphxSamples
namespace
migraphxSamples
{
{
...
@@ -38,12 +40,6 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat
...
@@ -38,12 +40,6 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat
// 获取配置文件参数
// 获取配置文件参数
cv
::
FileNode
netNode
=
configurationFile
[
"Classifier"
];
cv
::
FileNode
netNode
=
configurationFile
[
"Classifier"
];
std
::
string
modelPath
=
(
std
::
string
)
netNode
[
"ModelPath"
];
std
::
string
modelPath
=
(
std
::
string
)
netNode
[
"ModelPath"
];
scale
=
(
float
)
netNode
[
"Scale"
];
meanValue
.
val
[
0
]
=
(
float
)
netNode
[
"MeanValue1"
];
meanValue
.
val
[
1
]
=
(
float
)
netNode
[
"MeanValue2"
];
meanValue
.
val
[
2
]
=
(
float
)
netNode
[
"MeanValue3"
];
swapRB
=
(
bool
)(
int
)
netNode
[
"SwapRB"
];
crop
=
(
bool
)(
int
)
netNode
[
"Crop"
];
useInt8
=
(
bool
)(
int
)
netNode
[
"UseInt8"
];
useInt8
=
(
bool
)(
int
)
netNode
[
"UseInt8"
];
useFP16
=
(
bool
)(
int
)
netNode
[
"UseFP16"
];
useFP16
=
(
bool
)(
int
)
netNode
[
"UseFP16"
];
...
@@ -79,14 +75,43 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat
...
@@ -79,14 +75,43 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat
{
{
srcImages
.
push_back
(
srcImage
);
srcImages
.
push_back
(
srcImage
);
}
}
// 数据预处理
std
::
vector
<
cv
::
Mat
>
image
;
for
(
int
i
=
0
;
i
<
srcImages
.
size
();
++
i
)
{
//BGR转换为RGB
cv
::
Mat
imgRGB
;
cv
::
cvtColor
(
srcImages
[
i
],
imgRGB
,
cv
::
COLOR_BGR2RGB
);
// 调整大小,使短边为256,保持长宽比
cv
::
Mat
shrink
;
float
ratio
=
(
float
)
256
/
min
(
imgRGB
.
cols
,
imgRGB
.
rows
);
if
(
imgRGB
.
rows
>
imgRGB
.
cols
)
{
cv
::
resize
(
imgRGB
,
shrink
,
cv
::
Size
(
256
,
int
(
ratio
*
imgRGB
.
rows
)),
0
,
0
);
}
else
{
cv
::
resize
(
imgRGB
,
shrink
,
cv
::
Size
(
int
(
ratio
*
imgRGB
.
cols
),
256
),
0
,
0
);
}
// 裁剪中心窗口为224*224
int
start_x
=
shrink
.
cols
/
2
-
224
/
2
;
int
start_y
=
shrink
.
rows
/
2
-
224
/
2
;
cv
::
Rect
rect
(
start_x
,
start_y
,
224
,
224
);
cv
::
Mat
images
=
shrink
(
rect
);
image
.
push_back
(
images
);
}
// normalize并转换为NCHW
cv
::
Mat
inputBlob
;
cv
::
Mat
inputBlob
;
cv
::
dnn
::
blobFromImages
(
srcImages
,
Image2BlobParams
image2BlobParams
;
inputBlob
,
image2BlobParams
.
scalefactor
=
cv
::
Scalar
(
1
/
58.395
,
1
/
57.12
,
1
/
57.375
);
scale
,
image2BlobParams
.
mean
=
cv
::
Scalar
(
123.675
,
116.28
,
103.53
);
inputSize
,
image2BlobParams
.
swapRB
=
false
;
meanValue
,
blobFromImagesWithParams
(
image
,
inputBlob
,
image2BlobParams
);
swapRB
,
false
);
std
::
unordered_map
<
std
::
string
,
migraphx
::
argument
>
inputData
;
std
::
unordered_map
<
std
::
string
,
migraphx
::
argument
>
inputData
;
inputData
[
inputName
]
=
migraphx
::
argument
{
inputShape
,
(
float
*
)
inputBlob
.
data
};
inputData
[
inputName
]
=
migraphx
::
argument
{
inputShape
,
(
float
*
)
inputBlob
.
data
};
std
::
vector
<
std
::
unordered_map
<
std
::
string
,
migraphx
::
argument
>>
calibrationData
=
{
inputData
};
std
::
vector
<
std
::
unordered_map
<
std
::
string
,
migraphx
::
argument
>>
calibrationData
=
{
inputData
};
...
@@ -114,10 +139,6 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat
...
@@ -114,10 +139,6 @@ ErrorCode Classifier::Initialize(InitializationParameterOfClassifier initializat
// log
// log
LOG_INFO
(
stdout
,
"InputSize:%dx%d
\n
"
,
inputSize
.
width
,
inputSize
.
height
);
LOG_INFO
(
stdout
,
"InputSize:%dx%d
\n
"
,
inputSize
.
width
,
inputSize
.
height
);
LOG_INFO
(
stdout
,
"InputName:%s
\n
"
,
inputName
.
c_str
());
LOG_INFO
(
stdout
,
"InputName:%s
\n
"
,
inputName
.
c_str
());
LOG_INFO
(
stdout
,
"Scale:%.6f
\n
"
,
scale
);
LOG_INFO
(
stdout
,
"Mean:%.2f,%.2f,%.2f
\n
"
,
meanValue
.
val
[
0
],
meanValue
.
val
[
1
],
meanValue
.
val
[
2
]);
LOG_INFO
(
stdout
,
"SwapRB:%d
\n
"
,(
int
)
swapRB
);
LOG_INFO
(
stdout
,
"Crop:%d
\n
"
,(
int
)
crop
);
LOG_INFO
(
stdout
,
"UseInt8:%d
\n
"
,(
int
)
useInt8
);
LOG_INFO
(
stdout
,
"UseInt8:%d
\n
"
,(
int
)
useInt8
);
LOG_INFO
(
stdout
,
"UseFP16:%d
\n
"
,(
int
)
useFP16
);
LOG_INFO
(
stdout
,
"UseFP16:%d
\n
"
,(
int
)
useFP16
);
...
@@ -133,15 +154,41 @@ ErrorCode Classifier::Classify(const std::vector<cv::Mat> &srcImages,std::vector
...
@@ -133,15 +154,41 @@ ErrorCode Classifier::Classify(const std::vector<cv::Mat> &srcImages,std::vector
return
IMAGE_ERROR
;
return
IMAGE_ERROR
;
}
}
// 数据预处理并转换为NCHW
// 数据预处理
std
::
vector
<
cv
::
Mat
>
image
;
for
(
int
i
=
0
;
i
<
srcImages
.
size
();
++
i
)
{
//BGR转换为RGB
cv
::
Mat
imgRGB
;
cv
::
cvtColor
(
srcImages
[
i
],
imgRGB
,
cv
::
COLOR_BGR2RGB
);
// 调整大小,使短边为256,保持长宽比
cv
::
Mat
shrink
;
float
ratio
=
(
float
)
256
/
min
(
imgRGB
.
cols
,
imgRGB
.
rows
);
if
(
imgRGB
.
rows
>
imgRGB
.
cols
)
{
cv
::
resize
(
imgRGB
,
shrink
,
cv
::
Size
(
256
,
int
(
ratio
*
imgRGB
.
rows
)),
0
,
0
);
}
else
{
cv
::
resize
(
imgRGB
,
shrink
,
cv
::
Size
(
int
(
ratio
*
imgRGB
.
cols
),
256
),
0
,
0
);
}
// 裁剪中心窗口为224*224
int
start_x
=
shrink
.
cols
/
2
-
224
/
2
;
int
start_y
=
shrink
.
rows
/
2
-
224
/
2
;
cv
::
Rect
rect
(
start_x
,
start_y
,
224
,
224
);
cv
::
Mat
images
=
shrink
(
rect
);
image
.
push_back
(
images
);
}
// normalize并转换为NCHW
cv
::
Mat
inputBlob
;
cv
::
Mat
inputBlob
;
cv
::
dnn
::
blobFromImages
(
srcImages
,
Image2BlobParams
image2BlobParams
;
inputBlob
,
image2BlobParams
.
scalefactor
=
cv
::
Scalar
(
1
/
58.395
,
1
/
57.12
,
1
/
57.375
);
scale
,
image2BlobParams
.
mean
=
cv
::
Scalar
(
123.675
,
116.28
,
103.53
);
inputSize
,
image2BlobParams
.
swapRB
=
false
;
meanValue
,
blobFromImagesWithParams
(
image
,
inputBlob
,
image2BlobParams
);
swapRB
,
false
);
// 创建输入数据
// 创建输入数据
std
::
unordered_map
<
std
::
string
,
migraphx
::
argument
>
inputData
;
std
::
unordered_map
<
std
::
string
,
migraphx
::
argument
>
inputData
;
...
...
Src/Classifier.h
View file @
1eff8465
...
@@ -27,10 +27,6 @@ private:
...
@@ -27,10 +27,6 @@ private:
std
::
string
inputName
;
std
::
string
inputName
;
migraphx
::
shape
inputShape
;
migraphx
::
shape
inputShape
;
float
scale
;
cv
::
Scalar
meanValue
;
bool
swapRB
;
bool
crop
;
bool
useInt8
;
bool
useInt8
;
bool
useFP16
;
bool
useFP16
;
...
...
Src/Utility/CommonDefinition.h
View file @
1eff8465
...
@@ -15,7 +15,7 @@ namespace migraphxSamples
...
@@ -15,7 +15,7 @@ namespace migraphxSamples
#define PATH_SEPARATOR '/'
#define PATH_SEPARATOR '/'
#endif
#endif
#define CONFIG_FILE
"../Resource/Configuration.xml"
#define CONFIG_FILE "../Resource/Configuration.xml"
typedef
enum
_ErrorCode
typedef
enum
_ErrorCode
{
{
...
@@ -35,18 +35,6 @@ typedef struct _ResultOfPrediction
...
@@ -35,18 +35,6 @@ typedef struct _ResultOfPrediction
}
ResultOfPrediction
;
}
ResultOfPrediction
;
typedef
struct
_ResultOfDetection
{
cv
::
Rect
boundingBox
;
float
confidence
;
int
classID
;
std
::
string
className
;
bool
exist
;
_ResultOfDetection
()
:
confidence
(
0.0
f
),
classID
(
0
),
exist
(
true
){}
}
ResultOfDetection
;
typedef
struct
_InitializationParameterOfClassifier
typedef
struct
_InitializationParameterOfClassifier
{
{
std
::
string
parentPath
;
std
::
string
parentPath
;
...
...
Src/Utility/CommonUtility.cpp
0 → 100644
View file @
1eff8465
#include <CommonUtility.h>
using
namespace
cv
;
using
namespace
cv
::
dnn
;
namespace
migraphxSamples
{
void
blobFromImagesWithParams
(
InputArrayOfArrays
images_
,
OutputArray
blob_
,
const
Image2BlobParams
&
param
)
{
if
(
images_
.
kind
()
!=
_InputArray
::
STD_VECTOR_MAT
&&
images_
.
kind
()
!=
_InputArray
::
STD_ARRAY_MAT
&&
images_
.
kind
()
!=
_InputArray
::
STD_VECTOR_VECTOR
)
{
String
error_message
=
"The data is expected as vectors of vectors or vectors of matrices."
;
CV_Error
(
Error
::
StsBadArg
,
error_message
);
}
CV_CheckType
(
param
.
ddepth
,
param
.
ddepth
==
CV_32F
||
param
.
ddepth
==
CV_8U
,
"Blob depth should be CV_32F or CV_8U"
);
Size
size
=
param
.
size
;
std
::
vector
<
Mat
>
images
;
images_
.
getMatVector
(
images
);
CV_Assert
(
!
images
.
empty
());
int
nch
=
images
[
0
].
channels
();
Scalar
scalefactor
=
param
.
scalefactor
;
if
(
param
.
ddepth
==
CV_8U
)
{
CV_Assert
(
scalefactor
==
Scalar
::
all
(
1.0
)
&&
"Scaling is not supported for CV_8U blob depth"
);
CV_Assert
(
param
.
mean
==
Scalar
()
&&
"Mean subtraction is not supported for CV_8U blob depth"
);
}
for
(
size_t
i
=
0
;
i
<
images
.
size
();
i
++
)
{
Size
imgSize
=
images
[
i
].
size
();
if
(
size
==
Size
())
size
=
imgSize
;
if
(
size
!=
imgSize
)
{
if
(
param
.
paddingmode
==
DNN_PMODE_CROP_CENTER
)
{
float
resizeFactor
=
std
::
max
(
size
.
width
/
(
float
)
imgSize
.
width
,
size
.
height
/
(
float
)
imgSize
.
height
);
resize
(
images
[
i
],
images
[
i
],
Size
(),
resizeFactor
,
resizeFactor
,
INTER_LINEAR
);
Rect
crop
(
Point
(
0.5
*
(
images
[
i
].
cols
-
size
.
width
),
0.5
*
(
images
[
i
].
rows
-
size
.
height
)),
size
);
images
[
i
]
=
images
[
i
](
crop
);
}
else
{
if
(
param
.
paddingmode
==
DNN_PMODE_LETTERBOX
)
{
float
resizeFactor
=
std
::
min
(
size
.
width
/
(
float
)
imgSize
.
width
,
size
.
height
/
(
float
)
imgSize
.
height
);
int
rh
=
int
(
imgSize
.
height
*
resizeFactor
);
int
rw
=
int
(
imgSize
.
width
*
resizeFactor
);
resize
(
images
[
i
],
images
[
i
],
Size
(
rw
,
rh
),
INTER_LINEAR
);
int
top
=
(
size
.
height
-
rh
)
/
2
;
int
bottom
=
size
.
height
-
top
-
rh
;
int
left
=
(
size
.
width
-
rw
)
/
2
;
int
right
=
size
.
width
-
left
-
rw
;
copyMakeBorder
(
images
[
i
],
images
[
i
],
top
,
bottom
,
left
,
right
,
BORDER_CONSTANT
);
}
else
resize
(
images
[
i
],
images
[
i
],
size
,
0
,
0
,
INTER_LINEAR
);
}
}
Scalar
mean
=
param
.
mean
;
if
(
param
.
swapRB
)
{
std
::
swap
(
mean
[
0
],
mean
[
2
]);
std
::
swap
(
scalefactor
[
0
],
scalefactor
[
2
]);
}
if
(
images
[
i
].
depth
()
==
CV_8U
&&
param
.
ddepth
==
CV_32F
)
images
[
i
].
convertTo
(
images
[
i
],
CV_32F
);
images
[
i
]
-=
mean
;
multiply
(
images
[
i
],
scalefactor
,
images
[
i
]);
}
size_t
nimages
=
images
.
size
();
Mat
image0
=
images
[
0
];
CV_Assert
(
image0
.
dims
==
2
);
if
(
param
.
datalayout
==
DNN_LAYOUT_NCHW
)
{
if
(
nch
==
3
||
nch
==
4
)
{
int
sz
[]
=
{
(
int
)
nimages
,
nch
,
image0
.
rows
,
image0
.
cols
};
blob_
.
create
(
4
,
sz
,
param
.
ddepth
);
Mat
blob
=
blob_
.
getMat
();
Mat
ch
[
4
];
for
(
size_t
i
=
0
;
i
<
nimages
;
i
++
)
{
const
Mat
&
image
=
images
[
i
];
CV_Assert
(
image
.
depth
()
==
blob_
.
depth
());
nch
=
image
.
channels
();
CV_Assert
(
image
.
dims
==
2
&&
(
nch
==
3
||
nch
==
4
));
CV_Assert
(
image
.
size
()
==
image0
.
size
());
for
(
int
j
=
0
;
j
<
nch
;
j
++
)
ch
[
j
]
=
Mat
(
image
.
rows
,
image
.
cols
,
param
.
ddepth
,
blob
.
ptr
((
int
)
i
,
j
));
if
(
param
.
swapRB
)
std
::
swap
(
ch
[
0
],
ch
[
2
]);
split
(
image
,
ch
);
}
}
else
{
CV_Assert
(
nch
==
1
);
int
sz
[]
=
{
(
int
)
nimages
,
1
,
image0
.
rows
,
image0
.
cols
};
blob_
.
create
(
4
,
sz
,
param
.
ddepth
);
Mat
blob
=
blob_
.
getMat
();
for
(
size_t
i
=
0
;
i
<
nimages
;
i
++
)
{
const
Mat
&
image
=
images
[
i
];
CV_Assert
(
image
.
depth
()
==
blob_
.
depth
());
nch
=
image
.
channels
();
CV_Assert
(
image
.
dims
==
2
&&
(
nch
==
1
));
CV_Assert
(
image
.
size
()
==
image0
.
size
());
image
.
copyTo
(
Mat
(
image
.
rows
,
image
.
cols
,
param
.
ddepth
,
blob
.
ptr
((
int
)
i
,
0
)));
}
}
}
else
if
(
param
.
datalayout
==
DNN_LAYOUT_NHWC
)
{
int
sz
[]
=
{
(
int
)
nimages
,
image0
.
rows
,
image0
.
cols
,
nch
};
blob_
.
create
(
4
,
sz
,
param
.
ddepth
);
Mat
blob
=
blob_
.
getMat
();
int
subMatType
=
CV_MAKETYPE
(
param
.
ddepth
,
nch
);
for
(
size_t
i
=
0
;
i
<
nimages
;
i
++
)
{
const
Mat
&
image
=
images
[
i
];
CV_Assert
(
image
.
depth
()
==
blob_
.
depth
());
CV_Assert
(
image
.
channels
()
==
image0
.
channels
());
CV_Assert
(
image
.
size
()
==
image0
.
size
());
if
(
param
.
swapRB
)
{
Mat
tmpRB
;
cvtColor
(
image
,
tmpRB
,
COLOR_BGR2RGB
);
tmpRB
.
copyTo
(
Mat
(
tmpRB
.
rows
,
tmpRB
.
cols
,
subMatType
,
blob
.
ptr
((
int
)
i
,
0
)));
}
else
image
.
copyTo
(
Mat
(
image
.
rows
,
image
.
cols
,
subMatType
,
blob
.
ptr
((
int
)
i
,
0
)));
}
}
else
CV_Error
(
Error
::
StsUnsupportedFormat
,
"Unsupported data layout in blobFromImagesWithParams function."
);
}
}
Src/Utility/CommonUtility.h
0 → 100644
View file @
1eff8465
// 常用工具
#ifndef __COMMON_UTILITY_H__
#define __COMMON_UTILITY_H__
#include <CommonDefinition.h>
using
namespace
cv
;
using
namespace
cv
::
dnn
;
namespace
migraphxSamples
{
enum
DataLayout
{
DNN_LAYOUT_UNKNOWN
=
0
,
DNN_LAYOUT_ND
=
1
,
//!< OpenCV data layout for 2D data.
DNN_LAYOUT_NCHW
=
2
,
//!< OpenCV data layout for 4D data.
DNN_LAYOUT_NCDHW
=
3
,
//!< OpenCV data layout for 5D data.
DNN_LAYOUT_NHWC
=
4
,
//!< Tensorflow-like data layout for 4D data.
DNN_LAYOUT_NDHWC
=
5
,
//!< Tensorflow-like data layout for 5D data.
DNN_LAYOUT_PLANAR
=
6
,
//!< Tensorflow-like data layout, it should only be used at tf or tflite model parsing.
};
enum
ImagePaddingMode
{
DNN_PMODE_NULL
=
0
,
// !< Default. Resize to required input size without extra processing.
DNN_PMODE_CROP_CENTER
=
1
,
// !< Image will be cropped after resize.
DNN_PMODE_LETTERBOX
=
2
,
// !< Resize image to the desired size while preserving the aspect ratio of original image.
};
struct
Image2BlobParams
{
Image2BlobParams
()
:
scalefactor
(
Scalar
::
all
(
1.0
)),
size
(
Size
()),
mean
(
Scalar
()),
swapRB
(
false
),
ddepth
(
CV_32F
),
datalayout
(
DNN_LAYOUT_NCHW
),
paddingmode
(
DNN_PMODE_NULL
)
{}
Image2BlobParams
(
const
Scalar
&
scalefactor_
,
const
Size
&
size_
,
const
Scalar
&
mean_
,
bool
swapRB_
,
int
ddepth_
,
DataLayout
datalayout_
,
ImagePaddingMode
mode_
)
:
scalefactor
(
scalefactor_
),
size
(
size_
),
mean
(
mean_
),
swapRB
(
swapRB_
),
ddepth
(
ddepth_
),
datalayout
(
datalayout_
),
paddingmode
(
mode_
)
{}
Scalar
scalefactor
;
//!< scalefactor multiplier for input image values.
Size
size
;
//!< Spatial size for output image.
Scalar
mean
;
//!< Scalar with mean values which are subtracted from channels.
bool
swapRB
;
//!< Flag which indicates that swap first and last channels
int
ddepth
;
//!< Depth of output blob. Choose CV_32F or CV_8U.
DataLayout
datalayout
;
//!< Order of output dimensions. Choose DNN_LAYOUT_NCHW or DNN_LAYOUT_NHWC.
ImagePaddingMode
paddingmode
;
//!< Image padding mode. @see ImagePaddingMode.
};
void
blobFromImagesWithParams
(
InputArrayOfArrays
images_
,
OutputArray
blob_
,
const
Image2BlobParams
&
param
);
}
#endif
Src/main.cpp
View file @
1eff8465
...
@@ -43,12 +43,12 @@ int main()
...
@@ -43,12 +43,12 @@ int main()
for
(
int
i
=
0
;
i
<
predictions
.
size
();
++
i
)
for
(
int
i
=
0
;
i
<
predictions
.
size
();
++
i
)
{
{
// 一个batch中第i幅图像的结果
// 一个batch中第i幅图像的结果
printf
(
"========== %d result ==========
\n
"
,
i
);
LOG_INFO
(
stdout
,
"========== %d result ==========
\n
"
,
i
);
std
::
vector
<
migraphxSamples
::
ResultOfPrediction
>
resultOfPredictions
=
predictions
[
i
];
std
::
vector
<
migraphxSamples
::
ResultOfPrediction
>
resultOfPredictions
=
predictions
[
i
];
for
(
int
j
=
0
;
j
<
resultOfPredictions
.
size
();
++
j
)
for
(
int
j
=
0
;
j
<
resultOfPredictions
.
size
();
++
j
)
{
{
migraphxSamples
::
ResultOfPrediction
prediction
=
resultOfPredictions
[
j
];
migraphxSamples
::
ResultOfPrediction
prediction
=
resultOfPredictions
[
j
];
printf
(
"label:%d,confidence:%f
\n
"
,
prediction
.
label
,
prediction
.
confidence
);
LOG_INFO
(
stdout
,
"label:%d,confidence:%f
\n
"
,
prediction
.
label
,
prediction
.
confidence
);
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment