javascript - 检查颜色是否接近

标签 javascript ios swift algorithm colors

  1. 我得到了这样一张图片,我想在上面应用一些特殊类型的滤镜:

img0

  1. 我得到深绿色区域(最大的一个)的 RGB 颜色(49、76、14)。

所以我想为我的过滤目的获得某种阈值属性:我想过滤每个图像像素以检查它的颜色是否接近给定的 RGB 值 (49, 76 , 14)。阈值表示偏移率。

Threshold small :
             --> `(49, 76, 14) close to (48, 75, 13)`
             --> `(49, 76, 14) "not" close to (50, 75, 13)`

Threshold big :
             --> `(49, 76, 14) close to (48, 75, 13)`
             --> `(49, 76, 14) "also" close to (50, 75, 13)`

用最小阈值过滤图像,只会过滤给定的 rgb 颜色:

img1

更大的阈值也会过滤给定 rgb 颜色附近的颜色:

img2

How can I achieve coding a function that is able to check if one color is close to another color (+threshold property) (+using rgb values)?

注意:

这是我在上面首先考虑的代码,但对其进行了测试 - 它并没有真正导致成功(通过过滤给定值,应该首先过滤小的左上角区域,因为它的颜色几乎看起来像给定的一个。但是这段代码首先匹配了明显不匹配给定颜色的灰色!)

 var offset = (threshold/100.0) * 255.0
 var color = [r,g,b]
 var r = redvalue, g = greenvalue, b = bluevalue
 if !(
      (r >= color[0]-offset) &&
      (r <= color[0]+offset) &&
      (g >= color[1]-offset) &&
      (g <= color[1]+offset) &&
      (b >= color[2]-offset) &&
      (b <= color[2]+offset)
     ) { // apply filter }

任何帮助将不胜感激。一些用 Swift 或 JavaScript 编写的源代码,甚至一些 PseudoCode 也可以。

编辑:一个自发的想法是将 rgb-colors 转换为 lab-colors 以随后计算欧氏距离 从两种颜色。但我不确定这个解决方案是否有效,也不确定它是否是最有效的:)

最佳答案

这不是完整的答案,而是我在评论中提出的建议的详细说明,OP 要求我提供一些代码。

我有一个应用程序,它通过计算与 X11 三元组列表中规范命名颜色的欧几里德距离来命名颜色(类似于 OP 试图做的,但目的不同)。我和他一样发现,使用 RGB 空间并不能给出直观的答案,所以我将每种颜色转换为 Hue Saturation Lightness (HSL) 维度,然后赋予 Hue 维度比其他两个更高的权重。这是实际的“距离”代码,以及转换维度的支持函数:

private let oneThird = 1.0 / 3.0
private let twoThirds = 2.0 / 3.0

func hsl(red: Double, green: Double, blue: Double) -> (hue: Double, saturation: Double, lightness: Double) {
    let minv = min(red, green, blue)
    let maxv = max(red, green, blue)
    let diff = maxv - minv
    let sum = maxv + minv

    let l = sum * 0.5
    var s = 0.0
    var h = 0.0

    if (diff > 0.0) {
        if (l < 0.5) {
            s = diff / sum
        } else {
            s = diff / (2.0 - sum)
        }

        let dr = (((maxv - red) / 6.0) + (diff / 2.0)) / diff
        let dg = (((maxv - green) / 6.0) + (diff / 2.0)) / diff
        let db = (((maxv - blue) / 6.0) + (diff / 2.0)) / diff

        if red == maxv {
            h = db - dg
        } else if green == maxv {
            h = oneThird + dr - db
        } else if blue == maxv {
            h = twoThirds + dg - dr
        }
    }
    return (modp(h, denominator: 1.0), s, l)
}

func modp<T: BinaryFloatingPoint>(_ numerator : T, denominator : T) -> T {
    // acts as fmod, but assures the result is positive between 0 and fabs(denominator)
    let myDenominator = abs(denominator)
    var myNumerator = numerator.remainder(dividingBy: myDenominator)
    //var myNumerator = fmod(numerator, myDenominator)
    while (myNumerator < 0) { myNumerator += myDenominator }
    return myNumerator
}

let (h1, s1, l1) = hsl(red: r1, green: g1, blue: b1) // The reference colour
let (h2, s2, l2) = hsl(red: r2, green: g2, blue: b2) // The colour to be tested
let (dh, ds, dl) = (h1 - h2, s1 - s2, l1 - l2)
let hueWeight = 10 // Arbitrary, but works.
let distance = sqrt(hueWeight * dh * dh + ds * ds + dl * dl)

然后您可以将您的距离值与您的阈值进行比较...

我认为 HSL 公式的原始来源是 here...

附注我为这些值使用了 Double - 那是因为我使用了我自己的颜色类型 - 如果你用 UIColor 实现它,你最好使用 CGFloats...

关于javascript - 检查颜色是否接近,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49239377/

相关文章:

xcode - 项目从 Objective-C 转换为 Swift 后无法同时满足约束

javascript - 如何合并两个对象数组并连接值?

javascript - 从 oracle sql 返回值为 -0

android - 如何模拟/ stub Flutter 平台 channel /插件?

ios - 获取 mp3 文件指定时间范围的字节范围位置

arrays - 用户按下按钮(保存)后如何从照片库中打开并选择照片

javascript - 在 Javascript 中加载多个 CSV 文件

javascript - Django url重写并从Javascript传递参数

ios - 当 UIView 直接覆盖在它上面时,如何处理 UIWebView 中的链接?

swift - 如何定义专门化泛型协议(protocol)的协议(protocol),使其可以在类型声明中使用?