【问题标题】:Changes Brightness in color replacement更改颜色替换的亮度
【发布时间】:2013-04-10 09:02:47
【问题描述】:

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

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

  1. How to change a particular color in an image? 我已经按照上述链接的答案执行了该步骤或采取了基本思路。在该链接的正确答案中,那个人告诉您只需要更改色调即可进行颜色替换。

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


现在我遇到了类似

的问题

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

发生这种情况是因为我没有考虑更换时的亮度。在这里我被卡住了改变亮度的公式或想法是什么?

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

编辑:
当我考虑替换源(即要处理的像素)的亮度时,我面临一个问题。让我根据我的应用场景进行解释。

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

任何帮助将不胜感激

【问题讨论】:

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


    【解决方案1】:

    没有看到你尝试过的代码,很难猜出你做错了什么。为了用一个具体的例子告诉你这是如何做到的,让我们改变这辆车难看的蓝色:

    这个简短的 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)
    

    你会得到:

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

    这里是如何获得请求的深红色汽车。首先我们得到红色的:

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

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

    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)
    

    【讨论】:

    • 据我所知,在 openCV 中:色相范围:0->180,周六:0->255 和亮度->0 到 255
    • 现在尝试将颜色更改为深红色,看看你会得到什么。
    • hm .. 这很简单,我第一次没有很好地理解 OP 的问题。请参阅我的更新答案。
    • 这很容易......通过手动更改方程式以使其匹配此特定的深色。现在,用同样的功能让它更亮?并使其匹配颜色 (R,G,B)=(10,192,150) ? :) 我发现这个答案确实缺乏普遍性:s
    • 嗯,这也很简单,我现在很忙,以后有时间也会为它写脚本:)
    【解决方案2】:

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

    你可以做的是改变像素的色调尝试匹配平均亮度。为此,只需计算要处理的所有像素的平均亮度B,然后将所有亮度值乘以Bt/B,其中Bt 是目标颜色的亮度。

    这样做会匹配色调(由于第一步)和亮度由于第二步,同时保留边缘(因为您只修改了平均亮度)。

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

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

    【讨论】:

    • 祝贺你在哈佛的职位。我认为您错过了反射光也取决于材料而不仅仅是物体的颜色这一点。
    • @Shambool 否:我认为您最初的回答没有指出当目标颜色较暗时,更改色调 /only/ 不会使像素按需要变暗。您刚刚编辑了答案以添加亮度偏移;但是,偏移可能会导致负值或对比度下降(无论如何这不是调整对象亮度的正确方法)。您还手动更改了偏移量,而没有考虑要匹配的 /desired/ 颜色(我怎么知道所需的颜色比亮度暗 80?)
    • 好吧,为了证明我的方法有效,我添加了输出图像,您清楚地看到“偏移可能导致负值或对比度松散”是不正确的。因为我不是简单地添加偏移量!
    • 关于您的第二个问题,对于给定的像素,如果用户输入所需的颜色 H/L,那么您只需与像素的当前 H/L 进行比较,瞧,您就有区别了。
    • 请查看我更新的问题我已经添加了对此解决方案的关注
    猜你喜欢
    • 2012-12-14
    • 2014-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-17
    • 1970-01-01
    相关资源
    最近更新 更多