Code Monkey home page Code Monkey logo

Comments (19)

jkomyno avatar jkomyno commented on May 5, 2024 3

May I propose a solution using something like Palitra? It is usable both as a library and as a CLI tool.
It allows to restrict the number of colours returned and the possible colours are the ones defined with a name by the CSS3 specification. This is similar to @lastzero proposal to use Material Design Palette's colours spec.

from photoprism.

darkLord19 avatar darkLord19 commented on May 5, 2024 1

@lastzero This sounds interesting. I will work on this. If I have any questions, I'll ask here.

from photoprism.

lastzero avatar lastzero commented on May 5, 2024 1

@jkomyno Yes, that looks great. Of course with the material color names (or similar simple ones). Nobody wants to search for "peachpuff", I guess.

from photoprism.

lastzero avatar lastzero commented on May 5, 2024

Source files:

Right now we're using the "github.com/RobCherry/vibrant" library, but I feel this is not what we want for a search. We want the human impression of the image. Let's say max 2 or 3 colors from the material design color palette.

from photoprism.

darkLord19 avatar darkLord19 commented on May 5, 2024

I am interested in contributing to this project. Can you please give some starting points to solve this issue?

from photoprism.

lastzero avatar lastzero commented on May 5, 2024

@darkLord19 It's not really something to fix, like a bug (except the panics this library causes).

If you look at the models / database tables and the indexer, you'll see that colors are being indexed, so that you can search for them. So now, we want the search to return good results. That means you want a defined, short list of colors you can search for (right now it's like 128 different colors). Also you want those colors to have something to do with the human perception of the image. Requires some research an experiments. I think it's fun. Just not straight forward.

from photoprism.

lastzero avatar lastzero commented on May 5, 2024

Thank you! Please post a proposal (containing algorithm, colors, performance,...) before you invest lots of time coding on a specific solution :)

from photoprism.

jkomyno avatar jkomyno commented on May 5, 2024

@lastzero Lol for the "peachpuff" example. I came up with a script to download the latest Material Design color spec as a JSON. It may be further normalized and processed to obtain a structure similar to this one.

The crawler script:

// Go to https://material.io/design/color/the-color-system.html#tools-for-picking-colors,
// open the Chrome console and run the following:

function getColors() {
  const elements = document.querySelectorAll('#tools-for-picking-colors .color-tag:first-child');
  return [].reduce.call(elements, (acc, color) => {
    const compositeShadeName = color.getElementsByClassName('shade')[0].textContent;
    const splitCompositeShadeName = compositeShadeName.split(' ');

    if (splitCompositeShadeName.length === 1) {
      // it's either black or white
      acc['black'] = '#000';
      acc['white'] = '#FFF';
    } else {
      const shadeName = compositeShadeName.split(' ').slice(0, -1).join(' ').toLowerCase();
      const colorVariants = color.parentNode.querySelectorAll('.color-tag:not(:first-child)');
      acc[shadeName] = [].reduce.call(colorVariants, (accVariant, colorVariant) => {
        const shade = colorVariant.getElementsByClassName('shade')[0].textContent;
        const hex = colorVariant.getElementsByClassName('hex')[0].textContent;
        accVariant[shade] = hex;

        return accVariant;
      }, {});
    }

    return acc;
  }, {});
}

The result:

JSON.stringify(getColors(), null, 2);
{
  "red": {
    "100": "#FFCDD2",
    "200": "#EF9A9A",
    "300": "#E57373",
    "400": "#EF5350",
    "500": "#F44336",
    "600": "#E53935",
    "700": "#D32F2F",
    "800": "#C62828",
    "900": "#B71C1C",
    "A100": "#FF8A80",
    "A200": "#FF5252",
    "A400": "#FF1744",
    "A700": "#D50000"
  },
  "pink": {
    "100": "#F8BBD0",
    "200": "#F48FB1",
    "300": "#F06292",
    "400": "#EC407A",
    "500": "#E91E63",
    "600": "#D81B60",
    "700": "#C2185B",
    "800": "#AD1457",
    "900": "#880E4F",
    "A100": "#FF80AB",
    "A200": "#FF4081",
    "A400": "#F50057",
    "A700": "#C51162"
  },
  "purple": {
    "100": "#E1BEE7",
    "200": "#CE93D8",
    "300": "#BA68C8",
    "400": "#AB47BC",
    "500": "#9C27B0",
    "600": "#8E24AA",
    "700": "#7B1FA2",
    "800": "#6A1B9A",
    "900": "#4A148C",
    "A100": "#EA80FC",
    "A200": "#E040FB",
    "A400": "#D500F9",
    "A700": "#AA00FF"
  },
  "deep purple": {
    "100": "#D1C4E9",
    "200": "#B39DDB",
    "300": "#9575CD",
    "400": "#7E57C2",
    "500": "#673AB7",
    "600": "#5E35B1",
    "700": "#512DA8",
    "800": "#4527A0",
    "900": "#311B92",
    "A100": "#B388FF",
    "A200": "#7C4DFF",
    "A400": "#651FFF",
    "A700": "#6200EA"
  },
  "indigo": {
    "100": "#C5CAE9",
    "200": "#9FA8DA",
    "300": "#7986CB",
    "400": "#5C6BC0",
    "500": "#3F51B5",
    "600": "#3949AB",
    "700": "#303F9F",
    "800": "#283593",
    "900": "#1A237E",
    "A100": "#8C9EFF",
    "A200": "#536DFE",
    "A400": "#3D5AFE",
    "A700": "#304FFE"
  },
  "blue": {
    "100": "#BBDEFB",
    "200": "#90CAF9",
    "300": "#64B5F6",
    "400": "#42A5F5",
    "500": "#2196F3",
    "600": "#1E88E5",
    "700": "#1976D2",
    "800": "#1565C0",
    "900": "#0D47A1",
    "A100": "#82B1FF",
    "A200": "#448AFF",
    "A400": "#2979FF",
    "A700": "#2962FF"
  },
  "light blue": {
    "100": "#B3E5FC",
    "200": "#81D4FA",
    "300": "#4FC3F7",
    "400": "#29B6F6",
    "500": "#03A9F4",
    "600": "#039BE5",
    "700": "#0288D1",
    "800": "#0277BD",
    "900": "#01579B",
    "A100": "#80D8FF",
    "A200": "#40C4FF",
    "A400": "#00B0FF",
    "A700": "#0091EA"
  },
  "cyan": {
    "100": "#B2EBF2",
    "200": "#80DEEA",
    "300": "#4DD0E1",
    "400": "#26C6DA",
    "500": "#00BCD4",
    "600": "#00ACC1",
    "700": "#0097A7",
    "800": "#00838F",
    "900": "#006064",
    "A100": "#84FFFF",
    "A200": "#18FFFF",
    "A400": "#00E5FF",
    "A700": "#00B8D4"
  },
  "teal": {
    "100": "#B2DFDB",
    "200": "#80CBC4",
    "300": "#4DB6AC",
    "400": "#26A69A",
    "500": "#009688",
    "600": "#00897B",
    "700": "#00796B",
    "800": "#00695C",
    "900": "#004D40",
    "A100": "#A7FFEB",
    "A200": "#64FFDA",
    "A400": "#1DE9B6",
    "A700": "#00BFA5"
  },
  "green": {
    "100": "#C8E6C9",
    "200": "#A5D6A7",
    "300": "#81C784",
    "400": "#66BB6A",
    "500": "#4CAF50",
    "600": "#43A047",
    "700": "#388E3C",
    "800": "#2E7D32",
    "900": "#1B5E20",
    "A100": "#B9F6CA",
    "A200": "#69F0AE",
    "A400": "#00E676",
    "A700": "#00C853"
  },
  "light green": {
    "100": "#DCEDC8",
    "200": "#C5E1A5",
    "300": "#AED581",
    "400": "#9CCC65",
    "500": "#8BC34A",
    "600": "#7CB342",
    "700": "#689F38",
    "800": "#558B2F",
    "900": "#33691E",
    "A100": "#CCFF90",
    "A200": "#B2FF59",
    "A400": "#76FF03",
    "A700": "#64DD17"
  },
  "lime": {
    "100": "#F0F4C3",
    "200": "#E6EE9C",
    "300": "#DCE775",
    "400": "#D4E157",
    "500": "#CDDC39",
    "600": "#C0CA33",
    "700": "#AFB42B",
    "800": "#9E9D24",
    "900": "#827717",
    "A100": "#F4FF81",
    "A200": "#EEFF41",
    "A400": "#C6FF00",
    "A700": "#AEEA00"
  },
  "yellow": {
    "100": "#FFF9C4",
    "200": "#FFF59D",
    "300": "#FFF176",
    "400": "#FFEE58",
    "500": "#FFEB3B",
    "600": "#FDD835",
    "700": "#FBC02D",
    "800": "#F9A825",
    "900": "#F57F17",
    "A100": "#FFFF8D",
    "A200": "#FFFF00",
    "A400": "#FFEA00",
    "A700": "#FFD600"
  },
  "amber": {
    "100": "#FFECB3",
    "200": "#FFE082",
    "300": "#FFD54F",
    "400": "#FFCA28",
    "500": "#FFC107",
    "600": "#FFB300",
    "700": "#FFA000",
    "800": "#FF8F00",
    "900": "#FF6F00",
    "A100": "#FFE57F",
    "A200": "#FFD740",
    "A400": "#FFC400",
    "A700": "#FFAB00"
  },
  "orange": {
    "100": "#FFE0B2",
    "200": "#FFCC80",
    "300": "#FFB74D",
    "400": "#FFA726",
    "500": "#FF9800",
    "600": "#FB8C00",
    "700": "#F57C00",
    "800": "#EF6C00",
    "900": "#E65100",
    "A100": "#FFD180",
    "A200": "#FFAB40",
    "A400": "#FF9100",
    "A700": "#FF6D00"
  },
  "deep orange": {
    "100": "#FFCCBC",
    "200": "#FFAB91",
    "300": "#FF8A65",
    "400": "#FF7043",
    "500": "#FF5722",
    "600": "#F4511E",
    "700": "#E64A19",
    "800": "#D84315",
    "900": "#BF360C",
    "A100": "#FF9E80",
    "A200": "#FF6E40",
    "A400": "#FF3D00",
    "A700": "#DD2C00"
  },
  "brown": {
    "100": "#D7CCC8",
    "200": "#BCAAA4",
    "300": "#A1887F",
    "400": "#8D6E63",
    "500": "#795548",
    "600": "#6D4C41",
    "700": "#5D4037",
    "800": "#4E342E",
    "900": "#3E2723"
  },
  "gray": {
    "100": "#F5F5F5",
    "200": "#EEEEEE",
    "300": "#E0E0E0",
    "400": "#BDBDBD",
    "500": "#9E9E9E",
    "600": "#757575",
    "700": "#616161",
    "800": "#424242",
    "900": "#212121"
  },
  "blue gray": {
    "100": "#CFD8DC",
    "200": "#B0BEC5",
    "300": "#90A4AE",
    "400": "#78909C",
    "500": "#607D8B",
    "600": "#546E7A",
    "700": "#455A64",
    "800": "#37474F",
    "900": "#263238"
  },
  "black": "#000",
  "white": "#FFF"
}

from photoprism.

lastzero avatar lastzero commented on May 5, 2024

Ah, I meant just the names! The variant doesn't matter. I would use a simple lookup table (like it is implemented now), but loading a custom table from an external json / yaml file might also be an idea. We only use yaml for config at the moment.

from photoprism.

jkomyno avatar jkomyno commented on May 5, 2024

The variant doesn't matter

Do you mean that you would only select the colors with, let's say, the 500 variant?
That would produce the following:

{
  "white": "#FFF",
  "black": "#000",
  "red": "#F44336",
  "pink": "#E91E63",
  "purple": "#9C27B0",
  "deep purple": "#673AB7",
  "indigo": "#3F51B5",
  "blue": "#2196F3",
  "light blue": "#03A9F4",
  "cyan": "#00BCD4",
  "teal": "#009688",
  "green": "#4CAF50",
  "light green": "#8BC34A",
  "lime": "#CDDC39",
  "yellow": "#FFEB3B",
  "amber": "#FFC107",
  "orange": "#FF9800",
  "deep orange": "#FF5722",
  "brown": "#795548",
  "gray": "#9E9E9E",
  "blue gray": "#607D8B"
}

from photoprism.

lastzero avatar lastzero commented on May 5, 2024

Best data structure probably is a map mapping unique color codes to (not unique) color names.

from photoprism.

lastzero avatar lastzero commented on May 5, 2024

@jkomyno Still working on this? I will set the issue to "in-progress" then. We are not in a hurry, just asking.

from photoprism.

IssueHuntBot avatar IssueHuntBot commented on May 5, 2024

@lastzero has funded $20.00 to this issue. See it on IssueHunt

from photoprism.

IssueHuntBot avatar IssueHuntBot commented on May 5, 2024

@issuehuntfest has funded $20.00 to this issue. See it on IssueHunt

from photoprism.

skunert avatar skunert commented on May 5, 2024

Hey, I am interested in picking up this issue. However, I am not sure I can follow the discussion here.

Right now, the vibrant library extracts colors from the picture. Then we compute the distance to the colors from the colornames library (which is responsible for the complicated names). So if I would define a new map only containing the colors you describe in the original post, wouldn't that solve the problem already? Why should we reimplement K-Means for this?

from photoprism.

evanoberholster avatar evanoberholster commented on May 5, 2024

Has anyone taken a look at: EdlinOrg/prominentcolor. It's based off of k-means and can be adjusted todo what was described above.

Instead of indexing via known color names, you could index based on Nearest-Neighbor search. Any thoughts on this?

from photoprism.

lastzero avatar lastzero commented on May 5, 2024

@evanoberholster Yes, but not sure why I haven't used it initially. prominentcolor can certainly serve as inspiration.

from photoprism.

lastzero avatar lastzero commented on May 5, 2024

I've just pushed an implementation that doesn't use random numbers. It also enables us to search specific parts of an image (3x3 pixels = up to 9 colors). Seems to work well for now!

Screenshot 2019-04-26 at 02 30 23

from photoprism.

IssueHuntBot avatar IssueHuntBot commented on May 5, 2024

@lastzero has rewarded $36.00 to @skunert. See it on IssueHunt

  • 💰 Total deposit: $40.00
  • 🎉 Repository reward(0%): $0.00
  • 🔧 Service fee(10%): $4.00

from photoprism.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.