重命名 imgtobin 为 img2bin
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
# img2bin
|
||||
|
||||
img2bin能够生成模型推理所需的输入数据,以.bin格式保存。
|
||||
有两类数据,一类是图片数据,另一类是模型需要的第二个输入数据,如fasterrcnn的第二个输入是图片的shape信息。
|
||||
|
||||
## 环境准备
|
||||
|
||||
执行此脚本需要安装python3的opencv,**如已安装可跳过环境准备**。
|
||||
|
||||
1. 在root用户下更换源。
|
||||
```
|
||||
vim /etc/apt/sources.list
|
||||
```
|
||||
把原有的源更换为国内可用的源,arm源可参考 https://bbs.huaweicloud.com/forum/thread-61366-1-1.html 。
|
||||
|
||||
|
||||
源更新后,执行以下命令更新软件列表。
|
||||
|
||||
```
|
||||
apt-get update
|
||||
```
|
||||
|
||||
|
||||
|
||||
2. 安装python3的依赖。
|
||||
|
||||
```
|
||||
apt-get install python3-setuptools python3-dev build-essential python3-pip
|
||||
```
|
||||
```
|
||||
pip3 install enum34==1.1.6 future==0.17.1 funcsigs==1.0.2 unique protobuf numpy
|
||||
```
|
||||
|
||||
>**说明:**
|
||||
>
|
||||
> pip3 install安装有报错“SSLError”时,请使用:pip3 install --trusted-host pypi.org --trusted-host files.pythonhosted.org numpy==1.11.2 enum34==1.1.6 future==0.17.1 funcsigs==1.0.2 unique protobuf 安装依赖,表示可信赖的主机解决问题。
|
||||
|
||||
3. 安装opencv。
|
||||
|
||||
```
|
||||
pip3 install opencv_python
|
||||
```
|
||||
|
||||
## 获取脚本
|
||||
|
||||
1. 下载压缩包方式获取。
|
||||
|
||||
将 https://gitee.com/atlasdevelop/c7x_samples 仓中的脚本下载至服务器的任意目录。
|
||||
|
||||
例如存放路径为:$HOME/AscendProjects/img2bin。
|
||||
|
||||
2. 命令行使用git命令方式获取。
|
||||
|
||||
在命令行中:$HOME/AscendProjects目录下执行以下命令下载代码。
|
||||
|
||||
**git clone https://gitee.com/atlasdevelop/c7x_samples.git**
|
||||
|
||||
## 使用方法
|
||||
进入脚本所在目录。
|
||||
```
|
||||
cd $HOME/AscendProjects/img2bin
|
||||
```
|
||||
|
||||
### 第一类图片:
|
||||
- -i后跟**目录**表示转换图片。
|
||||
- 脚本会将 -i 后指定的图片目录下的所有图片按参数设置做相应的预处理,并以"文件名.bin"命名保存在-o指定的输出目录下。
|
||||
|
||||
```
|
||||
python3 img2bin.py -i ./images -w 416 -h 416 -f BGR -a NHWC -t uint8 -m [104,117,123] -c [1,1,1] -o ./out
|
||||
```
|
||||
|
||||
### 第二类:
|
||||
- -i后跟**文件路径**表示转换第二类数据。
|
||||
- 第二类数据,需要新建一个文件,文件模板为test.txt,"input_node"为数据,"shape"为数据的shape信息。
|
||||
- 第二类数据只需 -i、-t、-o三个参数。
|
||||
- 参数 -i 需要指定文件的路径,-t 需要指定数据类型,-o指定输出目录。
|
||||
|
||||
```
|
||||
python3 img2bin.py -i ./test.txt -t uint8 -o ./out
|
||||
```
|
||||
|
||||
## 参数说明
|
||||
|
||||
| 参数名 | 说明 |
|
||||
| - | - |
|
||||
| -i | 图片的输入目录或第二个输入的文件路径 |
|
||||
| -w | 输出图片宽 |
|
||||
| -h | 输出图片高 |
|
||||
| -f | 输出图片色彩格式,支持(BGR/RGB/YUV/GRAY) |
|
||||
| -a | 输出图片格式,支持(NCHW/NHWC) |
|
||||
| -t | 图片或第二个数据的输出数据类型,支持(float32/uint8/int32/uint32) |
|
||||
| -m | 减均值,默认为[0,0,0],顺序与图片色彩格式保持一致 <br>当色彩格式为yuv时,设置[0,0] <br>当色彩格式为gray时,设置[0] |
|
||||
| -c | 归一化,默认为 [1,1,1],顺序与图片色彩格式保持一致 <br>当色彩格式为yuv时,设置[1,1] <br>当色彩格式为gray时,设置[1] |
|
||||
| -o | 输出目录 |
|
||||
@@ -0,0 +1,234 @@
|
||||
# !/usr/bin/env python3
|
||||
# -*- coding: UTF-8 -*-
|
||||
#
|
||||
# =======================================================================
|
||||
#
|
||||
# Copyright (C) 2018, Hisilicon Technologies Co., Ltd. All Rights Reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1 Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2 Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3 Neither the names of the copyright holders nor the names of the
|
||||
# contributors may be used to endorse or promote products derived from this
|
||||
# software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# =======================================================================
|
||||
#
|
||||
import argparse
|
||||
import configparser
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(
|
||||
conflict_handler='resolve',
|
||||
description='''eg1: python3 imgtobin.py
|
||||
-i ./images -w 416 -h 416 -f BGR -a NCHW -m [104,117,123] -o ./out
|
||||
eg2: python3 imgtobin.py -i ./test.txt -t uint8''')
|
||||
parser.add_argument('-i', '--input', required=True, type=str, \
|
||||
help='folder of input image or file of other input.')
|
||||
parser.add_argument('-w', '--width', type=int, \
|
||||
help='resized image width before inference.')
|
||||
parser.add_argument('-h', '--height', type=int, \
|
||||
help='resized image height before inference.')
|
||||
parser.add_argument('-f', '--output_image_format', default='BGR', type=str, \
|
||||
help='output image format in (BGR/RGB/YUV/GRAY).')
|
||||
parser.add_argument('-a', '--output_format', default='NCHW', type=str, \
|
||||
help='output format in (NCHW/NHWC).')
|
||||
parser.add_argument('-t', '--output_type', required=True, type=str, \
|
||||
help='output type in (float32/uint8/int32/uint32).')
|
||||
parser.add_argument('-m', '--mean', default='[0, 0, 0]', \
|
||||
help='reduce mean for each channel.')
|
||||
parser.add_argument('-c', '--coefficient', default='[1, 1, 1]', \
|
||||
help='multiplying coefficients for each channel.')
|
||||
parser.add_argument('-o', '--output', default='./', \
|
||||
help='output path.')
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def eprint(*args, **kwargs):
|
||||
"""print error message to stderr
|
||||
"""
|
||||
print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
|
||||
def check_args(args):
|
||||
"""check console parameters according to restrictions.
|
||||
:return: True or False
|
||||
"""
|
||||
check_flag = True
|
||||
is_dir = True
|
||||
if os.path.isdir(args.input):
|
||||
#print(args)
|
||||
if not os.listdir(args.input):
|
||||
eprint('[ERROR] input image path=%r is empty.' % path)
|
||||
check_flag = False
|
||||
elif os.path.isfile(args.input):
|
||||
is_dir = False
|
||||
else:
|
||||
eprint('[ERROR] input path=%r does not exist.' % path)
|
||||
check_flag = False
|
||||
|
||||
if args.output_image_format not in ('BGR','RGB', 'YUV', 'GRAY'):
|
||||
eprint("ERROR:Convert to %d is not support"%(args.output_image_format))
|
||||
check_flag = False
|
||||
# if os.path.isfile(args.output_path):
|
||||
# eprint('[ERROR] argument output_path should be a folder.')
|
||||
# elif not os.path.exists(args.output_path):
|
||||
# os.makedirs(args.output_path)
|
||||
# if not 16 <= args.model_width <= 4096:
|
||||
# eprint('[ERROR] resized image width should between 16 and 4096.')
|
||||
# check_flag = False
|
||||
# if not 16 <= args.model_height <= 4096:
|
||||
# eprint('[ERROR] resized image height should between 16 andd 4096.')
|
||||
# check_flag = False
|
||||
return check_flag, is_dir
|
||||
|
||||
|
||||
def convert_img(args, input_img):
|
||||
if args.output_image_format == 'BGR':
|
||||
converted_input_img = input_img
|
||||
elif args.output_image_format == 'RGB':
|
||||
converted_input_img = cv.cvtColor(input_img, cv.COLOR_BGR2RGB)
|
||||
elif args.output_image_format == 'YUV':
|
||||
if input_img.shape[0] % 2 == 1:
|
||||
if input_img.shape[1] % 2 == 1:
|
||||
input_img = cv.resize(input_img, ((input_img.shape[0] + 1), (input_img.shape[1] + 1)))
|
||||
else:
|
||||
input_img = cv.resize(input_img, ((input_img.shape[0] + 1), input_img.shape[1]))
|
||||
elif input_img.shape[1] % 2 == 1:
|
||||
input_img = cv.resize(input_img, (input_img.shape[0], input_img.shape[1] + 1))
|
||||
converted_input_img = cv.cvtColor(input_img, cv.COLOR_BGR2YUV_I420)
|
||||
elif args.output_image_format == 'GRAY':
|
||||
converted_input_img = cv.cvtColor(input_img, cv.COLOR_BGR2GRAY)
|
||||
return converted_input_img
|
||||
|
||||
|
||||
def resize_img(args, input_img):
|
||||
resized_img = cv.resize(input_img, (args.width, args.height))
|
||||
return resized_img
|
||||
|
||||
|
||||
def change_type(args, input_img):
|
||||
if args.output_type == 'float32':
|
||||
change_type_img = input_img.astype(np.float32)
|
||||
elif args.output_type == 'int32':
|
||||
change_type_img = input_img.astype(np.int32)
|
||||
elif args.output_type == 'uint32':
|
||||
change_type_img = input_img.astype(np.uint32)
|
||||
else:
|
||||
change_type_img = input_img.astype(np.uint8)
|
||||
return change_type_img
|
||||
|
||||
|
||||
def mean(args, input_img):
|
||||
if isinstance (args.mean, str):
|
||||
args.mean = json.loads(args.mean)
|
||||
input_img = input_img.astype(np.float32)
|
||||
if args.output_image_format == 'GRAY':
|
||||
input_img[:, :] -= args.mean[0]
|
||||
elif args.output_image_format in ('BGR', 'RGB'):
|
||||
input_img[:, :, 0] -= args.mean[0]
|
||||
input_img[:, :, 1] -= args.mean[1]
|
||||
input_img[:, :, 2] -= args.mean[2]
|
||||
else:
|
||||
input_img[: int(args.width / 1.5), :] -= args.mean[0]
|
||||
input_img[int(args.width / 1.5) :, :: 2] -= args.mean[1]
|
||||
input_img[int(args.width / 1.5) :, 1: 2] -= args.mean[2]
|
||||
return input_img
|
||||
|
||||
|
||||
def coefficient(args, input_img):
|
||||
if isinstance (args.coefficient, str):
|
||||
args.coefficient = json.loads(args.coefficient)
|
||||
input_img = input_img.astype(np.float32)
|
||||
if args.output_image_format == 'GRAY':
|
||||
input_img[:, :] *= args.coefficient[0]
|
||||
elif args.output_image_format in ('BGR', 'RGB'):
|
||||
input_img[:, :, 0] *= args.coefficient[0]
|
||||
input_img[:, :, 1] *= args.coefficient[1]
|
||||
input_img[:, :, 2] *= args.coefficient[2]
|
||||
else:
|
||||
input_img[: int(args.width / 1.5), :] *= args.coefficient[0]
|
||||
input_img[int(args.width / 1.5) :, :: 2] *= args.coefficient[1]
|
||||
input_img[int(args.width / 1.5) :, 1: 2] *= args.coefficient[2]
|
||||
return input_img
|
||||
|
||||
|
||||
def change_format(args, input_img):
|
||||
if args.output_format == 'NCHW':
|
||||
if args.output_image_format in ('RGB', 'BGR'):
|
||||
change_format_img = input_img.transpose(2,0,1).copy()
|
||||
return change_format_img
|
||||
return input_img
|
||||
|
||||
|
||||
def mkdir_output(args):
|
||||
if not os.path.exists(args.output):
|
||||
os.makedirs(args.output)
|
||||
return
|
||||
|
||||
|
||||
def main():
|
||||
"""main function to receive params them change data to bin.
|
||||
"""
|
||||
args = get_args()
|
||||
ret,is_dir = check_args(args)
|
||||
if ret:
|
||||
if is_dir:
|
||||
img_names = os.listdir(args.input)
|
||||
for img_name in img_names:
|
||||
img_path = os.path.join(args.input, img_name)
|
||||
input_img = cv.imread(img_path)
|
||||
if args.output_image_format == 'YUV':
|
||||
resized_img1 = resize_img(args, input_img)
|
||||
converted_img = convert_img(args, resized_img1)
|
||||
mean_img = mean(args, converted_img)
|
||||
else:
|
||||
converted_img = convert_img(args, input_img)
|
||||
resized_img = resize_img(args, converted_img)
|
||||
mean_img = mean(args, resized_img)
|
||||
coefficient_img = coefficient(args, mean_img)
|
||||
change_type_img = change_type(args, coefficient_img)
|
||||
change_format_img = change_format(args, change_type_img)
|
||||
out_path = os.path.join(args.output, os.path.splitext(img_name)[0] + ".bin")
|
||||
mkdir_output(args)
|
||||
change_format_img.tofile(out_path)
|
||||
else:
|
||||
config = configparser.ConfigParser()
|
||||
config.read(args.input)
|
||||
input_node = json.loads(config['baseconf']['input_node'])
|
||||
shape = json.loads(config['baseconf']['shape'])
|
||||
input_node_np = np.array(input_node)
|
||||
change_type_img_info = change_type(args, input_node_np)
|
||||
img_info = np.reshape(change_type_img_info, shape)
|
||||
out_path = os.path.join(args.output, os.path.splitext(args.input)[0] + ".bin")
|
||||
mkdir_output(args)
|
||||
img_info.tofile(out_path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,3 @@
|
||||
[baseconf]
|
||||
input_node=[1200,1150,416,416]
|
||||
shape=[1,4]
|
||||
Reference in New Issue
Block a user