文章介绍
图片超分是指通过硬件或软件算法将一幅低分辨率的图像恢复生成高分辨率图像,本文介绍了基于 高通Snapdragon Neural Processing Engine SDK和SESR模型实现一个图片超分功能的应用。该应用的所有源代码都可以在https://github.com/quic/qidk/tree/master/Solutions/VisionSolution2-ImageSuperResolution上获得。
我们使用Snapdragon® 8 Gen 2 的Android手机验证测试这些代码,实际上这些示例代码在任何支持Snapdragon Neural Processing Engine SDK的手机上都可以运行,一次编写多次部署。
这里我们使用的模型为SESR, 原始论文《Collapsible Linear Blocks for Super-Efficient Super Resolution》(https://arxiv.org/abs/2103.09404) ,SESR网络建立了一种新的高效超分辨率技术,它是基于CNNs的线性过参数化,并为SISR创建了一个有效的模型体系结构。 SESR实现了与最先进的模型相似或更好的图像质量,同时需要减少2倍至330倍的Multiply-Accumulate (MAC)操作。如何使能SESR模型可以在高通AIMET Model Zoo获得 (https://github.com/quic/aimet-model-zoo/#pytorch-model-zoo)。
前置条件
- 安卓手机,推荐Snapdragon® 8 Gen 2系列手机
- 在PC上下载并设置好Qualcomm® Neural Processing SDK
相关步骤参考Snapdragon Neural Processing Engine SDK: SNPE Setup
- Android Studio导入示例项目
- Android NDK构建本地代码
- 一台Linux机器
操作步骤:
1. 将模型转换为DLC的步骤
- 确保完成本章开头提到的前期配置
- 注意:作为一般做法,请先将PYTORCH型号转换为ONNX,然后将ONNX转换为DLC。
- 要将PYTORCH转换为ONNX,请clone AIMET-MODEL-ZOO repo。在以下步骤中,我们通过repo指向此header。
git clone https://github.com/quic/aimet-model-zoo.git
cd aimet-model-zoo/
git reset --hard b7a21a02f3a33387548f376bdf7831b4cc5cc41b
- 在此python文件中进行以下更改:inference.py。路径:aimet-model-zoo\zoo_arch\examples\superres\utils\reaction.py。
- 注解如下import:
#from aimet_torch.quantsim import QuantizationSimModel
#from aimet_torch.qc_quantize_op import QuantScheme
- 将如下码块:
with torch.no_grad():
sr_img = model(img_lr.unsqueeze(0).to(device)).squeeze(0)
images_sr.append(post_process(sr_img))
替换为
# With this block
with torch.no_grad():
sr_img = model(img_lr.unsqueeze(0).to(device)).squeeze(0)
input_shape = [1, 3, 128, 128]
input_data = torch.randn(input_shape)
torch.onnx.export(model, input_data, "super_resolution.onnx", export_params=True,
opset_version=11, do_constant_folding=True, input_names = ['lr'], output_names = ['sr'])
images_sr.append(post_process(sr_img))
- 在此jupyter notebook superres_quanteval.ipynb中进行以下更改。路径:aimet-model-zoo\zoo_arch\examples\superres\notebooks\superres_quanteval.ipynb
- 注释如下import:
#from aimet_torch.quantsim import QuantizationSimModel
#from aimet_torch.qc_quantize_op import QuantScheme
- 如上所述设置以下变量
- DATA_DIR = './data'
- DATASET_NAME = 'Set14'
- use_cuda = False
- model_index = 6
- 创建目录aimet-model-zoo\zoo_arch\examples\superres\notebooks\data\Set14,并将任何一个图像(.jpg)放在此文件夹中。这是运行superres_quanteval.ipynb所必需的。
- 在“Create model instance and load weights”一节中,注释除“model_original_fp32”之外的所有设置
- 在“Model Inference”部分中,注释除“IMAGES_SR_original_fp32”以外的所有设置
- 请忽略superres_quanteval.ipynb中的最后一块代码
- 运行superres_quanteval.ipynb。在inference.py中所做的更改将用于superres_quanteval.ipynb
- 在运行脚本时,代码将自动从AIMET model zoo下载预先训练好的“release_sesr-xl_2x.tar.gz”:https://github.com/quic/aimet-model-zoo/releases/tag/sesr-checkpoint-pytorch
- 通过以上步骤,应生成ONNX模型。
- 使用以下命令将ONNX模型转换为DLC。请注意,我们在上面的代码中锁定了输入维度
snpe-onnx-to-dlc --input_network super_resolution.onnx --output_path super_resolution_sesr_opt.dlc
- 将DLC打包到application/src/<Package_name>/assets文件夹中
2. 代码实现过程
代码架构:
- demo:包含演示视频、GIF
- doc:包含当前项目的文档/图像
- snpe版本:包含SDK版本二进制文件。如果随着时间的推移,SDK版本发生重大变化,建议**重新生成DLC并替换SDK版本二进制文件**
- superresolution:包含标准Android应用程序格式的源文件。
模型初始化
在使用模型之前,必须先对其进行初始化。初始化过程需要以下参数:
- Context:Activity 或Application context
- ModelName:要使用的Model的名称
- String runtime:一个特定的runtime(run_time可选择的有CPU、GPU_FLOAT16和DSP)。
package com.qcom.enhancement;
...
public class SNPEActivity extends AppCompatActivity {
public static final String ENHANCEMENT_SNPE_MODEL_NAME = "enlight_axisQ_cached";
...
public Result<EnhancedResults> process(Bitmap bmps, String run_time){
....
enhancOps = new EnhancOps();
// Model is initialised in below fun. Model config been set as per AI SDK.
boolean enhancementInited = enhancOps.initializingModel(this, ENHANCEMENT_SNPE_MODEL_NAME, run_time);
}
}
运行Model
初始化Model后,可以传递要处理的bitmaps列表。
如前所述,DLC模型可以使用特定的图像大小。因此,在将图像传递给DLC之前,我们需要将输入图像调整为DLC接受的大小
此源代码使用运算符来帮助用户进行图像预处理。sizeOperation参数为Process方法,可用于预处理图像,如下所示:
注意:如果用户已经传递了确切的输入大小240x320 sizeOperation应设置为1。
- 0:没有更改
- 1:if(IMAGE_WITH=INPUT_HEIGHT and IMAGE_HEIGHT=INPUT_WIDTH)(用户根据型号要求传递输入大小)
- 2:if((IMAGE_WITH/INPUT_WIDTH)=(IMAGE_HEIGHT/INPUT_HEIGHT))(需要缩放输入)
int sizeOperation = 1;
// Function to process the enhancement operation
result = enhancOps.process(new Bitmap[] {bmps}, sizeOperation);
Results
- 处理后的结果在普通类型为EnhancedResults的Result对象中返回。
- EnhancedResults包含一个bitmaps数组,每个bitmaps表示一个增强过程(在示例中只有一个bitmaps)。
- 除了此列表之外,还有用于获取性能信息的inferenceTime进程。
Release
由于Model初始化过程发生在native端,因此不会进行内存回收;因此,您需要在结束之后释放它。
enhancOps.freeNetwork();
3. 整体执行操作流程
- Clone QIDK repo。
- 使用上述步骤生成DLC(super_resolution_sesr_opt.dlc)
- 将Qualcomm Developer Network发布的“Qualcomm Neural Processing SDK for AI”中android文件夹中的“snpe-release.aar”文件复制到此文件夹中:VisionSolution2-ImageSuperResolution\snpe-release\
- 将步骤2中生成的DLC复制到:VisionSolution2-ImageSuperResolution\superresolution\src\main\assets\ (super_resolution_sesr_opt.dlc)
- 导入文件夹VisionSolution2-ImageSuperResolution作为Android Studio中的项目
- 编译项目。
- 应生成APK文件:superresolution-debug.apk
- 准备Qualcomm Innovators开发工具包以安装应用程序(不要在模拟器上运行APK)
如果未检测到未签名或已签名的DSP运行时,请检查logcat日志中的FastRPC错误。如果由于SELinux权限的原因,可能无法检测到DSP 运行时。请尝试以下命令来设置SE Linux权限。
adb disable-verity
adb reboot
adb root
adb remount
adb shell setenforce 0
- 9.安装和测试应用程序:superresolution-debug.apk
adb install -r -t enhancement-debug.apk
- 10.启动应用程序
以下是“图像超分”Android应用程序的基本操作
1. 从下拉列表中选择一个给定的图像
2. 选择运行时间以运行模型(CPU、GPU或DSP)
3. 在屏幕上观察模型的结果
4. 注意特定运行时的性能指标
演示视频和性能细节如下所示:
作者:戴忠忠,高通工程师