lokesh / color-thief

Grab the color palette from an image using just Javascript. Works in the browser and in Node.
https://lokeshdhakar.com/projects/color-thief/
MIT License
12.32k stars 1.31k forks source link

Incorrect dominant colour #126

Open marklanhamhc opened 6 years ago

marklanhamhc commented 6 years ago

This looks like it's showing the wrong dominant colour still. screen shot 2017-08-29 at 10 45 25

AlfredJKwack commented 5 years ago

Current implementation looks fine.

screenshot 2018-12-02 at 17 18 06
brianlovin commented 4 years ago

@lokesh is this still a known issue? I ran this image through the demo site (and on my machine) and the dominant color just seems wrong (should be red, right?)

cafe

Screenshot 2019-08-17 20 20 18

marklanhamhc commented 4 years ago

It seems theres a chance the white could be the dominant colour as there are 2 shades of red and maybe theres more white than each of the shades of red. To test this theory try making the red one solid colour and test it again.

brianlovin commented 4 years ago

@marklanhamhc great point, that could make sense. This is really naive of me, but just curious if there's any thought on accounting for relative-ness of colors. In the photo above, it seems like any human would probably say that one of those reds is the dominant color, even if there are technically more white pixels. So in this case, we probably want white to "count" for less.

I can't think in my head how you'd approach that systematically, but perhaps there's prior art in thinking about perceived dominance vs. real dominance.

marklanhamhc commented 4 years ago

Sounds like the algorithm would need changing. It might be better to add an option to include/ignore certain colours (such as white) and set a tolerance level. That said, I guess the palette above shows the most dominant colour from left to right and if the first one is white then just take the second one.

That said, that wouldn't work if you wanted to automate this on a larger scale so adding an option to filter the results would be handy. That way you could parse a colour value to ignore and set a tolerance value in the script. Just a thought.

brianlovin commented 4 years ago

Interesting thought, thanks for weighing in. I'm a bit out of my depth on the "right" way to do this, but what you've described makes sense (although breaks in the case where people actually want to know when a dominant color is white to perform some other logic).

I'm wondering if this could also be solved at a user/client level with a "randomized" retry or something. Basically you could run the script, and if the palette doesn't look right to the human doing the evaluation, they could have a retry button which passes a different set of options to getPalette - that would need some work on the plugin end, but basically let me say I want to regenerate with a different mechanism for dominance calculation. So I could just retry a few times until I find something that "feels" right, acknowledging as a user that by doing so it's not "mathematically correct" but more "aesthetically correct"

marklanhamhc commented 4 years ago

I think this is a tricky one and possibly a bit of a slippery slope as we are expecting the script to return a set of values based on logic but then if we don't like the result we are using subjectivity over logic which surely defeats the object of using the script in the first place.

I would say the best thing is to just look at what you're trying to achieve and work backwards from there. In your example, if each logo/colour is to be reviewed by a human then maybe the script can just make a recommendation and return a scale of the 3 most dominant colours based on probability logic, then the user selects one.

The way I was using it was completely different, I needed to set a background colour in a banner based on the most dominant colour in the logo and we had about 3 thousand logos so the whole thing needed to be automated. Therefore when a user visited a page with that logo in the banner it would automatically render the correct background colour to match the logo.

brianlovin commented 4 years ago

if we don't like the result we are using subjectivity over logic which surely defeats the object of using the script in the first place.

Totally understand, and agreed. It seems fairly straightforward to use the results from getPalette as an option list for the end user to "replace dominant color" clientside :)

lokesh commented 4 years ago

@brianlovin Thanks for sharing the sample image and how it misaligns with expectations. I think it is a fair concern and something I am interesting in improving. I'm planning a deep-dive on the algorithm and doing other explorations to improve results in the next couple weeks and will report back here.

An example of something that is already implemented to help meet expectations that sidesteps the algorithm is the removal of white and very-near-white colors from being processed. When I was doing my initial tests with logo pngs, that often lacked transparency, they were almost always returning white as the dominant color because that colors prevalence in the background.

robinscholz commented 2 years ago

color

my node implementation returns [ 252, 220, 220] instead of [255, 220, 220] for this image. Both Photoshop as well as the native mac color meter show the image color as [255, 220, 220]

robinscholz commented 2 years ago

color

This image is analyzed as [252, 4, 4] instead of [255, 0, 0]