Python图像的灰度转换

2024-10-05 11:05:45 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我做了一个脚本,把图像转换成灰度。在

我知道很多模块都可以像.convert('grey')那样自动完成这项工作,但我想自己手动完成,以了解更多关于python编程的知识。在

它的工作正常,但它非常慢,对于一个200pX200p的图像,它需要10秒,所以,我可以修改什么使它更快?在

它是这样工作的,它取一个像素,计算R,G和B值的平均值,将三个值设置为平均值,将每个值加上40以增加亮度并写入像素。 代码如下:

import imageio
import os
from PIL import Image, ImageDraw
from random import randrange


img = '/storage/emulated/0/DCIM/Camera/IMG_20190714_105429.jpg'
f = open('network.csv', 'a+')
pic = imageio.imread(img)
picture = Image.open(img)
draw = ImageDraw.Draw(picture)
f.write('\n')

def por():
    cien = pic.shape[0] * pic.shape[1]
    prog = pic.shape[1] * (h - 1) + w
    porc = prog * 100 / cien
    porc = round(porc)
    porc = str(porc)
    print(porc + '%')
rh = int(pic.shape[0])
wh = int(pic.shape[1])
for h in range(rh):
    for w in range(wh):
        prom = int(pic[h , w][0]) + int(pic[h, w][1]) + int(pic[h, w][2])
        prom = prom / 3
        prom = round(prom)
        prom = int(prom)
        prom = prom + 40
        por()
        draw.point( (w,h), (prom,prom,prom))
picture.save('/storage/emulated/0/DCIM/Camera/Modificada.jpg')

Tags: from图像imageimportimg像素int平均值
3条回答

Python是一种解释性语言,对于像素循环来说还不够快。cython是一个姊妹项目,它可以将Python编译为可执行文件,对于这样的代码,它可以比普通Python更快。在

您还可以尝试使用Python数学库,如numpy或{a3}。这些向Python添加数组操作:您可以编写类似a += 12 * b的行,其中a和{}是整个图像,它们将同时对每个像素进行操作。你可以自己控制操作的每一个细节,再加上类似C的速度

例如,在pyvips中,您可以写下:

import sys
import pyvips

x = pyvips.Image.new_from_file(sys.argv[1], access="sequential")
x = 299 / 1000 * x[0] + 587 / 1000 * x[1] + 114 / 1000 * x[2]
x.write_to_file(sys.argv[2])

从Vasu Deo.S的优秀答案中复制方程式,然后用类似的方法运行:

^{pr2}$

读取JPG图像k2.jpg并编写一个名为x.png的灰度PNG。在

假设源映像是sRGB,则可以在线性空间中使用pow前后近似转换:

x = x ** 2.2
x = 299 / 1000 * x[0] + 587 / 1000 * x[1] + 114 / 1000 * x[2]
x = x ** (1 / 2.2)

但这并不完全正确,因为它缺少sRGB幂函数的线性部分。在

您还可以简单地使用x = x.colourspace('b-w'),pyvips的内置灰度操作。在

将RGB转换为灰度的方法称为平均。在

from PIL import Image

image = Image.open(r"image_path").convert("RGB")

mapping = list(map(lambda x: int(x[0]*.33 + x[1]*.33 + x[2]*.33), list(image.getdata())))

Greyscale_img = Image.new("L", (image.size[0], image.size[1]), 255)

Greyscale_img.putdata(mapping)

Greyscale_img.show()

不建议使用上述方法(平均)将彩色图像转换为灰度。因为它平等地对待每一个颜色通道,假设人类平等地感知所有的颜色(这不是事实)。在

您应该使用类似于ITU-r601-2luma transform(PIL用于将RGB转换为L的方法)。因为它使用感知亮度保持转换为灰度。在

换个线就行了

^{pr2}$

mapping = list(map(lambda x: int(x[0]*(299/1000) + x[1]*(587/1000) + x[2]*(114/1000)), list(image.getdata())))

p.S.:-我没有给每个像素值加上40,因为这在图像转换为灰度时没有任何意义。在

皮尔是为你做的。在

from PIL import Image
img = Image.open('image.png').convert('grey')
img.save('modified.png')

相关问题 更多 >

    热门问题