如何用另一种颜色替换颜色?

时间:2015-07-07 12:57:08

标签: image colors bitmap

这是一般性问题(在编程和数学之间):

如何在位图中替换另一种颜色?

我假设位图是2D阵列 示例:让RGB颜色[234,205,10]替换RGB颜色[234,211,23]。

如何进行此颜色替换,以便更换相邻颜色?即光滑的颜色替换。

我假设存在类似邻居颜色的线性插值等方法。

有哪些经典方法可以做到这一点?

以下是如何在500x500px图像位图数组x中检测颜色 RGB 234,211,23 及其相邻颜色的示例:

for i in range(500):
  for j in range(500):
    if abs(x[i,j][0] - 234) < TRESH and abs(x[i,j][1] - 211) < TRESH and abs(x[i,j][2] - 23) < TRESH:
        x[i,j] = ... # how to set the new color in a smooth way?

3 个答案:

答案 0 :(得分:1)

我认为您可以使用的一种好方法是将整个图像更改为新的色彩空间,我宁愿使用HSV色彩空间而不是RGB,您可以在此处找到一些信息:{{3} }。

当您希望搜索特定颜色时,RGB模型不是最佳选择,主要原因是颜色的亮度和暗度之间的较大变化。在这种情况下,RGB颜色空间的阈值无用。 在HSV色彩空间中,您有一个通道可以选择您感兴趣的颜色,另外两个通道用于颜色的饱和度和亮度。但是你只能使用Hue通道(第一个)获得准确的结果。您唯一需要注意的是要意识到您需要将此通道作为循环缓冲区使用,因为最大值和最小值的颜色非常相似,都是红色。

一旦检测到颜色,就可以设置新颜色,并且可以保持旧颜色的饱和度和亮度属性,通过这样做,颜色变化看起来更平滑。

答案 1 :(得分:0)

如果您想要替换2D阵列中像素的颜色,请执行以下操作:

数组[x] [y] =新值

其中x和y代表像素的位置,但请记住,图像使用右手系统,因此y的值从下到上逐渐增长,而在计算机中使用左手系统,因此y值从从上到下。分配新颜色值的确切语法取决于您使用的编程语言(上面的示例适用于ruby)。此外,一些编程语言已经提供了内置的图像处理功能,因此请务必阅读文档以避免实现已实现的功能。

答案 2 :(得分:0)

新答案

新答案即将来临 - 现在我明白你的意思是颜色意义上的邻居而不是几何意义......

您可以计算从图像的每个像素到要更改的颜色的矢量颜色距离,并将其用作蒙版。因此,如果我们创建与下面相同的图像...说我们有一个红黄色渐变作为背景,上面有蓝色方块,我们希望在中间替换中央橙色。

# Make red-yellow gradient with blue square within
convert -size 500x500 gradient:red-yellow -fill none -stroke blue -strokewidth 10 -draw "rectangle 100,100 400,400" image.png

enter image description here

现在克隆该图像,并使用我们要替换的橙色色调填充克隆,然后计算从每个像素到橙色色调的矢量颜色距离:

convert image.png \( +clone -fill "rgb(255,128,0)" -colorize 100% \) \
   -compose difference -composite                                    \
   -evaluate Pow 2 -separate                                         \
   -evaluate-sequence Add -evaluate pow 0.5                          \
   -negate                                                           \
   colour_distance.png

enter image description here

然后你可以使用这个colour_distance.png作为alpha合成的掩码,所以如果我们决定用粉红色代替那个橙色调,我们可以这样做:

convert image.png                                   \
   \( +clone -fill fuchsia -colorize 100% \)        \
   \( colour_distance.png -sigmoidal-contrast 20 \) \
   -composite z.png

enter image description here

请注意,我已将pow 0.5更改为pow 0.3以更加清晰地滚动遮罩。

原始答案

这是一种方法。假设我们有一个红黄色渐变作为背景,上面有一个蓝色方块,我们希望用绿色代替蓝色...

首先,将所有蓝色像素提取到透明背景上,然后将它们更改为绿色并模糊它们,使它们扩散到相邻像素中。然后将模糊的绿色像素叠加到原始图像上。

我选择使用ImageMagick,但您似乎很乐意适应其他语言和库......

#!/bin/bash
# Make red-yellow gradient with blue square within
convert -size 500x500 gradient:red-yellow -fill none -stroke blue -strokewidth 10 -draw "rectangle 100,100 400,400" image.png

# Make everything blue green, then everything else transparent, then blur the lot
convert image.png -fill green -opaque blue -fill white +opaque green -transparent white -blur x6 x.png

# Now overlay the blurred greeness onto the original after replacing blues with green
convert x.png \( image.png -fill green -opaque blue \) -compose overlay -composite result.png

<强> Image.png

enter image description here

x.png (模糊的,颜色替换的图像)

enter image description here

<强> result.png

enter image description here