利用Python实现证件照底色替换(k-means)
时间:2022-07-23
本文章向大家介绍利用Python实现证件照底色替换(k-means),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
最近在看了一部分的超像素分割相关资料,主要看了SLIC的原理及实现。其实就是利用k-means实现像素的聚类,再进行一部分操作,进而实现对图像的分割。
对于证件照来说,其有一个很重要的特点:图像边缘明显。因此就想到如果把图像分割用在证件照上效果肯定特别明显,于是就动手实现了一下。可以看到在人像和背景部分的分割线是很明显的,效果还不错。
而想到本科毕业时大家有一个需求,有些时候大家存的证件照底色不符合上传要求,这时就要用ps搞一下,并不是每一个人电脑上都会装ps,总不能为了换个底色装个Photoshop吧,因此想到既然都已经实现分割了,为何不把底色部分换个颜色进而实现证件照换底色操作呢。于是就做了。
过程大致分为四步:
- 读入图像建立k-meanss样本;
- 使用k-means图像分割,指定指定分类数目;
- 取左上角的label得到背景cluster index;
- 生成alpha图,然后选取新背景进行合成。
代码如下:
# coding: utf-8
import numpy as np
import cv2 as cv
image = cv.imread('idid.jpg')
cv.imshow("input", image)
h, w ,ch = image.shape
# 构建图像数据
data = image.reshape((-1,3))
data = np.float32(data)
# 图像分割
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
num_clusters = 4
ret,label,center=cv.kmeans(data, num_clusters, None, criteria, num_clusters, cv.KMEANS_RANDOM_CENTERS)
# 生成mask区域
index = label[0][0]
center = np.uint8(center)
color = center[0]
mask = np.ones((h, w), dtype=np.uint8)*255.
label = np.reshape(label, (h, w))
# alpha图
mask[label == index] = 0
# 下面其实就是在Photoshop中的操作
# 高斯模糊
se = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
# 膨胀,防止背景出现
cv.erode(mask, se, mask)
#边缘模糊
mask = cv.GaussianBlur(mask, (5, 5), 0)
cv.imshow('alpha-image',mask)
# 白色背景
bg = np.ones(image.shape, dtype=np.float)*255.
# 红色背景
red = np.array([0, 0, 255])
bg_color = np.tile(red, (image.shape[0], image.shape[1], 1))
alpha = mask.astype(np.float32) / 255.
fg = alpha[..., None] * image
new_image = fg + (1 - alpha[..., None])*bg
new_image_purle = fg + (1 - alpha[..., None])*bg_color
cv.imwrite("idwhite.jpg", np.hstack((image, new_image.astype(np.uint8))))
cv.imwrite("idred.jpg", np.hstack((image, new_image_purle.astype(np.uint8))))
cv.waitKey(0)
cv.destroyAllWindows()
效果如下:(证件照来自网络,图侵删)其中蓝色为原图。
就是做着玩,大佬勿喷。
- 《Redis设计与实现》读书笔记(十四) ——Redis RDB文件创建、载入与自动保存原理
- 框架 | Spark中的combineByKey
- 《Redis设计与实现》读书笔记(十五) ——Redis AOF持久化原理与实现
- PHP CodeBase: 生成N个不重复的随机数
- PHP转义Json里的特殊字符的函数
- PHP使用SOAP调用.net的WebService问题
- 框架 | spray-routing的核心流程
- 高通msm8909耳机调试
- 了解PHP中Stream(流)的概念与用法
- 动态绑定与静态绑定
- Android4.0 声卡配置-高通msm8916移植
- PHP安全:session劫持的防御
- 函数式非凡的抽象能力
- 设备树的interrupt
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 无法用排他锁锁定该数据库,以执行该操作。 (Microsoft SQL Server,错误: 5030)
- Spring security OAuth2.0认证授权学习第四天(SpringBoot集成)
- php hash算法类
- Spring security OAuth2.0认证授权学习第三天(认证流程)
- uni-app搜索历史记录功能实现
- [903]linux文件删除后磁盘空间没有释放
- Spring如何实现AOP,请不要再说cglib了!
- Redis安装问题解决方案
- 高效的5个pandas函数,你都用过吗?
- jz2440重新分区
- 腾讯云TCB云函数趣应用:巧用 puppeteer 五分钟实现一个云加社区个人成就爬虫
- NFS挂载的2种方式
- Angular Component 开发时属性和运行时属性的对照
- 第002课 ubuntu环境搭建和ubuntu图形界面操作(免费)
- 爆破cobalt strike密码脚本