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

使用opencv实现更换证件照背景颜色

1 概述

生活中经常要用到各种要求的证件照电子版,红底,蓝底,白底等,大部分情况我们只有其中一种,本文通过opencv实现证件照背景的颜色替换。

1.1 opencv介绍

OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库。它最初由英特尔在1999年开发,后来由Willow Garage和Itseez(现为部分的Intel)维护。OpenCV旨在提供一个易于使用的计算机视觉基础设施,帮助人们实现复杂的视觉分析任务。

1.2 RGB介绍

RGB 是我们接触最多的颜色空间,由三个通道表示一幅图像,分别为红色(R),绿色(G)和蓝色(B)。这三种颜色的不同组合可以形成几乎所有的其他颜色。

RGB 颜色空间是图像处理中最基本、最常用、面向硬件的颜色空间,比较容易理解。RGB 颜色空间利用三个颜色分量的线性组合来表示颜色,任何颜色都与这三个分量有关,而且这三个分量是高度相关的,所以连续变换颜色时并不直观,想对图像的颜色进行调整需要更改这三个分量才行。

自然环境下获取的图像容易受自然光照、遮挡和阴影等情况的影响,即对亮度比较敏感。而 RGB 颜色空间的三个分量都与亮度密切相关,即只要亮度改变,三个分量都会随之相应地改变,而没有一种更直观的方式来表达。

但是人眼对于这三种颜色分量的敏感程度是不一样的,在单色中,人眼对红色最不敏感,蓝色最敏感,所以 RGB 颜色空间是一种均匀性较差的颜色空间。如果颜色的相似性直接用欧氏距离来度量,其结果与人眼视觉会有较大的偏差。对于某一种颜色,我们很难推测出较为精确的三个分量数值来表示。所以,RGB 颜色空间适合于显示系统,却并不适合于图像处理。

1.3 HSV 颜色空间

基于上述理由,在图像处理中使用较多的是 HSV 颜色空间,它比 RGB 更接近人们对彩色的感知经验。非常直观地表达颜色的色调、鲜艳程度和明暗程度,方便进行颜色的对比。在 HSV 颜色空间下,比 BGR 更容易跟踪某种颜色的物体,常用于分割指定颜色的物体。

HSV 表达彩色图像的方式由三个部分组成:

  • Hue(色调、色相)
  • Saturation(饱和度、色彩纯净度)
  • Value(明度)

用下面这个圆柱体来表示 HSV 颜色空间,圆柱体的横截面可以看做是一个极坐标系 ,H 用极坐标的极角表示,S 用极坐标的极轴长度表示,V 用圆柱中轴的高度表示。

Hue 用角度度量,取值范围为0~360°,表示色彩信息,即所处的光谱颜色的位置。表示如下: 

颜色圆环上所有的颜色都是光谱上的颜色,从红色开始按逆时针方向旋转,Hue=0 表示红色,Hue=120 表示绿色,Hue=240 表示蓝色等等。在 GRB中 颜色由三个值共同决定,比如黄色为即 (255,255,0);在HSV中,黄色只由一个值决定,Hue=60即可。

HSV 圆柱体的半边横截面(Hue=60):

 其中水平方向表示饱和度,饱和度表示颜色接近光谱色的程度。饱和度越高,说明颜色越深,越接近光谱色饱和度越低,说明颜色越浅,越接近白色。饱和度为0表示纯白色。取值范围为0~100%,值越大,颜色越饱和。

竖直方向表示明度,决定颜色空间中颜色的明暗程度,明度越高,表示颜色越明亮,范围是 0-100%。明度为0表示纯黑色(此时颜色最暗)。

可以通俗理解为:

在Hue一定的情况下,饱和度减小,就是往光谱色中添加白色,光谱色所占的比例也在减小,饱和度减为0,表示光谱色所占的比例为零,导致整个颜色呈现白色。

明度减小,就是往光谱色中添加黑色,光谱色所占的比例也在减小,明度减为0,表示光谱色所占的比例为零,导致整个颜色呈现黑色。

HSV 对用户来说是一种比较直观的颜色模型。我们可以很轻松地得到单一颜色,即指定颜色角H,并让V=S=1,然后通过向其中加入黑色和白色来得到我们需要的颜色。增加黑色可以减小V而S不变,同样增加白色可以减小S而V不变。例如,要得到深蓝色,V=0.4 S=1 H=240度。要得到浅蓝色,V=1 S=0.4 H=240度。

HSV 的拉伸对比度增强就是对 S 和 V 两个分量进行归一化(min-max normalize)即可,H 保持不变。

RGB颜色空间更加面向于工业,而HSV更加面向于用户,大多数做图像识别这一块的都会运用HSV颜色空间,因为HSV颜色空间表达起来更加直观!

1.4 HLS 颜色空间

HLS 和 HSV 比较类似,这里一起介绍。HLS 也有三个分量,hue(色相)、saturation(饱和度)、lightness(亮度)。

HLS 和 HSV 的区别就是最后一个分量不同,HLS 的是 light(亮度),HSV 的是 value(明度)。

HLS 中的 L 分量为亮度,亮度为100,表示白色,亮度为0,表示黑色;HSV 中的 V 分量为明度,明度为100,表示光谱色,明度为0,表示黑色。

下面是 HLS 颜色空间圆柱体:

提取白色物体时,使用 HLS 更方便,因为 HSV 中的Hue里没有白色,白色需要由S和V共同决定(S=0, V=100)。而在 HLS 中,白色仅由亮度L一个分量决定。所以检测白色时使用 HSL 颜色空间更准确。

注意:在 OpenCV 中 HLS 三个分量的范围为:

  • H = [0,179]
  • L = [0,255]
  • S = [0,255]

2 使用opencv替换证件照背景颜色

2.1 导入图片并改变图片大小

原始图片:

代码实现:

img = cv2.imread('../data/card_girl01.jpeg')# 缩放
rows, cols, channels = img.shape
img = cv2.resize(img, None, fx=0.5, fy=0.5)
rows, cols, channels = img.shape

2.2 获取背景区域

首先将读取的图像默认BGR格式转换为HSV格式,然后通过inRange函数获取背景的mask。

代码实现:

# 转换hsv
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_blue = np.array([78, 43, 46])
upper_blue = np.array([110, 255, 255])
mask_img = cv2.inRange(hsv, lower_blue, upper_blue)new_image = show_multi_imgs(4, [img, cv2.cvtColor(mask_img, cv2.COLOR_GRAY2BGR)], (1, 2))
cv2.namedWindow('img&mask_img', 0)
cv2.imshow('img&mask_img', new_image)
cv2.waitKey(0)

运行代码显示:

如图所示蓝色的背景在图中用白色表示,白色区域就是要替换的部分,但是黑色区域内有白点干扰,所以进一步优化。

2.3 腐蚀和膨胀

代码实现:

# 腐蚀膨胀
erode_img = cv2.erode(mask_img, None, iterations=1)new_image = show_multi_imgs(4, [img, cv2.cvtColor(erode_img, cv2.COLOR_GRAY2BGR)], (1, 2))
cv2.namedWindow('img&erode_img', 0)
cv2.imshow('img&erode_img', new_image)
cv2.waitKey(0)dilate_img = cv2.dilate(erode_img, None, iterations=1)
new_image = show_multi_imgs(4, [img, cv2.cvtColor(dilate_img, cv2.COLOR_GRAY2BGR)], (1, 2))
cv2.namedWindow('img&dilate_img', 0)
cv2.imshow('img&dilate_img', new_image)
cv2.waitKey(0)

运行代码显示:

处理后图像单独白色点消失。

2.4 替换背景色

遍历全部像素点,如果该颜色为dilate里面为白色(255)则说明该点所在背景区域,于是在原图img中进行颜色替换。

示例代码:

# 遍历替换
final_img = img.copy()
for i in range(rows):for j in range(cols):if dilate_img[i, j] == 255:# 此处替换颜色,为BGR通道final_img[i, j] = (0, 0, 255)new_image = show_multi_imgs(4, [img, final_img], (1, 2))
cv2.namedWindow('img&final_img', 0)
cv2.imshow('img&final_img', new_image)
cv2.waitKey(0)

 运行代码显示:

2.5 完整代码

import cv2
import numpy as np# 一个窗口显示多张图片
def show_multi_imgs(scale, imglist, order=None, border=10, border_color=(255, 255, 0)):""":param scale: float 原图缩放的尺度:param imglist: list 待显示的图像序列:param order: list or tuple 显示顺序 行×列:param border: int 图像间隔距离:param border_color: tuple 间隔区域颜色:return: 返回拼接好的numpy数组"""if order is None:order = [1, len(imglist)]allimgs = imglist.copy()ws, hs = [], []for i, img in enumerate(allimgs):if np.ndim(img) == 2:allimgs[i] = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)allimgs[i] = cv2.resize(img, dsize=(0, 0), fx=scale, fy=scale)ws.append(allimgs[i].shape[1])hs.append(allimgs[i].shape[0])w = max(ws)h = max(hs)# 将待显示图片拼接起来sub = int(order[0] * order[1] - len(imglist))# 判断输入的显示格式与待显示图像数量的大小关系if sub > 0:for s in range(sub):allimgs.append(np.zeros_like(allimgs[0]))elif sub < 0:allimgs = allimgs[:sub]imgblank = np.zeros(((h+border) * order[0], (w+border) * order[1], 3)) + border_colorimgblank = imgblank.astype(np.uint8)for i in range(order[0]):for j in range(order[1]):imgblank[(i * h + i*border):((i + 1) * h+i*border), (j * w + j*border):((j + 1) * w + j*border), :] = allimgs[i * order[1] + j]return imgblankimg = cv2.imread('../data/card_girl01.jpeg')# 缩放
rows, cols, channels = img.shape
img = cv2.resize(img, None, fx=0.5, fy=0.5)
rows, cols, channels = img.shape# 转换hsv
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_blue = np.array([78, 43, 46])
upper_blue = np.array([110, 255, 255])
mask_img = cv2.inRange(hsv, lower_blue, upper_blue)new_image = show_multi_imgs(4, [img, cv2.cvtColor(mask_img, cv2.COLOR_GRAY2BGR)], (1, 2))
cv2.namedWindow('img&mask_img', 0)
cv2.imshow('img&mask_img', new_image)
cv2.waitKey(0)# 腐蚀膨胀
erode_img = cv2.erode(mask_img, None, iterations=1)new_image = show_multi_imgs(4, [img, cv2.cvtColor(erode_img, cv2.COLOR_GRAY2BGR)], (1, 2))
cv2.namedWindow('img&erode_img', 0)
cv2.imshow('img&erode_img', new_image)
cv2.waitKey(0)dilate_img = cv2.dilate(erode_img, None, iterations=1)
new_image = show_multi_imgs(4, [img, cv2.cvtColor(dilate_img, cv2.COLOR_GRAY2BGR)], (1, 2))
cv2.namedWindow('img&dilate_img', 0)
cv2.imshow('img&dilate_img', new_image)
cv2.waitKey(0)# 遍历替换
final_img = img.copy()
for i in range(rows):for j in range(cols):if dilate_img[i, j] == 255:# 此处替换颜色,为BGR通道final_img[i, j] = (0, 0, 255)new_image = show_multi_imgs(4, [img, final_img], (1, 2))
cv2.namedWindow('img&final_img', 0)
cv2.imshow('img&final_img', new_image)
cv2.waitKey(0)

相关文章:

使用opencv实现更换证件照背景颜色

1 概述 生活中经常要用到各种要求的证件照电子版&#xff0c;红底&#xff0c;蓝底&#xff0c;白底等&#xff0c;大部分情况我们只有其中一种&#xff0c;本文通过opencv实现证件照背景的颜色替换。 1.1 opencv介绍 OpenCV&#xff08;Open Source Computer Vision Librar…...

Unity打出的安卓包切换后台再恢复前台,卡顿许久问题记录

连接AndroidStudio发现当切换后台时提示&#xff1a;D/Unity: Multi-casting "[IP] 192.168.31.231 [Port] 55000 [Flags] 19 [Guid] 1268732307 [EditorId] 264356214 [Version] 1048832 [Id] AndroidPlayer(11,Xiaomi_M2012K11AC192.168.31.231) [Debug] 0 [PackageName…...

Linux常用命令----shutdown命令

文章目录 命令概述参数解释使用示例及解释 命令概述 shutdown 命令用于安全地关闭或重启 Linux 系统。它允许管理员指定一个时间点执行操作&#xff0c;并可发送警告信息给所有登录的用户。 参数解释 时间参数 ([时间]): now: 立即执行关闭或重启操作。m: 在 m 分钟后执行操作…...

美创科技受邀亮相第二届全球数字贸易博览会

11月23日-27日&#xff0c;由浙江省人民政府、商务部共同主办的第二届全球数字贸易博览会&#xff08;以下简称“数贸会”&#xff09;圆满落幕。围绕“国家级、国际性、数贸味”的目标定位&#xff0c;以“数字贸易 商通全球”为主题&#xff0c;数贸会重点展示数字贸易全产业…...

有n件物品,每件物品都有一个花费,要求每m个中必须至少选2个,求最小花费

题目 #include<bits/stdc.h> using namespace std; #define int long long #pragma GCC optimize(2) const int maxn 2e4 5, maxm 2e3 5, inf 1e9; int a[maxn]; int f[maxm][maxm];//f[i][j]表示选了第i个&#xff0c;上一个选的是第i-j个&#xff08;每m个中选2个…...

Hive数据库与表操作

文章目录 一、准备工作二、Hive数据库操作&#xff08;一&#xff09;Hive数据存储&#xff08;二&#xff09;创建数据库&#xff08;三&#xff09;查看数据库&#xff08;四&#xff09;修改数据库信息 一、准备工作 二、Hive数据库操作 &#xff08;一&#xff09;Hive数据…...

C语言数据结构之顺序表(上)

前言&#xff1a; ⭐️此篇博文主要分享博主在学习C语言的数据结构之顺序表的知识点时写的笔记&#xff0c;若有错误&#xff0c;还请佬指出&#xff0c;一定感谢&#xff01;制作不易&#xff0c;若觉得内容不错可以点赞&#x1f44d;收藏❤️&#xff0c;这是对博主最大的认可…...

详解原生Spring中的控制反转和依赖注入-构造注入和Set注入

&#x1f609;&#x1f609; 学习交流群&#xff1a; ✅✅1&#xff1a;这是孙哥suns给大家的福利&#xff01; ✨✨2&#xff1a;我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 &#x1f96d;&#x1f96d;3&#xff1a;QQ群&#xff1a;583783…...

数组中的第 K 个最大元素(C++实现)

数组中的第 K 个最大元素 题目思路代码 题目 数组中的第 K 个最大元素 思路 通过使用优先队列&#xff08;最大堆&#xff09;来找到数组中第k大的元素。通过弹出最大堆中的前k-1个元素&#xff0c;留下堆中的顶部元素作为结果返回。 代码 class Solution { public:int find…...

C++ day42背包理论基础01 + 滚动数组

背包问题的重中之重是01背包 01背包 有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品只能用一次&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 每一件物品其实只有两个状态&#xff0c;取或者不…...

数字人透明屏幕是如何工作的?

数字人透明屏幕是一种令人兴奋的科技产品&#xff0c;它结合了人脸识别、全息影像技术以及透明屏幕&#xff0c;为人们带来了全新的互动体验。本文将详细介绍数字人透明屏幕的工作原理以及其应用场景。 工作原理 数字人透明屏幕的工作原理主要包括人脸识别和全息影像技术。人脸…...

MIGO收货报替代“ZF002“, 步骤““ 中存在语法错误消息号 GB032错误

MIGO收货报替代"ZF002", 步骤"" 中存在语法错误消息号 GB032错误。替代"ZF002", 步骤"" 中存在语法错误消息号 GB032诊断 在 ABAP 代码生成过程中&#xff0c;在替代ZF002中发现了语法错误。 系统响应 未为该布尔陈述生成 ABAP 代码&…...

Vue3的transition标签以及animate.css使用详解

一&#xff1a;前言 在项目开发中&#xff0c;有一种特殊情况是使用动画过渡去完成某个效果。比如淡入淡出&#xff0c;或者在动画完成后执行某些操作等。在以前开发中我们通常会选择使用 CSS3 进行研发。但是这样会有很多不好的地方&#xff0c;比如最原始化的封装&#xff0c…...

IDEA不支持Java8了怎么办?

IDEA不支持Java8了怎么办&#xff1f; 01 异常发生场景 当我准备创建一个springboot项目时&#xff0c;发现Java8没了 02 问题的产生及其原因 查阅了官方文档之后&#xff0c;确认了是Spring Boot 不再支持 Java 8&#xff0c;不是我的问题&#xff0c;这一天终于还是来了 0…...

flutter的TextField参数、案例整理(上)

TextField 概述 TextField 用于文本输入 构造函数 const TextField({Key key,this.controller, this.focusNode,this.decoration const InputDecoration(),TextInputType keyboardType,this.textInputAction,this.textCapitalization TextCapitalization.none,this.style…...

【Linux进阶之路】进程间通信

文章目录 一、原理二、方式1.管道1.1匿名管道1.1.1通信原理1.1.2接口使用 1.2命名管道 2.共享内存2.1原理2.2接口使用 3.消息队列原理 4.信号量引入原理 总结 一、原理 进程间的通信是什么&#xff1f;解释&#xff1a; 简单理解就是&#xff0c;不同进程之间进行数据的输入输出…...

深度学习框架配置

目录 1. 配置cuda环境 1.1. 安装cuda和cudnn 1.1.1. 显卡驱动配置 1.1.2. 下载安装cuda 1.1.3. 下载cudnn&#xff0c;将解压后文件复制到cuda目录下 1.2. 验证是否安装成功 2. 配置conda环境 2.1. 安装anaconda 2.2. conda换源 2.3. 创建conda环境 2.4. pip换源 3.…...

全局配置

1.全局配置文件及其配置项 1.1.小程序窗口 1.2 窗口节点 1.2.1 导航栏标题 标题&#xff1a; 标题颜色&#xff1a; 背景色&#xff1a;只支持16进制值 下拉刷新&#xff1a; 刷新背景色&#xff1a; 刷新样式&#xff1a; 触底距离&#xff1a;...

leetcode算法之字符串

目录 1.最长公共前缀2.最长回文子串3.二进制求和4.字符串相乘 1.最长公共前缀 最长公共前缀 class Solution { public:string longestCommonPrefix(vector<string>& strs) {//法一&#xff1a;两两比较string ret strs[0];for(int i1;i<strs.size();i){ret f…...

mongodb查询数据库集合的基础命令

基础命令 启动mongo服务 mongod -f /usr/local/mongodb/mongod.conf //注意配置文件路径停止mongo服务 关闭mongodb有三种方式&#xff1a; 一种是进入mongo后通过mongo的函数关闭&#xff1b; use admin db.shutdownServer()一种是通过mongod关闭&#xff1b; mongod --s…...

C++“流星蝴蝶剑”动画的解析

C流星蝴蝶剑萍乡C创意编码精灵库案例这段视频展示了一个使用 C 编写的图形化演示程序&#xff0c;名为“C 流星蝴蝶剑”。视频主要分为三个部分&#xff1a;最终效果展示、生成“光剑”的代码解析、以及生成背景飞舞文字的代码框架解析。 以下是详细的视频与程序描述&#xff…...

AI_概念篇_MCP

AI_概念篇_MCP让 AI 真正能"动手"的标准协议没有 MCP 之前&#xff1a;重复造轮子的时代 早期 Agent&#xff08;2023 年前后的 AutoGPT、早期 GitHub Copilot 等&#xff09;要调用外部工具&#xff0c;每个平台都得自己硬编码实现一遍&#xff1a; Cursor 自…...

小白也能用的AI神器:Anything to RealCharacters 2.5D转真人引擎全流程体验

小白也能用的AI神器&#xff1a;Anything to RealCharacters 2.5D转真人引擎全流程体验 1. 从动漫到真人的神奇转换 你是否曾经想过&#xff0c;把自己喜欢的动漫角色变成真实人物会是什么样子&#xff1f;或者想把游戏中的虚拟形象变成一张可以打印的照片&#xff1f;现在&a…...

PHP 8.9 GC性能瓶颈诊断全流程:从memory_get_usage()到gc_status()再到xdebug_gc_dump()的4步精准定位法

第一章&#xff1a;PHP 8.9 垃圾回收优化方法PHP 8.9 引入了基于引用计数增强与周期检测协同的混合式垃圾回收&#xff08;GC&#xff09;机制&#xff0c;显著降低了内存泄漏风险并提升了长生命周期对象的清理效率。该版本默认启用增量式 GC 扫描&#xff0c;并支持运行时动态…...

打破虚拟世界语言壁垒:VRCT实现VRChat跨语言交流的技术方案与实践指南

打破虚拟世界语言壁垒&#xff1a;VRCT实现VRChat跨语言交流的技术方案与实践指南 【免费下载链接】VRCT VRCT(VRChat Chatbox Translator & Transcription) 项目地址: https://gitcode.com/gh_mirrors/vr/VRCT 在全球化的虚拟社交平台VRChat中&#xff0c;语言差异…...

STM32F103RCT6定时器实战:从基础配置到PWM波形测量

1. STM32F103RCT6定时器基础入门 第一次接触STM32的定时器时&#xff0c;我完全被各种专业术语搞晕了。什么预分频器、自动重装寄存器、时基单元&#xff0c;听起来就像天书一样。但实际用起来才发现&#xff0c;定时器就像厨房里的定时闹钟&#xff0c;只不过更精确、更灵活。…...

SmolVLA实战教程:USAGE.md文档结构解析与核心功能速查表

SmolVLA实战教程&#xff1a;USAGE.md文档结构解析与核心功能速查表 1. 引言&#xff1a;为什么你需要关注SmolVLA&#xff1f; 如果你正在寻找一个既强大又轻量的机器人控制模型&#xff0c;那么SmolVLA绝对值得你花时间了解。想象一下&#xff0c;一个只有5亿参数的模型&am…...

JAVA:Spring Boot 集成 RDF4J 实现欺诈技术检测

1、简述 在大数据、知识图谱和金融风控等领域,RDF(Resource Description Framework) 是一种用于表示和查询关联数据的强大工具。RDF4J 是一个流行的 Java 库,用于操作 RDF 数据集,并支持 SPARQL 查询,能够帮助我们进行复杂的欺诈检测。 项目的核心功能: RDF 数据存储:…...

zookeeper 常用命令之zkCli

简介&#xff1a;介绍zkCli客户端非常常用的命令 zkCli.sh 不填后面的参数&#xff0c;默认连接的就是localhost:2181zk节点类似Linux的目录&#xff0c;比如/uar/local&#xff0c;-s表示持久的节点&#xff0c;-e是临时的节点。data是往这个节点里面放入哪些数据&#xff0c…...

DoL-Lyra整合包:三步打造你的专属Degrees of Lewdity游戏体验

DoL-Lyra整合包&#xff1a;三步打造你的专属Degrees of Lewdity游戏体验 【免费下载链接】DOL-CHS-MODS Degrees of Lewdity 整合 项目地址: https://gitcode.com/gh_mirrors/do/DOL-CHS-MODS 你是否厌倦了在Degrees of Lewdity英文原版游戏中费力查找词典&#xff1f;…...