কীভাবে স্বয়ংক্রিয়ভাবে এন "স্বতন্ত্র" রঙ তৈরি করা যায়?


194

স্বয়ংক্রিয়ভাবে এন পৃথক রং নির্বাচন করতে আমি নীচের দুটি পদ্ধতি লিখেছি। এটি আরজিবি কিউবে পিসওয়াসার লিনিয়ার ফাংশনটি সংজ্ঞায়িত করে কাজ করে। এর সুবিধাটি হ'ল আপনি যা চান তা যদি আপনি প্রগতিশীল স্কেলও পেতে পারেন তবে এন বড় হয়ে গেলে রঙগুলি একই রকম দেখতে শুরু করতে পারে। আমি আরজিবি কিউবটিকে একটি জালিতে সমানভাবে বিভাজন এবং তারপরে পয়েন্টগুলি আঁকতেও কল্পনা করতে পারি। কেউ কি অন্য কোন পদ্ধতি জানেন? আমি একটি তালিকা সংজ্ঞায়িত করার রায় দিচ্ছি এবং তারপরে এটির মাধ্যমে সাইকেল চালিয়ে যাচ্ছি। আমার এও বলা উচিত যে তারা সাধারণত সংঘর্ষে জড়িত হয় বা সুন্দর না দেখায় আমার সাধারণত যত্ন নেই they

public static List<Color> pick(int num) {
    List<Color> colors = new ArrayList<Color>();
    if (num < 2)
        return colors;
    float dx = 1.0f / (float) (num - 1);
    for (int i = 0; i < num; i++) {
        colors.add(get(i * dx));
    }
    return colors;
}

public static Color get(float x) {
    float r = 0.0f;
    float g = 0.0f;
    float b = 1.0f;
    if (x >= 0.0f && x < 0.2f) {
        x = x / 0.2f;
        r = 0.0f;
        g = x;
        b = 1.0f;
    } else if (x >= 0.2f && x < 0.4f) {
        x = (x - 0.2f) / 0.2f;
        r = 0.0f;
        g = 1.0f;
        b = 1.0f - x;
    } else if (x >= 0.4f && x < 0.6f) {
        x = (x - 0.4f) / 0.2f;
        r = x;
        g = 1.0f;
        b = 0.0f;
    } else if (x >= 0.6f && x < 0.8f) {
        x = (x - 0.6f) / 0.2f;
        r = 1.0f;
        g = 1.0f - x;
        b = 0.0f;
    } else if (x >= 0.8f && x <= 1.0f) {
        x = (x - 0.8f) / 0.2f;
        r = 1.0f;
        g = 0.0f;
        b = x;
    }
    return new Color(r, g, b);
}

4
আকর্ষণীয় উত্তর সহ দৃ relevant়ভাবে প্রাসঙ্গিক প্রোগ্রামারদের প্রশ্ন: " রঙিন স্কিমগুলি উত্পাদন - তত্ত্ব এবং অ্যালগরিদম ।"
আলেক্সি পপকভ

2
দুর্ভাগ্যক্রমে মানব বর্ণ উপলব্ধি রৈখিক নয়। আপনি যদি বিভিন্ন তীব্রতা ব্যবহার করে থাকেন তবে আপনাকে বেজল্ড ব্র্যাক শিফ্টের জন্য অ্যাকাউন্টও দিতে হবে। : এছাড়া ভাল তথ্য এখানে vis4.net/blog/posts/avoid-equidistant-hsv-colors
spex

উত্তর:


80

আপনার রঙগুলি তৈরি করতে আপনি এইচএসএল রঙের মডেল ব্যবহার করতে পারেন ।

যদি আপনি চান সমস্ত হ'ল (সম্ভাব্য) আলাদা হয় এবং হালকা বা স্যাচুরেশনের কিছুটা ভিন্নতা হয় তবে আপনি এই জাতীয় রঙগুলি বিতরণ করতে পারেন:

// assumes hue [0, 360), saturation [0, 100), lightness [0, 100)

for(i = 0; i < 360; i += 360 / num_colors) {
    HSLColor c;
    c.hue = i;
    c.saturation = 90 + randf() * 10;
    c.lightness = 50 + randf() * 10;

    addColor(c);
}

2
এই কৌশলটি স্মার্ট। আমি বাজি ধরছি এটি আমার চেয়ে আরও নান্দনিক ফলাফল পাবে।
এমকিপিপি

45
এটি ধরে নিয়েছে যে সমান-ব্যবধানযুক্ত হিউ মানগুলি বোধগম্যভাবে পৃথক। এমনকি বর্ণবিন্যাসের বিভিন্ন ধরণের ছাড় ছাড়াই, বেশিরভাগ লোকের ক্ষেত্রে এটি সত্য নয়: 120 ° (সবুজ) এবং 135 ° (খুব সামান্য পুদিনা সবুজ) এর মধ্যে পার্থক্য অনর্থক, যখন 30 ° (কমলা) এবং 45 ° (পীচ) এর মধ্যে পার্থক্য বেশ সুস্পষ্ট। সেরা ফলাফলের জন্য আপনার হিউ বরাবর একটি লিনিয়ার ফাঁকা স্থান প্রয়োজন।
ফোগজ

18
@ ম্যাকান্দার - এটি মোটেই স্মার্ট নয়। এই অ্যালগরিদমটিকে দুর্ঘটনাক্রমে দুটি প্রায় অভিন্ন রঙ বাছাই করা থেকে বিরত করার মতো কিছুই নেই। আমার উত্তরটি আরও ভাল, এবং ওহাদস্কের উত্তরটি আরও ভাল।
রকেটম্যাগনেট

1
এটি ইতিমধ্যে উল্লিখিত কারণগুলির জন্য ভুল, তবে আপনি একইভাবে বাছাই করছেন না বলেও এটি ভুল ।
সাম হোচেভার

3
@ স্ট্র্যাজারটি এলোমেলো () এর প্রত্যাশিত মানটি কি
কিলরওর

242

এই প্রশ্নগুলি বেশ কয়েকটি এসও আলোচনায় উপস্থিত হয়:

বিভিন্ন সমাধান প্রস্তাব করা হয়, তবে কোনওটিই অনুকূল নয়। ভাগ্যক্রমে, বিজ্ঞান উদ্ধার করতে আসে

নির্বিচারে এন

সর্বশেষ 2 টি বেশিরভাগ বিশ্ববিদ্যালয়ের গ্রন্থাগার / প্রক্সিগুলির মাধ্যমে বিনামূল্যে হবে।

এন সীমাবদ্ধ এবং তুলনামূলকভাবে ছোট

এই ক্ষেত্রে, একটি তালিকা সমাধানের জন্য যেতে পারে। বিষয়টির একটি খুব আকর্ষণীয় নিবন্ধ নিখরচায় পাওয়া যায়:

বিবেচনা করার জন্য বেশ কয়েকটি রঙের তালিকা রয়েছে:

  • বয়েনটনের 11 টি রঙের তালিকা যা প্রায় কখনও বিভ্রান্ত হয় না (পূর্ববর্তী বিভাগের প্রথম কাগজে পাওয়া যায়)
  • কেলির সর্বাধিক বিপরীতে 22 টি রঙ (উপরের কাগজে পাওয়া যায়)

আমি এমআইটি-র এক ছাত্র দ্বারা এই প্যালেটেও ছুটে এসেছি । শেষ অবধি, নিম্নলিখিত লিঙ্কগুলি বিভিন্ন রঙ সিস্টেম / স্থানাঙ্কের মধ্যে রূপান্তর করতে কার্যকর হতে পারে (নিবন্ধগুলির কয়েকটি রঙ আরজিবিতে নির্দিষ্ট করা হয়নি, উদাহরণস্বরূপ):

কেলি এবং বয়ন্টনের তালিকার জন্য, আমি ইতিমধ্যে আরজিবিতে রূপান্তর করেছি (সাদা এবং কালো বাদে, যা স্পষ্ট হওয়া উচিত)। কিছু সি # কোড:

public static ReadOnlyCollection<Color> KellysMaxContrastSet
{
    get { return _kellysMaxContrastSet.AsReadOnly(); }
}

private static readonly List<Color> _kellysMaxContrastSet = new List<Color>
{
    UIntToColor(0xFFFFB300), //Vivid Yellow
    UIntToColor(0xFF803E75), //Strong Purple
    UIntToColor(0xFFFF6800), //Vivid Orange
    UIntToColor(0xFFA6BDD7), //Very Light Blue
    UIntToColor(0xFFC10020), //Vivid Red
    UIntToColor(0xFFCEA262), //Grayish Yellow
    UIntToColor(0xFF817066), //Medium Gray

    //The following will not be good for people with defective color vision
    UIntToColor(0xFF007D34), //Vivid Green
    UIntToColor(0xFFF6768E), //Strong Purplish Pink
    UIntToColor(0xFF00538A), //Strong Blue
    UIntToColor(0xFFFF7A5C), //Strong Yellowish Pink
    UIntToColor(0xFF53377A), //Strong Violet
    UIntToColor(0xFFFF8E00), //Vivid Orange Yellow
    UIntToColor(0xFFB32851), //Strong Purplish Red
    UIntToColor(0xFFF4C800), //Vivid Greenish Yellow
    UIntToColor(0xFF7F180D), //Strong Reddish Brown
    UIntToColor(0xFF93AA00), //Vivid Yellowish Green
    UIntToColor(0xFF593315), //Deep Yellowish Brown
    UIntToColor(0xFFF13A13), //Vivid Reddish Orange
    UIntToColor(0xFF232C16), //Dark Olive Green
};

public static ReadOnlyCollection<Color> BoyntonOptimized
{
    get { return _boyntonOptimized.AsReadOnly(); }
}

private static readonly List<Color> _boyntonOptimized = new List<Color>
{
    Color.FromArgb(0, 0, 255),      //Blue
    Color.FromArgb(255, 0, 0),      //Red
    Color.FromArgb(0, 255, 0),      //Green
    Color.FromArgb(255, 255, 0),    //Yellow
    Color.FromArgb(255, 0, 255),    //Magenta
    Color.FromArgb(255, 128, 128),  //Pink
    Color.FromArgb(128, 128, 128),  //Gray
    Color.FromArgb(128, 0, 0),      //Brown
    Color.FromArgb(255, 128, 0),    //Orange
};

static public Color UIntToColor(uint color)
{
    var a = (byte)(color >> 24);
    var r = (byte)(color >> 16);
    var g = (byte)(color >> 8);
    var b = (byte)(color >> 0);
    return Color.FromArgb(a, r, g, b);
}

এবং এখানে হেক্স এবং আর-চ্যানেল 8-বিট-প্রতি চ্যানেল উপস্থাপনায় আরজিবি মান রয়েছে:

kelly_colors_hex = [
    0xFFB300, # Vivid Yellow
    0x803E75, # Strong Purple
    0xFF6800, # Vivid Orange
    0xA6BDD7, # Very Light Blue
    0xC10020, # Vivid Red
    0xCEA262, # Grayish Yellow
    0x817066, # Medium Gray

    # The following don't work well for people with defective color vision
    0x007D34, # Vivid Green
    0xF6768E, # Strong Purplish Pink
    0x00538A, # Strong Blue
    0xFF7A5C, # Strong Yellowish Pink
    0x53377A, # Strong Violet
    0xFF8E00, # Vivid Orange Yellow
    0xB32851, # Strong Purplish Red
    0xF4C800, # Vivid Greenish Yellow
    0x7F180D, # Strong Reddish Brown
    0x93AA00, # Vivid Yellowish Green
    0x593315, # Deep Yellowish Brown
    0xF13A13, # Vivid Reddish Orange
    0x232C16, # Dark Olive Green
    ]

kelly_colors = dict(vivid_yellow=(255, 179, 0),
                    strong_purple=(128, 62, 117),
                    vivid_orange=(255, 104, 0),
                    very_light_blue=(166, 189, 215),
                    vivid_red=(193, 0, 32),
                    grayish_yellow=(206, 162, 98),
                    medium_gray=(129, 112, 102),

                    # these aren't good for people with defective color vision:
                    vivid_green=(0, 125, 52),
                    strong_purplish_pink=(246, 118, 142),
                    strong_blue=(0, 83, 138),
                    strong_yellowish_pink=(255, 122, 92),
                    strong_violet=(83, 55, 122),
                    vivid_orange_yellow=(255, 142, 0),
                    strong_purplish_red=(179, 40, 81),
                    vivid_greenish_yellow=(244, 200, 0),
                    strong_reddish_brown=(127, 24, 13),
                    vivid_yellowish_green=(147, 170, 0),
                    deep_yellowish_brown=(89, 51, 21),
                    vivid_reddish_orange=(241, 58, 19),
                    dark_olive_green=(35, 44, 22))

আপনার সকল জাভা বিকাশকারীদের জন্য এখানে জাভাএফএক্স রঙ রয়েছে:

// Don't forget to import javafx.scene.paint.Color;

private static final Color[] KELLY_COLORS = {
    Color.web("0xFFB300"),    // Vivid Yellow
    Color.web("0x803E75"),    // Strong Purple
    Color.web("0xFF6800"),    // Vivid Orange
    Color.web("0xA6BDD7"),    // Very Light Blue
    Color.web("0xC10020"),    // Vivid Red
    Color.web("0xCEA262"),    // Grayish Yellow
    Color.web("0x817066"),    // Medium Gray

    Color.web("0x007D34"),    // Vivid Green
    Color.web("0xF6768E"),    // Strong Purplish Pink
    Color.web("0x00538A"),    // Strong Blue
    Color.web("0xFF7A5C"),    // Strong Yellowish Pink
    Color.web("0x53377A"),    // Strong Violet
    Color.web("0xFF8E00"),    // Vivid Orange Yellow
    Color.web("0xB32851"),    // Strong Purplish Red
    Color.web("0xF4C800"),    // Vivid Greenish Yellow
    Color.web("0x7F180D"),    // Strong Reddish Brown
    Color.web("0x93AA00"),    // Vivid Yellowish Green
    Color.web("0x593315"),    // Deep Yellowish Brown
    Color.web("0xF13A13"),    // Vivid Reddish Orange
    Color.web("0x232C16"),    // Dark Olive Green
};

উপরের অর্ডার অনুসারে নীচে অরসোর্টড কেলি রঙগুলি রয়েছে।

অমীমাংসিত কেলি রঙ

নীচে বর্ণমালা অনুসারে বাছাই করা কেলি রঙগুলি দেওয়া হয়েছে (লক্ষ্য করুন যে কয়েকটি ইয়াও খুব বিপরীত নয়)

 সাজানো কেলি রঙ


+1 এই দুর্দান্ত উত্তরের জন্য আপনাকে অনেক ধন্যবাদ! BTW লিংক colour-journal.org/2010/5/10 মারা গেছে, এই নিবন্ধটি এখনও পাওয়া যায় web.archive.org এ
আলেক্সি পপকভ


16
দুর্দান্ত উত্তর, ধন্যবাদ! এই দুটি রঙের সেটগুলিকে একটি সুবিধাজনক জেসফিডেলে
ডেভিড মিলস

1
কেবলমাত্র লক্ষ করা গেছে যে এই তালিকায় যথাক্রমে কেবলমাত্র 20 এবং 9 টি রঙ রয়েছে। আমি অনুমান করছি এটি সাদা এবং কালো বাদ দেওয়া হয়েছে।
ডেভিড মিলস

2
ওয়েব পরিষেবা এখনও উপলব্ধ?
জানুস ট্রয়লসন

38

উরি কোহেনের উত্তরের মতো তবে এটির পরিবর্তে একটি জেনারেটর। দূরে রঙ ব্যবহার করে শুরু হবে। নির্ণায়ক।

নমুনা, বাম রঙগুলি প্রথমে: নমুনা

#!/usr/bin/env python3.5
from typing import Iterable, Tuple
import colorsys
import itertools
from fractions import Fraction
from pprint import pprint

def zenos_dichotomy() -> Iterable[Fraction]:
    """
    http://en.wikipedia.org/wiki/1/2_%2B_1/4_%2B_1/8_%2B_1/16_%2B_%C2%B7_%C2%B7_%C2%B7
    """
    for k in itertools.count():
        yield Fraction(1,2**k)

def fracs() -> Iterable[Fraction]:
    """
    [Fraction(0, 1), Fraction(1, 2), Fraction(1, 4), Fraction(3, 4), Fraction(1, 8), Fraction(3, 8), Fraction(5, 8), Fraction(7, 8), Fraction(1, 16), Fraction(3, 16), ...]
    [0.0, 0.5, 0.25, 0.75, 0.125, 0.375, 0.625, 0.875, 0.0625, 0.1875, ...]
    """
    yield Fraction(0)
    for k in zenos_dichotomy():
        i = k.denominator # [1,2,4,8,16,...]
        for j in range(1,i,2):
            yield Fraction(j,i)

# can be used for the v in hsv to map linear values 0..1 to something that looks equidistant
# bias = lambda x: (math.sqrt(x/3)/Fraction(2,3)+Fraction(1,3))/Fraction(6,5)

HSVTuple = Tuple[Fraction, Fraction, Fraction]
RGBTuple = Tuple[float, float, float]

def hue_to_tones(h: Fraction) -> Iterable[HSVTuple]:
    for s in [Fraction(6,10)]: # optionally use range
        for v in [Fraction(8,10),Fraction(5,10)]: # could use range too
            yield (h, s, v) # use bias for v here if you use range

def hsv_to_rgb(x: HSVTuple) -> RGBTuple:
    return colorsys.hsv_to_rgb(*map(float, x))

flatten = itertools.chain.from_iterable

def hsvs() -> Iterable[HSVTuple]:
    return flatten(map(hue_to_tones, fracs()))

def rgbs() -> Iterable[RGBTuple]:
    return map(hsv_to_rgb, hsvs())

def rgb_to_css(x: RGBTuple) -> str:
    uint8tuple = map(lambda y: int(y*255), x)
    return "rgb({},{},{})".format(*uint8tuple)

def css_colors() -> Iterable[str]:
    return map(rgb_to_css, rgbs())

if __name__ == "__main__":
    # sample 100 colors in css format
    sample_colors = list(itertools.islice(css_colors(), 100))
    pprint(sample_colors)

নমুনার জন্য +1, খুব দুর্দান্ত এবং স্কিমটি আকর্ষণীয়ও দেখায়। এখানে অন্যান্য উত্তরগুলি একই কাজ করে উন্নত করা হবে এবং তারপরে সহজেই তুলনা করা যেতে পারে।
ডন হ্যাচ

3
ল্যাম্বডাসের পরিমাণ খুব বেশি n ল্যাম্বদা এটির সাথে শক্তিশালী।
গাইফিস

দেখতে দুর্দান্ত দেখাচ্ছে, কিন্তু আটকে যায় যখন আমি এটি 2.7-এ চালানোর চেষ্টা করি
এলাদ ওয়েইস

33

এখানে একটি ধারণা। এইচএসভি সিলিন্ডারের কল্পনা করুন

উজ্জ্বলতা এবং স্যাচুরেশনের জন্য আপনি উপরের এবং নিম্ন সীমাটি নির্ধারণ করুন Def এটি স্থানের মধ্যে বর্গাকার ক্রস বিভাগের রিংটি সংজ্ঞায়িত করে।

এখন, স্ক্যাটার এন এই স্থানের মধ্যে এলোমেলোভাবে পয়েন্ট।

তারপরে একটি নির্দিষ্ট সংখ্যক পুনরাবৃত্তির জন্য বা পয়েন্টগুলি স্থির না হওয়া পর্যন্ত তাদের উপর পুনরাবৃত্তির পুনরুক্তি অ্যালগরিদম প্রয়োগ করুন।

আপনার আগ্রহী রঙের জায়গাগুলির মধ্যে যতটা সম্ভব পৃথকভাবে N বর্ণের প্রতিনিধিত্বকারী এন পয়েন্ট থাকা উচিত।

হুগো


30

আগত প্রজন্মের জন্য আমি পাইথনে স্বীকৃত উত্তরটি এখানে যুক্ত করব।

import numpy as np
import colorsys

def _get_colors(num_colors):
    colors=[]
    for i in np.arange(0., 360., 360. / num_colors):
        hue = i/360.
        lightness = (50 + np.random.rand() * 10)/100.
        saturation = (90 + np.random.rand() * 10)/100.
        colors.append(colorsys.hls_to_rgb(hue, lightness, saturation))
    return colors

18

প্রত্যেকে মনে হয় খুব দরকারী YUV রঙের স্থানের অস্তিত্ব মিস করেছেন যা মানব চাক্ষুষ সিস্টেমের বর্ণগত পার্থক্য উপস্থাপনের জন্য ডিজাইন করা হয়েছিল। YUV- এর দূরত্বগুলি মানুষের উপলব্ধিতে পার্থক্য উপস্থাপন করে। আমার MagicCube4D এর জন্য এই কার্যকারিতাটির দরকার ছিল যা 4-মাত্রিক রুবিকের কিউবস এবং অন্যান্য 4D টুইস্টি ধাঁধাগুলির সীমাহীন সংখ্যক মুখগুলি নির্ধারণ করে imple

আমার সমাধানটি YUV এ র্যান্ডম পয়েন্টগুলি নির্বাচন করে এবং তারপরে পুনরাবৃত্তভাবে নিকটতম দুটি পয়েন্ট ভেঙে এবং ফলাফলটি ফেরত দেওয়ার সময় কেবল আরজিবিতে রূপান্তর করে শুরু হয় solution পদ্ধতিটি হ'ল (এন) 3) তবে এটি সংখ্যক সংখ্যক বা ক্যাশে হওয়া লোকের পক্ষে গুরুত্বপূর্ণ নয়। এটি অবশ্যই আরও দক্ষ করা যেতে পারে তবে ফলাফলগুলি দুর্দান্ত বলে মনে হয়।

ফাংশনটি উজ্জ্বলতার প্রান্তিকের alচ্ছিক স্পেসিফিকেশনের অনুমতি দেয় যাতে কোনও রঙ তৈরি করতে না পারে যাতে কোনও উপাদান প্রদত্ত পরিমাণের চেয়ে আরও উজ্জ্বল বা গাer় হয় না। আপনি কালো বা সাদা কাছাকাছি মানগুলি নাও পেতে পারেন। ফলস্বরূপ বর্ণগুলি মূল রঙ হিসাবে ব্যবহৃত হবে যা পরে আলো, লেয়ারিং, স্বচ্ছতা ইত্যাদির মাধ্যমে শেড করা হয় এবং অবশ্যই তাদের বেস রঙগুলি থেকে পৃথক হওয়া উচিত This

import java.awt.Color;
import java.util.Random;

/**
 * Contains a method to generate N visually distinct colors and helper methods.
 * 
 * @author Melinda Green
 */
public class ColorUtils {
    private ColorUtils() {} // To disallow instantiation.
    private final static float
        U_OFF = .436f,
        V_OFF = .615f;
    private static final long RAND_SEED = 0;
    private static Random rand = new Random(RAND_SEED);    

    /*
     * Returns an array of ncolors RGB triplets such that each is as unique from the rest as possible
     * and each color has at least one component greater than minComponent and one less than maxComponent.
     * Use min == 1 and max == 0 to include the full RGB color range.
     * 
     * Warning: O N^2 algorithm blows up fast for more than 100 colors.
     */
    public static Color[] generateVisuallyDistinctColors(int ncolors, float minComponent, float maxComponent) {
        rand.setSeed(RAND_SEED); // So that we get consistent results for each combination of inputs

        float[][] yuv = new float[ncolors][3];

        // initialize array with random colors
        for(int got = 0; got < ncolors;) {
            System.arraycopy(randYUVinRGBRange(minComponent, maxComponent), 0, yuv[got++], 0, 3);
        }
        // continually break up the worst-fit color pair until we get tired of searching
        for(int c = 0; c < ncolors * 1000; c++) {
            float worst = 8888;
            int worstID = 0;
            for(int i = 1; i < yuv.length; i++) {
                for(int j = 0; j < i; j++) {
                    float dist = sqrdist(yuv[i], yuv[j]);
                    if(dist < worst) {
                        worst = dist;
                        worstID = i;
                    }
                }
            }
            float[] best = randYUVBetterThan(worst, minComponent, maxComponent, yuv);
            if(best == null)
                break;
            else
                yuv[worstID] = best;
        }

        Color[] rgbs = new Color[yuv.length];
        for(int i = 0; i < yuv.length; i++) {
            float[] rgb = new float[3];
            yuv2rgb(yuv[i][0], yuv[i][1], yuv[i][2], rgb);
            rgbs[i] = new Color(rgb[0], rgb[1], rgb[2]);
            //System.out.println(rgb[i][0] + "\t" + rgb[i][1] + "\t" + rgb[i][2]);
        }

        return rgbs;
    }

    public static void hsv2rgb(float h, float s, float v, float[] rgb) {
        // H is given on [0->6] or -1. S and V are given on [0->1]. 
        // RGB are each returned on [0->1]. 
        float m, n, f;
        int i;

        float[] hsv = new float[3];

        hsv[0] = h;
        hsv[1] = s;
        hsv[2] = v;
        System.out.println("H: " + h + " S: " + s + " V:" + v);
        if(hsv[0] == -1) {
            rgb[0] = rgb[1] = rgb[2] = hsv[2];
            return;
        }
        i = (int) (Math.floor(hsv[0]));
        f = hsv[0] - i;
        if(i % 2 == 0)
            f = 1 - f; // if i is even 
        m = hsv[2] * (1 - hsv[1]);
        n = hsv[2] * (1 - hsv[1] * f);
        switch(i) {
            case 6:
            case 0:
                rgb[0] = hsv[2];
                rgb[1] = n;
                rgb[2] = m;
                break;
            case 1:
                rgb[0] = n;
                rgb[1] = hsv[2];
                rgb[2] = m;
                break;
            case 2:
                rgb[0] = m;
                rgb[1] = hsv[2];
                rgb[2] = n;
                break;
            case 3:
                rgb[0] = m;
                rgb[1] = n;
                rgb[2] = hsv[2];
                break;
            case 4:
                rgb[0] = n;
                rgb[1] = m;
                rgb[2] = hsv[2];
                break;
            case 5:
                rgb[0] = hsv[2];
                rgb[1] = m;
                rgb[2] = n;
                break;
        }
    }


    // From http://en.wikipedia.org/wiki/YUV#Mathematical_derivations_and_formulas
    public static void yuv2rgb(float y, float u, float v, float[] rgb) {
        rgb[0] = 1 * y + 0 * u + 1.13983f * v;
        rgb[1] = 1 * y + -.39465f * u + -.58060f * v;
        rgb[2] = 1 * y + 2.03211f * u + 0 * v;
    }

    public static void rgb2yuv(float r, float g, float b, float[] yuv) {
        yuv[0] = .299f * r + .587f * g + .114f * b;
        yuv[1] = -.14713f * r + -.28886f * g + .436f * b;
        yuv[2] = .615f * r + -.51499f * g + -.10001f * b;
    }

    private static float[] randYUVinRGBRange(float minComponent, float maxComponent) {
        while(true) {
            float y = rand.nextFloat(); // * YFRAC + 1-YFRAC);
            float u = rand.nextFloat() * 2 * U_OFF - U_OFF;
            float v = rand.nextFloat() * 2 * V_OFF - V_OFF;
            float[] rgb = new float[3];
            yuv2rgb(y, u, v, rgb);
            float r = rgb[0], g = rgb[1], b = rgb[2];
            if(0 <= r && r <= 1 &&
                0 <= g && g <= 1 &&
                0 <= b && b <= 1 &&
                (r > minComponent || g > minComponent || b > minComponent) && // don't want all dark components
                (r < maxComponent || g < maxComponent || b < maxComponent)) // don't want all light components

                return new float[]{y, u, v};
        }
    }

    private static float sqrdist(float[] a, float[] b) {
        float sum = 0;
        for(int i = 0; i < a.length; i++) {
            float diff = a[i] - b[i];
            sum += diff * diff;
        }
        return sum;
    }

    private static double worstFit(Color[] colors) {
        float worst = 8888;
        float[] a = new float[3], b = new float[3];
        for(int i = 1; i < colors.length; i++) {
            colors[i].getColorComponents(a);
            for(int j = 0; j < i; j++) {
                colors[j].getColorComponents(b);
                float dist = sqrdist(a, b);
                if(dist < worst) {
                    worst = dist;
                }
            }
        }
        return Math.sqrt(worst);
    }

    private static float[] randYUVBetterThan(float bestDistSqrd, float minComponent, float maxComponent, float[][] in) {
        for(int attempt = 1; attempt < 100 * in.length; attempt++) {
            float[] candidate = randYUVinRGBRange(minComponent, maxComponent);
            boolean good = true;
            for(int i = 0; i < in.length; i++)
                if(sqrdist(candidate, in[i]) < bestDistSqrd)
                    good = false;
            if(good)
                return candidate;
        }
        return null; // after a bunch of passes, couldn't find a candidate that beat the best.
    }


    /**
     * Simple example program.
     */
    public static void main(String[] args) {
        final int ncolors = 10;
        Color[] colors = generateVisuallyDistinctColors(ncolors, .8f, .3f);
        for(int i = 0; i < colors.length; i++) {
            System.out.println(colors[i].toString());
        }
        System.out.println("Worst fit color = " + worstFit(colors));
    }

}

এই কোডের কোথাও কোনও সি # সংস্করণ রয়েছে? আমি এটিকে রূপান্তর করার চেষ্টা করেছি এবং একইভাবে যুক্তিগুলি দিয়ে চালানোর চেষ্টা করেছি যা আপনি জেনারেটলিস্টিস্টিন্টল্যান্ড () তৈরি করতে পেরেছেন এবং মনে হচ্ছে এটি বেশ ধীর গতিতে চলেছে। এটা কি প্রত্যাশিত?
ক্রিস স্মিথ

আপনি কি একই ফলাফল পান? এটি আমার প্রয়োজনের জন্য প্রচুর দ্রুত তবে আমি যেমন বলেছিলাম, আমি এটিকে অনুকূল করার চেষ্টা করিনি, সুতরাং যদি এটিই আপনার একমাত্র সমস্যা হয় তবে আপনার সম্ভবত মেমরি বরাদ্দ / অবলম্বনের দিকে মনোযোগ দেওয়া উচিত। আমি সি # মেমরি পরিচালনা সম্পর্কে কিছুই জানি না। সবচেয়ে খারাপভাবে, আপনি 1,000 এর বাহ্যিক লুপকে ধীরে ধীরে আরও ছোট কিছুতে হ্রাস করতে পারেন এবং গুণমানের পার্থক্যটি এমনকি নজরে নাও যেতে পারে।
মেলিন্ডা সবুজ

1
আমার প্যালেটে অবশ্যই নির্দিষ্ট রঙ থাকতে হবে তবে আমি অতিরিক্তগুলি পূরণ করতে চেয়েছিলাম। আমি আপনার পদ্ধতিটি b / c পছন্দ করি আমি আমার প্রয়োজনীয় রঙগুলি প্রথমে আপনার যুব অ্যারেতে রেখে দিতে পারি এবং তারপরে আমার প্রয়োজনীয় রঙগুলির পরে অনুকূলকরণ শুরু করতে "j = 0" সংশোধন করতে পারি। আমি আশা করি সবচেয়ে খারাপ জোড় ভাঙ্গা একটু স্মার্ট হয়েছিল তবে আমি বুঝতে পারি কেন এটি শক্ত।
রায়ান

আমি মনে করি আপনার yuv2rgb পদ্ধতিতে বাতা (0,255) অনুপস্থিত।
রায়ান

yuv2rgb সমস্ত ভাসমান, বায়ান রায়ান নয়। দয়া করে আলোচনার জন্য melinda@superliminal.com লিখুন।
মেলিন্ডা সবুজ

6

এইচএসএল রঙের মডেলটি "বাছাই" রঙগুলির জন্য উপযুক্ত হতে পারে তবে আপনি যদি স্বতন্ত্র রঙের সন্ধান করেন তবে এর পরিবর্তে আপনার অবশ্যই ল্যাব রঙের মডেল প্রয়োজন ।

সিআইএলএবিবি ডিজাইন করা হয়েছিল মানব বর্ণের দৃষ্টিভঙ্গির সাথে সম্মতভাবে অভিন্ন হওয়ার জন্য, যার অর্থ এই মূল্যবোধগুলিতে একই পরিমাণে পরিবর্তিত হওয়া একই পরিমাণের দৃষ্টিভঙ্গি পরিবর্তনের সাথে মিলিত হয়।

একবার আপনি জানেন যে, বিস্তৃত রং থেকে এন রঙের সর্বোত্তম উপসেট সন্ধান করা এখনও একটি (এনপি) কঠিন সমস্যা, ট্র্যাভেলিং সেলসম্যান সমস্যার অনুরূপ এবং কে-গড় অ্যালগরিদম বা কোনও কিছু ব্যবহার করে সমস্ত সমাধান সত্যই ঘটবে না সহায়তা।

এটি বলে, এন যদি খুব বেশি বড় না হয় এবং আপনি যদি রঙের একটি সীমিত সেট দিয়ে শুরু করেন তবে আপনি খুব সহজেই একটি সাধারণ এলোমেলো ফাংশন সহ একটি ল্যাব দূরত্ব অনুযায়ী রঙের একটি খুব ভাল উপসেট খুঁজে পাবেন।

আমি আমার নিজের ব্যবহারের জন্য এই জাতীয় একটি সরঞ্জাম কোড করেছি (আপনি এটি এখানে পেতে পারেন: https://mokole.com/palette.html ), আমি এন = 7 এর জন্য যা পেয়েছি তা এখানে: এখানে চিত্র বর্ণনা লিখুন

এটি সমস্ত জাভাস্ক্রিপ্ট তাই পৃষ্ঠার উত্সটি একবার দেখার জন্য নির্দ্বিধায় এবং আপনার নিজের প্রয়োজনের জন্য এটি খাপ খাইয়ে নিচ্ছে


1
» একই পরিমাণে সংখ্যা পরিবর্তন ([...] একই পরিমাণে দৃশ্যমান অনুভূত পরিবর্তন Regarding) সম্পর্কিত « আমি একটি সিআইই ল্যাব রঙ চয়নকারী দিয়ে প্রায় খেলেছি এবং এটি মোটেও নিশ্চিত করতে পারিনি। আমি রেঞ্জ ব্যবহার ল্যাব রং নির্দেশ করবে L0 থেকে 128 এবং aএবং b-128 থেকে 128. করার ¶ আমি দিয়ে শুরু L, = 0 a= -128, b= -128 যা উজ্জ্বল নীল হয়। তারপরে আমি aতিনগুণ বেড়ে গেলাম । Big বড় পরিবর্তন (+128) a= 50 এর ফলাফল কেবলমাত্র কিছুটা গাer় নীল। + (+85) a= 85 ফলাফল এখনও নীল in ❸ তবে, অপেক্ষাকৃত ছোট পরিবর্তন (+43) a= 128 সম্পূর্ণরূপে ফুচিয়াতে রঙ পরিবর্তন করে।
সোসোইই

এটি আমার জন্য খুব দরকারী। ফলাফলগুলি অনুলিপি-পেস্ট করা সহজ হলেও এটি আদর্শ হবে।
মিচেল ভ্যান জুয়েলেন

5

আপনার "স্বতন্ত্র" ইস্যুটি পরিচালনা করার জন্য এখানে একটি সমাধান রয়েছে, যা পুরোপুরি চাপিয়ে দেওয়া হয়েছে:

রিপিলিং চার্জ সহ একটি ইউনিট গোলক এবং ড্রপ পয়েন্ট তৈরি করুন। একটি কণা সিস্টেম চালান যতক্ষণ না তারা আর না সরায় (বা ডেল্টা "যথেষ্ট ছোট")। এই মুহুর্তে, প্রতিটি পয়েন্ট যথাসম্ভব একে অপরের থেকে দূরে রয়েছে। (X, y, z) থেকে আরজিবি রূপান্তর করুন।

আমি এটি উল্লেখ করেছি কারণ কিছু শ্রেণির সমস্যার জন্য, এই ধরণের সমাধানটি জোর বলয়ের চেয়ে আরও ভাল কাজ করতে পারে।

আমি মূলত একটি গোলককে পরীক্ষা করার জন্য এই পদ্ধতির বিষয়টি এখানে দেখেছি ।

আবার, এইচএসএল স্পেস বা আরজিবি স্পেসকে অনুসরণ করার সর্বাধিক সুস্পষ্ট সমাধান সম্ভবত খুব সূক্ষ্মভাবে কাজ করবে।


1
এটি একটি ভাল ধারণা, তবে সম্ভবত একটি গোলকের চেয়ে কিউবটি ব্যবহার করা বোধগম্য।
রকেটম্যাগনেট

1
আমার YUV- ভিত্তিক সমাধানটি 3 ডি বাক্সের জন্য (কিউব নয়) এটি করে।
মেলিন্ডা সবুজ

3

আমি স্যাচুরেশন এবং লুমিনেশন সর্বাধিক স্থির করার চেষ্টা করব এবং কেবল বর্ণের উপরে ফোকাস করব। আমি এটি দেখতে পাচ্ছি, এইচ 0 থেকে 255 পর্যন্ত যেতে পারে এবং তারপরে চারপাশে মোড়ানো হতে পারে। এখন আপনি যদি দুটি বিপরীতমুখী রঙ চান তবে আপনি এই রিংটির বিপরীত দিকগুলি গ্রহণ করবেন, অর্থাৎ 0 এবং 128 you আপনি যদি 4 টি রঙ চান তবে আপনি বৃত্তটির 256 দৈর্ঘ্যের 1/4 দ্বারা আলাদা করে নিয়ে যাবেন, 0, 64,128,192। এবং অবশ্যই, অন্যরা যখন আপনাকে এন রঙের প্রয়োজনের পরামর্শ দিয়েছিল, আপনি কেবল তাদের 256 / এন দ্বারা পৃথক করতে পারেন।

আমি এই আইডিয়ায় যা যুক্ত করব তা হ'ল এই ক্রমটি তৈরি করতে বাইনারি সংখ্যার বিপরীত উপস্থাপনা ব্যবহার করা। এটা দেখ:

0 = 00000000  after reversal is 00000000 = 0
1 = 00000001  after reversal is 10000000 = 128
2 = 00000010  after reversal is 01000000 = 64
3 = 00000011  after reversal is 11000000 = 192

... এইভাবে যদি আপনার এন এর বিভিন্ন রঙের প্রয়োজন হয় তবে আপনি কেবল প্রথম এন নম্বর নিতে পারেন, তাদের বিপরীত করতে পারেন এবং আপনি যতটা সম্ভব দূরের পয়েন্টগুলি পেতে পারেন (এন এর পক্ষে দু'জনের শক্তি হওয়ায়) একই সাথে প্রতিটির প্রতিটি উপসর্গ সংরক্ষণ করে ক্রম অনেক আলাদা।

এটি আমার ব্যবহারের ক্ষেত্রে একটি গুরুত্বপূর্ণ লক্ষ্য ছিল, কারণ আমার একটি চার্ট ছিল যেখানে রঙগুলি এই রঙ দ্বারা coveredাকা অঞ্চল অনুসারে সাজানো হয়েছিল। আমি চেয়েছিলাম চার্টের বৃহত্তম ক্ষেত্রগুলির বৃহত্তর বৈসাদৃশ্য রয়েছে এবং আমি কয়েকটি ছোট অঞ্চলগুলির সাথে শীর্ষ দশের মতো রঙ ধারণ করছিলাম ঠিক কারণ অঞ্চলটি পর্যবেক্ষণ করে এটি কোনটি কোনটি পাঠকের পক্ষে স্পষ্ট ছিল।


আমার উত্তরে আমি এটিই করেছি, যদিও আরও কিছুটা " গাণিতিক "। ফাংশন দেখুন getfracs। তবে আপনার দৃষ্টিভঙ্গি নিম্ন-স্তরের ভাষাগুলিতে দ্রুত এবং "সহজ": কিছুটা সিতে বিপরীত
জানুস ট্রয়লসন


1

যদি এন যথেষ্ট বড় হয় তবে আপনি কিছু অনুরূপ বর্ণগুলি পেতে চলেছেন। বিশ্বে তাদের মধ্যে কেবলমাত্র অনেকগুলি রয়েছে।

কেন ঠিক একইভাবে বর্ণালী মাধ্যমে তাদের বিতরণ না:

IEnumerable<Color> CreateUniqueColors(int nColors)
{
    int subdivision = (int)Math.Floor(Math.Pow(nColors, 1/3d));
    for(int r = 0; r < 255; r += subdivision)
        for(int g = 0; g < 255; g += subdivision)
            for(int b = 0; b < 255; b += subdivision)
                yield return Color.FromArgb(r, g, b);
}

আপনি যদি ক্রমটি মিশ্রণ করতে চান যাতে অনুরূপ রঙগুলি একে অপরের পাশে না থাকে তবে আপনি সম্ভবত ফলাফলের তালিকাটি পরিবর্তন করতে পারেন।

আমি কি এটিকে বিবেচনা করছি?


2
হ্যাঁ, আপনি এটি ভাবছেন। দুর্ভাগ্যক্রমে মানব বর্ণ উপলব্ধি রৈখিক নয়। আপনি যদি বিভিন্ন তীব্রতা ব্যবহার করে থাকেন তবে আপনাকে বেজল্ড ব্র্যাক শিফ্টের জন্য অ্যাকাউন্টও দিতে হবে। : এছাড়া ভাল তথ্য এখানে vis4.net/blog/posts/avoid-equidistant-hsv-colors
spex

1

এটি ম্যাটল্যাব-এ তুচ্ছ (এখানে এইচএসভি কমান্ড রয়েছে):

cmap = hsv(number_of_colors)

1

আমি আর একটি প্যাকেজ লিখেছি যাকে কোয়ালিপালার বলা হয় যা এই উদ্দেশ্যে বিশেষভাবে ডিজাইন করা হয়েছে। এটি আপনাকে কীভাবে কাজ করে তা সন্ধান করার জন্য আমি আপনাকে ভিগনেটটি দেখার পরামর্শ দিচ্ছি , তবে আমি মূল পয়েন্টগুলি সংক্ষেপে জানার চেষ্টা করব।

কোয়ালিপালার এইচএসএল রঙের জায়গার রঙগুলির স্পেসিফিকেশন নেয় (যা আগে এই থ্রেডে বর্ণিত ছিল) এটি DIN99d রঙের স্থানটিতে প্রবর্তন করে (যা অনুধাবনভাবে অভিন্ন) এবং এটি nকোনও ওয়েফের মধ্যে সর্বনিম্ন দূরত্বকে সর্বাধিকতম করে তোলে।

# Create a palette of 4 colors of hues from 0 to 360, saturations between
# 0.1 and 0.5, and lightness from 0.6 to 0.85
pal <- qualpal(n = 4, list(h = c(0, 360), s = c(0.1, 0.5), l = c(0.6, 0.85)))

# Look at the colors in hex format
pal$hex
#> [1] "#6F75CE" "#CC6B76" "#CAC16A" "#76D0D0"

# Create a palette using one of the predefined color subspaces
pal2 <- qualpal(n = 4, colorspace = "pretty")

# Distance matrix of the DIN99d color differences
pal2$de_DIN99d
#>        #69A3CC #6ECC6E #CA6BC4
#> 6ECC6E      22                
#> CA6BC4      21      30        
#> CD976B      24      21      21

plot(pal2)

এখানে চিত্র বর্ণনা লিখুন


1

আমি মনে করি এই সাধারণ পুনরাবৃত্তির অ্যালগরিদম স্বতন্ত্র বর্ণের মান তৈরি করতে স্বীকৃত উত্তরকে পরিপূরণ করে। আমি এটি এইচএসভির জন্য তৈরি করেছি, তবে অন্যান্য রঙের জায়গাগুলির জন্যও এটি ব্যবহার করা যেতে পারে।

এটি প্রতিটি চক্রের মধ্যে একে অপরের থেকে যথাসম্ভব পৃথক পৃথক চক্রের বর্ণ তৈরি করে।

/**
 * 1st cycle: 0, 120, 240
 * 2nd cycle (+60): 60, 180, 300
 * 3th cycle (+30): 30, 150, 270, 90, 210, 330
 * 4th cycle (+15): 15, 135, 255, 75, 195, 315, 45, 165, 285, 105, 225, 345
 */
public static float recursiveHue(int n) {
    // if 3: alternates red, green, blue variations
    float firstCycle = 3;

    // First cycle
    if (n < firstCycle) {
        return n * 360f / firstCycle;
    }
    // Each cycle has as much values as all previous cycles summed (powers of 2)
    else {
        // floor of log base 2
        int numCycles = (int)Math.floor(Math.log(n / firstCycle) / Math.log(2));
        // divDown stores the larger power of 2 that is still lower than n
        int divDown = (int)(firstCycle * Math.pow(2, numCycles));
        // same hues than previous cycle, but summing an offset (half than previous cycle)
        return recursiveHue(n % divDown) + 180f / divDown;
    }
}

আমি এখানে এই ধরণের অ্যালগরিদম খুঁজে পেতে অক্ষম ছিল। আমি আশা করি এটি সাহায্য করে, এটি এখানে আমার প্রথম পোস্ট।


0

এই ওপেনসিভি ফাংশনটি nসর্বাধিক এস = 1.0 এবং ভি = 1.0 এর সাথে 0 <= এইচ <= 360º এর আশেপাশে সমানভাবে বিতরণ করা রঙ উত্পাদন করতে এইচএসভি রঙের মডেল ব্যবহার করে । ফাংশনটি বিজিআর রঙগুলিকে এতে আউটপুট করে bgr_mat:

void distributed_colors (int n, cv::Mat_<cv::Vec3f> & bgr_mat) {
  cv::Mat_<cv::Vec3f> hsv_mat(n,CV_32F,cv::Vec3f(0.0,1.0,1.0));
  double step = 360.0/n;
  double h= 0.0;
  cv::Vec3f value;
  for (int i=0;i<n;i++,h+=step) {
    value = hsv_mat.at<cv::Vec3f>(i);
    hsv_mat.at<cv::Vec3f>(i)[0] = h;
  }
  cv::cvtColor(hsv_mat, bgr_mat, CV_HSV2BGR);
  bgr_mat *= 255;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.