【问题标题】:RGB LUT to grayscale - IR ImagingRGB LUT 到灰度 - 红外成像
【发布时间】:2018-07-16 16:27:57
【问题描述】:

对于我的工作,我需要将 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 秒,但我有几千张图像要处理),则此代码会非常慢,因为我需要将每个像素提供给函数以获得最接近的匹配。

我发现另一段代码在替换颜色方面工作得非常快:

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 Setchell 提出的解决方案时遇到了一些困难。 我非常确信使用 ImageMAgick 是解决我特定问题的最佳解决方案,遗憾的是,由于我的 PC 上的安全设置,我无法安装该解决方案。

我想出的解决方案基本上是将彩色图像转换为灰度,然后对每个像素应用另一个灰度值,其中新的灰度将跨越旧灰度值的 +/- 6 个灰度值。 (例如,从 242 到 255 的所有内容都将替换为 255) 这个解决方案的运行速度并不快,也没有给出最好的结果,但目前看来,在不久的将来,这一切似乎都是可行的。

感谢您的回答,它帮助我重新思考了这个过程。

【问题讨论】:

    标签: python numpy opencv rgb grayscale


    【解决方案1】:

    嗯... JPEG 很少是 “数据” 类型图像的好选择,因为它固有的损耗性 - 总是更喜欢 PNGTIFF,或者为了最终的简单性,古老的NetPBM 格式(PGMPPMPAM)和 PFM 用于浮点数。

    无论如何,您可以使用 ImageMagick 在命令行中以极快的速度重新映射图像,而无需编码,该工具安装在大多数 Linux 发行版上,也可用于 macOS 和 Windows。 p>

    因此,将所需颜色的字典(仅一行像素)保存为名为 LUT.png(查找表)的 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 Parallel 使用所有那些可爱的 CPU 内核并行快速、快速地完成它们:

    parallel convert {} +dither -map LUT.png {.}.png ::: *.jpg
    

    地点:

    • {}代表当前正在处理的文件,
    • {.} 代表没有扩展名的文件,并且
    • ::: 表示要处理的文件名的开始

    显然,在使用互联网上奇怪的人建议的任何东西之前,先进行备份,然后只处理数据的子集;-)

    【讨论】:

    • 我会试一试,一个额外的问题,你知道是否可以从 python 脚本运行它?理想情况下,整个事情都包含在一个大“程序”中,所以我可以启动它并让程序完成所有艰苦的工作。由于理想情况下并不总是可用,因此两步过程显然比没有过程要好:-)
    • 你当然可以 "shell out" 从 Python 运行convert,就像这样stackoverflow.com/a/89243/2836621
    【解决方案2】:

    你为什么不使用 PIL 库:

    greyImage = Image.open(colorImageName).convert('L')
    

    “L”代表亮度。

    像素数据可通过 getdata() 方法获得。

    【讨论】:

    • 亮度会反映与颜色值相关的灰度值吗? (我开始的 RGB 值列表?)或者这是像 RGB 到 HSV 的转换,我只会选择一个通道?为了获得正确的输出,将特定的 RGB 链接到特定的灰度值非常重要。
    • 据我所知,没有记录。但是,我使用它并看到与应用 gray = (r * 11 + g * 16 + b * 5)/32 相同的结果
    • @KJohnson:在github.com/whatupdave/pil/blob/master/PIL/Image.py 我们可以找到“将彩色图像转换为黑白(模式“L”)时,库使用 ITU-R 601-2 亮度变换:L = R * 299/1000 + G * 587/1000 + B * 114/100"
    猜你喜欢
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    • 2019-11-27
    • 1970-01-01
    • 1970-01-01
    • 2018-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多