0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何使用TensorFlow Hub的ESRGAN模型来在安卓app中生成超分图片

Tensorflowers 来源:TensorFlow 作者:魏巍 2020-11-26 09:40 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

从一张低分辨率的图片生成一张对应的高分辨率图片的任务通常被称为单图超分(Single Image Super Resolution - SISR)。尽管可以使用传统的插值方法(如双线性插值和双三次插值)来完成这个任务,但是产生的图片质量却经常差强人意。深度学习,尤其是对抗生成网络 GAN,已经被成功应用在超分任务上,比如 SRGAN 和 ESRGAN 都可以生成比较真实的超分图片。那么在本文里,我们将介绍一下如何使用TensorFlow Hub上的一个预训练的 ESRGAN 模型来在一个安卓 app 中生成超分图片。最终的 app 效果如下图,我们也已经将完整代码开源给大家参考。

SRGAN
https://arxiv.org/abs/1609.04802

ESRGAN
https://arxiv.org/abs/1809.00219

完整代码
https://github.com/tensorflow/examples/tree/master/lite/examples/super_resolution

首先,我们可以很方便的从 TFHub 上加载 ESRGAN 模型,然后很容易的将其转化为一个 TFLite 模型。注意在这里我们使用了动态范围量化(dynamic range quantization),并将输入图片的尺寸固定在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'

TFHub
https://hub.tensorflow.google.cn/

TFHub(转化后模型)
https://hub.tensorflow.google.cn/captain-pool/lite-model/esrgan-tf2/1

现在 TFLite 已经支持动态大小的输入,所以你也可以在模型转化的时候不指定输入图片的大小,而在运行的时候动态指定。如果你想使用动态输入大小,请参考这个例子。

例子
https://github.com/tensorflow/tensorflow/blob/c58c88b23122576fc99ecde988aab6041593809b/tensorflow/lite/python/lite_test.py#L529-L560

模型转化完之后,我们可以很快验证 ESRGAN 生成的超分图片质量确实比双三次插值要好很多。如果你想更多的了解 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 model interpreter.set_tensor(input_details[0]['index'], lr) interpreter.invoke() # Extract the output and postprocess it output_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)

教程
https://tensorflow.google.cn/hub/tutorials/image_enhancing

LR: 输入的低分辨率图片,该图从 DIV2K 数据集中的一张蝴蝶图片中切割出来. ESRGAN (x4): ESRGAN 模型生成的超分图片,单边分辨率提升4倍. Bicubic: 双三次插值生成图片. 在这里大家可以很容易看出来,双三次插值生成的图片要比 ESRGAN 模型生成的超分图片模糊很多

你可能已经知道,TensorFlow Lite 是 TensorFlow 用于在端侧运行的官方框架,目前全球已有超过40亿台设备在运行 TFLite,它可以运行在安卓,iOS,基于 LinuxIoT 设备以及微处理器上。你可以使用 Java, C/C++ 或其他编程语言来运行 TFLite。在这篇文章中,我们将使用 TFLite C API,因为有许多的开发者表示希望我们能提供这样一个范例。

DIV2K
https://data.vision.ee.ethz.ch/cvl/DIV2K/

Java, C/C++
https://tensorflow.google.cn/lite/guide/android

TFLite C API
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/c/c_api.h

我们在预先编译好的 AAR 文件中包含了 TFLite C API需要的头文件和库 (包括核心库和 GPU 库)。为了正确的设置好 Android 项目,我们首先需要下载两个 JAR 文件并将相应的头文件和库抽取出来。我们可以在一个 download.gradle 文件中定义这些任务,然后将这些任务导入 build.gradle。下面我们先定义下载 TFLite JAR 文件的两个任务:

task downloadTFLiteAARFile() { download { src "https://bintray.com/google/tensorflow/download_file?file_path=org%2Ftensorflow%2Ftensorflow-lite%2F2.3.0%2Ftensorflow-lite-2.3.0.aar" dest "${project.rootDir}/libraries/tensorflow-lite-2.3.0.aar" overwrite false retries 5 } } task downloadTFLiteGPUDelegateAARFile() { download { src "https://bintray.com/google/tensorflow/download_file?file_path=org%2Ftensorflow%2Ftensorflow-lite-gpu%2F2.3.0%2Ftensorflow-lite-gpu-2.3.0.aar" dest "${project.rootDir}/libraries/tensorflow-lite-gpu-2.3.0.aar" overwrite false retries 5 } }

AAR 文件
https://tensorflow.google.cn/lite/guide/android#use_tflite_c_api

然后我们定义另一个任务来讲头文件和库解压然后放到正确的位置:

task fetchTFLiteLibs() { copy { from zipTree("${project.rootDir}/libraries/tensorflow-lite-2.3.0.aar") into "${project.rootDir}/libraries/tensorflowlite/" include "headers/tensorflow/lite/c/*h" include "headers/tensorflow/lite/*h" include "jni/**/libtensorflowlite_jni.so" } copy { from zipTree("${project.rootDir}/libraries/tensorflow-lite-gpu-2.3.0.aar") into "${project.rootDir}/libraries/tensorflowlite-gpu/" include "headers/tensorflow/lite/delegates/gpu/*h" include "jni/**/libtensorflowlite_gpu_jni.so" }

因为我们是用安卓 NDK 来编译这个 app,我们需要让 Android Studio 知道如何处理对应的原生文件。我们在 CMakeList.txt 文件中这样写:

set(TFLITE_LIBPATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../../libraries/tensorflowlite/jni") set(TFLITE_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/../../../../libraries/tensorflowlite/headers") set(TFLITE_GPU_LIBPATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../../libraries/tensorflowlite-gpu/jni") set(TFLITE_GPU_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/../../../../libraries/tensorflowlite-gpu/headers") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14") set(CMAKE_CXX_STANDARD 14) add_library(SuperResolution SHARED SuperResolution_jni.cpp SuperResolution.cpp) add_library(lib_tensorflowlite SHARED IMPORTED) set_target_properties(lib_tensorflowlite PROPERTIES IMPORTED_LOCATION ${TFLITE_LIBPATH}/${ANDROID_ABI}/libtensorflowlite_jni.so) add_library(lib_tensorflowlite_gpu SHARED IMPORTED) set_target_properties(lib_tensorflowlite_gpu PROPERTIES IMPORTED_LOCATION ${TFLITE_GPU_LIBPATH}/${ANDROID_ABI}/libtensorflowlite_gpu_jni.so) find_library(log-lib log) include_directories(${TFLITE_INCLUDE}) target_include_directories(SuperResolution PRIVATE ${TFLITE_INCLUDE}) include_directories(${TFLITE_GPU_INCLUDE}) target_include_directories(SuperResolution PRIVATE ${TFLITE_GPU_INCLUDE}) target_link_libraries(SuperResolution android lib_tensorflowlite lib_tensorflowlite_gpu ${log-lib})

我们在 app 里包含了3个示例图片,这样用户可能会运行同一个模型多次,这意味着为了提高运行效率,我们需要将 TFLite 解释执行器进行缓存。这一点我们可以在解释执行器成功建立后通过将其指针从 C++ 传回到 Java 来实现:

extern "C" JNIEXPORT jlong JNICALL Java_org_tensorflow_lite_examples_superresolution_MainActivity_initWithByteBufferFromJNI(JNIEnv *env, jobject thiz, jobject model_buffer, jboolean use_gpu) { const void *model_data = static_cast(env->GetDirectBufferAddress(model_buffer)); jlong model_size_bytes = env->GetDirectBufferCapacity(model_buffer); SuperResolution *super_resolution = new SuperResolution(model_data, static_cast(model_size_bytes), use_gpu); if (super_resolution->IsInterpreterCreated()) { LOGI("Interpreter is created successfully"); return reinterpret_cast(super_resolution); } else { delete super_resolution; return 0; } }

解释执行器建立之后,运行模型实际上就非常简单了,我们只需要按照 TFLite C API 来就好。不过我们需要注意的是如何从每个像素中抽取 RGB 值:

// Extract RGB values from each pixel float input_buffer[kNumberOfInputPixels * kImageChannels]; for (int i = 0, j = 0; i < kNumberOfInputPixels; i++) { // Alpha is ignored input_buffer[j++] = static_cast((lr_img_rgb[i] >> 16) & 0xff); input_buffer[j++] = static_cast((lr_img_rgb[i] >> 8) & 0xff); input_buffer[j++] = static_cast((lr_img_rgb[i]) & 0xff); }

TFLite C API
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/c/c_api.h

运行完模型后我们需要再将 RGB 值再打包进每个像素:

// Postprocess the output from TFLite int clipped_output[kImageChannels]; auto rgb_colors = std::make_unique(kNumberOfOutputPixels); for (int i = 0; i < kNumberOfOutputPixels; i++) { for (int j = 0; j < kImageChannels; j++) { clipped_output[j] = std::max(0, std::min(255, output_buffer[i * kImageChannels + j])); } // When we have RGB values, we pack them into a single pixel. // Alpha is set to 255. rgb_colors[i] = (255u & 0xff) << 24 | (clipped_output[0] & 0xff) << 16 | (clipped_output[1] & 0xff) << 8 | (clipped_output[2] & 0xff); }

那么到这里我们就完成了这个 app 的关键步骤,我们可以用这个 app 来生成超分图片。您可以在对应的代码库中看到更多信息。我们希望这个范例能作为一个好的参考来帮助刚刚起步的开发者更快的掌握如何使用 TFLite C/C++ API 来搭建自己的机器学习 app。

对应的代码库中
https://github.com/tensorflow/examples/tree/master/lite/examples/super_resolution

致谢

作者十分感谢 @captain__pool 将他实现的 ESRGAN 模型上传到 TFHub, 以及 TFLite 团队的 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. Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network.

[2] Xintao Wang, Ke Yu, Shixiang Wu, Jinjin Gu, Yihao Liu, Chao Dong, Chen Change Loy, Yu Qiao, Xiaoou Tang. 2018. ESRGAN: Enhanced Super-Resolution Generative Adversarial Networks.

[3] Tensorflow 2.x based implementation of EDSR, WDSR and SRGAN for single image super-resolution

https://github.com/krasserm/super-resolution

[4] @captain__pool 的 ESGRAN 代码实现

https://github.com/captain-pool/GSOC

[5] Eirikur Agustsson, Radu Timofte. 2017. NTIRE 2017 Challenge on Single Image Super-Resolution: Dataset and Study.

责任编辑:xj

原文标题:学习教程 | 使用 TensorFlow Lite 在 Android App 中生成超分图片

文章出处:【微信公众号:TensorFlow】欢迎添加关注!文章转载请注明出处。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Android
    +关注

    关注

    12

    文章

    3986

    浏览量

    133110
  • APP
    APP
    +关注

    关注

    33

    文章

    1589

    浏览量

    75666
  • tensorflow
    +关注

    关注

    13

    文章

    332

    浏览量

    61862

原文标题:学习教程 | 使用 TensorFlow Lite 在 Android App 中生成超分图片

文章出处:【微信号:tensorflowers,微信公众号:Tensorflowers】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    利用微型 Neuton ML 模型解锁 SoC 边缘人工智能

    才能做好。 现在,这些阻碍即将被解决。 Neuton 是一个自动生成 ML 模型的框架,其大小仅为 TensorFlow Lite 等传统框架的一小部。对于开发人员来说,这意味着要训
    发表于 08-31 20:54

    Copilot操作指南(一):使用图片生成原理图符号、PCB封装

    “  上周推出支持图片生成模型的华秋发行版之后,得到了很多小伙伴的肯定。但看到更多的回复是:为什么我的 Copilot 无法生成符号?只有普通的文本回复?今天就为大家详细讲解下
    的头像 发表于 07-15 11:14 3968次阅读
    Copilot操作指南(一):使用<b class='flag-5'>图片</b><b class='flag-5'>生成</b>原理图符号、PCB封装

    无法将Tensorflow Lite模型转换为OpenVINO™格式怎么处理?

    Tensorflow Lite 模型转换为 OpenVINO™ 格式。 遇到的错误: FrontEnd API failed with OpConversionFailure:No translator found for TFLite_Detection_PostP
    发表于 06-25 08:27

    手机APP远程控制,智能家居监测、智能控制系统(STM32L4、服务器、源码)实例项目打包下载

    手机APP远程控制,智能家居监测、智能控制系统(STM32L4、服务器、源码)实例项目打包,推荐下载!
    发表于 05-29 21:47

    手机APP远程控制,智能家居监测、智能控制系统(STM32L4、服务器、源码)

    手机APP远程控制,智能家居监测、智能控制系统(STM32L4、服务器、源码) 项目实例下载! 纯分享帖,需要者可点击附件免费获取完整资料~~~【免责声明】本文系网络转载,版权归原作者所有。本文所用视频、
    发表于 05-23 21:00

    有人接rk3576的视频硬件解码的实现么?

    我们这边是有做好了一个app的,然后我们这边是有用软解的方式播放了网络摄像枪的实时视频的,但是因为占用CPU太高了,所以就想转成视频硬解的方式播放实时视频。 目前我们是有采购了一个电视机顶盒硬件
    发表于 05-19 09:52

    迅为RK3588开发板GPIO调用APP运行测试

    Android Studio 的 locat 日志打印窗口,筛选打印“package:mine”,然后点击 APP 界面的“调用 GPIO”按钮,会循环打印 GPIO 引脚打开和 GPIO 引脚关闭,如下图所示: 到此,
    发表于 05-13 10:49

    使用gpif designer fx2lpCTL0中生成波形连接FPGA 以便从FPGA获取数据,为什么不能正常工作?

    我想使用gpif designer fx2lp CTL0 中生成波形连接FPGA 以便从FPGA 获取数据。 它在 CTL0 的下降沿逐帧获取数据。 每帧有 32 个脉冲,但是当我这样配置时,它不能正常工作。 我不明白。 我
    发表于 05-06 13:01

    将YOLOv4模型转换为IR的说明,无法将模型转换为TensorFlow2格式怎么解决?

    遵照 将 YOLOv4 模型转换为 IR 的 说明,但无法将模型转换为 TensorFlow2* 格式。 将 YOLOv4 darknet 转换为 Keras 模型时,收到 Type
    发表于 03-07 07:14

    无法GPU上运行ONNX模型的Benchmark_app怎么解决?

    CPU 和 GPU 上运行OpenVINO™ 2023.0 Benchmark_app推断的 ONNX 模型 CPU 上推理成功,但在 GPU 上失败。
    发表于 03-06 08:02

    可以使用OpenVINO™工具包将中间表示 (IR) 模型转换为TensorFlow格式吗?

    无法将中间表示 (IR) 模型转换为 TensorFlow* 格式
    发表于 03-06 06:51

    使用各种TensorFlow模型运行模型优化器时遇到错误非法指令怎么解决?

    使用各种 TensorFlow 模型运行模型优化器时遇到 [i]错误非法指令
    发表于 03-05 09:56

    为什么无法使用OpenVINO™模型优化器转换TensorFlow 2.4模型

    已下载 ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8 型号。 使用将模型转换为中间表示 (IR) ssd_support_api_v.2.4.json
    发表于 03-05 09:07

    自制 AirTag,支持/鸿蒙/PC/Home Assistant,无需拥有 iPhone

    ,模拟发出 FindMy 蓝牙广播。 这样制作出的定位标签,不需要苹果手机绑定,支持/鸿蒙/PC/Home Assistant 查看标签的位置。 制作教程 我 gitee 上建了一个项目
    发表于 02-25 11:22

    声智APP畅享多元模型体验

    重点并生成思维导图。 ——这不是科幻电影,而是声智APP用户正在经历的真实日常 ,它就像一个时刻待命的 “AI 脑”,为用户的生活、工作和学习排忧解难,让每一个复杂任务都变得轻松简单。 声智
    的头像 发表于 02-22 14:09 998次阅读