2011-09-21 29 views
8

insan tarafından okunabilir rengini (ör. Kırmızı, Yeşil, vb.) Programsal olarak belirleme Program aracılığıyla bir program aracılığıyla çalışacak ve bana birincil renk (ler) olduğunu söyleyen bir komut dosyası oluşturmaya çalışıyorum.Bir resmin

Şu anda komut dosyası her pikselin RGB değerini alıyor. Onları önceden tanımlanmış kurallarla karşılaştırır ve her rengin piksel sayısını saymaya çalışır.

Sorunum, komutun küçük bir hit ve özlediğidir. Bunu yapmanın daha iyi bir yolu (belki de İngilizce'ye çeviri yapmak için daha kolay olan farklı bir renk kodlama sistemi kullanarak) veya RGB'leri kullanarak renkleri tanımlayan mevcut bir kural grubunu biliyor mu? Eğer bir grafik kütüphanesi var, bu yüzden orada bir ortalama zımbırtı olmalıdır

<?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

Hmm, ilginç. Korkarım ki tek katkım, "insan tarafından okunabilir" renkleri tanımlamakla ilgili [bu uyarı] (http://www.thedoghousediaries.com/?p=1406)! – Widor

+0

Gerçek renkli bir görüntünün potansiyel olarak her pikselin benzersiz olduğunu düşünürseniz, benzer renkleri birlikte "topluyor" olarak başlatmadığınız sürece fazla kazanmayacaksınız. Belki de görüntüyü 1x1 piksele küçültmek ve baskın rengini anlamak daha kolay olurdu. –

+0

RGB, burada [en az kullanışlı renk modeli seçimi] gibi görünüyor (http://www.wowarea.com/english/help/color.htm). @Widor, şüphesiz betik bir IsGuy parametresi alacaktır. ;) – bzlm

cevap

2

Çözüm Herbert tarafından önerildiği şekilde HSL, RGB dönüştürmek oldu. İnsana dönüştürme işlevi hala biraz ayarlamaya/sonlandırmaya ihtiyaç duyar ancak burada:

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

Tamam, size resim, pikselleri almak ortalama ve bitirdiniz tadaam?

Ve burada bulunan en basit çözümdür: 1x1px için yeniden boyutlandırmak, olsun colorat:

Get image color

oldukça kolay olduğunu, bir yerde insan okunabilir (örneğin html renklerine rgb ayrıntılı bir listesini bulduktan sonra), bunu bir dizi olarak kodlayın ve betiğinizde kullanın -> yuvarlak() r, g, b, verilerinizin kesinliğini doğrular ve rengi alır.

İstediğiniz renk parçacığını belirlemeli ve oradan nereye gidileceğini belirlemelisiniz -> adlandırılmış renk kümelerinizi bulun (tüm 8bit renklerinin bir yerlerde bir isim olduğunu düşünüyorum) ve daha sonra rgb bilginizi azaltın. o (hızlı) okumadan önce veya okuma zaman (renk listesindeki açısından daha esnek renk bilgisini azaltarak görüntü

bazı rgb-insan okunabilir kaynaklarının

Temel örnek:.

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

Diğerleri:

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

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

+0

Şu andaki zor kısım, insan tarafından okunabilir RGB'nin ayrıntılı listesini buluyor. Komut ayrıca, ortalama renkten biraz daha zeki olmalı. 50/50 kırmızı/mavi bir imaja sahip olduğumda, kırmızı ve mavi olduğunu bilmem gerekiyor, buna mor olduğu söylenemez. – Dan

+0

"HTML renkleri" yi arayarak web'de herhangi bir yerde bulabileceğiniz RGB listesi, belirli bir ayrıntıya (istediğiniz gibi göründüğünden daha fazlasına) sahip bir alt kümeye sahip olacaksınız - bir örnek eklediniz. Birden fazla renk hakkında sadece aşağıdakileri yapabilirsiniz: 4x4, foreach colorat, rütbe ve eğer uygunsa sınayın. eğer daha iyi bir deneme yapmıyorsanız. –

+0

HSL renk alanı kullanılarak sonlandırıldı. 3 farklı değişkeni takip etmeye ve ne renk olduğuna karar vermekten ziyade bir renk tonu aralığında bir renk tanımlamak çok daha kolay. Yine de giriş için teşekkürler. – Dan

İlgili konular