发布者:Wei Wei,TensorFlow开发者倡导者
从低分辨率的对应图像中恢复高分辨率(HR)的任务通常被称为单图像超分辨率(SISR)。虽然插值方法,如双线性或立方体插值,可以用来对低分辨率的图像进行超采样,但所得到的图像质量通常不太吸引人。深度学习,特别是生成对抗网络,已经成功地应用于生成更多的照片逼真的图像,例如,SRGAN和ESRGAN。在这篇博客中,我们将使用来自TensorFlow Hub的预训练的ESRGAN模型,并在Android应用中使用TensorFlow Lite生成超分辨率图像。最终的应用程序看起来如下,完整的代码已经发布在TensorFlow的例子repo中供参考。
首先,我们可以方便地从TFHub加载ESRGAN模型,并轻松将其转换为TFLite模型。注意,这里我们使用的是动态范围量化,并将输入图像尺寸固定为50x50。转换后的模型已经上传到TFHub,但我们想演示一下如何做,以防你想自己转换(例如,在你自己的应用程序中尝试不同的输入尺寸)。
model = hub.load("https://tfhub.dev/captain-pool/esrgan-tf2/1")concrete_func = model.signatures[tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY]concrete_func.inputs[0].set_shape([1, 50, 50, 3])converter = tf.lite.TFLiteConverter.from_concrete_functions([concrete_func])converter.optimizations = [tf.lite.Optimize.DEFAULT]tflite_model = converter.convert()# Save the TF Lite model.with tf.io.gfile.GFile('ESRGAN.tflite', 'wb') as f: f.write(tflite_model)esrgan_model_path = './ESRGAN.tflite'
你也可以在转换时不硬编码输入尺寸而转换模型,然后在运行时调整输入张量的大小,因为TFLite现在支持动态形状的输入。更多信息请参考这个例子。
一旦模型转换完成,我们可以快速验证ESRGAN TFLite模型确实比双三次插值生成的图像好得多。如果你想更好地了解这个模型,我们还有另一个关于ESRGAN的教程。
lr = cv2.imread(test_img_path)lr = cv2.cvtColor(lr, cv2.COLOR_BGR2RGB)lr = tf.expand_dims(lr, axis=0)lr = tf.cast(lr, tf.float32)# Load TFLite model and allocate tensors.interpreter = tf.lite.Interpreter(model_path=esrgan_model_path)interpreter.allocate_tensors()# Get input and output tensors.input_details = interpreter.get_input_details()output_details = interpreter.get_output_details()# Run the modelinterpreter.set_tensor(input_details[0]['index'], lr)interpreter.invoke()# Extract the output and postprocess itoutput_data = interpreter.get_tensor(output_details[0]['index'])sr = tf.squeeze(output_data, axis=0)sr = tf.clip_by_value(sr, 0, 255)sr = tf.round(sr)sr = tf.cast(sr, tf.uint8)
![]() |
| LR:从DIV2K数据集中的蝴蝶图像中裁剪出来的低分辨率输入图像。ESRGAN (x4):使用ESRGAN模型生成的超分辨率输出图像,放大率=4。Bicubic:使用二元插值生成的输出图像。从这里可以看出,二元插值生成的图像比ESRGAN生成的图像要模糊得多。PSNR在ESRGAN生成的图像上也更高。 |
你可能已经知道,TensorFlow Lite是在边缘设备上用TensorFlow模型运行推理的官方框架,并被部署在全球超过40亿的边缘设备上,支持Android、iOS、基于Linux的物联网设备和微控制器。你可以在Java、C/C++或其他语言中使用TFLite来构建Android应用程序。在这篇博客中,我们将使用TFLite的C语言API,因为很多开发者都要求提供这样一个例子。
我们将TFLite C头文件和库分布在预构建的AAR文件中(核心库和GPU库)。为了正确设置Android的构建,我们需要做的第一件事是下载AAR文件并提取头文件和共享库。请看一下在download.gradle文件中是如何完成的。
由于我们使用Android NDK来构建应用程序(NDK r20被确认可以工作),我们需要让Android Studio知道应该如何处理本地文件。这在CMakeList.txt文件中完成。
我们在应用中包含了3个样本图像,所以用户可能会很容易地多次运行同一个模型,这意味着我们需要缓存解释器以获得更好的效率。这是在解释器成功创建后,通过将解释器指针从C++代码传递给Java代码来实现的。
extern "C" JNIEXPORT jlong JNICALLJava_org_tensorflow_lite_examples_superresolution_MainActivity_initWithByteBufferFromJNI(JNIEnv *env, jobject thiz, jobject model_buffer, jboolean use_gpu) { const void *model_data = static_cast<void *>(env->GetDirectBufferAddress(model_buffer)); jlong model_size_bytes = env->GetDirectBufferCapacity(model_buffer); SuperResolution *super_resolution = new SuperResolution(model_data, static_cast<size_t>(model_size_bytes), use_gpu); if (super_resolution->IsInterpreterCreated()) { LOGI("Interpreter is created successfully"); return reinterpret_cast<jlong>(super_resolution); } else { delete super_resolution; return 0; }}
一旦解释器被创建,运行模型是相当直接的,因为我们可以按照TFLite C的API文档进行操作。我们首先需要仔细提取每个像素的RGB值。现在我们可以运行解释器了。
// Feed input into modelstatus = TfLiteTensorCopyFromBuffer(input_tensor, input_buffer, kNumberOfInputPixels * kImageChannels * sizeof(float));…...// Run the interpreterstatus = TfLiteInterpreterInvoke(interpreter_);…...// Extract the output tensor dataconst TfLiteTensor* output_tensor = TfLiteInterpreterGetOutputTensor(interpreter_, 0);float output_buffer[kNumberOfOutputPixels * kImageChannels];status = TfLiteTensorCopyToBuffer(output_tensor, output_buffer, kNumberOfOutputPixels * kImageChannels * sizeof(float));…...
有了模型的结果,我们就可以把RGB值重新打包到每个像素中。
这就是你所拥有的。一个使用TFLite在设备上生成超分辨率图像的参考Android应用程序。更多的细节可以在代码库中找到。希望这对那些开始在C/C++中使用TFLite来建立惊人的ML应用的Android开发者来说是有用的参考。
反馈意见
我们期待着看到你用TensorFlow Lite构建的东西,以及听到你的反馈。请直接与我们分享您的使用案例,或在Twitter上使用#TFLite和#PoweredByTF标签。要报告错误和问题,请在GitHub上与我们联系。
鸣谢
作者要感谢@captain__pool将ESRGAN模型上传到TFHub,感谢Tian Lin和Jared Duke提供的有益反馈。
[1] Christian Ledig, Lucas Theis, Ferenc Huszar, Jose Caballero, Andrew Cunningham, Alejandro Acosta, Andrew Aitken, Alykhan Tejani, Johannes Totz, Zehan Wang, Wenzhe Shi.2016.使用生成式对抗网络的照片真实性单幅图像超分辨率。
[2] Xintao Wang, Ke Yu, Shixiang Wu, Jinjin Gu, Yihao Liu, Chao Dong, Chen Change Loy, Yu Qiaoqiao, Xiaoou Tang.2018.ESRGAN: Enhanced Super-Resolution Generative Adversarial Networks.
[3]基于Tensorflow 2.x的EDSR、WDSR和SRGAN的实现,用于单张图像的超级分辨率
[5] Eirikur Agustsson, Radu Timofte.2017.NTIRE 2017年关于单幅图像超级分辨率的挑战。数据集和研究。

