# 超分辨率重建 ## 模型简介 图像超分辨率重建技术是指设计并采用某种算法,使得可以通过观测到的低分辨率(Low Resolution, LR)图像重建出近似真实高分辨率(High Resolution , HR)图像的方法。本次部署的超分模型是2016提出的ESPCN网络,主要通过一系列卷积层不断提取图像特征,最后通过sub-pixel亚像素卷积层提高图像分辨率,从而实现图像超分辨率的方法。ESPCN网络结构如下图所示: ![Superresolution_01](../Images/Superresolution_01.png) 本示例采用onnx官方提供的ESPCN模型示例:https://github.com/onnx/models/tree/main/vision/super_resolution/sub_pixel_cnn_2016,将super.onnx文件保存在Resource\Models\Super_Resolution文件夹下。 ## 预处理 在将数据输入到模型之前,需要对输入图像做如下预处理操作: ​ 1.图像尺寸resize到224x224 ​ 2.分离图像通道,变为B、G、R三个通道图像; ​ 3.BGR格式通过公式转换为YCrCb格式,得到Y、Cb、Cr三通道图像; ​ 4.只处理Y通道图像,转换数据排布为NCHW; 本示例代码采用了OpenCV实现预处理操作: ```python def bgr_to_ycbcr(B, G, R): Y = 0.299 * R + 0.587 * G + 0.114 * B Cr = (R - Y) * 0.713 + 128 Cb = (B - Y) * 0.564 + 128 return Y, Cr, Cb def Preprocessing(pathOfImage): orig_img = cv2.imread(pathOfImage, cv2.IMREAD_COLOR) # cv2.IMREAD_COLOR:彩色图,cv2.IMREAD_GRAYSCALE:灰度图 img = cv2.resize(orig_img, (224,224)) # 调整图像为固定尺寸224x224 bImg, gImg, rImg = cv2.split(img) # 分离图片 img_y_0, img_cr, img_cb = bgr_to_ycbcr(bImg, gImg, rImg) # bgr转换为YCbCr img_ndarray = np.asarray(img_y_0) # 复制img_y_0对象,转换为array([224,224]) img_y = np.reshape(img_ndarray, (1,1,224,224)) # 改变数组形状,满足模型输入,变为(1,1,224,224) 转换为(N,C,H,W)格式 img_y = img_y.astype(np.float32) / 255.0 # unit8转换成float32 return img_y, img_cr, img_cb ``` ## 推理 完成图像预处理后,就开始执行推理,得到推理结果。 ```python if __name__ == '__main__': # 加载模型 model = migraphx.parse_onnx("../../Resource/Models/Super/super.onnx") inputName = model.get_parameter_names() inputShape = model.get_parameter_shapes() print("inputName:{0} \ninputShape:{1}".format(inputName, inputShape)) # 编译模型 model.compile(t=migraphx.get_target("gpu"), device_id=0) # device_id: 设置GPU设备,默认为0号设备 # 图像预处理 pathOfImage = "../../Resource/Images/cat.jpg" img_Y, img_cr, img_cb = Preprocessing(pathOfImage) # 模型推理结果 results = model.run({"input": img_Y}) # 获取输出节点属性 result = results[0] # 获取第一个输出节点的数据,migraphx.argument类型 outputShape = result.get_shape() # 输出节点的shape,migraphx.shape类型 outputSize = outputShape.lens() # 每一维大小,维度顺序为(N,C,H,W) numberOfOutput = outputShape.elements() # 输出节点元素的个数 data = np.array(results[0])[0] img_out_y = np.uint8((data * 255.0).clip(0, 255)[0]) # 将浮点型数据转换为0-255之间整型数据 # 将YCbCr格式转换为BGR格式,再将三通道合并到一起,得到重建图像 img_cr = cv2.resize(img_cr, (672, 672)) img_cb = cv2.resize(img_cb, (672, 672)) final_img = ycbcr_to_bgr(img_out_y, img_cr, img_cb) cv2.imwrite("output.jpg", final_img) # 保存超分辨率重建图像的结果 ``` 1.Preprocessing函数返回Y、Cr、Cb三通道图像,只将Y通道图像作为输入数据,通过执行model.run({"input": img_Y})得到推理结果,因为只有输入一张图片,所以只通过results[0]获取第一个输出节点的数据即可。 2.该模型只处理Y通道图像,得到推理结果之后,再通过ycrcb_to_bgr()函数将YCrCb格式转换为BGR格式,转换公式采用的是opencv官方提供的公式,链接:https://docs.opencv.org/3.4.11/de/d25/imgproc_color_conversions.html,最后再将三通道合并到一起,得到最终的重建图像。 ## 运行示例 1.参考《MIGraphX教程》中的安装方法安装MIGraphX并设置好PYTHONPATH 2.安装依赖: ``` # 进入migraphx samples工程根目录 cd # 进入示例程序目录 cd Python/Super_Resolution # 安装依赖 pip install -r requirements.txt ``` 3.在Python/Super_Resolution目录下执行如下命令运行该示例程序: ```python # 运行示例 python Espcn.py ``` 输出结果如下,左图为原图,右图为重建过后的图像,分辨率提高了三倍。 ![Superresolution_03](../Images/Superresolution_03.png)