简陋无比的 Python 抠图方案,好像还挺像回事儿?
Python编程学习点击免费领取
背景介绍
从某APP中截取了我的背单词曲线之后,我敏锐地发现了蕴藏在其中的数学规律。
每六个月达到一次峰值,峰值的高度不断减小。为了在图上画一条线来拟合这个折线,我打开 MATLAB 一通操作猛如虎,画出了一个正弦函数受到一个衰减指数函数的调制的图像。但问题来了,我不知道怎么把这两个图贴在一起,需要把 MATLAB 绘制的曲线从白色背景中抠出来。
联想到曾经我用 Excel 抠二维码的憨批操作(当时不用PS),我觉得还是有必要进化一下我的抠图技能。
纯色背景抠图
从原理上讲,从这么一个简单背景中把图案抠出来,无非就是对每一个像素点检查它的颜色,如果是背景色就把透明度变成0,否则保留。因此,这是非常容易实现的。
from PIL import Imageim = Image.open('SaoMaYouJingXi.jpg') #读取图片
im = im.convert('RGBA') #转化成RGBA(RBG+透明度)格式
pix = im.load()width = im.size[0]
height = im.size[1]for x in range(width):for y in range(height): r, g, b, a = pix[x, y] if (r>100)&(g>100): #如果是白色a = 0 #透明度改成0im.putpixel((x,y),(r,g,b,a)) #把四个参数还给这个像素im.save("SaoMaYouJingXi.PNG") #保存# 早期写的东西甚至完全没有代码规范意识
复制代码
小试牛刀:
不愧是精确到像素的抠图,放大了看也这么干净利索。
变色背景抠图
但,从纯色简单背景中抠图就太没意思了。我又联想到曾经用Excel从照片里抠手绘的班徽:
当时也是费了很大功夫,抠出来的效果在浅色背景下还可以,但是放在深色背景中就非常不堪入目了。于是,我打算想办法把班徽重新抠一下。
第一次尝试
既然不是简单的纯黑或纯白背景,没办法直接判断颜色的RGB值大概在什么范围,那么我们首先要让程序去识别并记住背景有哪些颜色,然后再把这些颜色的像素抠掉。
所以我们要分两大步:
- 手动从背景中采样,截图保存,导入程序,供其识别、记录;
- 把整个图片导入,处理,导出。
这张班徽的照片里,我在四条边附近分别截取了一张背景样本,后来为了优化效果,又在没抠掉的地方补了一张。
接下来就是让计算机记住这些出现过的颜色。
我们知道,一个像素的颜色可以用R(0-255)
、G(0-255)
、B(0-255)
三个变量来表示,一张图中的颜色总数不超过256^3
。
鉴于我们现在只关心某一种颜色有没有出现过,不妨创建一个256x256x256
的三维哈希表。
可以想象一个大的正方体,里边有256^3
个小格子。初始状态下每个小格子里都是0
,当计算机看到出现某一种颜色(m,n,p)
,就把第m行
、第n列
、第p层
的那个小格子里的0
变成1
。等计算机遍历完了所有的像素,这些格子里该填1
的都填上了1
。
这里,我们为了减小计算机的工作量,可以把相邻的3
个R/G/B
值简化成一个(如R=0,1,2→R'=0
、R=3,4,5→R'=1
),把这个256x256x256
的正方体压缩一下,长宽高各变为原来的1/3
,列表大小缩小到原来的1/27
。
matrix=[]
for i in range(85):matrix.append([])for j in range(85):matrix[i].append([])for k in range(85):matrix[i][j].append(0)
复制代码
然后我们不动这个大盒子,让计算机再去检查第二个样本……等到所有的样本都看完了,盒子就填得差不多了。这时候,背景中出现过的颜色大部分已经被标记了。
我们把这个检查的过程定义为learn
:
def learn(str):im = Image.open(str)pix = im.load()width = im.size[0]height = im.size[1]for x in range(width):for y in range(height):r, g, b = pix[x, y]matrix[r][g][b]=1
复制代码
在本例中,让程序learn
完五张采样得到的背景图,再执行抠图的主程序,保存图片。
接下来我们看下效果:
失望,非常失望。无论我再怎么给它查漏补缺,补充新的背景来learn
,抠出来还是会有大量残留。
不过没关系,我们可以再模糊一点。宁可错抠一千,不放过一个。
第二次尝试
接下来,我们增设一个模糊度dim
,意思是在抠图的判断条件中,只要这个点的RGB
坐标出现在被标记坐标的附近,三个坐标分量都在某被标记点对应坐标分量±dim
的范围内,即该点的RGB
坐标在以某被标记点为中心、棱长为2*dim
的正方体内,我们就把它抠掉。
具体操作不再赘述。随着我不断增大dim
的值,残留的区域确实越来越少,但是结果总是不尽人意。
第三次尝试
于是,我不再满足于小立方体级别的模糊,决定大手一挥,激进一点。
这次,我打算计算出背景中所有像素点的R、G、B
各自的最大值和最小值,然后把所有R、G、B
都在最大值之下、最小值之上(包含最值)的像素全部抠掉。
为了判断方案的可行性,我把图片信息按颜色展开,在坐标系中呈现出来。
这里,X、Y、Z轴分别是压缩之后的RGB值,范围是[0,85]
中的整数。
每个点的颜色就是它的坐标对应的RGB值所对应的颜色。
在三维坐标系中,引入透明度,可以刻画第四个维度的信息。我们选取该坐标处像素的数量(也就是在原图中有多少个点同为这个颜色)作为透明度的自变量。
为了控制因变量,也就是透明度的范围在[0,1]
,我们需要知道最多有多少个像素是同一个颜色,把这个最大值作为分母。
同时,为了避免这个最大值过大,导致大部分点的透明度都非常高(透明度越接近0,记为越高),我们换一种映射,把通过比值求出来的相对透明度开四次根号。
最终,我们画出来的图像是这样的:
越不透明的点表示对应颜色的像素越多。
下面我们回到抠图。
分析一下刚刚费了不少力气画的这个图,我们发现,三种主色还是相对来说界限分明的。如果你不信,我可以随便找一张图给你展开一下:
我们来看一下背景样本中所有颜色的R、G、B的最大值和最小值。
这个结果其实非常符合预期,因为从刚才那个坐标系中可以看到,跟背景相近的颜色都集中在R、G、B都非常大的地方。
我们把R、G、B都在对应区间里的点抠掉,然后看一下效果:
AMAZING!
简直完美。尽管我事实上并不认可这个原理,毕竟本质上这属于莽夫行为。但是不得不说,这个效果确实是非常不错的。
对比一下Excel抠图、learn抠图和莽夫抠图:
简直是一部愈演愈烈的革命乐章!
总结
至此,我已经完成了我最初的目标,并且积累了一套极其简陋但却好像还挺像回事儿的抠图方案。
在我看来,代码抠图的魅力不仅在于它精确到像素的精准打击,也在于它可以让你随心所欲定制需求的可塑性,还在于它只需要你更改一两个参数、点一下编译运行,就能自动输出成果的便捷。
此外,我还顺便做了一些同样没什么用的小功能,比如马赛克:
不论是抠图也好,打码也好,逻辑上不难理解,代码上也不难实现。在日常生活中,有时候手边就是缺乏处理简单任务的专业工具,比如 PhotoShop 。这时候与其安装 Ps ,倒不如自己写一个程序,根据自己的需求编码实现功能,看似麻烦,实则不失为一条捷径。
①3000多本Python电子书有
②Python开发环境安装教程有
③Python400集自学视频有
④软件开发常用词汇有
⑤Python学习路线图有
⑥项目源码案例分享有如果你用得到的话可以直接拿走,在我的QQ技术交流群里(技术交流和资源共享,广告勿入)可以自助拿走,群号是895937462。
简陋无比的 Python 抠图方案,好像还挺像回事儿?相关推荐
- 好像还挺好玩的GAN8——SRGAN实现图像的分辨率提升
好像还挺好玩的GAN8--SRGAN实现图像的分辨率提升 注意事项 学习前言 什么是SRGAN 代码与训练数据的下载 神经网络组成 1.生成网络 2.判别网络 训练思路 1.对判别模型进行训练 2.对 ...
- 好像还挺好玩的GAN重制版4——Pytorch搭建SRGAN平台进行图片超分辨率提升
好像还挺好玩的GAN重制版4--Pytorch搭建SRGAN平台进行图片超分辨率提升 学习前言 源码下载地址 网络构建 一.什么是SRGAN 二.生成网络的构建 三.判别网络的构建 训练思路 一.判别 ...
- 好像还挺好玩的GAN2——Keras搭建DCGAN利用深度卷积神经网络实现图片生成
好像还挺好玩的GAN2--Keras搭建DCGAN利用深度卷积神经网络实现图片生成 注意事项 学习前言 什么是DCGAN 神经网络构建 1.Generator 2.Discriminator 训练思路 ...
- 好像还挺好玩的GAN重制版2——Keras搭建SRGAN平台进行图片超分辨率提升
好像还挺好玩的GAN重制版2--Keras搭建SRGAN平台进行图片超分辨率提升 学习前言 源码下载地址 网络构建 一.什么是SRGAN 二.生成网络的构建 三.判别网络的构建 训练思路 一.判别器的 ...
- python编程抠图_你还在自己抠图吗?我用Python5行代码就可实现批量抠图哦(赶紧收藏吧!)...
前言 对于会PhotoShop的人来说,抠图是非常简单的操作了,有时候几秒钟就能扣好一张图.不过一些比较复杂的图,有时候还是要画点时间的,今天小编就给大家带来了一个非常快速简单的办法,用Python来 ...
- python 抠图源码_别再自己抠图了,Python用5行代码实现批量抠图
前言 对于会PhotoShop的人来说,抠图是非常简单的操作了,有时候几秒钟就能扣好一张图.不过一些比较复杂的图,有时候还是要画点时间的,今天就给大家带了一个非常快速简单的办法,用Python来批量抠 ...
- python抠图精确到发丝_别再用PS了,我用五行Python代码就实现了批量抠图
对于会PhotoShop的人来说,抠图是非常简单的操作了,有时候几秒钟就能扣好一张图.不过对于一些比较复杂的图,有时候还是需要花点时间的,今天就给大家带了一个非常快速简单的办法,用Python来批量抠 ...
- python抠图精确到发丝_Python用5行代码实现批量抠图的示例代码
前言 对于会PhotoShop的人来说,抠图是非常简单的操作了,有时候几秒钟就能扣好一张图.不过一些比较复杂的图,有时候还是要画点时间的,今天就给大家带了一个非常快速简单的办法,用Python来批量抠 ...
- python抠图_别再用PS了,我用五行Python代码就实现了批量抠图
对于会PhotoShop的人来说,抠图是非常简单的操作了,有时候几秒钟就能扣好一张图.不过对于一些比较复杂的图,有时候还是需要花点时间的,今天就给大家带了一个非常快速简单的办法,用Python来批量抠 ...
最新文章
- java opengl es_Java-Android-使用openGL ES绘制3D然后绘制2D
- 2、Ktor学习-自动重新加载;
- python迭代法求解非线性方程_荐【数学知识】非线性方程求解的二分法以及牛顿迭代法...
- mysql存储语句_MYSQL 常用语句保存
- OSPF——GRE Tunnel(含配置命令)详解
- P4行为模型BMV2依赖关系安装:thrift nanomsg nnpy安装
- 给notepad++添加右键菜单
- win10家庭版无法安装mysql_Win10安装MySQL
- Java面试题:final和Object类常见的方法
- python 共享文件_通过 Python 快速实现局域网内文件共享
- Swing Copters摇摆直升机高分攻略,游戏攻略
- ZKT门禁机标准联接线(按键开关不经过卡机)
- 2023年4月动漫新番最新资讯已公布52部!
- 三阶齐次线性方程求通解_三阶常系数线性微分方程特解的简单求法
- dnf剑魂buff等级上限_DNF剑魂职业定位、装备、加点、猴戏、新老换装详解
- 运行时异常一般异常的区别
- pcb布线时爬电距离的总结与算法
- AI芯片加持,安防下一爆点会是边缘计算?
- 产品营销策划方案怎么写?,总结4步!
- 索尼笔记本 触摸屏 fn 快捷键处理