2017-08-05 9 views
2

私は以下のスキーマとして1つのRGBカラーに近い複数のカラーを生成できるようにしたいと思います。ここで rgb値に近い色を生成する方法は?

enter image description here

だ私は、Pythonを使って作られたもの:

def similarColors(rgb, loop=6): 
    difference = 30 
    colors = [] 
    for i in range(loop): 
     red = rgb[0] 
     red_highest = red + difference 
     red_lowest = red - difference 
     red = randint(red_lowest, red_highest) 

     green = rgb[1] 
     green_highest = green + difference 
     green_lowest = green - difference 
     green = randint(green_lowest, green_highest) 

     blue = rgb[2] 
     blue_highest = blue + difference 
     blue_lowest = blue - difference 
     blue = randint(blue_lowest, blue_highest) 

     colors.append([red, green, blue]) 
    return colors 

palette = similarColors([244, 83, 28]) 

質問:私はこの方法で物事を過度に複雑てるようは、私は上記のコードを作成する方法があると感じクリーナーと短い?

それぞれの色(赤、青、緑)ごとに同じプロセスを別々にしないようにしたいのですが、この方法が達成しようとしているものに対して本当に正確かどうかはわかりません。

+0

私は、人間の視覚システムのISNことを(部分的に)事実を補償する私の答えに新しいバージョンを追加しました赤、緑、青に等しく敏感です。 –

答えて

2

RGBコンポーネントをループすることで、そのコードをかなり縮めることができます。しかし、現在のアルゴリズムにはバグがあります:< 0または> 255のカラーチャネル値を生成できるので、修正する必要があります。

from random import randint 

def similarColors(rgb, loop=6): 
    colors = [] 
    delta = 30 
    for i in range(loop): 
     new_rgb = [randint(max(0, x - delta), min(x + delta, 255)) for x in rgb] 
     colors.append(new_rgb)     
    return colors 

colors = similarColors([244, 83, 28]) 
print(colors) 

典型的な出力

[[249, 75, 28], [226, 111, 34], [235, 85, 46], [228, 66, 28], [244, 62, 8], [233, 102, 21]] 

あなたは言った:「私はまた、この方法は、私が達成しようとしている何のために本当に正確であるかどうかわからないです」。私はあなたが達成しようとしていることは正確にはわかりませんが、人間の視覚システムはR、G、& Bに等しく敏感ではないということがわかります。そのため、別のチャンネルの同じ変更と同じ効果があります。これを適切に処理するには、人間の視覚システムに一層緊密に調整された色空間、たとえばLab color spaceで作業する必要があります。しかし、チャネルデルタにスケーリングファクタを使用することで、合理的な近似を得ることができます。

y = 0.299*R + 0.587*G + 0.114*B 

この式は、アナログNTSC & PALテレビに使用した:

GrayscaleにWikipediaの記事は、RGBカラーの輝度を計算するために使用され得る式を提供します。

これらのスケーリングファクタを使用する上記のコードのバージョンを示します。我々の基底deltaをこれらの倍率で割るので、青のデルタが最も大きく、&緑のデルタが最も小さくなります。なぜなら、目が緑に最も敏感で、青に最も敏感でないからです。

def similarColors(rgb, loop=6): 
    colors = [] 
    delta = 10 
    deltas = [round(delta/u) for u in (0.299, 0.587, 0.114)] 
    for i in range(loop): 
     new_rgb = [randint(max(0, x - delta), min(x + delta, 255)) 
      for x, delta in zip(rgb, deltas)] 
     colors.append(new_rgb) 
    return colors 

colors = similarColors([244, 83, 28]) 
print(colors) 

典型的な出力

[[236, 84, 65], [233, 74, 78], [226, 93, 73], [249, 88, 89], [240, 84, 40], [226, 75, 22]] 

我々はdeltasアレイを事前に計算することができ、固定ベースdeltaを使用して、なくているので、そのコードをより効率的に各再計算similarColorsと呼びます。

+0

これを実行すると、戻り値がなく、ピクチャのすべてのピクセルにこれを適用すると画像が自動的に変更されます – Sanitiy

+1

@SanitiyすべてのPython関数は何かを返します。オブジェクトが明示的に返される確かに、関数はリストargを受け入れることができ、新しいカラーリストでそれを拡張することができます。グローバルな 'colors'リストを拡張するよりも良いでしょう。 'similarColor'はargとして単一のカラー値をとり、6つのカラー値を返すので、あなたが正確に"ピクチャのすべてのピクセルにこれを適用 "することによって、正確に何を意味するのか分かりません。 –

+0

精度については、色がオレンジであれば、他の色の代わりにオレンジの色合いが表示されることを意味しました。 – Lindow

1

各色をコピー&ペーストする必要はありません、あなたは次のようにforループを使用することができます

def similarColors(rgb, loop=6, difference=30): 
    colors = [] 
    for _ in range(loop): 
     color = [] 
     for curr_color in rgb: 
      color.append(randint(curr_color - difference, curr_color + difference)) 
     colors.append(color) 

    return colors 

お知らせは、私はまた、パラメータにdifferenceを置きます。

rgbの部分が< 0または> 255の場合は、max(0, min(255, randint(curr_color - difference, curr_color + difference)))を使用して修正できます。

1

あなたがnumpyを使用することができた場合は、はるかにコンパクトなソリューションはこれです:

import numpy as np 

def similarColors(rgb, loop=6): 
    delta = 30 
    origClrs = np.tile(np.array(rgb), (loop, 1)) 
    randOffsets = np.random.randint(-delta, delta, size=(loop, 3)) 
    return origClrs + randomOffsets 
関連する問題