近日,有关人贩子“梅姨”的图片在朋友圈以及网络平台热传,所有人都以为这是一张官方发布的照片,于是纷纷在朋友圈转发。

但是当天下午,公安部儿童失踪信息紧急发布平台曾发布消息称,“梅姨”的第二张画像非官方公布信息,CCSER不是公安机关官方权威平台。

后来更是被爆料出CCSER其实是一个民间民间互助平台,并非官方组织。

广东省公安厅未邀请专家对"梅姨"进行二次画像。那么这张彩色照片到底是怎么来的呢?

原来是今年3月份,因接触过‘梅姨’的人认为此前‘梅姨’画像不像,于是邀请了画像专家林宇辉对进行了第二次画像。

林宇辉说,通过与“梅姨”同居两年的当地老人及其女儿进行沟通,画出了这一张新的黑白照片。

这个林宇辉专家,在震惊中外的章莹颖案件中,根据三段模糊的远距离视频,画出嫌疑犯相貌。嫌疑犯抓获后,发现其长相与画上相似度达80%

有热心人士看到这张新画的黑白画像后,用电脑合成了蓝底的彩色“梅姨”画像,发给了被拐儿童家属。于是儿童家属把这个彩色的画像发布到社交平台上和媒体手上。

后来被CCSER使用,加了二维码,在朋友圈传播开来。

新闻中说,彩色照片是通过黑白照片经过电脑合成的,那么,计算机在合成的时候,背后的技术原理是什么呢?

照片上色技术

这种技术被称之为"图像彩色化",这项技术目前已经非常成熟了,广泛应用于各个领域,比较普遍的就是照片修复。

目前也有很多这样的网站,下图就是我们在https://colourise.sg/ 网站上,上传了"梅姨"的黑白照,经过人工智能处理后,获得的彩色照片。

提到人工智能为照片上色,不得不提的一个技术就是GAN(生成对抗网络)。

生成式对抗网络(GAN)是近年来大热的深度学习模型。

GAN的基本原理其实非常简单,这里以生成图片为例进行说明。假设我们有两个网络,G(Generator)和D(Discriminator)。正如它的名字所暗示的那样,它们的功能分别是:

G是一个生成图片的网络,它接收一个随机的噪声z,通过这个噪声生成图片,记做G(z)。

D是一个判别网络,判别一张图片是不是“真实的”。它的输入参数是x,x代表一张图片,输出D(x)代表x为真实图片的概率,如果为1,就代表100%是真实的图片,而输出为0,就代表不可能是真实的图片。

在训练过程中,生成网络G的目标就是尽量生成真实的图片去欺骗判别网络D。而D的目标就是尽量把G生成的图片和真实的图片分别开来。这样,G和D构成了一个动态的“博弈过程”。

最后博弈的结果是什么?在最理想的状态下,G可以生成足以“以假乱真”的图片G(z)。对于D来说,它难以判定G生成的图片究竟是不是真实的,因此D(G(z)) = 0.5。

这样我们的目的就达成了:我们得到了一个生成式的模型G,它可以用来生成图片。

那么,如何利用GAN技术为图片上色呢?

这要看下目前人工给图片上色的过程:

  • 对照片的历史、地理、文化背景进行深入研究,以推断出合适的颜色;

  • 用 Photoshop 等软件工具对黑白图像进行上色。

同样,计算机程序也需要完成两项任务:

  • 识别黑白照片中的目标并基于之前见过的照片推断出适合目标的颜色;

  • 给黑白照片上色

接下来我们直接上代码,代码参考自:https://zhuanlan.zhihu.com/p/70192339

上色实战

上色的首要条件就是对图片进行预处理:

class PairImageDataset(data.Dataset):    def __init__(self, path):        files = os.listdir(path)        self.files = [os.path.join(path, x) for x in files]

    def __len__(self):        return len(self.files)

    def __getitem__(self, index):        img = Image.open(self.files[index])        yuv = rgb2yuv(img)        y = yuv[..., 0] - 0.5        u_t = yuv[..., 1] / 0.43601035        v_t = yuv[..., 2] / 0.61497538        return torch.Tensor(np.expand_dims(y, axis=0)), torch.Tensor(            np.stack([u_t, v_t], axis=0))

这段小巧的代码,就是我们定义的数据输入器,使用pytorch的dataset API编写。通过读取图片,RGB转到YUV,然后分离Y和UV通道,就可以构建我们的输入数据了!

在之前我写的30行代码自动上色的程序里面,我们用很少的代码实现了一个自动上色程序,这次使用GAN方法略显复杂,但实际代码并不多:

train_ds = PairImageDataset(args.training_dir)    logging.info('loaded dataset from: {}, data length: {}'.format(args.training_dir, train_ds.__len__()))    train_dataloader = data.DataLoader(train_ds, batch_size=args.batch_size, shuffle=True, num_workers=0)

    i = 0    adversarial_loss = torch.nn.BCELoss()    optimizer_G = torch.optim.Adam(G.parameters(),                                   lr=args.g_lr,                                   betas=(0.5, 0.999))    optimizer_D = torch.optim.Adam(D.parameters(),                                   lr=args.d_lr,                                   betas=(0.5, 0.999))    for epoch in range(start_epoch, args.epoch):        for i, (y, uv) in enumerate(train_dataloader):            try:                # Adversarial ground truths                valid = Variable(torch.Tensor(y.size(0), 1).fill_(1.0),                                requires_grad=False).to(device)                fake = Variable(torch.Tensor(y.size(0), 1).fill_(0.0),                                requires_grad=False).to(device)

                yvar = Variable(y).to(device)                uvvar = Variable(uv).to(device)                real_imgs = torch.cat([yvar, uvvar], dim=1)

                optimizer_G.zero_grad()                uvgen = G(yvar)                # Generate a batch of images                gen_imgs = torch.cat([yvar.detach(), uvgen], dim=1)

                # Loss measures generator's ability to fool the discriminator                g_loss_gan = adversarial_loss(D(gen_imgs), valid)                g_loss = g_loss_gan + args.pixel_loss_weights * torch.mean(                    (uvvar - uvgen)**2)                if i % args.g_every == 0:                    g_loss.backward()                    optimizer_G.step()

                optimizer_D.zero_grad()                # Measure discriminator's ability to classify real from generated samples                real_loss = adversarial_loss(D(real_imgs), valid)                fake_loss = adversarial_loss(D(gen_imgs.detach()), fake)                d_loss = (real_loss + fake_loss) / 2                d_loss.backward()                optimizer_D.step()                if i % 300 == 0:                    logging.info("Epoch: %d, iter: %d, D loss: %f, G total loss: %f, GAN Loss: %f"                        % (epoch, i, d_loss.item(), g_loss.item(), g_loss_gan.item()))                    save_weights(                        {'D': D.state_dict(), 'G': G.state_dict(), 'epoch': epoch},                        epoch                    )

                    # snap some images from dir                    test_imgs = glob.glob('images/*.jpeg')                    for test_img in test_imgs:                        snap_image_result_from_file(test_img, G)

            except KeyboardInterrupt:                logging.info('interrupted. try saving model now..')                save_weights(                    {'D': D.state_dict(), 'G': G.state_dict(), 'epoch': epoch}, 0                )                logging.info('saved.')                exit(0)

其中最核心是D和G的loss传递过程,首先我们定义了D的loss是BCEloss,也就是两个类别的交叉商,然后将返回的插值用来更新G,而D的loss呢则是生成的BCE和真实值的BCE二者的均值。

代码几乎没有什么比较难以理解的地方,唯一复杂的就是训练的步骤和方式。

好啦,有了Python+GAN,我们也可以把黑白照片美化成彩色照片咯!~

参考资料:

https://zhuanlan.zhihu.com/p/24767059

https://zhuanlan.zhihu.com/p/70192339

有道无术,术可成;有术无道,止于术

欢迎大家关注Java之道公众号

好文章,我在看❤️

网传梅姨照片竟然是电脑合成的!仅需 100 行代码,你也能做到!相关推荐

  1. 100行代码教你爬取斗图网(Python多线程队列)

    100行代码教你爬取斗图网(Python多线程队列) 前言 根据之前写的两篇文章,想必大家对多线程和队列有了一个初步的了解,今天这篇文章就来实战一下,用多线程 + 队列 爬取斗图网的全网图片. 你还在 ...

  2. 网传毕业神会到底神不神? ICME仅剩72小时截稿

    点击文末公众号卡片,不错过计算机会议投稿信息 ICME2023(International Conference on Multimedia&Expo)截稿时间为北京时间2022年12月16日 ...

  3. html5魔塔编辑器安卓版,Mota: 纪元魔塔前传。童年魔塔记忆。使用手机编写的5000行代码...

    #Mota 程序说明: 纪元魔塔前传是一个由HTML5(Canvas + 原生JavaScript)开发的小游戏,所有素材均来自原版的元祖魔塔(魔塔50层) 这个游戏时跨平台的,任何支持HTML5的浏 ...

  4. Python爬取网站用户手机号_用Python爬虫爬取学校网妹子QQ号,100行代码撩妹,用技术脱单...

    前言: 其实这个项目没什么难度,稍微懂一点爬虫的人或者是已经就业的程序员都可以用自己学的编程语言写出来,但是正是这也原因,也间接证明现在网络很多安全问题的存在,简单的说就是这个网站的程序员偷懒,让用户 ...

  5. 网传字节跳动将取消 1500 元房补,网友:赶紧取消吧,节区房价格都嚣张的什么样了!...

    转自「进击的Coder」 编辑:可可 来源:开发者技术前线 部分来源:脉脉社区 最近除了外国大厂"降本增效",国内知名大厂也不得不开始"降本增效",更多的企业选 ...

  6. 本周AI热点回顾:30行代码,让27吨发电机原地爆炸;Photoshop把AI论文demo打包实现了;2块钱就能买上千张人脸照片

    点击左上方蓝字关注我们 01 Photoshop把AI论文demo打包实现了:照片上色.改年龄.换表情只需要点点鼠标 这两年,我们从很多论文中看到过一些令人惊艳的 demo,比如老照片自动上色.低画质 ...

  7. 梅姨一定想不到 中国人最爱的英国货竟然是一本童书

    有英国"新铁娘子"之称的特蕾莎·梅今天正式开启了她任内的首次访华行程.在中国人眼中,英国一直是一个充满了人文底蕴的国家,这里是莎士比亚.邱吉尔.披头士的故乡,这里诞生了福尔摩斯.0 ...

  8. 梅姨眼中最爱读英国书籍的人竟然是TA?

    看到这个标题,你第一秒想到的就是<哈利波特>中扮演赫敏的学霸女神艾玛·沃特森(Emma Watson)对不对? 这位毕业于世界名校布朗大学的艾玛曾同时被牛津.剑桥录取,堪称"集美 ...

  9. 全国人,都在找梅姨!眼球被挖,处女膜破裂,多处器官坏死……被拐孩子究竟经历了什么?...

    最近,一则关于梅姨案的新闻迅速登上热搜. 梅姨,真实姓名不详,平时以做红娘为生,暗地里倒卖孩子,涉嫌多起拐卖案件. 警方曾公布梅姨模拟画像公开征集线索,遗憾的是,时至今日,仍未将其抓捕归案. (注:警 ...

最新文章

  1. php抢购排队是怎样做的,基于swoole的抢购排队通用中间件,适合抢购秒杀场景,跟具体业务解耦...
  2. CSS3 Filter详解(改变模糊度 亮度 透明度等方法)
  3. Linux中sudo的用法和sudoers配置详解
  4. 斯坦福全球测试,四国本科生CS技能大比拼,中国学生竟然输在了考试上?!...
  5. mysql随机生成 姓名+电话
  6. 枚举类中的valueOf用法
  7. 单个html页面面包屑,充分利用网页设计中的面包屑
  8. 基于ANT+通讯协议软件开发环境搭建
  9. [流行偶像]分析王菲唱腔的精辟文字(转载)
  10. 单机魔域显示服务器未启动,魔域单机版_开始游戏
  11. 关于动物识别论文的阅读笔记——青鳉鱼的个体识别和“面部反转效应”
  12. 给Android新手的六条建议,听说安卓不火了?
  13. 盒模型--标准盒模型---怪异盒模型
  14. 数学建模之差分方程模型详解
  15. 深刻理解Linux进程间通信(IPC)
  16. TPM1.2到TPM 2.0的变化
  17. oracle数据库dblink创建语句_Oracle进阶学习之创建dblink
  18. 千万年斗转星移,小屏幕见大宇宙 - “钦天明时” 天文时钟万年历应用程序(iOS App)说明
  19. jquery 绘图工具 flot 使用
  20. java引入string类_Java基础教程——String类

热门文章

  1. linux读取dmp备份数据打开,Linux 中 Oracle dmp 文件导入导出(转)
  2. php.ini var dump,php安装xdebug后var_dump()不能输变量内容解决办法
  3. 进程管理程序java,运维经验分享(四)--关于 java进程管理的服务控制脚本编程思路分析...
  4. 汉字转html实体符号js_js转html实体
  5. 由最小生成树算法改到最短路径算法代码----为了区分两者的区别
  6. (王道408考研操作系统)第二章进程管理-第四节2:死锁处理策略之预防死锁
  7. (王道408考研数据结构)第一章绪论-第二节2:算法的时间复杂度和空间复杂度
  8. matplotlib 快速绘图
  9. ubuntu清空回收站
  10. Python爬虫中文乱码问题(爬虫乱码)