我有10,000张图片需要按颜色分类,以便制作成印刷品。
我已经做了一些工作。现在我已经计算出它们的平均颜色,所以我有两个目录:一个是所有原始图像的目录(original_images/),另一个是名字相同的jpeg文件,它们的颜色是平均的(averages/)。
接下来,我使用PHP对这些平均图像进行排序:
// $images is an array with all the filenames.
$sorted_images = array();
$loop_limit = count($images);
for($i = 0; $i < $loop_limit; $i++) {
$image = imagecreatefromjpeg("averages/" . $images[$i]);
$rgb = imagecolorat($image, 50, 50);
imagedestroy($image);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$hsv = rgb_to_hsv($r, $g, $b); // function to convert rgb to Hue/Sat/Value
$h = (string) $hsv['H'];
if(isset($sorted_h[$h])) {
$duplicates++;
echo("oh no! " . $h . " is a dupe! found " . $duplicates . " duplicates so far.<br>");
}
$sorted_h[$h] = $images[$i];
}
// sort the array by key:
ksort($sorted_images, SORT_NUMERIC);
编辑 问题在于键$h
的范围似乎从-0.1666666667到大约1。我的直觉是重复值的机会非常小,但实际上有超过6000个重复的键。我尝试将$h
的值转换为字符串,因为我想也许数组键是四舍五入的?
但这种方法行不通。这是将RGB转换为HSV的函数,我在某个地方找到它,没有任何文档...
function RGB_TO_HSV ($R, $G, $B) {
$HSV = array();
$var_R = ($R / 255);
$var_G = ($G / 255);
$var_B = ($B / 255);
$var_Min = min($var_R, $var_G, $var_B);
$var_Max = max($var_R, $var_G, $var_B);
$del_Max = $var_Max - $var_Min;
$V = $var_Max;
if ($del_Max == 0)
{
$H = 0;
$S = 0;
}
else
{
$S = $del_Max / $var_Max;
$del_R = ( ( ( $max - $var_R ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
$del_G = ( ( ( $max - $var_G ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
$del_B = ( ( ( $max - $var_B ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
if ($var_R == $var_Max) $H = $del_B - $del_G;
else if ($var_G == $var_Max) $H = ( 1 / 3 ) + $del_R - $del_B;
else if ($var_B == $var_Max) $H = ( 2 / 3 ) + $del_G - $del_R;
if (H<0) $H++;
if (H>1) $H--;
}
$HSV['H'] = $H;
$HSV['S'] = $S;
$HSV['V'] = $V;
return $HSV;
}
现在的问题是:
- rgb_to_hsv()函数是否正确?
- 如何确保在数组中不会覆盖键,但值(近似)保持不变?例如;如果两个图像具有$h-value$为0.01111111111,则将第二个图像推送到数组中时,它的键应该是0.01111111112吗?
(旧编辑:)
编辑: 我已经将rename()
更改为copy()
,这样每次出错时我就不必重新上传10,000张图片;-)。我还使用了ini_set("max_execution_time", 300);
将最大执行时间从60增加到300,通过添加imagedestroy($image)
来减少内存使用量,并通过将$i < count($images)
更改为$loop_limit = count($images)
来改进for循环。
编辑2:好的,我发现了一个问题。图像的$h$(色相)值偶尔会相同。因此,在数组中使用sorted_images[$h] = $images[$i]
会覆盖该键在数组中的值。实际上;竟然有超过6000个重复值...我应该如何修复它,而不会太多地影响$h-value$?
imagedestroy($image);
。 - Alain Tiemblofor
循环中的count($images)
是有史以来最糟糕的做法! - Shiplu Mokaddim