python 中将jpg格式的图像转换成png格式,并进行程序改进

首先进行科普的是,png格式与普通的图像格式有何不同。

最直观的感受就是,相比于其他格式,png格式多了一个alpha通道,用来存储透明度信息,像素位置 img(x,y) 取值255为不透明,取值为0则为透明。这就使得png具有背景透明的显示效果。如下图所示,这是本人项目中的一部分,提取人脸面部的某些特征,用绿色显示,而在将像素矩阵存储为jpg格式图片时,背景区域会显示为黑色(0,0,0)。

在很多场合,如AE、Edius等制作视频时,添加素材,我们需要的只是素材主体,而不需要背景,即这种效果

这就需要在存储图片时将背景去掉。这就是png格式的好处之一,可以设置透明度,将背景去掉。

 

接下来步入正题,如何将jpg转换成png,也就是增加一个通道,记录透明度信息。

python的pillow库中有对应api,直接添加A通道。这里有一篇参考文章。https://blog.csdn.net/A156348933/article/details/85503453,将其程序段贴出来

# pip install Pillow
import PIL.Image as Image
# 以第一个像素为准,相同色改为透明
def transparent_back(img):
    img = img.convert('RGBA')
    L, H = img.size
    color_0 = (255,255,255,255)#要替换的颜色
    for h in range(H):
        for l in range(L):
            dot = (l,h)
            color_1 = img.getpixel(dot)
            if color_1 == color_0:
                color_1 = color_1[:-1] + (0,)
                img.putpixel(dot,color_1)
    return img

if __name__ == '__main__':
    img=Image.open('img.png')
    img=transparent_back(img)
    img.save('img2.png')

当然,图片中那一部分像素设置成透明,这需要我们根据自己的项目需求自行设定。以上文章中,设定的条件是

color_0 = (255,255,255,255)#要替换的颜色

其中,前三个通道的自己设定,最后一个通道即新添加的alpha通道,默认值全是255。而这个通道,也就是我们要针对修改的值。上述代码中有两个for循环,逐个像素进行处理,效率比较低。笔者用来处理9张1632x1224尺寸的图片,在8核2.4赫兹主频的服务器上运行时间为

这很难满足生产需要。因此这一次的改进主要是去掉上述代码的for循环。

def convertPNG(img1):
    img = img1.convert('RGBA')
    r, g, b, a = img.split()    
    a0 = np.array(b) #转换为np矩阵
    a1 = cv2.threshold(a0,10,255,cv2.THRESH_BINARY) #设定阈值
    a2 = Image.fromarray(a1[1]) #转换为Image的tube格式,注意为a1[1]
    a3 = np.array(a2)
    a4 = Image.fromarray(a3.astype('uint8')) #由float16转换为uint8
    img = Image.merge("RGBA", (b, g, r, a4))  
    return img

if __name__ == '__main__':
    img=Image.open('white.png')
    img1=convertPNG(img)
    img1.save('img2.png')

上述代码,简易言之,就是将pillow图片格式转换到opencv能够处理的格式(uint8的ndarray),然后用矩阵计算的方式来代替两个for循环,之后再转换为pillow能够处理的格式。这样的好处就是节约了大量时间。同样环境下,处理同样图片,时间如下

效率提升2个数量级。

另外要讨论的是,这一次用到了cv2.threshhold设定阈值,将阈值以下的像素,alpha通多直接设置成透明。如果需要指定某一特定值(0-255)的像素为透明,则可以用两次cv2.threshhold,其中一次用INV取反,也可以进行矩阵计算。

  • 12
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值