Pillow库学习笔记之Image.convert去底色详解

本文介绍了如何使用Python的PIL库处理图像,通过操作数组和使用convert方法去除图片中的背景色。在处理过程中,通过比较像素RGB值并设置阈值实现背景色替换。同时,探讨了convert方法的二值化选项,包括无抖动和Floyd-Steinberg抖动算法的影响,展示了如何避免不必要的残余。最后,通过convert('1')一步到位实现去背景色和二值化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目的

在这里插入图片描述
需要提取出图中的数字,但是图中数字受到两种背景色的影响,因此需要先将其去掉。

实现

方法一(直接对数组操作)

首先按照官网示例看看图片的基本信息。

from PIL import Image
im = Image.open("xxx.jpg")
print(im.format, im.size, im.mode)

分别打印出图片的格式,尺寸,颜色模式如下:

JPEG (144, 231) RGB

图片是RGB模式也就意味着图片包含三个通道的信息,我们实际要处理的是231(高度)x144(宽度)x3(R,G,B)的数组。那么接下来以数组的形式读取:

import numpy as np
arr = np.array(im,dtype=int) #像素值默认为ubyte,范围为0-255,做加减会溢出

这里需要注意如果不写dtype=int在可能的加减运算中会有溢出警告提示,虽然在这里无加减,但为了规范,统一int导入utype导出。
随意打印几个特殊点的像素值进行分析:

print(arr[52][71])   #162,223,224
print(arr[181][56])  #224,159,223
print(arr[82][33]) #0,2,5

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里推荐进去左下选图片拾色,在线查看图片各点像素值。可以发现黑色的RGB值都很低,而其他两种颜色的RGB值较高。我们选取R通道进行操作:

for x in range(0,arr.shape[0]):
    for y in range(0,arr.shape[1]):
        if arr[x][y][0]>128:
            arr[x][y]=255

遍历所有像素值,一旦R通道值大于128,则将其RGB三通道值变为255,也就是纯白。

new_im = Image.fromarray(arr.astype(np.ubyte))
new_im.show()

将数组以之前说的ubyte形式导出至Image对象,并显示处理后的图片。

// A code block
var foo = 'bar';

在这里插入图片描述
可以发现两种颜色基本被去掉,但有边角残余,完美主义者是不能接受的。

img = new_im.convert('1')
img.show()

再调用convert方法转换二值化。
在这里插入图片描述
可以发现残余被去掉了,但这样太麻烦了,能不能直接调用convert方法一步到位呢?

方法二(调用convert+操纵数组)

实际上调用convert方法也有两种实际上的操作,先讲复杂的。

im = im.convert('L')
im.show()

L代表灰度模式,1代表二值化(0和1)模式。为加深理解,这里先转化为灰度模式:
在这里插入图片描述
还是和之前一样变为数组导入,此时由于是灰度模式,会发现我们的数组维度变成了(231,144),没有三通道信息,和先前一样把大于128的值变为255。

import numpy as np
arr = np.array(im,dtype=int)
for x in range(0,arr.shape[0]):
    for y in range(0,arr.shape[1]):
        if arr[x][y]>128:     #此时没有了第三个维度[0]
            arr[x][y]=255
new_im = Image.fromarray(arr.astype(np.ubyte))
new_im.show()

在这里插入图片描述
先灰度再对数组进行操作就没有那些残余了。当然,还有更简单的方法。

方法三(一步到位convert)

肯定有人会和我一样的想法,为什么不直接二值化呢?让我们看看结果:

img = im.convert('1')
img.show()

在这里插入图片描述
为什么会有这么多点?不是把128以上的变成白,128以下的变成黑了吗?难不成背景颜色中的值其实相差很大?
其实,这是默认算法中的Floyd-Steinberg dither(弗洛伊德-斯滕伯格抖动)算法的影响。简单理解就是把该点的像素抖动到了附近的点上,原因是我们的人眼是对一个区域做出反应,所以该算法有助于降低图像的损失,但显然这是我们不需要的

img = im.convert('1',dither=Image.NONE)
img.show()

在这里插入图片描述

img = im.convert('1',dither=Image.FLOYDSTEINBERG)
img.show()

在这里插入图片描述
真相大白了。原来是里面的dither参数有两个值可以接受,
一是Image.NONE,二是Image.FLOYDSTEINBERG。
默认的是带抖动的。
其实这里官方文档也写的不清楚,API里写的默认是dither=None。然后我把None填入发现没有变化,其实是Image.NONE注意是全部大写的NONE

总结

现在最大的感受就是一个库的官方教程都是虚的,把这些东西搬运来搬运去没有什么价值,只有进行实践才会发现有许多值得探索和注意的地方,即需要在看API的同时多敲代码。

<think>好的,用户的问题是关于如何在Python PIL中使用图像转换和保存功能的。首先,我需要回顾一下PIL的基本知识,确保自己理解正确。用户提到了PIL和Pillow的关系,记得Pillow是PIL的分支,支持Python3,所以现在大多数情况下都是用Pillow。接下来,用户想了解convert和save方法的使用。 首先,convert方法用于图像模式转换,比如将RGB转为灰度图(L模式)。需要说明不同的模式以及转换方式。例如,使用im.convert("L")可以得到灰度图像。可能还需要提到其他模式,如RGBA、CMYK等,但用户可能更关注常见的情况。 然后,保存功能是用save方法,支持多种格式,如JPEG、PNG、GIF。需要指出保存时的参数,比如质量参数quality,以及不同格式的注意事项。例如,JPEG不支持透明通道,保存为PNG时可能需要处理透明度。 另外,用户提供的引用中有提到ImageEnhance、resize方法等,但用户的问题集中在转换和保存,所以可能不需要深入这些部分。不过,如果有相关的内容可以关联,可以简要提及,比如在转换模式后进行图像增强再保存。 需要注意代码示例的正确性,确保语法正确,比如正确的导入的方式,使用Image.open,然后convert和save。还要注意文件路径的处理,比如保存时指定文件名和格式。 用户可能遇到的常见问题,比如模式转换后颜色异常,或者保存时格式不支持的问题,应该在注意事项里提到。例如,将带有透明通道的图像保存为JPEG时会自动合并透明通道,或者转换模式时可能的数据丢失。 还要检查是否有需要引用的地方,比如引用中提到resize方法的参数,或者ImageEnhance的使用,但用户的问题主要关于convert和save,所以可能引用4关于resample的部分可能相关,但暂时可能不需要。不过,引用4中的convert示例可以直接引用,比如展示如何转换模式。 最后,生成相关问题时要围绕convert和save的扩展,比如调整图像大小、增强图像、处理多帧图像等。确保问题与主题相关,帮助用户进一步学习。</think>### Python PIL中图像转换与保存功能的使用方法 #### 1. 图像模式转换(`convert`方法) `convert`方法用于将图像转换为不同的颜色模式,语法为: $$ \text{Image.convert}(mode, \ matrix, \ dither, \ palette, \ colors) $$ 其中`mode`参数是必选项,表示目标模式(如灰度图$L$、RGB$、RGBA$等)。 **示例代码**: ```python from PIL import Image # 打开图像并转换为灰度图 im = Image.open("input.jpg") im_L = im.convert("L") # 转为灰度模式 im_L.show() # 将灰度图重新转为RGB模式 im_rgb = im_L.convert("RGB") im_rgb.show() ``` **说明**: - 常见模式:$L$(8位灰度)、$RGB$(24位真彩色)、$RGBA$(带透明度通道)[^4] - 模式转换可能导致数据丢失,例如从$RGBA$转为$RGB$时会丢弃透明度信息 --- #### 2. 图像保存(`save`方法) `save`方法支持多种格式保存,语法为: $$ \text{Image.save}(fp, \ format=None, \ **params) $$ **示例代码**: ```python # 保存为不同格式 im.save("output.png") # 自动识别格式 im_L.save("grayscale.jpg", quality=95) # 指定JPEG质量参数 im_rgb.save("result.tiff", compression="tiff_deflate") ``` **关键参数**: - `quality`:JPEG格式的质量(1-100) - `compression`:TIFF/PNG的压缩算法 - `optimize`:启用PNG/JPG优化(布尔值) - `dpi`:设置图像分辨率 --- #### 3. 组合应用场景 **案例:转换并保存透明背景图像** ```python # 将RGBA图像转换为带白色背景的RGB im = Image.open("transparent.png") background = Image.new("RGB", im.size, (255, 255, 255)) background.paste(im, mask=im.split()[3]) # 使用alpha通道作为遮罩 background.save("opaque.jpg") ``` --- #### 注意事项 1. JPEG格式不支持透明度,保存透明图像时会自动填充为黑色背景 2. 多帧图像(如GIF)需配合`ImageSequence`处理[^2] 3. 模式转换可通过矩阵实现更复杂的颜色空间计算[^5]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值