Python——图像缺失弥补

这篇具有很好参考价值的文章主要介绍了Python——图像缺失弥补。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        最近开始确认自己想要在Python和深度学习学习的一个方向,就是图像处理,自己对这部分还是很有兴趣的,所以最近看视频,然后根据代码做了一个图像缺失弥补的程序。这个课程我2年前是看过的,但是因为那时候的笔记本没办法跑这种吃资源的项目,所以工作后自己凑了一台3060的笔记本和2060的台式,专门用来跑程序。以下是对程序的理解。

        一、模型解读

        这个项目来源于一篇论文Globally and Locally Consistent Image Completion,如果想要理解这个模型,需要先大致了解一下这个论文。论文的中心思想是:先给图片挖掉一部分区域——用
这个图片去跑global completion网络,并且把网络参数保存——然后在completion基础上,用global completion得到的全局图片和生成的local图片分别跑Global Discriminator和local Discriminator,项目模型可以看下图:注意这里的图片输入,一个是完整未动过的图片(completion生成的),一个是从网络自己生成的图片中截取的local图片。我们本文的模型是跑一个completion和一个completion+discriminator,然后结果可以比较。

Python——图像缺失弥补

        二、网络解读

        通过模型可以看到这里面有两个大网络:completion和discriminator,而discriminator又分为global和local两部分,论文中对网络组成进行了详细描述,如下图:

Python——图像缺失弥补

其中的dilated conv是指空洞卷积,其目的是为了增加感受野,而deconv conv是反卷积,目的是把图片进行还原。在tensorflow中用空洞卷积使用tf.nn.atrous_conv2d(x, filters, dilation, padding='SAME'),而反卷积使用tf.nn.conv2d_transpose(x, filters, output_shape, [1, stride, stride, 1]),这个是比较方便的。网络的定义如下代码所示:

        

from layer import *
import tensorflow as tf
class Network:
    def __init__(self, x, mask, local_x, global_completion, local_completion, is_training, batch_size):
        self.batch_size = batch_size
        self.imitation = self.generator(x * (1 - mask), is_training)
        self.completion = self.imitation * mask + x * (1 - mask)
        # 由真的图片上截取下来的local_x跟原图x,输出结果就是True
        self.real = self.discriminator(x, local_x, reuse=False)
        # 由completion自己补的图片跟local discriminator补出来的图片,输出结果就是Fake
        self.fake = self.discriminator(global_completion, local_completion, reuse=True)
        self.g_loss = self.calc_g_loss(x, self.completion)
        self.d_loss = self.calc_d_loss(self.real, self.fake)
        self.g_variables = tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.TRAINABLE_VARIABLES, scope='generator')
        self.d_variables = tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.TRAINABLE_VARIABLES, scope='discriminator')

    def generator(self, x, is_training):
        with tf.compat.v1.variable_scope('generator'):
            with tf.compat.v1.variable_scope('conv1'):
                x = conv_layer(x, [5, 5, 3, 64], 1)
                x = batch_normalize(x, is_training)
                x = tf.nn.relu(x)
            with tf.compat.v1.variable_scope('conv2'):
                x = conv_layer(x, [3, 3, 64, 128], 2)
                x = batch_normalize(x, is_training)
                x = tf.nn.relu(x)
            with tf.compat.v1.variable_scope('conv3'):
                x = conv_layer(x, [3, 3, 128, 128], 1)
                x = batch_normalize(x, is_training)
                x = tf.nn.relu(x)
            with tf.compat.v1.variable_scope('conv4'):
                x = conv_layer(x, [3, 3, 128, 256], 2)
                x = batch_normalize(x, is_training)
                x = tf.nn.relu(x)
            with tf.compat.v1.variable_scope('conv5'):
                x = conv_layer(x, [3, 3, 256, 256], 1)
                x = batch_normalize(x, is_training)
                x = tf.nn.relu(x)
            with tf.compat.v1.variable_scope('conv6'):
                x = conv_layer(x, [3, 3, 256, 256], 1)
                x = batch_normalize(x, is_training)
                x = tf.nn.relu(x)
            with tf.compat.v1.variable_scope('dilated1'):
                x = dilated_conv_layer(x, [3, 3, 256, 256], 2)
                x = batch_normalize(x, is_training)
                x = tf.nn.relu(x)
            with tf.compat.v1.variable_scope('dilated2'):
                x = dilated_conv_layer(x, [3, 3, 256, 256], 4)
                x = batch_normalize(x, is_training)
                x = tf.nn.relu(x)
            with tf.compat.v1.variable_scope('dilated3'):
                x = dilated_conv_layer(x, [3, 3, 256, 256], 8)
                x = batch_normalize(x, is_training)
                x = tf.nn.relu(x)
            with tf.compat.v1.variable_scope('dilated4'):
                x = dilated_conv_layer(x, [3, 3, 256, 256], 16)
                x = batch_normalize(x, is_training)
                x = tf.nn.relu(x)
            with tf.compat.v1.variable_scope('conv7'):
                x = conv_layer(x, [3, 3, 256, 256], 1)
                x = batch_normalize(x, is_training)
                x = tf.nn.relu(x)
            with tf.compat.v1.variable_scope('conv8'):
                x = conv_layer(x, [3, 3, 256, 256], 1)
                x = batch_normalize(x, is_training)
                x = tf.nn.relu(x)
            with tf.compat.v1.variable_scope('deconv1'):
                x = deconv_layer(x, [4, 4, 128, 256], [self.batch_size, 64, 64, 128], 2)
                x = batch_normalize(x, is_training)
                x = tf.nn.relu(x)
            with tf.compat.v1.variable_scope('conv9'):
                x = conv_layer(x, [3, 3, 128, 128], 1)
                x = batch_normalize(x, is_training)
                x = tf.nn.relu(x)
            with tf.compat.v1.variable_scope('deconv2'):
                x = deconv_layer(x, [4, 4, 64, 128], [self.batch_size, 128, 128, 64], 2)
                x = batch_normalize(x, is_training)
                x = tf.nn.relu(x)
            with tf.compat.v1.variable_scope('conv10'):
                x = conv_layer(x, [3, 3, 64, 32], 1)
                x = batch_normalize(x, is_training)
                x = tf.nn.relu(x)
            with tf.compat.v1.variable_scope('conv11'):
                x = conv_layer(x, [3, 3, 32, 3], 1)
                x = tf.nn.tanh(x)

        return x


    def discriminator(self, global_x, local_x, reuse):
        def global_discriminator(x):
            is_training = tf.constant(True)
            with tf.compat.v1.variable_scope('global'):
                with tf.compat.v1.variable_scope('conv1'):
                    x = conv_layer(x, [5, 5, 3, 64], 2)
                    x = batch_normalize(x, is_training)
                    x = tf.nn.relu(x)
                with tf.compat.v1.variable_scope('conv2'):
                    x = conv_layer(x, [5, 5, 64, 128], 2)
                    x = batch_normalize(x, is_training)
                    x = tf.nn.relu(x)
                with tf.compat.v1.variable_scope('conv3'):
                    x = conv_layer(x, [5, 5, 128, 256], 2)
                    x = batch_normalize(x, is_training)
                    x = tf.nn.relu(x)
                with tf.compat.v1.variable_scope('conv4'):
                    x = conv_layer(x, [5, 5, 256, 512], 2)
                    x = batch_normalize(x, is_training)
                    x = tf.nn.relu(x)
                with tf.compat.v1.variable_scope('conv5'):
                    x = conv_layer(x, [5, 5, 512, 512], 2)
                    x = batch_normalize(x, is_training)
                    x = tf.nn.relu(x)
                with tf.compat.v1.variable_scope('fc'):
                    x = flatten_layer(x)
                    x = full_connection_layer(x, 1024)
            return x

        def local_discriminator(x):
            is_training = tf.constant(True)
            with tf.compat.v1.variable_scope('local'):
                with tf.compat.v1.variable_scope('conv1'):
                    x = conv_layer(x, [5, 5, 3, 64], 2)
                    x = batch_normalize(x, is_training)
                    x = tf.nn.relu(x)
                with tf.compat.v1.variable_scope('conv2'):
                    x = conv_layer(x, [5, 5, 64, 128], 2)
                    x = batch_normalize(x, is_training)
                    x = tf.nn.relu(x)
                with tf.compat.v1.variable_scope('conv3'):
                    x = conv_layer(x, [5, 5, 128, 256], 2)
                    x = batch_normalize(x, is_training)
                    x = tf.nn.relu(x)
                with tf.compat.v1.variable_scope('conv4'):
                    x = conv_layer(x, [5, 5, 256, 512], 2)
                    x = batch_normalize(x, is_training)
                    x = tf.nn.relu(x)
                with tf.compat.v1.variable_scope('fc'):
                    x = flatten_layer(x)
                    x = full_connection_layer(x, 1024)
            return x

        with tf.compat.v1.variable_scope('discriminator', reuse=reuse):
            global_output = global_discriminator(global_x)
            local_output = local_discriminator(local_x)
            with tf.compat.v1.variable_scope('concatenation'):
                output = tf.compat.v1.concat((global_output, local_output), 1)
                output = full_connection_layer(output, 1)
               
        return output


    def calc_g_loss(self, x, completion):
        loss = tf.compat.v1.nn.l2_loss(x - completion)
        return tf.reduce_mean(loss)


    def calc_d_loss(self, real, fake):
        alpha = 4e-4
        d_loss_real = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=real, labels=tf.ones_like(real)))
        d_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=fake, labels=tf.zeros_like(fake)))
        return tf.add(d_loss_real, d_loss_fake) * alpha

        关于loss值的选取:对于completion比较简单,采用MSE值来计算,就是简单地用生成的图片和真实图片做一个减法,就可以得出loss值;而discriminator则比较复杂一点,我理解了很久,因为论文提及用fake和real来进行判别,使用tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=fake, labels=tf.zeros_like(fake)))来进行计算,但是对于谁是fake谁是real并不是很清晰,我分析代码后得出:

由真的图片上截取下来的local_x跟原图x,输出结果就是True
由completion自己补的图片跟local discriminator补出来的图片,输出结果就是Fake

在程序中,它们的定义为

self.real = self.discriminator(x, local_x, reuse=False)
self.fake = self.discriminator(global_completion, local_completion, reuse=True)

        三、程序分析

        程序的架构是:数据处理——网络定义——建立模型——模型计算——结果展示

        数据处理:这次补全的图片采用人像,整个数据有20万+,如果每次都导入这么多数据,将会非常浪费时间跟资源,因此,程序先将这些图片进行压缩,并且转为npy格式,同时,为了节省资源,只选取其中5000张图片,x_train为95%。

        网络定义:已经在上面讲过,这里不再赘述。

        建立模型:模型建立就是把一些过程量定义出来,这里需要解释一下mask,它本身是一个黑白图,把要被填充的地方,置为1,其它地方置为0,而这部分是通过get_points函数来实现,这个函数计算出local的大小和坐标,然后对该部分进行填充,代码如下所示。

x = tf.compat.v1.placeholder(tf.float32,[BATCH_SIZE,IMAGE_SIZE,IMAGE_SIZE,3])
    mask = tf.compat.v1.placeholder(tf.float32,[BATCH_SIZE,IMAGE_SIZE,IMAGE_SIZE,1])
    local_x = tf.compat.v1.placeholder(tf.float32,[BATCH_SIZE,LOCAL_SIZE,LOCAL_SIZE,3])
    global_completion = tf.compat.v1.placeholder(tf.float32,[BATCH_SIZE,IMAGE_SIZE,IMAGE_SIZE,3])
    local_completion = tf.compat.v1.placeholder(tf.float32,[BATCH_SIZE,LOCAL_SIZE,LOCAL_SIZE,3])
    is_training = tf.compat.v1.placeholder(tf.bool,[])
    model = Network(x, mask, local_x, global_completion, local_completion, is_training, batch_size=BATCH_SIZE)
    sess = tf.compat.v1.Session()
    global_step = tf.compat.v1.Variable(0,name='global_step',trainable=False)
    epoch = tf.compat.v1.Variable(0,name='epoch',trainable=False)
    opt = tf.compat.v1.train.AdamOptimizer(learning_rate=LEARNING_RATE)
    # var_list:默认是GraphKeys.TRAINABLE_VARIABLES
    g_train_op = opt.minimize(model.g_loss, global_step=global_step, var_list=model.g_variables)
    d_train_op = opt.minimize(model.d_loss, global_step=global_step, var_list=model.d_variables)
    init_opt = tf.compat.v1.global_variables_initializer()
    sess.run(init_opt)
def get_points():
    points = []
    mask = []
    for i in range(BATCH_SIZE):
        # starting coordinate of the hole
        x1, y1 = np.random.randint(0, IMAGE_SIZE - LOCAL_SIZE + 1, 2)
        x2, y2 = np.array([x1, y1]) + LOCAL_SIZE
        points.append([x1, y1, x2, y2])

        # weight,height
        w, h = np.random.randint(HOLE_MIN, HOLE_MAX + 1, 2)
        p1 = x1 + np.random.randint(0, LOCAL_SIZE - w)
        q1 = y1 + np.random.randint(0, LOCAL_SIZE - h)
        p2 = p1 + w
        q2 = q1 + h

        m = np.zeros((IMAGE_SIZE, IMAGE_SIZE, 1), dtype=np.uint8)
        m[q1:q2 + 1, p1:p2 + 1] = 1
        mask.append(m)

    return np.array(points), np.array(mask)

         模型计算:通过模型定义,我们给定一个PRETRAIN_EPOCH值,如果epoch超过这个值,就停止completion的计算,保存模型参数,然后开始计算discriminator,而这部分源程序中没有给出停止的条件,所以我给定一个stop_loss:1e-4,当loss值低于这个数就保存模型跳出。这里就是跑的最久的地方,如果batch_size给的太大,电脑资源容易不够,我用台式电脑:6g 2060显卡跑这个模型,只能用batch_size=16,不然就会算不下去。

        模型展示:最后,我们通过x_test来看一下计算结果,结果分为两个,一个是completion完成的,一个是completion+discriminator完成的。

        下图是completion最后出来的图,效果还可以,有点像打了马赛克;

Python——图像缺失弥补

        下图是原始图和模型图的对照,结果也还不错,如果模型继续训练可以得到更好的结果,论文中的图是跑了好几天的:

        Python——图像缺失弥补

        下图是一个是completion(上)完成的,一个是completion+discriminator(下)完成的,下面那张的肤色比上面的偏白。

Python——图像缺失弥补

 

Python——图像缺失弥补

 代码下载链接python图像缺失弥补源码资源-CSDN文库文章来源地址https://www.toymoban.com/news/detail-437236.html

到了这里,关于Python——图像缺失弥补的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 最近超火的Stable Diffusion来了,用文本AI生成图像!

    前言 Stable Diffusion 应该是目前最流行的两个项目之一,另外一个就是大名鼎鼎的 ChatGPT前几天也给大家更新过 。     软件介绍 最近抖音小红人刷屏的AI人物,基本都是这款软件做的,相信很多做设计的小伙伴都知道它 ,只需要描述一段文字,它就能帮你生成一张图片。

    2024年02月10日
    浏览(84)
  • 上位机图像处理和嵌入式模块部署(qmacvisual缺失的光源控制)

    【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】         有些场景下面,是不需要光源和光源控制的,比如说利用摄像头识别对应区域的库位,这部分直接利用红外光采集对应的图像就可以了。但是还有一些场景,是需要进行光源控制的,

    2024年04月16日
    浏览(36)
  • C++ GDAL找出多时相遥感影像缺失的日期并自动生成新的全零图像作为替补

      本文介绍基于 C++ 语言的 GDAL 库,基于一个 存储大量遥感影像 的 文件夹 ,依据 每一景遥感影像 的文件名中 表示日期 的那个字段,找出这些遥感影像中 缺失的成像日期 ,并新生成多个像元值全部为 0 的栅格文件,作为这些 缺失日期当日 的遥感影像文件的方法。   

    2024年02月16日
    浏览(46)
  • 【最新最近】详细介绍图像修复评价指标MaPSNR、DISTS、FQeIQA、L0SSIM、LPIPSvgg、FID

    目录 MaPSNR DISTS FQeIQA L0SSIM LPIPSvgg FID MaPSNR(Multi-scale Peak Signal-to-Noise Ratio)是一种多尺度峰值信噪比指标。它是PSNR (Peak Signal-to-Noise Ratio) 的一种变体。MaPSNR是Mean-adjusted Peak Signal-to-Noise Ratio的缩写,即平均调整峰值信噪比。 在传统的PSNR指标中,只考虑了图像的全局信息,而没

    2024年02月11日
    浏览(90)
  • 从零开始快速构建自己的Flink应用

    本文介绍如何在 mac 下快速构建属于自己的 Flink 应用。 在 mac 上使用homebrew安装 flink: 查看安装的位置: 进入安装目录,启动 flink 集群: 进入 web 页面:http://localhost:8081/ 基于模板直接构建一个项目: 在项目的 DataStreamJob 类实现如下计数的功能: 在上面的例子中,我们使用

    2024年02月20日
    浏览(51)
  • 从0开始构建自己的AI大模型

    在过去的几年里,人工智能(AI)技术取得了巨大的进步,这主要是由于深度学习(Deep Learning)技术的迅速发展。深度学习是一种通过神经网络模拟人类大脑的学习过程来自动学习和预测的技术。随着数据规模的增加和计算能力的提高,深度学习已经取得了在图像识别、语音

    2024年02月20日
    浏览(28)
  • 当你开始用 ChatGPT 时,我已经开始调教自己的 AI 机器人了!

    作者 :明明如月学长, CSDN 博客专家,蚂蚁集团高级 Java 工程师,《性能优化方法论》作者、《解锁大厂思维:剖析《阿里巴巴Java开发手册》》、《再学经典:《EffectiveJava》独家解析》专栏作者。 热门文章推荐 : (1)《人工智能时代,软件工程师们将会被取代?》 (2)

    2024年02月04日
    浏览(56)
  • 《C++入门篇》——弥补C不足

    C++是业内一门久负盛名的计算机语言,从C语言发展起来的它,不仅支持C语言的语法,还新添加了面向对象、泛型等特性,以及祖师爷本贾尼博士补充C语言的不足。 这一篇我们先来讲讲C++对C语言不足部分的补充。 一.命名空间 Cpp能很好的支持C,所以在Cpp文件中写C语言程序是

    2024年01月18日
    浏览(34)
  • LeetCode 刷题记录——从零开始记录自己一些不会的

    1. 最多可以摧毁的敌人城堡数目 题意 思路 两层循环,太low了 用一个变量记录前一个位置 代码 2. 到达终点的数字 题意 思路 代码 3. 单词的压缩编码 题意 思路 代码 思路2 去找到是否不同的单词具有相同的后缀,我们可以将其反序之后插入字典树中。例如,我们有 “time”

    2024年02月09日
    浏览(67)
  • Python 处理缺失值

    删除所有缺失值的行 df.dropna() 删除所有缺失值的列 df.dropna(axis = ‘columns’)/df.dropna(axis = 1) 删除带有nan的行df.dropna(how = ‘nan’) 删除所有值都缺失的行 df.dropna(how = ‘all’) 删除至少有两个缺失值的行 df.dropna(thresh = 2) 删除指定的列范围 df.dropna(subset = [‘B’,‘D’]) 删除指定列

    2024年02月11日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包