更改颜色替换的亮度

时间:2013-03-31 17:15:31

标签: iphone objective-c opencv image-processing core-graphics

我正在努力用用户选择的颜色替换图像中的某些颜色。我使用OpenCV进行颜色替换。

总之,我已经描述了从哪里获得帮助以及我得到了什么。

  1. How to change a particular color in an image? 我已经按照上面的链接回答了步骤或采取了基本的想法。在那个链接的正确答案中,那个人告诉你只需要改变色调来替换颜色。

  2. 之后我遇到了类似的问题 color replacement in image for iphone application(即对于那些完全是初学者的人来说,它是替换颜色的好代码)
    从那个问题我得到了一个想法,我也需要改变“饱和度”。


  3. 现在我遇到了像

    这样的问题

    “当我的源图像太亮(即高亮度)并且我用一些深色替换颜色时,颜色在替换图像中看起来很亮而不是暗,因为它看起来像替换颜色不匹配使用我们完成替换的颜色“

    这是因为我没有考虑更换亮度。在这里,我被困在改变亮度的公式或想法是什么?

    假设我用目标颜色的亮度替换图像的亮度然后看起来像平坦的替换物,图像将失去它的实际阴影或边缘。

    修改
    当我在更换中考虑光源的亮度(即要处理的像素)时,我面临一个问题。让我按照我的应用场景解释。

    例如,我正在改变汽车的颜色(如whiteAngl解释)之后,我正在擦除新颜色汽车的一小部分。我再次对擦除的部分进行重新着色,但现在发生的事情是擦除后的颜色和擦除之前的颜色不匹配,因为两次我都得到不同的亮度,因为我的处理像素都被改变了,并且由于它的亮度颜色在输出中改变了。如何克服这个问题

    任何帮助将不胜感激

    Coloured Image Erased Few portion Recoloured

2 个答案:

答案 0 :(得分:10)

如果没有看到你尝试过的代码,就不容易猜出你做错了什么。为了向您展示如何完成这项工作,让我们改变这辆车的丑陋蓝色:

enter image description here

这个简短的python脚本显示了我们如何使用HSV颜色空间更改颜色:

import cv2
orig = cv2.imread("original.jpg")
hsv = cv2.cvtColor(orig, cv2.COLOR_BGR2HSV)
hsv[:,:,0] += 100
bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
cv2.imwrite('changed.jpg', bgr)

你得到: enter image description here

wikipedia上,您会看到色调介于0到360度之间,但对于OpenCV中的值,请参阅the documentation。你看,我在图像中的每个像素的色调中添加了100。我想你想要改变你图像的一部分颜色,但是你可能从上面的脚本中得到了想法。

以下是如何获得所需的深红色汽车。首先我们得到红色的: red card

我试图保持金属感的深红色: dark red car

正如我所说,用于移动颜色光的等式取决于您想要对象的材质。在这里,我提出了一个快速而肮脏的方程式来保持汽车的金属材料。此脚本从第一个浅蓝色汽车图像产生上述深红色汽车图像:

import cv2
orig = cv2.imread("original.jpg")
hls = cv2.cvtColor(orig, cv2.COLOR_BGR2HLS)
hls[:,:,0] += 80 # change color from blue to red, hue
for i in range(1,50): # 50 times reduce lightness 
 # select indices where lightness is greater than 0 (black) and less than very bright 
 # 220-i*2 is there to reduce lightness of bright pixel fewer number of times (than 50 times), 
 # so in the first iteration we don't reduce lightness of pixels which have lightness >= 200, in the second iteration we don't touch pixels with lightness >= 198 and so on
 ind = (hls[:,:,1] > 0) & (hls[:,:,1] < (220-i*2))
 # from the lightness of the selected pixels we subtract 1, using trick true=1 false=0
 # so the selected pixels get darker
 hls[:,:,1] -= ind
bgr = cv2.cvtColor(hls, cv2.COLOR_HLS2BGR)
cv2.imwrite('changed.jpg', bgr)

答案 1 :(得分:1)

你是对的:只改变色调根本不会改变亮度(或者由于一些感知效果而非常微弱),你想要的也是改变亮度。正如您所提到的,将亮度设置为目标亮度将会丢失所有像素值(您只会看到饱和度的变化)。接下来是什么?

您可以做的是更改像素的色调尝试匹配平均亮度。要做到这一点,只需计算要处理的所有像素的平均亮度B,然后将所有亮度值乘以Bt/B,其中Bt是目标颜色的亮度。< / p>

这样做既可以匹配色调(由于第一步)和第二步产生的亮度,同时保留边缘(因为你只修改了平均亮度)。

这是直方图匹配的一种特殊情况,在这里,您的目标直方图具有单个值(目标颜色),因此只能以合理的方式匹配均值。

如果你正在寻找你的赏金申请中所说的“可靠来源”,我是哈佛大学的博士后,并将在今年的Siggraph上发表关于颜色直方图匹配的论文;)。