当前位置: 首页 > news >正文

基于深度学习的图片上色(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 测试访问公网固定二级子域名 转载自内网穿透工具的文章&#xff1a;使用Nextcl…...

Revit问题:墙体被楼板剪切及材质库被锁定问题

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

CPU信息查询与CPU测试方法总结

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

ChatGPT时代,我们可能站到了自然语言编程的大门口

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

深入理解AMQP协议

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

大型体检管理系统源码:适用于大中型医院或独立体检中心

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

ACM 1000 | 简单的a+b

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

系统分析师选择题笔记

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

MySQL隐式类型转换

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

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...