2019-12-18 20:22:46 weixin_44222014 阅读数 257
  • 深度学习图像处理之垃圾分类

    图像分类是图像处理领域的基本任务,同时也是深度学习领域的“Hello Word”,掌握好相关的基础知识,才能更好地开展识别、分割、去噪等更加复杂的任务。本课程将以当下最火热的垃圾分类作为主题,手把手地带领大家实现图像分类任务的完整过程。课程可以分为三个板块: (1)深度学习在图像处理领域的发展过程; (2)解析经典的卷积神经网络; (3)垃圾分类实战。本课程将使用Pytorch深度学习框架进行实战,并在ubuntu系统上进行演示,包括:不同标注文件下的数据集读取、编写卷积神经网络、训练垃圾分类数据集、测试训练网络模型、网络可视化、性能评估等。

    522 人正在学习 去看看 郭冰洋

1. 引言

在深度学习中,为了丰富图像数据的训练集,更好的提取图像特征,泛化模型(防止模型过拟合),一般都会对图像数据进行数据增强(Data Augmentation)。

2. 数据增强

在深度学习中,为了避免出现过拟合(Overfitting),通常我们需要输入充足的数据量。若数据量比较小,可以对原有的图像数据进行几何变换,改变图像像素的位置并保证特征不变。

数据增强,一般常用的方式有旋转图像,剪切图像,改变图像色差,扭曲图像特征,改变图像尺寸大小,增强图像噪音(一般使用高斯噪音,椒盐噪音)等。但是需要注意,尽量不要加入其他图像轮廓的噪音。

  • 旋转 | 反射变换(Rotation/reflection): 随机旋转图像一定角度; 改变图像内容的朝向;
  • 翻转变换(flip): 沿着水平或者垂直方向翻转图像;
  • 缩放变换(zoom): 按照一定的比例放大或者缩小图像;
  • 平移变换(shift): 在图像平面上对图像以一定方式进行平移;
    可以采用随机或人为定义的方式指定平移范围和平移步长, 沿水平或竖直方向进行平移. 改变图像内容的位置;
  • 尺度变换(scale): 对图像按照指定的尺度因子, 进行放大或缩小; 或者参照SIFT特征提取思想, 利用指定的尺度因子对图像滤波构造尺度空间. 改变图像内容的大小或模糊程度;
  • 对比度变换(contrast): 在图像的HSV颜色空间,改变饱和度S和V亮度分量,保持色调H不变. 对每个像素的S和V分量进行指数运算(指数因子在0.25到4之间), 增加光照变化;
  • 噪声扰动(noise): 对图像的每个像素RGB进行随机扰动, 常用的噪声模式是椒盐噪声和高斯噪声;
  • 颜色变换(color): 在训练集像素值的RGB颜色空间进行PCA, 得到RGB空间的3个主方向向量,3个特征值, p1, p2, p3, λ1, λ2, λ3.

3. 数据增强方法代码示例

# -*- coding:utf-8 -*-
"""数据增强
   1. 翻转变换 flip
   2. 随机修剪 random crop
   3. 色彩抖动 color jittering
   4. 平移变换 shift
   5. 尺度变换 scale
   6. 对比度变换 contrast
   7. 噪声扰动 noise
   8. 旋转变换/反射变换 Rotation/reflection
   author: XiJun.Gong
   date:2016-11-29
"""
 
from PIL import Image, ImageEnhance, ImageOps, ImageFile
import numpy as np
import random
import threading, os, time
import logging
import cv2
logger = logging.getLogger(__name__)
ImageFile.LOAD_TRUNCATED_IMAGES = True
 
 
class DataAugmentation:
    """
    包含数据增强的八种方式
    """
 
 
    def __init__(self):
        pass
 
    @staticmethod
    def openImage(image):
        return Image.open(image, mode="r")
 
    @staticmethod
    def randomRotation(image, mode=Image.BICUBIC):
        """
         对图像进行随机任意角度(0~360度)旋转
        :param mode 邻近插值,双线性插值,双三次B样条插值(default)
        :param image PIL的图像image
        :return: 旋转转之后的图像
        """
        random_angle = np.random.randint(1, 360)
        return image.rotate(random_angle, mode)
        #return image.rotate(180, mode)
 
    @staticmethod
    def randomFlip(image):
        #图像翻转(类似于镜像,镜子中的自己)
        #FLIP_LEFT_RIGHT,左右翻转
        #FLIP_TOP_BOTTOM,上下翻转
        #ROTATE_90, ROTATE_180, or ROTATE_270.按照角度进行旋转,与randomRotate()功能类似
        return image.transpose(Image.FLIP_LEFT_RIGHT)
   
    @staticmethod
    def Tranform(image):
        #t图像变换
        #im.transform(size, method, data) ⇒ image
 
        #im.transform(size, method, data, filter) ⇒ image
        #1:image.transform((300,300), Image.EXTENT, (0, 0, 300, 300)) 
        #   变量data为指定输入图像中两个坐标点的4元组(x0,y0,x1,y1)。
        #   输出图像为这两个坐标点之间像素的采样结果。
        #   例如,如果输入图像的(x0,y0)为输出图像的(0,0)点,(x1,y1)则与变量size一样。
        #   这个方法可以用于在当前图像中裁剪,放大,缩小或者镜像一个任意的长方形。
        #   它比方法crop()稍慢,但是与resize操作一样快。
        #2:image.transform((300,300), Image.AFFINE, (1, 2,3, 2, 1,4))
        #   变量data是一个6元组(a,b,c,d,e,f),包含一个仿射变换矩阵的第一个两行。
        #   输出图像中的每一个像素(x,y),新值由输入图像的位置(ax+by+c, dx+ey+f)的像素产生,
        #   使用最接近的像素进行近似。这个方法用于原始图像的缩放、转换、旋转和裁剪。
        #3: image.transform((300,300), Image.QUAD, (0,0,0,500,600,500,600,0))
        #   变量data是一个8元组(x0,y0,x1,y1,x2,y2,x3,y3),它包括源四边形的左上,左下,右下和右上四个角。
        #4: image.transform((300,300), Image.MESH, ())
        #   与QUAD类似,但是变量data是目标长方形和对应源四边形的list。
        #5: image.transform((300,300), Image.PERSPECTIVE, (1,2,3,2,1,6,1,2))
        #   变量data是一个8元组(a,b,c,d,e,f,g,h),包括一个透视变换的系数。
        #   对于输出图像中的每个像素点,新的值来自于输入图像的位置的(a x + b y + c)/(g x + h y + 1),
        #   (d x+ e y + f)/(g x + h y + 1)像素,使用最接近的像素进行近似。
        #   这个方法用于原始图像的2D透视。
        return image.transform((300,300), Image.EXTENT, (0, 0, 300, 300))
 
    @staticmethod
    def randomCrop(image):
        """
        对图像随意剪切,考虑到图像大小范围(68,68),使用一个一个大于(36*36)的窗口进行截图
        :param image: PIL的图像image
        :return: 剪切之后的图像
        """
        image_width = image.size[0]
        image_height = image.size[1]
        crop_win_size = np.random.randint(40, 68)
        random_region = (
            (image_width - crop_win_size) >> 1, (image_height - crop_win_size) >> 1, (image_width + crop_win_size) >> 1,
            (image_height + crop_win_size) >> 1)
        return image.crop(random_region)
 
    @staticmethod
    def randomColor(image):
        """
        对图像进行颜色抖动
        :param image: PIL的图像image
        :return: 有颜色色差的图像image
        """
        random_factor = np.random.randint(0, 31) / 10.  # 随机因子
        color_image = ImageEnhance.Color(image).enhance(random_factor)  # 调整图像的饱和度
        random_factor = np.random.randint(10, 21) / 10.  # 随机因子
        brightness_image = ImageEnhance.Brightness(color_image).enhance(random_factor)  # 调整图像的亮度
        random_factor = np.random.randint(10, 21) / 10.  # 随机因1子
        contrast_image = ImageEnhance.Contrast(brightness_image).enhance(random_factor)  # 调整图像对比度
        random_factor = np.random.randint(0, 31) / 10.  # 随机因子
        return ImageEnhance.Sharpness(contrast_image).enhance(random_factor)  # 调整图像锐度
 
    @staticmethod
    def randomGaussian(image, mean=0.2, sigma=0.3):
        """
         对图像进行高斯噪声处理
        :param image:
        :return:
        """
 
        def gaussianNoisy(im, mean=0.2, sigma=0.3):
            """
            对图像做高斯噪音处理
            :param im: 单通道图像
            :param mean: 偏移量
            :param sigma: 标准差
            :return:
            """
            for _i in range(len(im)):
                im[_i] += random.gauss(mean, sigma)
            return im
 
        # 将图像转化成数组
        img = np.asarray(image)
        img.flags.writeable = True  # 将数组改为读写模式
        width, height = img.shape[:2]
        img_r = gaussianNoisy(img[:, :, 0].flatten(), mean, sigma)
        img_g = gaussianNoisy(img[:, :, 1].flatten(), mean, sigma)
        img_b = gaussianNoisy(img[:, :, 2].flatten(), mean, sigma)
        img[:, :, 0] = img_r.reshape([width, height])
        img[:, :, 1] = img_g.reshape([width, height])
        img[:, :, 2] = img_b.reshape([width, height])
        return Image.fromarray(np.uint8(img))
 
    @staticmethod
    def saveImage(image, path):
        image.save(path)
 
 
def makeDir(path):
    try:
        if not os.path.exists(path):
            if not os.path.isfile(path):
                # os.mkdir(path)
                os.makedirs(path)
            return 0
        else:
            return 1
    except Exception, e:
        print str(e)
        return -2
 
 
def imageOps(func_name, image, des_path, file_name, times=5):
    #funcMap = {"randomRotation": DataAugmentation.randomRotation,
    #           "randomCrop": DataAugmentation.randomCrop,
    #           "randomColor": DataAugmentation.randomColor,
    #           "randomGaussian": DataAugmentation.randomGaussian
    #           "randomFlip":DataAugmentation.randomFlip,
    #           }
    funcMap = {
               "Tranform":DataAugmentation.Tranform
               }
    if funcMap.get(func_name) is None:
        logger.error("%s is not exist", func_name)
        return -1
 
    for _i in range(0, times, 1):
        new_image = funcMap[func_name](image)
        DataAugmentation.saveImage(new_image, os.path.join(des_path, func_name + str(_i) + file_name))
 
 
#opsList = {"randomFlip","randomRotation", "randomCrop", "randomColor", "randomGaussian"}
opsList = { "Tranform"}
 
def threadOPS(path, new_path):
    """
    多线程处理事务
    :param src_path: 资源文件
    :param des_path: 目的地文件
    :return:
    """
    if os.path.isdir(path):
        img_names = os.listdir(path)
    else:
        img_names = [path]
    for img_name in img_names:
        print img_name
        tmp_img_name = os.path.join(path, img_name)
        if os.path.isdir(tmp_img_name):
            if makeDir(os.path.join(new_path, img_name)) != -1:
                threadOPS(tmp_img_name, os.path.join(new_path, img_name))
            else:
                print 'create new dir failure'
                return -1
                # os.removedirs(tmp_img_name)
        elif tmp_img_name.split('.')[1] != "DS_Store":
            # 读取文件并进行操作
            image = DataAugmentation.openImage(tmp_img_name)
            threadImage = [0] * 5
            _index = 0
            for ops_name in opsList:
                threadImage[_index] = threading.Thread(target=imageOps,
                                                       args=(ops_name, image, new_path, img_name,))
                threadImage[_index].start()
                _index += 1
                time.sleep(0.2)
 
 
if __name__ == '__main__':
    threadOPS("D:\datasets\dataArgument\JPEGImages",
              "D:\datasets\dataArgument\Dealed_JPEGImages")
2016-11-21 09:47:27 u010402786 阅读数 4346
  • 深度学习图像处理之垃圾分类

    图像分类是图像处理领域的基本任务,同时也是深度学习领域的“Hello Word”,掌握好相关的基础知识,才能更好地开展识别、分割、去噪等更加复杂的任务。本课程将以当下最火热的垃圾分类作为主题,手把手地带领大家实现图像分类任务的完整过程。课程可以分为三个板块: (1)深度学习在图像处理领域的发展过程; (2)解析经典的卷积神经网络; (3)垃圾分类实战。本课程将使用Pytorch深度学习框架进行实战,并在ubuntu系统上进行演示,包括:不同标注文件下的数据集读取、编写卷积神经网络、训练垃圾分类数据集、测试训练网络模型、网络可视化、性能评估等。

    522 人正在学习 去看看 郭冰洋

  在9月23日到9月24日的MDCC 2016年中国移动者开发大会“人工智能与机器人”专场中,阿里云技术专家周昌进行了题为《寻找下一款Prisma APP:深度学习在图像处理中的应用探讨》的演讲。演讲中,他主要介绍深度学习在图像处理领域中的应用,主要内容包括:传统的图像处理:如超分辨、灰度图彩色化、2D/3D转换等;图像/视频风格化;图像生成。

  图像处理类过程主要分为三步,包括图像增强、图像变换、图像生成。图像增强是指从图像到图像;图像变换是指从图像到另外一张图像;图像生成是指直接生成新的图像,这三类都可以在开发者领域找到突破点。

图像增强:从图像到图像

265b245a00b13fbdd6e75ab6baa8b88cd9129c66

  图像增强包括分辨率增强、清晰度增强、画面改善、色彩的增强等。这里通过几个图像增强的小案例进行详细讲解,例如在下雨场景中把雨滴去掉、B站常用的waifu2x以及一些老旧照片彩色化、去掉马赛克等案例。

e82d4f6077c76ec813252ce15f81a1c7ae11c38c

  分辨率增强是指超分辨率,是将低分辨率的图像转换为高分辨率的图像,目前可以实现“标清”转换为“高清”,通常是2X,也可以是4X;上文提到的waifu2x是基于深度学习里的开源软件,目前在B站上以waifu2x为关键词可以搜出60多个老片子,迎合目前的需求。

994791eb21b8b3d1087778836954b4d02f59af0c

  清晰度增强,主要包括去噪声和去马赛克。可以将一些比较低的片源、照片变换为比较清晰一点的照片,主要用于老的港片可以变成很清晰的版本,将很老的照片变得清晰。

1f4feaef08b609870d84d752cb3132e4fe7d9c1b

  这是图像增强的另一个应用,用于画面改善,如去雾、去雨,常见的应用是做成相应的滤镜。

fa2272e745b0b34f89e178deb9b8dbc83351d951

  上图是色彩的增强的案例,将灰度图彩色化。它的核心是CV领域内很少用到的神经网络,用户无需关心网络架构,只需熟悉框架应用,熟知如何将其部署在移动端、云端即可。

7d6ede1885a8c0c6f37f8514bc2fa713877e8844

  除上述介绍的应用之外,还有更多的图像增强类应用,如常见的视频增强应用,用于频率变换,从25fps到50fps;从2D到3D转换,手机视频去抖动以及视频直播应用等。目前,阿里云也推出了云端服务,用户可以通过部署在云端来满足相应的应用或算法需求。

图像变换:从图像到另外一张图像

8a406b09a990cf5cbb39b109e2e197148ca49673

  上文讲到的是从图像到图像的倾向于常规的图像处理的应用,这些应用是无法处理得到炫酷的效果,但通过云端可以实现。通过对存量的图像、视频进行去噪或放大处理,得到另一张图像,其中最为知名的是风格化处理,它是指一张图片转变为另一张图片时,变换了风格。

f9689bb4a4635d0e1f137be919902ed7fedd2c97

  如图所示的风格是通过Google的Deepdream实现的,通过卷积网络反向传播的思想,强迫它激活某个神经元,最后生成一个从未见过的神奇图像。

风格化:全局的纹理学习

8ae3a3b8a064cbd382a460baa555ee4d1fe732e0

  真正风格化实现的第一篇论文是全局的纹理学习,是一篇德国的论文。它的重点是全局的风格,通过指定一张照片,指定一张需要学习的风格的图像,通过若干次的运算(运算非常缓慢,即使在GPU上,也需要秒级以上),最后输出所需要的神奇图像。

9110ba74293419d877ca26517fe9e668b0901adf

  上图所示的Github开源项目,目前有一万多个点击,是将输入的照片按照毕加索画的风格输出,是一种典型的全局风格。

d818e15e143c4b3307aef948c2fd9602d9965d3f

  上述的方法是通过指定一张图片再指定一张风格图片,通过BB操作生成图片非常慢。如果通过网络生成,速度是否会加快,这就是ADP思路。Prisma使得绝大数手机上即可实现该功能,通过引擎优化了卷积网络,并进行适当的裁剪,牺牲了部分性能,使得可以在手机上运行。目前,Prisma的日活大概有200多M,通过售卖风格获得收入。

局部风格化:利用位置信息

4dc94faacd5bdab564b8e8a96a43c05ba631bd31

  另一种风格化的是局部风格化,如图所示,图上眼睛和眼睛一样,不会跟随头发风格的变化而变化,这是利用位置信息做出的效果,非常逼真,但运算较慢,这是因为它需要根据两幅图的相似区域,在Feature map上直接融合出需要的目标。

交互式涂鸦

2102d38f2d91165fe48a5d35923c4944cbe83ff0

  此外,还有一种交互式涂鸦的方式,它并不是直接生成或自动生成一副图片,而是允许用一些方块、拖拉等方式对图片进行处理。这个思路结合上文的风格化方式可以形成一些PGC图像,在将来,这可能是一个爆款APP。

4fd81beb8e89b2e232afd63faf75f9f0147abb0d

  总结来看,风格化的技术演变分为四个阶段:第一阶段是基于BP全局风格化;第二阶段是纹理网络;第三阶段是局部风格化;第四阶段是用户交互,其中后两个阶段尚未出现较好的APP应用。

图像生成:直接生成新的图像

b0cbaa3f9edb82c668b5fd0328727224d4853c46

  图像生成是指从无到有,直接生成新的图像,生成图像的原理很简单,让电脑看一万只猫,它可以生成一万零一只猫,而且是你从未见过的猫。

c035e93f0e9aa87058b85bb8c9b0fe66790c3661

  最简单的图像生成网络是CPPN网络,CPPN非常巧妙的通过设计网络输入为坐标, 将网络视为一个复杂的连续函数,输出为对应坐标的像素的灰度(或者 RGB )值,因此这种网络可以构造大分辨率的图像。为了输出有效的图像,注意下面两点:
  所有网络层的权重初始化为 Norm(0, 1) 分布,不能用太小的值;
  网络的坐标输入确保值范围[-1, 1] 附近,不可以过大。
7b72e6c063494490ff3c25383f79e2fb2608761e

  另一种方式是DCGAN,是通过对抗网络的方法,由大量的样本生成新的图片,例如海报生成过程中,存在某些隐变量,通过隐变量的组合对某一张图片进行加眼镜的操作、变男或变女的操作等类似的应用;这种方法生成的模型还可以应用于去除水印,电视上或短视频的水印都可以去除掉。

  除了生成图像,目前还有应用可以生成视频,这是一个新的发展方向,将一副图片添加到应用后,应用会根据输出的动作进行之后的几帧动作。

总结和展望

35afab5fea50efbcb654af4cf5212fc83ecc0671

  上文介绍了三类图像应用,这三类图像应用的好处是只需一台FPU机器、会一点点技术,而且无需任何成本,所有的图像都不需要标注,可以零成本从互联网上获得。

  但此类应用需要考虑两个端之间关系,一种方式是全终端;另一种是云端方式,两种方式都有不同的部署方案。目前,全部在终端上完成存在一定困难的(除非愿意做一些优化);在云端完成可以选择CPU或GPU的方式,由于GPU的费用昂贵,在应用设计过程中,需要均衡成本。

c2306d36c7318f8c80b51f0af5552aadaec31d86

  云上的智能美工将是图像处理的下一个方向。如果大家在淘宝上搜美工或者搜图片处理,反馈回来很多的搜索结果,如上图所示。仔细看时,这些搜索结果存在两个关键词:去水印和抠图,这种重复性质的PS劳动非常之多,之所以有这种需求是因为太多的淘宝卖家拿别人的图放在自家内,抠图虽然是人工完成的,但都很便宜。

  通过前面的总结可以看出,有一个领域是AI真正可以涉足的,尽管看起来不是呢么高大上,但可以真正地节省人工劳动,也就是所谓的云上智能美工,可以完成抠图等基础的底层图处理。

739579868cdfab20281de75c83f5bdfee84d4b85

  再下一步的方向应该是智能设计,如上图所示,左侧是Google的时装设计,它是基于一些样本,进行新的服装设计,得到的结果再由艺术家进行专业评鉴;右侧是的国内的电商美学,将其与AI结合,这在将来也是一个非常有趣的方向。

项目链接

文中涉及的项目链接如下:

图像增强

分辨率增强:https://arxiv.org/pdf/1501.00092v3.pdf

清晰度增强:http://mmlab.ie.cuhk.edu.hk/projects/ARCNN.html

画面改善:https://arxiv.org/pdf/1609.02087.pdf

色彩增强:http://tinyclouds.org/colorize/

更多图像增强类应用:https://www.aliyun.com/solution/media/videorevive

图像变换

风格化:https://arxiv.org/abs/1508.06576

局部风格化:https://github.com/chuanli11/CNNMRF

图像生成

CPPN:http://zhouchang.info/blog/2016-04-08/simple-cppn.html

VAE + CPPN:http://blog.otoro.net/2016/04/01/generating-large-images-from-latent-vectors/

DCGAN:https://github.com/Newmu/dcgan_code

VideoGan:http://web.mit.edu/vondrick/tinyvideo/

智能设计

https://techcrunch.com/2016/09/02/googles-new-project-muse-proves-machines-arent-that-great-at-fashion-design/

http://www.deepdraw.cn/

转载地址
https://yq.aliyun.com/articles/61941

2019-05-13 10:26:25 whale52hertz 阅读数 161
  • 深度学习图像处理之垃圾分类

    图像分类是图像处理领域的基本任务,同时也是深度学习领域的“Hello Word”,掌握好相关的基础知识,才能更好地开展识别、分割、去噪等更加复杂的任务。本课程将以当下最火热的垃圾分类作为主题,手把手地带领大家实现图像分类任务的完整过程。课程可以分为三个板块: (1)深度学习在图像处理领域的发展过程; (2)解析经典的卷积神经网络; (3)垃圾分类实战。本课程将使用Pytorch深度学习框架进行实战,并在ubuntu系统上进行演示,包括:不同标注文件下的数据集读取、编写卷积神经网络、训练垃圾分类数据集、测试训练网络模型、网络可视化、性能评估等。

    522 人正在学习 去看看 郭冰洋

三星推出增加了深度学习和图像处理功能的Exynos 7应用处理器

文章来源:ATYUN AI平台 

三星新推出的中端移动应用处理器Exynos 7 9610具有深度学习和更快的图像处理能力,并将于2018年下半年推出。

三星电子(Samsung Electronics)推出了一款中端移动应用处理器(AP),增强了深度学习和图像处理能力。

这家韩国科技巨头表示,针对中端智能手机的Eyxnos 7 9610,采用10纳米工艺制造,增强了图像处理能力,可满足高清摄像与多媒体使用的手机趋势。

三星推出增加了深度学习和图像处理功能的Exynos 7应用处理器

借助深度学习技术和优化硬件,新AP在拍照时可以识别人脸,甚至当你的脸被头发或帽子遮挡时,新AP也可以在拍摄时识别出你的面部。

三星表示,深度检测的精确度更高,可以更好地聚焦,即使是单台相机。

Eyxnos 7 9610支持能够以每秒120帧(fps)速度拍摄4K的编解码器,与前一代产品Exynos 7 788相比,其图像单一处理速度快1.6倍。这些功能首先出现在三星高级AP——Eyxnos 9 9810上,该公司也将其用在自己的智能手机上。

其移动行业处理器接口将AP和图像传感器连接起来,速度提高了两倍。即使使用2层图像传感器,也可拍摄480fps全高清慢动作视频。

八核处理器有四个2.3GHz Cortex-A73大内核和1.6GHz Cortex-A53小内核,以及一个基于Bifrost的ARM Mali-G72 GPU。它有一个6模式调制解调器,覆盖2G CDMA到4G LTE,并且具有高达600Mbps的下载速度和150Mbps的上传速率。

三星表示,预计将在今年下半年批量生产。像Exynos 7这样的中端产品主要针对中国市场。

三星的逻辑芯片业务正在分散投资组合。去年,该公司开始向汽车制造商奥迪(Audi) 提供Eyxnos接触器,用于后者的信息娱乐系统。

上个月,该公司开始销售具有慢动作功能的图像传感器,目前该系统正用于Galaxy S9。

本文转自ATYUN人工智能媒体平台,原文链接:三星推出增加了深度学习和图像处理功能的Exynos 7应用处理器

更多推荐

使用交互组件(ipywidgets)“盘活”Jupyter Notebook(上)

ScaledInference:AMP.AI个性化折扣购物应用程序

Gamalon:机器学习不会使“理解”过时

美国又出超级计算机新计划:AMD和Cray将共同制造世界最快的超级计算机

欢迎关注ATYUN官方公众号,商务合作及内容投稿请联系邮箱:bd@atyun.com
欢迎关注ATYUN官方公众号,商务合作及内容投稿请联系邮箱:bd@atyun.com

 

2017-12-27 13:26:37 RogeDL 阅读数 462
  • 深度学习图像处理之垃圾分类

    图像分类是图像处理领域的基本任务,同时也是深度学习领域的“Hello Word”,掌握好相关的基础知识,才能更好地开展识别、分割、去噪等更加复杂的任务。本课程将以当下最火热的垃圾分类作为主题,手把手地带领大家实现图像分类任务的完整过程。课程可以分为三个板块: (1)深度学习在图像处理领域的发展过程; (2)解析经典的卷积神经网络; (3)垃圾分类实战。本课程将使用Pytorch深度学习框架进行实战,并在ubuntu系统上进行演示,包括:不同标注文件下的数据集读取、编写卷积神经网络、训练垃圾分类数据集、测试训练网络模型、网络可视化、性能评估等。

    522 人正在学习 去看看 郭冰洋

在《TensorFlow实战Google深度学习框架》中,关于图像处理的程序因为版本变更,运行时会报错,现在按照最新的函数方式调试通过,记录下来备查:


# -*- coding: utf-8 -*-
"""
Created on Tue Dec 26 11:27:16 2017


@author: Administrator
"""


import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import os


PIC_DIR = './datasets'
PIC_FILE= 'cat.jpg'


'''
print(os.getcwd())
os.chdir(os.getcwd()+"\\datasets")
print(os.getcwd())
'''


image_raw_data = tf.gfile.FastGFile(os.path.join(PIC_DIR,PIC_FILE),'rb').read()


with tf.Session() as sess:
    img_data = tf.image.decode_jpeg(image_raw_data)
    
    # 输出解码之后的三维矩阵。
    # 解码之后的结果是一个张量,使用它的取值前需要明确调用运行的过程
    print(img_data.eval())
    img_data.set_shape([1797,2673,3])
    print(img_data.get_shape())


with tf.Session() as sess:
    plt.imshow(img_data.eval())
    plt.show()
    
    # 重新编码保存为 jpg 图像:
    encoded_image = tf.image.encode_jpeg(img_data)
    with tf.gfile.FastGFile(os.path.join(PIC_DIR,'catsave.jpg'),'wb') as f:
        f.write(encoded_image.eval())
    
'''
# 重新调整图片大小
with tf.Session() as sess:
    # method:图像调整算法:取值 0 - 3
    # 0: 双线性插值法
    # 1: 最近邻居法
    # 2: 双三次插值法
    # 3: 面积插值法
    # 注意:这里:600是 y 坐标,300是 x 坐标
    resized = tf.image.resize_images(img_data,[600,300],method=0)
    print(img_data.get_shape())
    
    # TensorFlow的函数处理图片后存储的数据是float32格式的,需要转换成uint8才能正确打印图片
    print('Digital type: ',resized.dtype)
    
    cat = np.asarray(resized.eval(),dtype='uint8')
    # tf.image.convert_image_dtype(img_data,dtype=tf.float32)
    plt.imshow(cat)
    plt.show()
    
# 裁剪和填充图片
with tf.Session() as sess:
    croped = tf.image.resize_image_with_crop_or_pad(img_data,1000,1000)
    padded = tf.image.resize_image_with_crop_or_pad(img_data,3000,3000)
    plt.imshow(croped.eval())
    plt.show()
    plt.imshow(padded.eval())
    plt.show()
    
# 截取中间50%的图片¶
with tf.Session() as sess:
    central_cropped = tf.image.central_crop(img_data,0.5)
    plt.imshow(central_cropped.eval())
    plt.show()
    
#  翻转图片
with tf.Session() as sess:
    # up and down turnover:
    flipped1 = tf.image.flip_up_down(img_data)
    
    # left right turnover:
    flipped2 = tf.image.flip_left_right(img_data)
    
    # transpose turnover:
    transposed = tf.image.transpose_image(img_data)
    
    plt.imshow(flipped1.eval())
    plt.show()
    
    plt.imshow(flipped2.eval())
    plt.show()
    
    plt.imshow(transposed.eval())
    plt.show()
    
    # 以一定概率上下翻转图片。
    flipped3 = tf.image.random_flip_up_down(img_data)
    plt.imshow(flipped3.eval())
    plt.show()
    
    # 以一定概率左右翻转图片。
    flipped4 = tf.image.random_flip_left_right(img_data)
    plt.imshow(flipped4.eval())
    plt.show()
    
# 图片色彩调整
with tf.Session() as sess:
    
    adjusted1 = tf.image.adjust_brightness(img_data,-0.5)
    
    adjusted2 = tf.image.adjust_brightness(img_data,0.5)
    
    adjusted3 = tf.image.random_brightness(img_data, max_delta=0.5)
    
    adjusted4 = tf.image.adjust_contrast(img_data,-5)
    
    adjusted5 = tf.image.adjust_contrast(img_data,5)


    adjusted6 = tf.image.random_contrast(img_data,1,8)


    plt.imshow(adjusted6.eval())
    plt.show()    
    
# 添加色相和饱和度
with tf.Session() as sess:
    hue_adjusted1 = tf.image.adjust_hue(img_data,0.1) 
    hue_adjusted2 = tf.image.adjust_hue(img_data, 0.3)
    hue_adjusted3 = tf.image.adjust_hue(img_data, 0.6)
    hue_adjusted4 = tf.image.adjust_hue(img_data, 0.9)
    
    # 在[-max_delta, max_delta]的范围随机调整图片的色相。max_delta的取值在[0, 0.5]之间。
    hue_adjusted5 = tf.image.random_hue(img_data, 0.5) 
    
    # 将图片的饱和度-5
    sat_adjusted1 = tf.image.adjust_saturation(img_data,-5)
    sat_adjusted2 = tf.image.adjust_saturation(img_data,-5)   
    
    # 在[lower, upper]的范围随机调整图的饱和度。
    sat_adjusted3 = tf.image.random_saturation(img_data, 1, 3)
    
    # 图像标准化过程:将代表一张图片的三维矩阵中的数字均值变为0,方差变为1。
    std_adjusted = tf.image.per_image_standardization(img_data)


    plt.imshow(std_adjusted.eval())
    plt.show()   
'''




# 添加标注框并裁减
with tf.Session() as sess:
    # 4个数字分别代表:[ymin,xmin,ymax,xmax]
    # 这里有2组数据,代表有2个标注框
    boxes = tf.constant([[[0.05, 0.05, 0.9, 0.7], [0.35, 0.47, 0.5, 0.56]]])
    
    img_data2 = tf.image.resize_images(img_data,[180,267],method=1)
    print(type(img_data2),' ** ', img_data2.shape, ' ** ', img_data2.dtype)
    print(img_data.get_shape())
    
    plt.imshow(img_data2.eval())
    plt.show()    
    
    batched = tf.expand_dims(tf.image.convert_image_dtype(img_data2,tf.float32),0)
    image_with_box = tf.image.draw_bounding_boxes(batched,boxes)    
    plt.imshow(image_with_box[0].eval())
    plt.show()




    begin,size,bbox_for_draw = tf.image.sample_distorted_bounding_box(tf.shape(img_data2),bounding_boxes=boxes,min_object_covered=0.1)    
    distorted_image = tf.slice(img_data2,begin,size)
    plt.imshow(distorted_image.eval())
    plt.show()

2019-08-15 16:29:21 hyk_1996 阅读数 3125
  • 深度学习图像处理之垃圾分类

    图像分类是图像处理领域的基本任务,同时也是深度学习领域的“Hello Word”,掌握好相关的基础知识,才能更好地开展识别、分割、去噪等更加复杂的任务。本课程将以当下最火热的垃圾分类作为主题,手把手地带领大家实现图像分类任务的完整过程。课程可以分为三个板块: (1)深度学习在图像处理领域的发展过程; (2)解析经典的卷积神经网络; (3)垃圾分类实战。本课程将使用Pytorch深度学习框架进行实战,并在ubuntu系统上进行演示,包括:不同标注文件下的数据集读取、编写卷积神经网络、训练垃圾分类数据集、测试训练网络模型、网络可视化、性能评估等。

    522 人正在学习 去看看 郭冰洋

之前在做光照对于高层视觉任务的影响的相关工作,看了不少基于深度学习的低光照增强(low-light enhancement)的文章[3,4,5,7,8,9,10],于是决定简单梳理一下。

光照估计(illumination estimation)和低光照增强(low-light enhancement)的区别:光照估计是一个专门的底层视觉任务(例如[1,2,6]),它的输出结果可以被用到其它任务中,例如图像增强、图像恢复(处理色差,白平衡)。而低光照增强是针对照明不足的图像存在的低亮度低对比度噪声、伪影等问题进行处理,提升视觉质量。值得一提的是,低光照增强方法有两种常见的模式,一种是直接end-to-end训练,另一种则包含了光照估计。

 

LLNet: A deep autoencoder approach to natural low-light image enhancement

2017 Pattern Recognition

这篇文章应该是比较早的用深度学习方法完成低光照增强任务的文章,它证明了基于合成数据训练的堆叠稀疏去噪自编码器能够对的低光照有噪声图像进行增强和去噪。模型训练基于图像块(patch),采用sparsity regularized reconstruction loss作为损失函数。

主要贡献如下:

(1)我们提出了一种训练数据生成方法(即伽马校正和添加高斯噪声)来模拟低光环境。

(2)探索了两种类型的网络结构:(a) LLNet,同时学习对比度增强和去噪;(b) S-LLNet,使用两个模块分阶段执行对比度增强和去噪。

(3)在真实拍摄到的低光照图像上进行了实验,证明了用合成数据训练的模型的有效性。

(4)可视化了网络权值,提供了关于学习到的特征的insights。

 

MSR-net:Low-light Image Enhancement Using Deep Convolutional Network

2017 arXiv

这篇文章引入了CNN,它提了一个有趣的观点,传统的multi-scale Retinex(MSR)方法可以看作是有着不同高斯卷积核的前馈卷积神经网络,并进行了详细论证。

接着,仿照MSR的流程,他们提出了MSR-net,直接学习暗图像到亮图像的端到端映射。MSR-net包括三个模块:多尺度对数变换->卷积差分->颜色恢复,上面的结构图画得非常清楚了。

训练数据采用的是用PS调整过的高质量图像和对应的合成低光照图像(随机减少亮度、对比度,伽马校正)。损失函数为带正则项的误差矩阵的F-范数平方,即误差平方和。

 

Learning a Deep Single Image Contrast Enhancer from Multi-Exposure Images

2018 TIP

这篇文章其实主要关注单图像对比度增强(SICE),针对的是欠曝光和过曝光情形下的低对比度问题。其主要贡献如下:

(1)构建了一个多曝光图像数据集,包括了不同曝光度的低对比度图像以及对应的高质量参考图像。

(2)提出了一个两阶段的增强模型,如上图所示。第一阶段先用加权最小二乘(WLE)滤波方法将原图像分解为低频成分和高频成分,然后对两种成分分别进行增强;第二阶段对增强后的低频和高频成分融合,然后再次增强,输出结果。

对于为什么要设计两阶段结构,文章中是这样解释的:单阶段CNN的增强结果并不令人满意,且存在色偏现象,这可能是因为单阶段CNN难以平衡图像的平滑成分与纹理成分的增强效果。

值得一提的是,模型第一阶段的Decomposition步骤采用的是传统方法,而后面介绍的Retinex-Net使用CNN实现了。

 

Deep Retinex Decomposition for Low-Light Enhancement

2018 BMVC

这篇文章是我前后读过许多遍,比较值得介绍。受Retinex理论的启发,它采用了两阶段式的先分解后增强的步骤,完全采用CNN实现。对于Decom-Net的训练,引入了反射图一致性约束(consistency of reflectance)和光照图平滑性约束(smoothness of illumination),非常容易复现,实验效果也不错。

主要贡献如下:

(1)构建了paired的低光照/正常光照数据集LOL dataset,应该也是第一个在真实场景下采集的paired dataset.该数据集分为两部分:真实场景的图像数据是通过改变相机感光度和曝光时间得到的;合成的图像数据是用Adobe Lightroom接口调节得到的,并且调节后图像的Y通道直方图必须尽可能地接近真实低光照场景。

(2)提出了Retinex-Net,它分为两个子网络:Decom-Net能够对图像进行解耦,得到光照图和反射图;Enhance-Net对前面得到的光照图进行增强,增强后的光照图和原来的反射图相乘就得到了增强结果。另外,考虑到噪声问题,采用一种联合去噪和增强的策略,去噪方法采用BM3D。

(3)提出一个structure-aware total variation constraint,就是用反射图梯度作为权值对TV loss进行加权,从而在保证平滑约束的同时不破坏纹理细节和边界信息。

 

MBLLEN: Low-light Image/Video Enhancement Using CNNs

2018 BMVC

这篇文章的核心思想是,网络中不同层次的特征的提取和融合。此外,该文的另一个亮点是针对视频的低光照增强网络,和一帧一帧处理的直接做法不同,它们使用3D卷积对网络进行了改进,有效提升了性能。

补充说明一下,视频的低光照增强会存在的一种负面情况,闪烁(flickering),即帧与帧之间可能存在不符合预期的亮度跳变。这一问题可以用AB(avr)指标(即平均亮度方差)来度量。

网络结构:包括特征提取模块FEM、增强模块EM和融合模块FM。FEM是有10层卷积的单流向网络,每层的输出都会被输入到各个EM子模块中分别提取层次特征。最终这些层次特征被拼接到一起并通过1x1卷积融合得到最终结果。为了用于视频增强,还需要对网络进行修改,具体可参考原文。

损失函数:本文不采用常规的MSE或者MAE损失,而是提了一个新的损失函数,包括三个部分,即结构损失、内容损失和区域损失。结构损失采用SSIM和MS-SSIM度量相结合的形式;内容损失,就是VGG提取的特征应该尽可能相似;区域损失令网络更关注于图像中低光照的区域。

 

Learning to See in the Dark

2018 CVPR

传统成像系统的pipeline
提出的新成像系统

这篇文章主要关注于极端低光条件和短时间曝光条件下的图像成像系统,它用卷积神经网络去完成Raw图像到RGB图像的处理,实验效果非常惊艳。

网络结构基于全卷积网络FCN,直接通过端到端训练,损失函数采用L1 loss。此外,文章提出了See-in-the-Dark数据集,由短曝光图像及对应的长曝光参考图像组成。

 

Kindling the Darkness: A Practical Low-light Image Enhancer

2019 arXiv

这篇文章在今年5月份挂到了arXiv上,干货挺多,据称是state-of-the-art。它提出了低光照增强任务存在的三个难点:

(1) 如何有效的从单张图像中估计出光照图成分,并且可以灵活调整光照level?

(2) 在提升图像亮度后,如何移除诸如噪声和颜色失真之类的退化?

(3) 在没有ground-truth的情况下,样本数目有限的情况下,如何训练模型?

这篇文章的增强思路还是沿用了Retinex-Net的decomposition->enhance的两阶段方式,网络总共分为三个模块:Decomposition-Net、Restoration-Net和Adjustment-Net,分别执行图像分解、反射图恢复、光照图调整。一些创新点如下:

(a)对于Decomposition-Net,其损失函数除了沿用Retinex-Net的重构损失和反射图一致损失外,针对光照图的区域平滑性和相互一致性,还增加了两个新的损失函数。

(b)对于Restoration-Net,考虑到了低光照情况下反射图往往存在着退化效应,因此使用了良好光照情况下的反射图作为参考。反射图中的退化效应的分布很复杂,高度依赖于光照分布,因此引入光照图信息。

(c)对于Adjustment-Net,实现了一个能够连续调节光照强度的机制(将增强比率作为特征图和光照图合并后作为输入)。通过和伽马校正进行对比,证明它们的调节方法更符合实际情况。

 

参考文献

[1] Shi, W., Loy, C. C., & Tang, X. (2016). Deep Specialized Network for Illuminant Estimation. ECCV9908, 371–387. https://doi.org/10.1007/978-3-319-46493-0

[2] Guo, X., Li, Y., & Ling, H. (2017). LIME: Low-light image enhancement via illumination map estimation. IEEE Transactions on Image Processing26(2), 982–993. https://doi.org/10.1109/TIP.2016.2639450

[3] Lore, K. G., Akintayo, A., & Sarkar, S. (2017). LLNet: A deep autoencoder approach to natural low-light image enhancement. Pattern Recognition61, 650–662. https://doi.org/10.1016/j.patcog.2016.06.008

[4] Shen, L., Yue, Z., Feng, F., Chen, Q., Liu, S., & Ma, J. (2017). MSR-net:Low-light Image Enhancement Using Deep Convolutional Network. ArXiv. Retrieved from http://arxiv.org/abs/1711.02488

[5] Cai, J., Gu, S., & Zhang, L. (2018). Learning a Deep Single Image Contrast Enhancer from Multi-Exposure Images. IEEE Transactions on Image Processing1(c), 1–14. Retrieved from http://www4.comp.polyu.edu.hk/~cslzhang/paper/SICE.pdf

[6] Gao, Y., Hu, H. M., Li, B., & Guo, Q. (2018). Naturalness preserved nonuniform illumination estimation for image enhancement based on retinex. IEEE Transactions on Multimedia20(2), 335–344. https://doi.org/10.1109/TMM.2017.2740025

[7] Chen, C., Chen, Q., Xu, J., & Koltun, V. (2018). Learning to See in the Dark. CVPR, 3291–3300. https://doi.org/10.1109/CVPR.2018.00347

[8] Lv, F., Lu, F., Wu, J., & Lim, C. (2018). MBLLEN: Low-light Image/Video Enhancement Using CNNs. BMVC, 1–13.

[9] Wei, C., Wang, W., Yang, W., & Liu, J. (2018). Deep Retinex Decomposition for Low-Light Enhancement. BMVC, (61772043). Retrieved from http://arxiv.org/abs/1808.04560

[10] Zhang, Y., Zhang, J., & Guo, X. (2019). Kindling the Darkness: A Practical Low-light Image Enhancer. ArXiv, 1–13. Retrieved from http://arxiv.org/abs/1905.04161

 

没有更多推荐了,返回首页