基于深度学习的图片上色(Opencv,Pytorch,CNN)
文章目录
- 1. 前言
- 2.图像格式(RGB,HSV,Lab)
- 2.1 RGB
- 2.2 hsv
- 2.3 Lab
- 3. 生成对抗网络(GAN)
- 3.1 生成网络(Unet)
- 3.2 判别网络(resnet18)
- 4. 数据集
- 5. 模型训练与预测流程图
- 5.1 训练流程图
- 5.2 预测流程图
- 6. 模型预测效果
- 7. GUI界面制作
- 8.代码下载
1. 前言
最近做了一个图像着色的项目,基于pytorch和opencv使用生成对抗网络对灰度图像自动上色,然后可以对上色后的图片手动调节亮度对比度等信息,最后可以保存上色后的图像,闲话少说,先看一下效果,文章最后附有全部代码及数据集下载链接。
灰度图自动上色
b站视频地址:b站视频地址
2.图像格式(RGB,HSV,Lab)
2.1 RGB
想要对灰度图片上色,首先要了解图像的格式,对于一副普通的图像通常为RGB格式的,即红、绿、蓝三个通道,可以使用opencv分离图像的三个通道,代码如下所示:
import cv2img=cv2.imread('pic/7.jpg')
B,G,R=cv2.split(img)
cv2.imshow('img',img)
cv2.imshow('B',B)
cv2.imshow('G',G)
cv2.imshow('R',R)
cv2.waitKey(0)
代码运行结果如下所示。
2.2 hsv
hsv是图像的另一种格式,其中h代表图像的色调,s代表饱和度,v代表图像亮度,可以通过调节h、s、v的值来改变图像的色调、饱和度、亮度等信息。
同样可以使用opencv将图像从RGB格式转换成hsv格式。然后可以分离h、s、v三个通道并显示图像代码如下所示:
import cv2img=cv2.imread('pic/7.jpg')
hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
h,s,v=cv2.split(hsv)
cv2.imshow('hsv',hsv)
cv2.imshow('h',h)
cv2.imshow('s',s)
cv2.imshow('v',v)
cv2.waitKey(0)
运行结果如下所示:
2.3 Lab
Lab是图像的另一种格式,也是本文使用的格式,其中L代表灰度图像,a、b代表颜色通道,本文使用L通道灰度图作为输入,ab两个颜色通道作为输出,训练生成对抗网络,将图像由RGB格式转换成Lab格式的代码如下所示:
import cv2img=cv2.imread('pic/7.jpg')
Lab=cv2.cvtColor(img,cv2.COLOR_BGR2Lab)
L,a,b=cv2.split(Lab)
cv2.imshow('Lab',Lab)
cv2.imshow('L',L)
cv2.imshow('a',a)
cv2.imshow('b',b)
cv2.waitKey(0)
3. 生成对抗网络(GAN)
生成对抗网络主要包含两部分,分别是生成网络和判别网络。
生成网络负责生成图像,判别网络负责鉴定生成图像的好坏,二者相辅相成,相互博弈。
本文使用U-net作为生成网络,使用ResNet18作为判别网络。U-net网络的结构图如下所示:
3.1 生成网络(Unet)
pytorch构建unet网络的代码如下所示:
class DownsampleLayer(nn.Module):def __init__(self,in_ch,out_ch):super(DownsampleLayer, self).__init__()self.Conv_BN_ReLU_2=nn.Sequential(nn.Conv2d(in_channels=in_ch,out_channels=out_ch,kernel_size=3,stride=1,padding=1),nn.BatchNorm2d(out_ch),nn.ReLU(),nn.Conv2d(in_channels=out_ch, out_channels=out_ch, kernel_size=3, stride=1,padding=1),nn.BatchNorm2d(out_ch),nn.ReLU())self.downsample=nn.Sequential(nn.Conv2d(in_channels=out_ch,out_channels=out_ch,kernel_size=3,stride=2,padding=1),nn.BatchNorm2d(out_ch),nn.ReLU())def forward(self,x):""":param x::return: out输出到深层,out_2输入到下一层,"""out=self.Conv_BN_ReLU_2(x)out_2=self.downsample(out)return out,out_2
class UpSampleLayer(nn.Module):def __init__(self,in_ch,out_ch):# 512-1024-512# 1024-512-256# 512-256-128# 256-128-64super(UpSampleLayer, self).__init__()self.Conv_BN_ReLU_2 = nn.Sequential(nn.Conv2d(in_channels=in_ch, out_channels=out_ch*2, kernel_size=3, stride=1,padding=1),nn.BatchNorm2d(out_ch*2),nn.ReLU(),nn.Conv2d(in_channels=out_ch*2, out_channels=out_ch*2, kernel_size=3, stride=1,padding=1),nn.BatchNorm2d(out_ch*2),nn.ReLU())self.upsample=nn.Sequential(nn.ConvTranspose2d(in_channels=out_ch*2,out_channels=out_ch,kernel_size=3,stride=2,padding=1,output_padding=1),nn.BatchNorm2d(out_ch),nn.ReLU())def forward(self,x,out):''':param x: 输入卷积层:param out:与上采样层进行cat:return:'''x_out=self.Conv_BN_ReLU_2(x)x_out=self.upsample(x_out)cat_out=torch.cat((x_out,out),dim=1)return cat_out
class UNet(nn.Module):def __init__(self):super(UNet, self).__init__()out_channels=[2**(i+6) for i in range(5)] #[64, 128, 256, 512, 1024]#下采样self.d1=DownsampleLayer(3,out_channels[0])#3-64self.d2=DownsampleLayer(out_channels[0],out_channels[1])#64-128self.d3=DownsampleLayer(out_channels[1],out_channels[2])#128-256self.d4=DownsampleLayer(out_channels[2],out_channels[3])#256-512#上采样self.u1=UpSampleLayer(out_channels[3],out_channels[3])#512-1024-512self.u2=UpSampleLayer(out_channels[4],out_channels[2])#1024-512-256self.u3=UpSampleLayer(out_channels[3],out_channels[1])#512-256-128self.u4=UpSampleLayer(out_channels[2],out_channels[0])#256-128-64#输出self.o=nn.Sequential(nn.Conv2d(out_channels[1],out_channels[0],kernel_size=3,stride=1,padding=1),nn.BatchNorm2d(out_channels[0]),nn.ReLU(),nn.Conv2d(out_channels[0], out_channels[0], kernel_size=3, stride=1, padding=1),nn.BatchNorm2d(out_channels[0]),nn.ReLU(),nn.Conv2d(out_channels[0],3,3,1,1),nn.Sigmoid(),# BCELoss)def forward(self,x):out_1,out1=self.d1(x)out_2,out2=self.d2(out1)out_3,out3=self.d3(out2)out_4,out4=self.d4(out3)out5=self.u1(out4,out_4)out6=self.u2(out5,out_3)out7=self.u3(out6,out_2)out8=self.u4(out7,out_1)out=self.o(out8)return out
3.2 判别网络(resnet18)
resnet18的结构图如下所示:
在pytorch内部自带resnet18模型,只需一行代码即可构建resnet18模型,然后还需要去除网络最后的全连接层,代码如下所示:
from torchvision import modelsresnet18=models.resnet18(pretrained=False)
del resnet18.fcprint(resnet18)
4. 数据集
本文使用的是自然风景类的数据图片,在网站上爬取了大概1000多张数据图片,部分图片如下所示
5. 模型训练与预测流程图
5.1 训练流程图
如下图所示,首先将RGB图像转换成Lab图像,然后将L通道作为生成网络输入,生成网络的输出为新的ab两通道,然后将图像原始的ab通道,与生成网络生成的ab通道输入判别网络中。
5.2 预测流程图
下图为模型的预测过程,在预测过程中判别网络已经没有作用了,首先将RGB图像转换成,Lab图像,接着将L灰度图输入生成网络可以得到新的ab通道图像,接着将L通道图像与生成的ab通道图像进行拼接(concate),拼接以后可以得到一张新的Lab图像,然后再将其转换成RGB格式,此时图像即为上色以后的图像。
6. 模型预测效果
下图为模型的预测效果。左侧的为灰度图像,中间的为原始的彩色图像,右侧的是模型上色以后的图像。整体上看,网络的上色效果还不错。
7. GUI界面制作
为了更加方便使用模型,本文使用pyqt5制作操作界面,其界面如下图所示:首先可以从电脑中加载图像,还可以切换上一张或者下一张,可以将图像灰度化显示。可以对其上色,然后可以调整上色后图像的H、S、V信息,最后支持图像导出,可以将上色后的图像保存到本地中。
8.代码下载
链接中包含了训练代码,测试代码,以及界面代码。此外还包含1000多张数据集,直接运行main.py程序即可弹出操作界面。
代码及数据集下载链接
相关文章:

基于深度学习的图片上色(Opencv,Pytorch,CNN)
文章目录 1. 前言2.图像格式(RGB,HSV,Lab)2.1 RGB2.2 hsv2.3 Lab 3. 生成对抗网络(GAN)3.1 生成网络(Unet)3.2 判别网络(resnet18) 4. 数据集5. 模型训练与预…...

Python爬虫
目录 爬虫总览 准备工作 一、爬虫基础 1、爬虫前导 1.1、爬虫介绍 1.2、HTTP与HTTPS 1.3、URL 1.4、开发工具 1.5、爬虫流程 2、requests模块 2.1、简介 2.2、安装 2.3、发送请求 二、爬虫 爬虫总览 准备工作 一、爬虫基础 1、爬虫前导 1.1、爬虫介绍 概念&…...

python基础案例题:进制转换、字符串加密的实现、猜拳游戏、多种方法计算π
目录 前言1.进制转换2.字符串加密的实现3.猜拳游戏4.多种方法计算π尾语 💝 前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! 1.进制转换 功能: 获取十进制整数的二进制串,相当于内置函数bin。 算法分析: 对2辗转相除&…...

Spring Boot入门与进阶
本文将为您详细讲解Spring Boot的入门与进阶知识,包括Spring Boot的简介、环境搭建、基本功能以及高级特性,并配以丰富的代码示例,帮助大家快速掌握Spring Boot。 一、Spring Boot简介 Spring Boot是基于Spring框架的一种轻量级、快速开发的…...

servlet(1)—javaEE
文章目录 1.认识servlet2.使用servlet2.1创建项目2.2引入依赖2.3创建目录2.4编写代码2.5打包2.6部署2.7运行2.8验证 3.开发步骤4.部署方式4.1打包4.2安装插件 5.访问出错的情况5.1 4045.2 4055.3其他 6.servlet的三大生命周期方法7.servlet api7.1HttpServlet7.2HttpServletReq…...

定制 Jenkins 镜像说明
Dockerfile模板示例 FROM jenkins/jenkins:2.332.4-jdk8 MAINTAINER jason USER root RUN sed -i ‘s/deb.debian.org/mirrors.aliyun.com/g’ /etc/apt/sources.list && apt update && apt install ca-certificates tzdata -y && rm -rf /var/cach…...

【离散数学】测试五 图论
1. n层正则m叉树一共有()片树叶。 A. nm B. mn C. mn 正确答案: B 2. 下图是一棵最优二叉树 A. 对 B. 错 正确答案: B 3. 要构造权为1,4,9,16,25,36,49,64,81,100一棵最优二叉树,则必须先构造权为5,9,16,25,36,49,64,81,100一棵最优二叉树. A. 对 B. 错 …...

根据cadence设计图学习硬件知识 day03 了解 一些芯片 和 数据手册下载的地方
1. MT53D512M32D2DS 芯片(动态随机存取存储器)的技术指标 1.1 16n Prefetch (预加载) (n --芯片位宽) DDR 体系 链接:DDR扫盲—-关于Prefetch(预取)与Burst(突发)的深入讨论_ddr prefetch_qq_25814297-npl的博客-CSDN博客 1.2 每个通…...

计算机组成原理——第五章中央处理器(中)
辞别再无相见月,终是一人度春秋 文章目录 前言5.4.1 硬布线控制器的设计5.4.2 微程序控制器的基本原理5.4.3 微指令的设计5.4.4 微程序控制单元的设计 前言 本文主要写的是控制器的设计,控制器的设计分为硬部件控制器(就是用纯硬件的方式来实现的一种控…...

ImageJ 用户手册——第三部分(ImageJ扩展)
ImageJ 用户手册-第三部分 ImageJ扩展14. 宏指令(Macros)宏程序设计 15. 脚本( Scripts)JavaScript编程 16. 插件( Plugins)开发ImageJ插件 17. 用其他语言编写脚本Fiji脚本编辑器 18. 从命令行运行ImageJ …...

RK3399平台开发系列讲解(PCI/PCI-E)PCIE相关配置说明
🚀返回专栏总目录 文章目录 一、DTS 配置二、menuconfig 配置三、cmdline 配置沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 本篇将介绍在使用 RK3399 平台 PCIE 时候的配置。 一、DTS 配置 ep-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>; 此项是设置 PCIe…...

NAS私有云存储 - 搭建Nextcloud私有云盘并公网远程访问
文章目录 摘要视频教程1. 环境搭建2. 测试局域网访问3. 内网穿透3.1 ubuntu本地安装cpolar3.2 创建隧道3.3 测试公网访问 4 配置固定http公网地址4.1 保留一个二级子域名4.1 配置固定二级子域名4.3 测试访问公网固定二级子域名 转载自内网穿透工具的文章:使用Nextcl…...

Revit问题:墙体被楼板剪切及材质库被锁定问题
一、Revit 墙体被楼板剪切怎么办? 建模的时候画的墙总是到楼板就停了,这是为什么?明明顶部约束到标高2了,这种情况如何解决? 首先来分析问题产生的原因是,我们在绘制楼板的时候选择了用楼板剪切重复部分的墙体。 解决…...

CPU信息查询与CPU测试方法总结
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请征得博主同意并附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/mainmaster/article/details/130267689 未经允许不能拷贝本文章内容发布到其他相关载体上。 CPU信息查询 我们知道在嵌入式系统…...

ChatGPT时代,我们可能站到了自然语言编程的大门口
ChatGPT大火,我现在有种感觉:我们可能站到了自然语言编程的门口,一脚下去,也许能把门踹开。 当然,也可能会踢到一块铁板。 回顾我们的编程之路,基本上就是一个编程门槛不断降低的历史。 最早的一批前辈们…...

深入理解AMQP协议
一.AMQP 是什么 AMQP(Advanced Message Queuing Protocol, 高级消息队列协议)是一个提供统一消息服务的 应用层标准高级 消息队列协议,是 应用层协议的一个 开放标准,为面向消息的中间件设计,是一个进程间传递 异步消息…...

大型体检管理系统源码:适用于大中型医院或独立体检中心
一套专业的体检管理系统源码,是医院、体检中心等单位开展体检业务的得力助手。它将以往人工操作的健康体检过程所得到信息转换成全信息化的电脑管理,使体检过程更为流畅、更有条理,更加便于管理,从而实现体检业务管理的自动化、信…...

ACM 1000 | 简单的a+b
文章目录 0x00 前言 0x01 题目描述 0x02 问题分析 0x03 代码设计 0x04 完整代码 0x05 运行效果 0x06 参考文献 0x07 总结 0x00 前言 C 语言网不仅提供 C 语言,还包括 C 、 java 、算法与数据结构等课程在内的各种入门教程、视频录像、编程经验、编译器教程及…...

系统分析师选择题笔记
目录 1、知识产权与标准化 1.1 保护范围与对象(★★★★) 1.2 保护期限(★) 1.3 知识产权人确定(★★★) 1.4 侵权判断(★★★) 1.5 标准的分类(★) 1.6 标准代号的识别(★) 2、系统配置与性能评价 2.1 系统性能概述 2.2 系统性能(性能指标)(★…...

MySQL隐式类型转换
当运算符与不同类型的操作数一起使用时,会发生类型转换以使操作数兼容。有些转换是隐式发生的。例如,MySQL会根据需要自动将字符串转换为数字,反之亦然。 转换规则 如果一个或两个参数都为NULL,则比较结果为NULL 。但是相等比较…...

IT知识百科:什么是SSID?
一、什么是SSID SSID(Service Set Identifier)是无线网络中的一个重要概念,它是一个用于标识无线局域网(WLAN)的名称。SSID可以看作是无线网络的名称,类似于有线网络中的网络名称或者路由器的名称。在无线…...

OpenAI-ChatGPT最新官方接口《从0到1生产最佳实例》全网最详细中英文实用指南和教程,助你零基础快速轻松掌握全新技术(十一)(附源码)
Production Best Practices 生产最佳实例 前言Introduction 导言Setting up your organization 设置您的组织Managing billing limits 管理计费限额API keys API密钥Staging accounts 演示账户 Building your prototype 构建您的原型Additional tips 其它技巧 Techniques for i…...

2023 IT市场权威榜单|美创数据库防火墙斩获“新一代信息技术创新产品”
4月20日,由赛迪顾问主办的“2023 IT市场权威榜单”评选结果正式发布,美创数据库防火墙斩获新一代信息技术创新产品! 美创数据库防火墙是一款抵御并消除由于应用程序业务逻辑漏洞或者缺陷所导致的数据库安全问题的专业级数据库安全产品&#x…...

30个超级有用的JavaScript单行代码
在这篇文章中,我列出了一个系列的 30 个 JavaScript 单行代码,它们在使用 vanilla js(≥ ES6)进行开发时非常有用。它们也是使用该语言在最新版本中为我们提供的所有功能来解决问题的优雅方式。 我将它们分为以下5大类࿱…...

【GitLab私有仓库】在Linux上用Gitlab搭建自己的私有库并配置cpolar内网穿透
前言 GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的Web服务。 Gitlab是被广泛使用的基于git的开源代码管理平台, 基于Ruby on Rails构建, 主要针对软件开发过程中产生的代码和文档进行管理, Gitlab主要针对…...

诊断CAPL自动化(1)—— CANoe自带的诊断工程分析
🍅 我是蚂蚁小兵,专注于车载诊断领域,尤其擅长于对CANoe工具的使用🍅 寻找组织 ,答疑解惑,摸鱼聊天,博客源码,点击加入👉【相亲相爱一家人】🍅 玩转CANoe,博客目录大全,点击跳转👉 📘前言 🍅 学习CANoe,官方的实例工程就是最好的学习模板,对于初学者,…...

【dp】最长递增子序列
文章目录 方法一:动态规划方法二:贪心 二分查找构造最长递增子序列 方法一:动态规划 dp[i]:末尾元素为arr[i]的最长子序列的长度 从0遍历到i - 1,若遍历到的元素小于当前值arr[i],表示当前值arr[i]可以和…...

docker容器:Docker-Compose
目录 一、Docker-Compose 1、Docker-Compose使用场景 2、Docker-Compose简介 3、Docker-Compose安装部署 4、YML文件编写注意事项 5、Compose配置常用字段 6、 Docker Compose 常用命令 7、Docker Compose 文件结构 8、docker Compose撰写nginx 镜像 9、docker Compos…...

如何使用DNS实现融合CDN功能
将托管DNS解决方案与CDN配对可为您的网站提供额外的性能、可靠性和灵活性。 域名系统(DNS)是一种用于计算机、服务或连接到Internet或专用网络的任何资源的分层分布式命名系统,它将各种信息与分配给每个参与实体的域名相关联,它基…...

有关实现深拷贝的四种方法
深拷贝与浅拷贝: 在开始之前我们需要先了解一下什么是浅拷贝和深拷贝,其实深拷贝和浅拷贝都是针对的引用类型,JS中的变量类型分为值类型(基本类型)和引用类型;对值类型进行复制操作会对值进行一份拷贝,而对…...