用python实现语音的传输功能_用Python实现PhotoShop%1的功能

import code
#import craft
#import design
#import others

difficulty = "easy-medium"

bc0d8b1b972d80e64d7c68777c39294e.png

今天为大家带来的是前景与背景叠加操作的Python代码实现。

和画图软件同属于平面图制作软件的PhotoShop,为我们带来的最突出的变革,莫过于引入了图层的概念。有了图层,我们可以在背景上提前绘制好前景,而不用担心位置不对,或者前景覆盖掉背景之类的问题。

前景图就像代码中的函数块一样,可以提前定义好,以后想搁哪用搁哪用。

dedeef67d1d75b785f0c99dd6f28fbe3.png

一张前景图和一张完整的矩形图片不同,它存在很多透明或是半透明的像素点。因此,传统图片的RGB三通道表示法就不够用了,需要引入第四个通道——Alpha,来表示每一个像素点的透明度。也就是说,一张带Alpha通道的图片所包含的信息,需要用一个width*height*4的三维向量来存储。

bca5f4b9eeecf723e7d064d8445f70a2.png

在OpenCV中,我们照常可以使用cv.imread方法打开一张Alpha图片(通常为png格式),不过该方法默认会将图片以三通道的形式导入,自动忽略掉Alpha信息。所以需要在图片地址后面添加一个参数(cv.IMREAD_UNCHANGED)来保证导入的图片为四通道图片。

import cv2 as cv
import numpy as np

foreground = cv.imread("hand.png", cv.IMREAD_UNCHANGED)
background = cv.imread("bg.jpg")

在导入了前景和背景图之后,我们需要考虑如何把他们叠加在一起。假设你的前景和背景拥有相同的长和宽。现在,用OpenCV自带的cv.add方法试试看?

test = cv.add(foreground, background)

------------------------------------
error Traceback (most recent call last)
-2-037009c9cb31> in 5 background = cv.imread("bg.jpg")6
----> 7 test = cv.add(foreground, background)
error: OpenCV(3.4.2) /opt/concourse/worker/vol
umes/live/0851a95b-0a19-4f3a-61a7-502b925fea13
/volume/opencv-suite_1535642710601/work/module
s/core/src/arithm.cpp:659: error: (-209:Sizes
of input arguments do not match) The operationis neither 'array op array' (where arrays hav
e the same size and the same number of channel
s), nor 'array op scalar', nor 'scalar op arra
y' in function 'arithm_op'

显然这样不行。弹出的错误提示告诉我们,用来加和的向量必须有相同的 sizechannel 才行。

那我们用 cv.splitcv.merge 方法把Alpha通道去掉试试看?

b,g,r,alpha = cv.split(foreground)
foreground_BGR = cv.merge((b,g,r))

test = cv.add(foreground_BGR, background)

cv.imshow("img", test)
cv.waitKey(0)
cv.destroyAllWindows()

24ee7a830b3a169c3af7537b90956122.png

虽然不报错了,可还是不行。

cv.add 方法的实现只是简单的像素点数值相加和,加起来大于255的像素点的值会变成255。因此,这个操作会把大部分区域的色值加到一个很高的值。

尤其是,PS在生成透明图的时候,会自动把Alpha=0的像素点的rgb值定为255,也就是白色。所以求和之后,透明区域只能得到白色。除非你很喜欢这个颜色,否则杰尼龟不建议你对喜爱的图片进行这个操作哟。

这时候,被我们冷落许久的Alpha通道看不下去了,大声喊道:我才是今天的主角!

别急,我们这就来临幸你。

首先,我们拆开前景的四个通道,将b, g, r三个通道merge成一张图片。然后把Alpha通道复制三份,同样merge成一张图片。

b,g,r,alpha = cv.split(foreground)
foreground_BGR = cv.merge((b,g,r))
alpha = cv.merge((alpha,alpha,alpha))

然后,我们将alpha中的每一个数除以255,得到一个被压扁的Alpha通道。

alpha = alpha.astype(float)/255

7f6d16bb035fad3764bbea451e65b970.png

注意,此时Alpha向量的数据类型已经从 np.uint8 型自动变为 float 型。为了用cv实现四则运算,我们需要把前景、背景图的数据类型也改为 float 型。

foreground_BGR = foreground_BGR.astype(float)
background = background.astype(float)

接下来就是Alpha图层的高光时刻了。

它已经不再是普通的Alpha通道了,我们不妨给它起一个更厉害的名字,Alpha蒙版。我们拿它直接和去掉透明通道的前景图相乘,啪,我们就得到了一张黑底图!

foreground_BGR = cv.multiply(alpha, foreground_BGR)

ccba2c1dc243fbb2564699bb41ded9bd.png

然后,再用 1.0 减去这个Alpha蒙版,我们就得到了它的反蒙版。用它和背景图相乘,啪,我们就得到了一张抠去手势的背景图!

background = cv.multiply(1.0 - alpha, background)

5c2ce2fa9a5c509f7891c10d9435eaef.png

把这两张图用 cv.add 加在一起...(记得把数据类型改回 np.uint8 )

outImage = cv.add(foreground_BGR, background).astype(np.uint8)

930cc0b55bc3b970245ba982ba953abf.png

砰!叠加完成!前景图和背景图完美地融合在了一起。

嗯,一个看似简单的操作,实际上后台做的事情挺多的,挺喧闹的。

想象一个上百个图层的PSD文件,当你点击另存为,选择jpg格式,点击保存的那一刻,你可能会听到后台隐隐约约传来的...

“突突突突突突突突突突突...”

——————————   End   ——————————

『    机枪扫射声中我们寻找遮蔽的战壕

        儿时沙雕的城堡毁坏了重新盖就好    』

                            《最后的战役》——周杰伦

周更太难了…

这次的背景图是MacBook Pro 15年版的拆机实拍图。前两天,杰尼龟刚刚通过非官方渠道,为服役4年的MBP换了块电池,顺便除了下多年的积灰。清完灰,MBP的主板布阵一下子映入眼帘。六块不同大小的电池,沿着风扇的弧边排列的电子元件,集成感爆棚。所以杰尼龟立马把它拍了下来,设成了电脑桌面。

想要原图的同学们可以向后台回复 insideMac() 索取(记得区分大小写哦)。

想要原代码的同学可回复 alpha() 获取Github链接。

作为OpenCV的初学者,我的代码从实现的角度肯定有很多不成熟的地方,希望CV大佬或者Numpy大佬不吝指点,我会感激不尽。

致匠心。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值