algorithm - Suivi: "Tri" des couleurs par caractère distinctif

Translate

Question originale

Si vous recevez N couleurs distantes au maximum (et une métrique de distance associée), pouvez-vous trouver un moyen de trier ces couleurs dans un ordre tel que les premiers M soient également raisonnablement proches d'être un ensemble au maximum distinct?

En d'autres termes, étant donné un tas de couleurs distinctes, établissez une commande afin que je puisse utiliser autant de couleurs que nécessaire en commençant par le début et être raisonnablement assuré qu'elles sont toutes distinctes et que les couleurs voisines sont également très distinctes (par exemple, le rouge bleuâtre n'est pas à côté du bleu rougeâtre).

La randomisation est acceptable mais certainement pas optimale.

Clarification: Étant donné un ensemble de couleurs large et visuellement distinct (disons 256 ou 1024), je veux les trier de sorte que lorsque j'utilise le premier, disons 16 d'entre elles, j'obtienne un sous-ensemble de couleurs relativement distinct visuellement. Cela équivaut, en gros, à dire que je veux trier cette liste de 1024 afin que plus les couleurs individuelles sont visuellement proches, plus elles sont éloignées sur la liste.

This question and all comments follow the "Attribution Required."

Toutes les réponses

Translate

Cela me semble aussi une sorte degraphique de résistanceoù vous essayez de tracer le chemin de moindre résistance. Si vous inversez les exigences, chemin de la résistance maximale, cela pourrait peut-être être utilisé pour produire un ensemble qui dès le départ produit une différence maximale au fur et à mesure, et vers la fin commence à revenir à des valeurs plus proches des autres.

Par exemple, voici une façon de faire peut-être ce que vous voulez.

  1. Calculez la distance (réfvotre autre message) de chaque couleur à toutes les autres couleurs
  2. Additionnez les distances pour chaque couleur, cela vous donne une indication pourà quelle distance cette couleur est au total de toutes les autres couleurs
  3. Trier la liste par distance, en descendant

Cela produirait, semble-t-il, une liste qui commence par la couleur la plus éloignée de toutes les autres couleurs, puis descendrait, les couleurs vers la fin de la liste seraient plus proches des autres couleurs en général.

Edit: La lecture de votre réponse à mon premier message, sur la subdivision spatiale, ne correspondrait pas exactement à la description ci-dessus, car les couleurs proches d'autres couleurs tomberaient au bas de la liste, mais disons que vous avez un groupe de couleurs quelque part, à au moins une des couleurs de ce groupe serait située près du début de la liste, et ce serait celle qui était généralement la plus éloignée de toutes les autres couleurs au total. Si ça a du sens.

La source
Translate

Ce problème s'appelle la quantification des couleurs et comporte de nombreux algorithmes bien connus:http://en.wikipedia.org/wiki/Color_quantizationJe connais des gens qui ont mis en œuvre l'approche octree à bon escient.

La source
Translate

Il semble que la perception est importante pour vous, dans ce cas, vous voudrez peut-être envisager de travailler avec un espace couleur perceptif tel que YUV, YCbCr ou Lab. Chaque fois que j'en ai utilisé, ils m'ont donné de bien meilleurs résultats que le sRGB seul.

La conversion vers et depuis sRGB peut être pénible, mais dans votre cas, cela pourrait en fait simplifier l'algorithme et en prime, cela fonctionnera principalement pour les daltoniens!

La source
Translate

N couleurs distantes au maximum peuvent être considérées comme un ensemble de points bien distribués dans un espace tridimensionnel (couleur). Si vous pouvez les générer à partir d'unSéquence de Halton, alors tout préfixe (les M premières couleurs) se compose également de points bien répartis.

La source
Translate

Si je comprends bien la question, vous souhaitez obtenir le sous-ensemble deMcouleurs avec ledistance moyenne la plus élevéeentre les couleurs, étant donné une fonction de distanced.

En d'autres termes, compte tenu de l'ensemble initial deNcouleurs sous la forme d'un grand graphique non orienté dans lequel toutes les couleurs sont connectées, vous voulez trouver lele plus long cheminqui visite toutMnœuds.

La résolution de problèmes de graphes NP-complets me dépasse, j'en ai peur, mais vous pouvez essayer d'exécuter une simple simulation physique:

  1. produireMpoints aléatoires dans l'espace colorimétrique
  2. Calculez la distance entre chaque point
  3. Calculez les vecteurs de répulsion pour chaque point qui l'éloigneront de tous les autres points (en utilisant 1 / (distance^ 2) comme la grandeur du vecteur)
  4. Additionner les vecteurs de répulsion pour chaque point
  5. Mettre à jour la position de chaque point en fonction des vecteurs de répulsion additionnés
  6. Contraindre toutes les coordonnées hors limites (telles que la luminosité devient négative ou supérieure à un)
  7. Répétez à partir de l'étape 2 jusqu'à ce que les points se stabilisent
  8. Pour chaque point, sélectionnez la couleur la plus proche de l'ensemble d'origine deN

C'est loin d'être efficace, mais pour les petitsMil peut être assez efficace et donner des résultats presque optimaux.

Si votre fonction de distance de couleur est simple, il peut y avoir une manière plus déterministe de générer le sous-ensemble optimal.

La source
Translate
  1. Commencez avec deux listes. CandidateColors, qui contient initialement vos couleurs distinctes et SortedColors, qui est initialement vide.
  2. Choisissez n'importe quelle couleur et supprimez-la de CandidateColors et placez-la dans SortedColors. Ceci est la première couleur et sera la plus courante, c'est donc un bon endroit pour choisir une couleur qui correspond bien à votre application.
  3. Pour chaque couleur dans CandidateColors, calculez sa distance totale. La distance totale est la somme de la distance entre CandidateColor et chacune des couleurs de SortedColors.
  4. Supprimez la couleur avec la plus grande distance totale de CandidateColors et ajoutez-la à la fin de SortedColors.
  5. Si CandidateColors n'est pas vide, revenez à l'étape 3.

Cet algorithme gourmand devrait vous donner de bons résultats.

La source
Translate

Vous pouvez simplement trier les couleurs candidates en fonction de la distance maximale de la distance minimale à l'une des couleurs d'index.

Utilisation de la distance de couleur euclidienne:

public double colordistance(Color color0, Color color1) {
    int c0 = color0.getRGB();
    int c1 = color1.getRGB();
    return distance(((c0>>16)&0xFF), ((c0>>8)&0xFF), (c0&0xFF), ((c1>>16)&0xFF), ((c1>>8)&0xFF), (c1&0xFF));
}

public double distance(int r1, int g1, int b1, int r2, int g2, int b2) {
    int dr = (r1 - r2);
    int dg = (g1 - g2);
    int db = (b1 - b2);
    return Math.sqrt(dr * dr + dg * dg + db * db);
}

Bien que vous puissiez le remplacer par tout ce que vous voulez. Il a juste besoin d'une routine de distance de couleur.

public void colordistancesort(Color[] candidateColors, Color[] indexColors) {
    double current;

    double distance[] = new double[candidateColors.length];
    for (int j = 0; j < candidateColors.length; j++) {
        distance[j] = -1;
        for (int k = 0; k < indexColors.length; k++) {
            current = colordistance(indexColors[k], candidateColors[j]);
            if ((distance[j] == -1) || (current < distance[j])) {
                distance[j] = current;
            }
        }
    }

    //just sorts.
    for (int j = 0; j < candidateColors.length; j++) {
        for (int k = j + 1; k < candidateColors.length; k++) {
            if (distance[j] > distance[k]) {
                double d = distance[k];
                distance[k] = distance[j];
                distance[j] = d;

                Color m = candidateColors[k];
                candidateColors[k] = candidateColors[j];
                candidateColors[j] = m;
            }
        }
    }
}
La source
Translate

Voulez-vous dire que dans un ensemble de N couleurs, vous devez choisir M couleurs, où M <N, de sorte que M est lemeilleurreprésentation des N couleurs dans l'espace M?

Comme meilleur exemple, réduisez une vraie couleur (espace colorimétrique 24 bits) à un espace colorimétrique mappé 8 bits (GIF?).

Il existe des algorithmes de quantification pour cela, comme leSubdivision spatiale adaptativealgorithme utilisé par ImageMagic.

Ces algorithmes ne choisissent généralement pas seulement les couleurs existantes de l'espace source, mais créent de nouvelles couleurs dans l'espace cible qui ressemblent le plus aux couleurs source. À titre d'exemple simplifié, si vous avez 3 couleurs dans l'image d'origine où deux sont rouges (avec une intensité différente ou des teintes bleuâtres, etc.) et la troisième est bleue, et devez réduire à deux couleurs, l'image cible pourrait avoir une couleur rouge c'est une sorte de moyenne des deux rouges originaux + la couleur bleue de l'image originale.

Si vous avez besoin d'autre chose, je n'ai pas compris votre question :)

La source
Translate

Vous pouvez les diviser au format RVB HEX afin de pouvoir comparer le R avec des R d'une couleur différente, de même que le G et B.

Même format que HTML

XX XX XX
RR GG BB

00 00 00 = black
ff ff ff = white
ff 00 00 = red
00 ff 00 = green
00 00 ff = blue

Donc, la seule chose que vous devez décider est de savoir à quelle distance vous voulez les couleurs et quelle est une différence acceptable pour que les segments soient considérés comme différents.

La source