对于我的工作,我需要将JPG中的伪彩色RGB值替换为灰度级以进行处理。 '颜色'图像具有特定范围的RGB颜色(20或255,取决于原点),需要链接到灰度值,以便对输出图像进行一些测量。 使用原始RGB值非常困难,因为指定的范围仅在PNG或tiff格式下正常工作,但转换为JPG会创建一些与预期RGB值有点偏离的RGB值,这会使我现有的分析变得无用
我在其中一个答案中找到了这段很好的代码,作为将某个点的颜色四舍五入到字典中最接近的相似颜色的解决方案。
def distance(c1, c2):
(r1,g1,b1) = c1
(r2,g2,b2) = c2
return math.sqrt((r1 - r2)**2 + (g1 - g2) ** 2 + (b1 - b2) **2)
colors = list(rgb_code_dictionary.keys())
closest_colors = sorted(colors, key=lambda color: distance(color, point))
closest_color = closest_colors[0]
code = rgb_code_dictionary[closest_color]
Python PIL - Finding Nearest Color (Rounding Colors)
rgb_code_dictionary被替换为rgb值的字典,并带有我想要应用的灰色值。
这非常好用,它可以产生我需要的输出。 然而,如果将此代码应用于完整图像(每个图像只需要18秒,但我需要处理几千个图像),此代码非常慢,因为我需要将每个像素提供给函数以获得最接近的匹配。 / p>
我找到了另一段能够快速替换颜色的代码:
Replacing RGB values in numpy array by integer is extremely slow
# Extract color codes and their IDs from input dict
colors = np.array(_color_codes.keys())
color_ids = np.array(_color_codes.values())
# Initialize output array
result = np.empty((img_arr.shape[0],img_arr.shape[1]),dtype=int)
result[:] = -1
# Finally get the matches and accordingly set result locations
# to their respective color IDs
R,C,D = np.where((img_arr == colors[:,None,None,:]).all(3))
result[C,D] = color_ids[R]
但是这个只有在字典中的RGB值与图像中的RGB值完美匹配时才有效。理想情况下,我会将两者合并在一起,以获得快速可靠的功能来替换颜色。 但我有问题将第一段代码翻译成"其中" numpy中的语句,以加快用灰度值交换RGB值的整个过程。
由于我不是受过教育的程序员(而且对python来说真的很新),我很难看到如何解决这个问题。搜索许多论坛并没有帮助找到一个好的解决方案(我理解并可以自己实现),因此我的问题。
是否有可以执行我想要的功能?或者有没有办法将两个函数合并为一个,所以转换既快速又正确?
非常感谢任何帮助(但如果可能,请保持简单:-))
由于
EDITED: 我最终得到了另一个解决方案,因为我在安装Mark Setchell提出的解决方案时遇到了一些困难。 我非常确信使用ImageMAgick是我特定问题的最佳解决方案,遗憾的是,由于我的PC上的安全设置,我无法安装解决方案。
我提出的解决方案基本上是将彩色图像转换为灰度,然后将另一个灰度值应用于每个像素,其中新的灰度将从旧的灰度值开始超过+/- 6灰度值。 (例如,242到255之间的所有内容都将替换为255) 这个解决方案并没有真正起作用,也没有给出最好的结果,但是现在这在短期内似乎是可行的。
感谢答案,它帮助我重新思考这个过程。
答案 0 :(得分:2)
嗯...由于内在的损失,JPEG很少是"数据" 类型图片的不错选择 - 总是更喜欢PNG
,TIFF
或者为了最终的简单性,使用古老的NetPBM格式(PGM
,PPM
,PAM
)和PFM
进行浮动。
无论如何,您可以使用 ImageMagick 在命令行中非常快速地重新映射图像,并且无需编码,该驱动程序安装在大多数Linux发行版上,也可用于macOS和Windows。
因此,将所需颜色的字典(仅一行像素)保存为名为PNG
的{{1}}文件(查找表)。我将使用 ImageMagick 制作一个红色,青柠色,蓝色,黑色和白色的小图片来向您展示它的外观:
LUT.png
除了:如果您将查找表的颜色设置为RGB三元组而不是命名颜色,则可以像这样使用它们:
convert xc:red xc:lime xc:blue xc:white xc:black +append LUT.png
现在拍摄你的一张照片,比如憨豆先生:
并将包含的颜色映射到查找表:
convert xc:"rgb(255,0,0)" xc:"rgb(0,255,0)" xc:"rgb(0,0,255)" +append LUT.png
请注意,从 ImageMagick 的v7开始,convert MrBean.jpg +dither -map LUT.png result.png
命令变为convert
,即:
magick
如果你有数百个要做的事情,那么使用 GNU Parallel
magick MrBean.jpg +dither -map LUT.png result.png
其中:
parallel convert {} +dither -map LUT.png {.}.png ::: *.jpg
表示当前正在处理的文件,{}
表示没有扩展名的文件,{.}
表示要处理的文件名的开头显然,首先进行备份,然后在使用互联网上的任何奇怪的人建议之前,先处理数据的子集; - )
答案 1 :(得分:1)
为什么不使用PIL库:
greyImage = Image.open(colorImageName).convert('L')
'L'代表亮度。
像素数据可通过getdata()方法获得。