在我的工作中,我需要将JPG中的伪彩色RGB值替换为灰度处理。“颜色”图像有一个特定的RGB颜色范围(根据原点而定),这些颜色需要链接到灰度值,以便对输出图像进行一些测量。使用原始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秒,但我要处理几千幅图像),则此代码非常慢,因为为了得到最接近的匹配,我需要将每个像素提供给函数。
我发现另一段代码可以非常快地替换颜色:
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中的"where“语句时遇到了问题,以便加快用灰度值交换RGB值的整个过程。
由于我不是一个受过教育的程序员(而且对python非常陌生),所以我很难了解如何解决这个问题。在许多论坛上搜索无助于找到一个好的解决方案(我理解并能够实现自己),因此我提出了一个问题。
有什么功能可以做我想做的事吗?或者有一种方法将这两个函数合并为一个,这样转换既快又正确?
任何帮助都是非常感谢的(但如果可能的话,请保持简单一点:-)
谢谢
编辑:我最终得到了另一个解决方案,因为我在安装Mark提出的解决方案时遇到了一些困难。我非常确信,使用ImageMAgick是解决我的具体问题的最佳解决方案,遗憾的是,由于个人电脑上的安全设置,我无法安装该解决方案。
我提出的解决方案基本上是将彩色图像转换为灰度,然后对每个像素应用另一个灰度值,其中新的灰度值将从旧的灰度值扩展到+/- 6灰度值。(例如从242到255的所有东西都将被255取代)这个解决方案并不是真的工作得很快,也没有给出最好的结果,但就目前而言,这似乎是在短期内是可行的。
谢谢你的回答,它帮助我重新思考了这个过程。
发布于 2018-02-06 17:29:10
嗯..。由于固有的有损性,JPEG很少是“数据”类型图像的好选择--总是喜欢PNG、TIFF,或者是为了最终的简单性,使用可尊敬的NetPBM格式(PGM、PPM、PAM)和PFM作为浮动格式。
无论如何,您可以在命令行使用安装在大多数Linux发行版上的ImageMagick重新映射映像,并且不需要进行任何编码,这也适用于macOS和macOS。
因此,将所需颜色的字典(只需一行像素)保存为一个名为PNG (查找表)的LUT.png文件。我将用ImageMagick制作一个红色、石灰绿色、蓝色、黑色和白色的小照片,向你展示它的外观:
convert xc:red xc:lime xc:blue xc:white xc:black +append LUT.png

旁白:如果您的查找表的颜色是RGB三胞胎,而不是命名颜色,您可以这样使用它们:
convert xc:"rgb(255,0,0)" xc:"rgb(0,255,0)" xc:"rgb(0,0,255)" +append LUT.png“现在照一张你的照片,”比恩先生说:

并将包含的颜色映射到查找表:
convert MrBean.jpg +dither -map LUT.png result.png

请注意,从ImageMagick,的v7开始,convert命令变为magick,即:
magick MrBean.jpg +dither -map LUT.png result.png如果你有几百个任务要做,你可以通过使用GNU并行,同时使用所有你付给英特尔的可爱的CPU核心来完成它们。
parallel convert {} +dither -map LUT.png {.}.png ::: *.jpg其中:
{}表示当前正在处理的文件,并且{.}表示没有扩展名的文件,并且:::表示要处理的文件名的开始。显然,先做一个备份,在使用互联网上任何奇怪的人之前,只需处理数据的子集;-)
发布于 2018-02-06 15:07:26
为什么不使用PIL库:
greyImage = Image.open(colorImageName).convert('L')“L”代表亮度。
像素数据可以通过getdata()方法获得。
https://stackoverflow.com/questions/48645896
复制相似问题