基于深度学习的图片上色(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 。但是相等比较…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
