我正在尝试想出一个脚本,它将通过编程运行一幅图像,并告诉我它是原色。
目前,该脚本获取每个像素的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));
?>发布于 2011-09-26 21:13:28
解决方案是按照Herbert的建议将RGB转换为HSL。转换为人的函数仍然需要一些调整/完成,但它是:
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;
}发布于 2011-09-22 17:21:04
好的,你已经有了一个图形库,里面肯定有一个平均的东西,你平均你的图片,取任何像素,然后tadaam,你完成了吗?
在这里找到的最简单的解决方案是:将大小调整为1x1px,获取colorat:
之后就很容易了,在某个地方找到一个人类可读的rgb的详细列表(例如html颜色),把它编码成一个数组,并在你的脚本-> ()中使用它来计算你数据的精度和检索颜色。
你应该确定你想要的颜色粒度,并从那里找到你的命名颜色集(我认为所有的8位颜色都有一个名字),然后减少你的->信息-要么在读取之前减少图像的颜色信息(更快),要么在读取时减少颜色信息(在颜色列表方面更灵活)。
一些rgb-人类可读资源的基本示例:
http://www.w3schools.com/html/html_colornames.asp
其他:
http://chir.ag/projects/name-that-color/#2B7C97
http://r0k.us/graphics/SIHwheel.html
https://stackoverflow.com/questions/7501737
复制相似问题