在 python/django 中进行灰度化的最佳方法是什么?

What's the best way to greyscale in python/django?

我想对将要上传到 Django 的图像进行灰度处理。于是找了两种方式,要么是opencv,要么是imagemagick。在 imagemagick 中,imagemagickWand 可能会更好,因为它减少了。

从教程来看,我认为 openCV 更容易实现。

有什么想法吗?

What's the best way to greyscale in python/django?

任你选。

ImageMagick 的魔杖库

from wand.image import Image
with Image(filename='logo:') as img:
    img.colorspace = 'gray'
    img.save(filename='logo_gray.jpg')

或CV2

import cv2
img = cv2.imread('example.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imwrite('example_gray.jpg',gray)

这两个项目都成熟、稳定,并且拥有庞大的社区基础。尝试安装这两个库,然后进行试验。

最后灰度刚好(来自wikipedia)。

Y = 0.2126 * RED + 0.7152 * GREEN + 0.0722 * BLUE

两者都做得很好,并且依赖委托(即 libjpeg)来读取和写入图像格式。

如果先转换为线性光,效果会更好。

sRGB 图像将应用约 2.4 的伽马,也就是说,明亮区域的范围比黑暗区域大。如果直接在 sRGB 图像上执行 0.2 r + 0.7 g + 0.1 b,它会扭曲亮度关系,例如:

左起分别是原图,sRGB简单重组的灰度图,非常奇特的局部自适应算法的灰度图,线性光下的灰度图。线性光版本比非线性版本更好地保持了红蓝差异,尽管它看起来不像自适应版本那么好。你可以 read about the adaptive algorithm here.

如果您确定拥有 sRGB,则可以通过简单的 ungamma 转换为线性光,或者更好的方法是使用 ICC 配置文件转换为 XYZ。 pyvips 内置线性光灰度转换,试试:

import pyvips

image = pyvips.Image.new_from_file("/home/john/pics/k2.jpg", access="sequential") 
image = image.colourspace("b-w")
image.write_to_file("x.jpg")

vips 相对于 PIL 或 imagemagick 的优势是质量更好,faster, and much lower memory use。对于 10,000 x 10,000 像素的 RGB JPEG,我看到:

$ time ./magickwand.py 
real    0m2.613s
user    0m2.084s
sys 0m0.500s
peak RES 840MB
$ time ./vips.py
real    0m1.722s
user    0m5.716s
sys 0m0.116s
peak RES 54MB

那是在双核笔记本电脑上。