- 我得到了这样一张图片,我想在上面应用一些特殊类型的滤镜:
- 我得到深绿色区域(最大的一个)的 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 颜色:
更大的阈值也会过滤给定 rgb 颜色附近的颜色:
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
实现它,你最好使用 CGFloat
s...
关于javascript - 检查颜色是否接近,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49239377/