我正在尝试分析图片。我基本上分两步完成:
我的程序在大多数情况下运行良好但并非全部。这主要是因为我从未真正理解过,如何将图片转换为黑白图片。我主要复制了我发现的代码,并使其与试验和错误一起工作(这就是为什么我最终,灰度而不是黑白,因为我没有找到,如何使灰度中的每个非白色像素变为黑色)
我正在使用PIL进行图片操作,我的图片操作主要功能如下(convert()使用一次,avgcol()用于转换图片的每个部分,我想分析)
def convert():
global im
matrix = (1.412453, 0.357580, 0.180423, 0,
0.212671, 0.715160, 0.072169, 0,
0.019334, 0.119193, 0.950227, 0 )
im = im.convert("L", matrix)
def avgcol(im):
p_colors=im.getcolors()
cnt_pix=(im.size[0])*(im.size[1])
avgpix=0
for i in range(len(p_colors)):
avgpix=avgpix+p_colors[i][0]*p_colors[i][1]
return round(avgpix/cnt_pix , 1)
我真的不知道,矩阵的作用是什么(没有找到一个解释单个值的网站)。 我现在的具体问题是,我想将绿色太多的像素转换成白色像素,但我很确定,如果这个问题得到解决,其他的东西会突然出现,所以一些基本的解释,这是怎样的完了,会很棒。 但我感谢任何指针朝着正确的方向发展。 请不要解决每个像素的循环问题。图片非常大,程序应该很快。
答案 0 :(得分:2)
如果你看the documentation,你会看到一些事情。
首先,convert
有一个参数版本,只需要mode
。
如果您只想进行RGB到灰度转换:
grey = im.convert("L")
提供矩阵的唯一原因是您不想使用默认转换。
你也可以直接转换为双层黑&白;
bw = im.convert("1")
正如文档所说:
转换为双层图像(模式“1”)时,源图像首先转换为黑白图像。然后将大于127的结果值设置为白色,并使图像抖动。要使用其他阈值,请使用point方法。
因此,如果您想要标准阈值和抖动,只需convert
。如果您想要不同的阈值,它看起来像这样:
grey = im.convert("L")
table = [int(i>200) for i in range(256)]
bw = grey.point(table, '1')
在你的回答中,你说:
...如何将灰度中的每个非白色像素变为黑色
如果您的意思是“绝对纯白色以外的任何东西”为“非白色”,则不能使用point
。即使您使用65536项表格convert
至L16
和point
,也无法区分99.998%和100%白色,并且可以想象您的某些原始像素不是白色得到匹配错误。因此,您可能希望直接迭代原始像素(使用load
函数)并手动构建新图像。
关于矩阵的作用......如果您了解矩阵数学的基础知识,那就非常简单了。 (如果你没有,我在这里无法解释,但the Wikipedia article可能是一个很好的起点。)
将每个源像素视为向量(例如,在RGBA图像中,向量<red, green, blue, alpha>
。将该向量乘以矩阵,然后得到一个新向量。将其视为目标色彩空间中的像素。
例如,如果您有D65 RGBA像素,并将每个像素乘以文档中给出的4x3矩阵,则结果为CIE XYZ像素。
这意味着没有理由使用4x3矩阵转换为L.你想要的是4x1矩阵。然后,只有你不想要默认值。正如文档所说:
当从彩色图像到黑白时,图书馆使用ITU-R 601-2亮度变换:
L = R * 299/1000 + G * 587/1000 + B * 114/1000
...这只是(.299, .587, .114, 0)
。
所以,如果你想:
将绿色太多的像素转换为白色像素
这有些含糊不清。但至少有一种做这样的事情的方法就是过分强调绿色。例如,如果您使用(.1495, .8448 , .0057, 0)
,绿色将比平时计算得多(红色和蓝色要少得多)以确定亮度。
同时,在你的问题结束时:
请不要解决每个像素的循环问题。图片非常大,程序应该很快。
当然,在bw = grey.point([int(i>200) for i in range(256)], '1')
之下的PIL命令实际上是用于循环grey
中的每个像素。它只是在C而不是Python中进行循环。您可以使用Cython自己做同样的事情,或者使用numpy隐式执行,或者只使用PyPy而不是现有的Python解释器(可以将您的Python循环到JIT)几乎是C速度。)
你为什么要那样做?好吧,看看每种方式的阈值代码:
# PIL
table = [int(i>200) for i in range(256)]
bw = grey.point(table, '1')
# Python (run in PyPy) or Cython
bw = [pixel > 200 for pixel in grey]
# numpy
bw = grey > 200