用OpenCV4实现图像的超分别率

本实验原文链接:·

https://arxiv.org/pdf/1807.06779.pdf

原文摘要

单图像超分辨率(SISR)的主要挑战是如何恢复微小纹理等高频细节。然而,大多数最先进的方法缺乏识别高频区域的特定模块,导致输出图像模糊。本文提出了一种基于注意的方法来区分纹理区域和平滑区域。高频细节定位后,进行高频补偿。这种方法可以与先前提出的SISR网络相结合。通过提供高频增强,可以获得更好的性能和视觉效果。本文还提出了自己的由DenseRes块组成的SISR网络。该模块提供了一种将低层特征和高层特征相结合的有效方法。大量的基准测试表明,本文提出的方法比SISR的最新作品有了显著的改进。

单图像超分辨率(SISR)的任务是从单低分辨率(LR)输入图像中推断出高分辨率(HR)图像。

这是一个高度不适定的问题,因为在低通滤波和下采样过程中,诸如微小纹理等高频信息会丢失。因此,SISR是一对多的映射,本文的任务是找到最合理的图像,尽可能地恢复微小的纹理。为了从LR图像中恢复HR图像,需要大的接收场从LR图像中获取更多的上下文信息。使用更深层的网络是增加接受视野的更好方法。深度网络的一个缺点是梯度问题的消失,使得网络难以训练。Heetal.[1]利用这些学习框架来进行网络训练。跳过连接是另一种通过网络增加梯度和信息流动的解决方案。低层特征包含了有效的信息,可以用来重建HR图像。SISR将从不同层次的集体信息中获益。SISR的难点在于恢复高频细节,如微小纹理。

输出图像与原始图像之间的均方误差(MSE)常作为损失函数来训练卷积神经网络。然而,在追求高峰值信噪比(PSNR)的过程中,MSE会返回许多可能解的均值,从而使输出图像变得模糊和不可信。为了恢复高频细节,人们提出了知觉损失[2],它鼓励生成特征表示相似的图像的网络,从而产生更清晰的图像。莱迪格在阿尔。[3] ,[4]结合对抗性网络、感知损失和纹理损失,鼓励输出图像恢复微小纹理等高频细节。但是所有这些网络并不清楚高频细节的位置,它们只是试图盲目地恢复

纹理。因此,这些网络的性能并不令人满意。为了解决这些问题,首先,在denseNet[5]的基础上,本文提出了一种新的由剩余积木块(Resblock)[1]组成的DenseRes块。每个Resblock的输出都连接到其他Resblock,增强了信息的流动性,避免了冗余特征的重新学习。利用DenseRes块,减少了梯度消失问题,网络易于训练。第二,本文提供一个注意机制来处理高频细节的恢复。受用于语义像素级分割的U-net[6]的启发,本文提出了一种新的混合密集连接U-net,以帮助网络区分是否存在需要修复或类似于插值图像的细小纹理区域。它作为一个特征选择器,有选择地增强高频特征。因此,可以尽可能接近地恢复纹理。这是第一次将注意机制引入SISR。方法简单有效。通过选择性地提供高频增强,它缓解了输出图像容易模糊的问题。注意机制可以与先前提出的SISR网络相结合。获得了较高的信噪比和信噪比。另一个贡献是本文提出了DenseRes块,它提供了一种有效的方法来结合低层特征和高层特征。这有利于恢复高频细节。本文在四个公开的基准数据集上评估本文的模型。它在PSNR和结构相似性(SSIM)指数方面优于当前最新的方法。PSNR比VDSR[7]和DRCN[8]分别提高了0.54db和0.52dB。

图像超像素

传统方式的图像超像素常见的方式就是基于立方插值跟金字塔重建。OpenCV中对这两种方式均有实现,低像素图像在纹理细节方面很难恢复,从低像素图像到高像素图像是典型的一对多映射,如果找到一种好的映射关系可以尽可能多的恢复或者保留图像纹理细节是图像超像素重建的难点之一,传统方式多数都是基于可推导的模型实现。而基于深度学习的超像素重新方式过程未知但是结果优于传统方式。在深度学习方式的超像素重建中,对低像素图像采样大感受野来获取更多的纹理特征信息。OpenVINO中提供的单张图像超像素网络参考了下面这篇文章

该网络模型主要分为两个部分

·       特征重建网络,实现从低分辨率到高分辨率的像素重建

·       注意力生成网络,主要实现图像中高频信息的修复

通过两个网络的的输出相乘,还可以得到高分辨率图像的残差。特征重建网络主要包括三个部分。卷积层实现特征提取,卷积层采样大感受野来得到更多纹理细节;多个DenseRes 叠加模块,级联DenseRes可以让网络更深,效果更好;一个亚像素卷积层作为上采样模块。注意力生成网络部分,用来恢复小的纹理细节,如图像的边缘与形状,网络可以准确定位到细节特征,然后进行相对提升,注意力特征网络设计受到UNet网络架构的启发。完整的模型结构如下:

一个更简介的网络结构如下:

其中LR表示低分辨率图像、HR表示高分辨率图像,Bicubic表示双立方插值上采样。

模型文件

OpenVINO提供的模型是在这个模型基础上进行简化,计算量更低,速度更快。从上面的模型结构知道,模型有两个输入部分,分别是输入的低分辨率图像与双立方上采样的图像

·

·

·

LR的输入:[1x3x270x480]双立方采样:[1x3x1080x1920]三通道顺序是:BGR

模型的输出

·

输出层是一个blob对象,格式为[1x3x1080x1920]

程序演示

首先需要加载网络模型,获取可执行网络,然后设置输入与输出的数据格式与数据精度,这部分的代码如下:

//  加载检测模型

CNNNetReader network_reader;

network_reader.ReadNetwork(model_xml);

network_reader.ReadWeights(model_bin);





// 请求网络输入与输出信息

auto network = network_reader.getNetwork();

InferenceEngine::InputsDataMap input_info(network.getInputsInfo());

InferenceEngine::OutputsDataMap output_info(network.getOutputsInfo());

// 设置输入格式

for (auto &item : input_info) {

      auto input_data = item.second;

      input_data->setPrecision(Precision::U8);

      input_data->setLayout(Layout::NCHW);

      input_data->getPreProcess().setResizeAlgorithm(RESIZE_BILINEAR);

      input_data->getPreProcess().setColorFormat(ColorFormat::BGR);

}

printf("get it \n");





// 设置输出格式

for (auto &item : output_info) {

      auto output_data = item.second;

      output_data->setPrecision(Precision::FP32);

}





// 创建可执行网络对象

auto executable_network = ie.LoadNetwork(network, "CPU");





// 请求推断图

auto infer_request = executable_network.CreateInferRequest();

代码演示步骤中有两个输入,对输入的设置可以使用下面的代码

/** Iterating over all input blobs **/

for (auto & item : input_info) {

      auto input_name = item.first;

      printf("input_name : %s \n", input_name.c_str());

      /** Getting input blob **/

      auto input = infer_request.GetBlob(input_name);

      size_t num_channels = input->getTensorDesc().getDims()[1];

      size_t h = input->getTensorDesc().getDims()[2];

      size_t w = input->getTensorDesc().getDims()[3];

      size_t image_size = h*w;

      Mat blob_image;

      resize(src, blob_image, Size(w, h));

      printf("input channel : %d, height : %d, width : %d \n", num_channels, h, w);

      // NCHW

      unsigned char* data = static_cast<unsigned char*>(input->buffer());

      for (size_t row = 0; row < h; row++) {

              for (size_t col = 0; col < w; col++) {

                       for (size_t ch = 0; ch < num_channels; ch++) {

                                data[image_size*ch + row*w + col] = blob_image.at<Vec3b>(row, col)[ch];

                       }

              }

      }

}

最后执行推理,完成对输出的解析,在解析输出的时候其实输的是[NCHW] = [1x3x1080x1920]的浮点数矩阵,需要转换为Mat类型为[HWC] =[1080x1920x3],采用的是循环方式,是不是有更好的数据处理方法可以转换这个,值得研究。解析部分的代码如下

// 执行预测

infer_request.Infer();





// 处理输出结果

for (auto &item : output_info) {

      auto output_name = item.first;





      // 获取输出数据

      auto output = infer_request.GetBlob(output_name);

      float* buff = static_cast<PrecisionTrait<Precision::FP32>::value_type*>(output->buffer());

      const int c = output->getTensorDesc().getDims()[1];

      const int h = output->getTensorDesc().getDims()[2];

      const int w = output->getTensorDesc().getDims()[3];





      // 获得输出的超像素图像

      Mat result = Mat::zeros(Size(w, h), CV_32FC3);

      for (int ch = 0; ch < c; ch++) {

              for (int row = 0; row < h; row++) {

                       for (int col = 0; col < w; col++) {

                                result.at<Vec3f>(row, col)[ch] = buff[ch*w*h+ row*w + col];

                       }

              }

      }

      printf("channel : %d, height : %d, width : %d \n", c, h, w);

      normalize(result, result, 0, 255.0, NORM_MINMAX);

      result.convertTo(result, CV_8U);

      imshow("High-Resolution Demo", result);

      imwrite("D:/result.png", result);

}

测试结果分别如下:(原图)

超分辨输出:(1920x1080)

总结

也许模型被简化的太厉害了,速度是很快了,单身效果感觉比双立方好那么一点点而已!

本文提出了一种基于注意的方法来区分纹理区域和平滑区域。当高频细节的位置被定位时,注意机制起到了增强高频特征和抑制平滑区域噪声的特征选择器的作用。因此,本文的方法避免了盲目地恢复高频细节。本文将该机制集成到包括SRResNet、VDSR和DRCN的SISR网络中,提高了这些SISR网络的性能。因此,本文验证了注意机制的有效性。对于特征重构网络,本文提出了DenseRes块,它提供了一种将低层特征和高层特征相结合的有效方法。通过多个致密块的级联,本文的网络有一个大的接收场。因此,从LR图像中获取有用的大区域上下文信息,以恢复HR图像中的高频细节。与目前最先进的方法相比,本文的方法具有最好的性能。今后,本文将探索注意机制在视频超分辨率中的应用,以产生直观、定量的高质量结果。

用OpenCV4实现图像的超分别率的更多相关文章

  1. 【opencv系列02】OpenCV4.X图像读取与显示

    一.读取图片 opencv中采用imread() 函数读取图像 imread(filename, flags=None)     filename 图片的路径     flags 图像读取方式 ● c ...

  2. 基于稀疏表示的图像超分辨率《Image Super-Resolution Via Sparse Representation》

    由于最近正在做图像超分辨重建方面的研究,有幸看到了杨建超老师和马毅老师等大牛于2010年发表的一篇关于图像超分辨率的经典论文<ImageSuper-Resolution Via Sparse R ...

  3. JPEG压缩图像超分辨率重建算法

    压缩图像超分辨率重建算法学习 超分辨率重建是由一幅或多幅的低分辨率图像重构高分辨率图像,如由4幅1m分辨率的遥感图像重构分辨率0.25m分辨率图像.在军用/民用上都有非常大应用. 眼下的超分辨率重建方 ...

  4. 【超分辨率】—图像超分辨率(Super-Resolution)技术研究

    一.相关概念 1.分辨率 图像分辨率指图像中存储的信息量,是每英寸图像内有多少个像素点,分辨率的单位为PPI(Pixels Per Inch),通常叫做像素每英寸.一般情况下,图像分辨率越高,图像中包 ...

  5. HMS Core机器学习服务图像超分能力,基于深度学习提升新闻阅读体验

    在移动端阅读资讯时,人们对高分辨率.高质量的图像要求越来越高.但受限于网络流量.存储.图片源等诸多因素,用户无法便捷获得高质量图片.移动端显示设备的高分辨率图片获得问题亟待解决.不久前,HMS Cor ...

  6. paper 89:视频图像去模糊常用处理方法

    随着“平安城市”的广泛建设,各大城市已经建有大量的视频监控系统,虽然监控系统己经广泛地存在于银行.商场.车站和交通路口等公共场所,但是在公安工作中,由于设备或者其他条件的限制,案情发生后的图像回放都存 ...

  7. HTML网页插入图像

    一.WEB上支持的图片格式: GIF:能保存256中颜色,支持透明色,支持动画效果 JPEG:不支持透明色和动画,颜色可达1670种 PNG:支持透明色,不支持动画,颜色有几种到1670种 二.将图片 ...

  8. 【超分辨率】- CVPR2019中SR论文导读与剖析

    CVPR2019超分领域出现多篇更接近于真实世界原理的低分辨率和高分辨率图像对应的新思路.具体来说,以前论文训练数据主要使用的是人为的bicubic下采样得到的,网络倾向于学习bicubic下采样的逆 ...

  9. OpenCV3入门(十四)图像特效—挤压、哈哈镜、扭曲

    一.图像挤压特效 1.原理 图像压效果本质的图像坐标的非线性变换,将图像向内挤压,挤压的过程产生压缩变形,从而形成的效果. 挤压效果的实现是通过极坐标的形式,设图像中心为O(x,y),某点距离中心O的 ...

随机推荐

  1. JavaScript动态设置div的样式的方法

    有时候需要根据需要动态设置div的样式,当然对于稍有经验的javascript开发者来说,这一切都是那么的简单,但是对于初学者或者说没有相关经验的开发者来说可能就是一个不大不小的难关,下面就通过实例简 ...

  2. Mysql Char 和 Varchar的区别

    CHAR和VARCHAR都是字符串类型,它们的具体区别为: 长度大小区别: CHAR(M)定义的列的长度为固定的,M取值可以为0-255之间: VARCHAR(M)定义的列的长度为可变长,M取值可以为 ...

  3. 缓冲区溢出分析第05课:编写通用的ShellCode

    前言 我们这次的实验所要研究的是如何编写通用的ShellCode.可能大家会有疑惑,我们上次所编写的ShellCode已经能够很好地完成任务,哪里不通用了呢?其实这就是因为我们上次所编写的ShellC ...

  4. Jenkins反序列化漏洞复现

    Jenkins Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. Jenkins功能包括: 持 ...

  5. 用最容易的方式学会单链表(Python实现)

    单链表与数组 在本博客中,我们介绍单链表这种数据结构,链表结构为基于数组的序列提供了另一种选择(例如Python列表). 基于数组的序列也会有如下缺点: 一个动态数组的长度可能超过实际存储数组元素所需 ...

  6. 记录数据库被攻击.md

    昨天的数据库还是正常的,早上想连接mysql,一直报错1045,最后才发现数据库被攻击了 navicat连接mysql疯狂报错1045 因为1045的报错,一般都是密码设置的问题,但是我怎么修改也没有 ...

  7. 一文解决MySQL时区相关问题

    前言: 在使用MySQL的过程中,你可能会遇到时区相关问题,比如说时间显示错误.时区不是东八区.程序取得的时间和数据库存储的时间不一致等等问题.其实,这些问题都与数据库时区设置有关,本篇文章将从数据库 ...

  8. CLS的探索:Python如何让日志免费云化

    前言 日志服务(Cloud Log Service,CLS)是腾讯云提供的一站式日志服务平台,提供了从日志采集.日志存储到日志检索,图表分析.监控告警.日志投递等多项服务,协助用户通过日志来解决业务运 ...

  9. QTableWidget - 基础讲解(1)

    转载:http://www.cnblogs.com/fuqia/p/8904196.html QTableWidget是QT程序中常用的显示数据表格的空间,很类似于VC.C#中的DataGrid.说到 ...

  10. Linux Test Project(一)

    http://www.vimlinux.com/lipeng/2014/09/12/ltp/ Testing Linux, one syscall at a time. LTP是从SGI开始的,后由I ...