2011-09-21 8 views
8

プログラムでプログラムを実行し、それが主要な色であることを伝えるスクリプトを作成しようとしています。イメージの人間が読める色(例えば、赤、緑など)をプログラムで決定する

現在、スクリプトは各ピクセルのRGB値を取得します。定義済みのルールと比較し、各色のピクセル数をカウントアップしようとします。

私の問題は、スクリプトが少しヒットしてミスです。誰かがこれをやるより良い方法を知っていますか(おそらく、英語に翻訳しやすい別の色分けシステムを使用しています)か、RGBを使って色を定義する既存の規則セットを知っていますか?あなたはグラフィックスライブラリを持っているので、そこでの平均的なブツがなければならない

<?php 
$file = "8629.jpg"; 

$colors = array("Red" => array("rel" => true, "r" => 0.65, "g" => 0.09, "b" => 0.25, "var" => 0.3), 
       "Blue" => array("rel" => true, "r" => 0.21, "g" => 0.32, "b" => 0.46, "var" => 0.3), 
       "Green" => array("rel" => true, "r" => 0, "g" => 0.67,"b" => 0.33, "var" => 0.3), 
       "Black" => array("rel" => false, "r" => 0, "g" => 0,"b" => 0, "var" => 30), 
       "White" => array("rel" => false, "r" => 255, "g" => 255,"b" => 255, "var" => 30));     

$total = 0; 

$im = imagecreatefromjpeg($file); 
$size = getimagesize($file); 

if (!$im) { 
    exit("No image found."); 
} 

for ($x = 1; $x <= $size[0]; $x++) { 
    for($y = 1; $y <= $size[1]; $y++) { 
     $rgb = imagecolorat($im, $x, $y); 
     $r = ($rgb >> 16) & 0xFF; 
     $g = ($rgb >> 8) & 0xFF; 
     $b = $rgb & 0xFF; 

     $colorTotal = $r + $g + $b; 

     $rRatio = $r > 0 ? $r/$colorTotal : 0; 
     $gRatio = $g > 0 ? $g/$colorTotal : 0; 
     $bRatio = $b > 0 ? $b/$colorTotal : 0; 

     foreach($colors as $key => $color) { 
      if ($color["rel"]) { 
       if ((($color["r"] - $color["var"]) <= $rRatio && $rRatio <= ($color["r"] + $color["var"])) && 
        (($color["g"] - $color["var"]) <= $gRatio && $gRatio <= ($color["g"] + $color["var"])) && 
        (($color["b"] - $color["var"]) <= $bRatio && $bRatio <= ($color["b"] + $color["var"]))) { 

        $colourCount[$key]++; 
        $total++; 
       } 
      } else { 
       if ((($color["r"] - $color["var"]) <= $r && $r <= ($color["r"] + $color["var"])) && 
        (($color["g"] - $color["var"]) <= $g && $g <= ($color["g"] + $color["var"])) && 
        (($color["b"] - $color["var"]) <= $b && $b <= ($color["b"] + $color["var"]))) { 

        $colourCount[$key]++; 
        $total++; 
       } 
      } 
     } 
    } 
} 

var_dump($colourCount); 

foreach($colourCount as $key => $color) { 
    $colourPrecent[$key] = $color/$total; 
} 

arsort($colourPrecent); 
var_dump($colourPrecent); 

foreach($colourPrecent as $key => $color) { 
    if ($prevVal) { 
     if ($color < ($prevVal - 0.1)) { 
      break; 
     } 
    } 

    $primary[] = $key; 
    $prevVal = $color; 
} 

echo("The primary colours in this image are " . implode(" and ", $primary)); 

?> 
+2

うん、面白いです。私の唯一の貢献は「人間が読める」色の定義について[この警告](http://www.thedoghousediaries.com/?p=1406)です! – Widor

+0

トゥルーカラーの画像では、すべてのピクセルがユニークである可能性があることを考慮すると、類似の色を一緒に「バッチ処理」しない限り、ほとんど得られません。おそらく、画像を1x1ピクセルに縮小し、その主な色を抽出するほうが簡単かもしれません。 –

+0

RGBは、ここではカラーモデルの中で最も有用な選択肢のようです(http://www.wowarea.com/english/help/color.htm)。 @Widor、確かにスクリプトはIsGuyパラメータを取るでしょう。 ;) – bzlm

答えて

2

ソリューションは、ハーバートにより示唆されるようにHSLにRGBを変換することでした。人間に変換する機能は少し微調整/仕上げを必要としますが、ここではそれがあります:

function hslToHuman($h, $s, $l) { 

$colors = array(); 

// Gray 
if ($s <= 10 && (9 <= $l && $l <= 90)) { 
    $colors[] = "gray"; 
} 

$l_var = $s/16; 

// White 
$white_limit = 93; 
if (($white_limit + $l_var) <= $l && $l <= 100) { 
    $colors[] = "white"; 
} 

// Black 
$black_limit = 9; 
if (0 <= $l && $l <= ($black_limit - $l_var)) { 
    $colors[] = "black"; 
} 

// If we have colorless colors stop here 
if (sizeof($colors) > 0) { 
    return $colors; 
} 

// Red 
if (($h <= 8 || $h >= 346)) { 
    $colors[] = "red"; 
} 

// Orange && Brown 
// TODO 

// Yellow 
if (40 <= $h && $h <= 65) { 
    $colors[] = "yellow"; 
} 

// Green 
if (65 <= $h && $h <= 170) { 
    $colors[] = "green"; 
} 

// Blue 
if (165 <= $h && $h <= 260) { 
    $colors[] = "blue"; 
} 

// Pink && Purple 
// TODO 

return $colors; 
} 
1

さてさて、あなたはあなたの写真は、任意のピクセルを取る平均化し、あなたは完了ですtadaam?

そして、ここで見つかった最も簡単な解決策は次のとおりです。1x1pxし、サイズ変更、取得colorat:

Get image color

それは非常に簡単ですので、どこかで人間が読める(たとえばhtmlの色にRGBの詳細なリストを見つけたら)、それを配列としてエンコードし、スクリプトで使用する - >あなたのr、g、b、valをデータの精度に丸めて色を取得する。

あなたは色の細かさを決めてそこから行くべきです - 名前付きの色のセットを見つけて(私は8bitの色にはどこかの名前が付いていると思いますが)、あなたのrgb情報を減らします。それを読む前に(速い)または読み取り時に色情報を削減することにより、画像(カラーリストの面でより柔軟ないくつかのRGB-人間が読める資源の

Basicの例:。

http://www.w3schools.com/html/html_colornames.asp

その他:

http://chir.ag/projects/name-that-color/#2B7C97

http://r0k.us/graphics/SIHwheel.html

+0

現時点で難しい部分は、人間が読めるRGBの詳細なリストを見つけることです。このスクリプトは、平均的な色だけではなく、少し知的である必要があります。 50/50赤色/青色のイメージがある場合は、赤色と青色であることを知る必要があります。紫色であるとは言わないでください。 – Dan

+0

"HTMLの色"を検索してWeb上の任意の場所にあるRGBリストを使用すると、名前付きのすべての色で特定の細かさ(十分な色以上)を持つサブセットが得られます。あなたの複数の色については、次のようにすることができます:4x4にサイズ変更、foreach colorat、ランク付け、それが合うかどうかテストします。より良いresを試していない場合。 –

+0

HSL色空間を使用して終了しました。色相範囲内で色を定義する方が、3つの異なる変数を追跡して、どの色であるかを判断するよりもはるかに簡単です。しかし、入力をありがとう。 – Dan

関連する問題