繁体   English   中英

图像的Python灰度转换

[英]Python gray-scale conversion of an image

因此,我制作了这个脚本,用于拍摄图像并将其转换为自身的灰度。

我知道很多模块都可以像.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')

PIL为您做到这一点。

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

用于将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()

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

您应该使用类似于ITU-R 601-2亮度转换PIL用于将RGB转换为L的方法 )之类的转换方法。 由于它使用可感知的亮度保留转换为灰度。

为此,只需替换行

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

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

PS:-我没有在每个像素值上加上40,因为在将图像转换为灰度时并没有任何意义。

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

您也可以尝试使用Python数学库,例如numpypyvips 这些将数组操作添加到Python:您可以编写a += 12 * b ,其中ab是完整图像,它们将同时对每个像素进行操作。 你得到的是能够指定自己用类似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的出色答案中的等式,然后执行以下操作:

./grey2.py ~/pics/k2.jpg x.png

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

您可以在近似线性空间转换之前和之后战俘,假设你的源图像的sRGB:

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM