Check If Color Is Blue(Ish), Red(Ish), Green(Ish),

Determine which color (red, blue, green or other) would be visible for a given RGB value combination?

If you define "being color-ish" as:

  • the color value is above 100
  • the color value is at least twice as the 2 other values

    • your current code states "at least half of the 2 other values" but this can't work because if you have "R:199 G:101 B:102", you could say that it is green-ish because G is above 100 and more than half 199 and half 102 (when it's obviously red-ish)

then your code looks almost good (just replace / with *).

I would just use an enum for the result:

enum Ish
{
Other, // 0 so this would be false if you convert it to bool
Red, // 1
Green, // 2
Blue // 3
}
if (R>100 && R>G*2 && R>B*2)
return Ish.Red;
if (G>100 && G>R*2 && G>B*2) // you had G>G/2 here /!\
return Ish.Green;
if (B>100 && B>G*2 && B>R*2)
return Ish.Blue;
return Ish.Other;

I used 2 for twice, but I think you can use other values as long as it is >1 (you can't say blue is dominant if B <= R for example)

This would be the redish values possible for R=100 (left image with factor 2, right image with factor 1):

Red-ish 100 fact 2 Red-ish 100 fact 1

And this for R=200 (left image with factor 2, right image with factor 1):

Red-ish 200 fact 2 Red-ish 200 fact 1

Therefore you could probably use a factor between 1 and 2

For R=200 you can see the red-ish colors depending on the factor below:

Red-ish 200 multifactor

Counting redish/blueish/greenish... colors in an image

You can convert pixels being processed into more convenient color model, namely HSL or HSV.

Then it could be simplier to define ranges of component values that belong to particular groups (reddish/blueish/etc).

How would u be able to tell if a color is red or blue ... tinted (Javascript)

That's pretty straight forward if you convert your hex code to hsv and use a lookup table to map the hue value to a color name.

Note that using this logic, the name for the hex code wouldn't be orange, but rather red. To get orange as a result, your color would need a hue value of at least 30° (#f9c000)

If you need orange for that value, you can adjust the lookup table to fit you needs.

(pardon me if the translations aren't correct. I just pasted the table into google translate)

const hex = '#f90900';
const name = hex2name(hex);
console.log (`Name of '${hex}' is '${name}'`);

const orangeHSV = [30, 1, 249];
const orangeRGB = hsv2rgb(...orangeHSV);
const orangeHEX = rgb2hex(...orangeRGB);
console.log (`hex for first orange value is '${orangeHEX}'`);

const test = hex2name(orangeHEX);
console.log (`Test if ${orangeHEX} yields orange: ${test}`)
<script>
// https://stackoverflow.com/a/54024653/1487756
function hsv2rgb(h,s,v) {
let f= (n,k=(n+h/60)%6) => v - v*s*Math.max( Math.min(k,4-k,1), 0);
return [f(5),f(3),f(1)];
}

// https://stackoverflow.com/a/54070620/1487756
function rgb2hsv(r,g,b) {
let v=Math.max(r,g,b), n=v-Math.min(r,g,b);
let h= n && ((v==r) ? (g-b)/n : ((v==g) ? 2+(b-r)/n : 4+(r-g)/n));
return [60*(h<0?h+6:h), v&&n/v, v];
}

const clrLkp = [["red", 0],["vermilion", 15],["brown", 20],["orange", 30],["safran", 45],["yellow", 60],["light green yellow", 75],["green yellow", 90],["limett", 105],["dark green", 120],["green", 120],["light blue-green", 135],["blue green", 150],["green cyan", 165],["cyan", 180],["blaucyan", 195],["green blue", 210],["light green blue", 225],["blue", 240],["indigo", 255],["violet", 270],["blue magenta", 285],["magenta", 300],["red magenta", 315],["blue red", 330],["light blue red", 345]].reverse()

const hex2rgb = hex => {
const parts = hex.slice(1).match(/../g);
if (!parts || parts.length <3) throw new Error('Invalid hex value');
const dec = parts.map(p => parseInt(p, 16));
return dec;
}
const hsv2name = (h,s,v) => clrLkp.find(([clr,val]) => h >= val)[0];
const hex2name = hex => [hex2rgb, rgb2hsv, hsv2name].reduce((a,v) => v(...[a].flat()),hex);

const pad = v => (v+'0').slice(0,2);
const rgb2hex = (r,g,b) => '#' + [r,g,b].map(Math.round).map(n => pad(n.toString(16))).join('');
</script>

Convert greenish to redish

Here's one approach using a tolerance value to decide on the -ish factor to set a mathematical notation to it -

def set_image(a, tol=100): #tol - tolerance to decides on the "-ish" factor

# define colors to be worked upon
colors = np.array([[255,0,0],[0,255,0],[0,0,0],[255,255,255]])

# Mask of all elements that are closest to one of the colors
mask0 = np.isclose(a, colors[:,None,None,:], atol=tol).all(-1)

# Select the valid elements for edit. Sets all nearish colors to exact ones
out = np.where(mask0.any(0)[...,None], colors[mask0.argmax(0)], a)

# Finally set all green to red
out[(out == colors[1]).all(-1)] = colors[0]
return out.astype(np.uint8)

A more memory-efficient approach would be to loop through those selective colors, like so -

def set_image_v2(a, tol=100): #tol - tolerance to decides on the "-ish" factor

# define colors to be worked upon
colors = np.array([[255,0,0],[0,255,0],[0,0,0],[255,255,255]])

out = a.copy()
for c in colors:
out[np.isclose(out, c, atol=tol).all(-1)] = c

# Finally set all green to red
out[(out == colors[1]).all(-1)] = colors[0]
return out

Sample run -

Input image :

Sample Image

from PIL import Image
img = Image.open('green.png').convert('RGB')
x = np.array(img)
y = set_image(x)
z = Image.fromarray(y, 'RGB')
z.save("tmp.png")

Output -

Sample Image

How to compare two UIColor which have almost same shade or range in iOS?

You need a tolerance, the value of which, only you can decide:

- (BOOL)color:(UIColor *)color1
isEqualToColor:(UIColor *)color2
withTolerance:(CGFloat)tolerance {

CGFloat r1, g1, b1, a1, r2, g2, b2, a2;
[color1 getRed:&r1 green:&g1 blue:&b1 alpha:&a1];
[color2 getRed:&r2 green:&g2 blue:&b2 alpha:&a2];
return
fabs(r1 - r2) <= tolerance &&
fabs(g1 - g2) <= tolerance &&
fabs(b1 - b2) <= tolerance &&
fabs(a1 - a2) <= tolerance;
}

...

UIColor *color1 = [UIColor colorWithRed:1 green:(CGFloat)0.4 blue:1 alpha:1];
UIColor *color2 = [UIColor colorWithRed:1 green:(CGFloat)0.2 blue:1 alpha:1];

if ([self color:color1 isEqualToColor:color2 withTolerance:0.2]) {
NSLog(@"equals");
} else {
NSLog(@"not equal");
}

Is there an easy way to compare how close two colors are to each other?

Delta-e, is a single number that represents the perceived 'distance' between two colors. The lower the number, the more similar the colors are to the human eye.

There are a few different ways to calculate it...CIE76 (aka CIE 1976 or dE76) being the most popular.

  • CIE76
  • CMC l:c
  • dE94
  • dE2000

Each one goes about things in a different way, but for the most part they all require you to convert to a better (for comparison) color model than RGB.

For CIE76 you basically just convert your colors to the LAB color space, then compute the 3 dimensional distance between them.

Wikipedia has all the formulae: http://en.wikipedia.org/wiki/Color_difference

You can check your work with online color calculators:

  • CIE76
  • CMC l:c

Why are UIColor.white, red, green, and blue not working, but all other color constants are working just fine?

Update: I found the issue.

I had an extension to UIColor that made it act more Swifty. It allowed accessing the RGB components as shown below. Now that UIColor has red, green, and blue properties that represent the colors red, green, and blue, there was a conflict.

For anyone else that's having a similar issue: make sure to check if you have any extensions that be causing the problem.

Swift 2 Extension

//
// UIColor+Swifty.swift
//
// Created by Cin316 on 3/6/16.
// Usage is permitted under the MIT license.
// This does not work in Swift 3.0 !
//

import SpriteKit

public extension UIColor {

public var alpha: CGFloat? {
get {
var a: CGFloat = 0
if (self.getWhite(nil, alpha: &a)) {
return a
} else {
return nil
}
}
}

public var white: CGFloat? {
get {
var w: CGFloat = 0
if (self.getWhite(&w, alpha: nil)) {
return w
} else {
return nil
}
}
}

public var red: CGFloat? {
get {
var r: CGFloat = 0
if (self.getRed(&r, green: nil, blue: nil, alpha: nil)) {
return r
} else {
return nil
}
}
}
public var green: CGFloat? {
get {
var g: CGFloat = 0
if (self.getRed(nil, green: &g, blue: nil, alpha: nil)) {
return g
} else {
return nil
}
}
}
public var blue: CGFloat? {
get {
var b: CGFloat = 0
if (self.getRed(nil, green: nil, blue: &b, alpha: nil)) {
return b
} else {
return nil
}
}
}

public var hue: CGFloat? {
get {
var h: CGFloat = 0
if (self.getHue(&h, saturation: nil, brightness: nil, alpha: nil)) {
return h
} else {
return nil
}
}
}
public var saturation: CGFloat? {
get {
var s: CGFloat = 0
if (self.getHue(nil, saturation: &s, brightness: nil, alpha: nil)) {
return s
} else {
return nil
}
}
}
public var brightness: CGFloat? {
get {
var b: CGFloat = 0
if (self.getHue(nil, saturation: nil, brightness: &b, alpha: nil)) {
return b
} else {
return nil
}
}
}

}

Swift 3 Extension

//
// UIColor+Swifty.swift
//
// Created by Cin316 on 3/6/16.
// Usage is permitted under the MIT license.
// Notice the addition of "Comp" to conflicting properties.
//

import SpriteKit

public extension UIColor {

public var alphaComp: CGFloat? {
get {
var a: CGFloat = 0
if (self.getWhite(nil, alpha: &a)) {
return a
} else {
return nil
}
}
}

public var whiteComp: CGFloat? {
get {
var w: CGFloat = 0
if (self.getWhite(&w, alpha: nil)) {
return w
} else {
return nil
}
}
}

public var redComp: CGFloat? {
get {
var r: CGFloat = 0
if (self.getRed(&r, green: nil, blue: nil, alpha: nil)) {
return r
} else {
return nil
}
}
}
public var greenComp: CGFloat? {
get {
var g: CGFloat = 0
if (self.getRed(nil, green: &g, blue: nil, alpha: nil)) {
return g
} else {
return nil
}
}
}
public var blueComp: CGFloat? {
get {
var b: CGFloat = 0
if (self.getRed(nil, green: nil, blue: &b, alpha: nil)) {
return b
} else {
return nil
}
}
}

public var hue: CGFloat? {
get {
var h: CGFloat = 0
if (self.getHue(&h, saturation: nil, brightness: nil, alpha: nil)) {
return h
} else {
return nil
}
}
}
public var saturation: CGFloat? {
get {
var s: CGFloat = 0
if (self.getHue(nil, saturation: &s, brightness: nil, alpha: nil)) {
return s
} else {
return nil
}
}
}
public var brightness: CGFloat? {
get {
var b: CGFloat = 0
if (self.getHue(nil, saturation: nil, brightness: &b, alpha: nil)) {
return b
} else {
return nil
}
}
}

}


Related Topics



Leave a reply



Submit