5

我有 10,000 张图像我想按颜色分类以打印。

我已经走得很远了。我已经平均了它们的颜色,所以现在我有两个目录:一个包含所有原始图像 (original_images/),另一个包含其平均颜色 (averages/) 的同名 jpeg。

接下来,我使用 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;
}

所以现在的问题是:

  1. rgb_to_hsv() 函数是否正确?
  2. 我如何确保数组中的键不会被覆盖,但值是(密切)维护的?例如; 如果两个图像的 $h 值为 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).

编辑2:好的,我发现了一个问题。图像的 $h (Hue) 值时不时地相同。因此 usingsorted_images[$h] = $images[$i]会覆盖数组中该键的值。实际上; 原来有超过 6000 个重复值......我将如何解决这个问题,而不会过多地弄乱 $h 值?

4

2 回答 2

1

您可能会遇到 max_execution_time - 允许脚本运行的时间限制。尝试设置更高的值。

http://php.net/manual/de/function.set-time-limit.php

你没有收到任何错误信息吗?

于 2012-10-16T07:46:31.817 回答
1

您是否尝试过启用错误消息?

error_reporting(E_ALL);
ini_set('display_errors', 1);

至于本地与主值。'local' 表示当前运行的脚本正在使用 300 秒的超时。'master' 适用于所有其他请求(除非明确修改)

Cron 将是一种方法,但我认为这不应该每 X 秒/分钟/小时执行多次?您可以简单地自己使用命令行来执行此操作。在这里查看更多信息:http ://www.php.net/manual/en/features.commandline.usage.php

看到脚本有效,很可能是以下问题之一:

memory_limit 不够高。应该在启用错误的情况下给出 PHP 错误。执行时间不够长。应该在启用错误的情况下给出 PHP 错误。

使用 init_set 方法来增加两者,如果您“只是”希望脚本运行,请将超时设置为 0 秒并将内存限制设置为尽可能高。如果您想真正了解确切原因,您可能会考虑查找“xdebug”以查看是否存在任何内存泄漏或哪些命令执行时间最长。查看代码,我假设它的复制命令需要一段时间才能执行(超过 1 毫秒,这在 10000 次迭代之后很多)

如果无法修改这些值,或者您只是想在资源有限的情况下使用高内存、长执行时间的脚本,请尝试重写脚本以批量执行重命名并设置一个 cron 来执行脚本每 X 分钟(只需在所有图像完成后删除 cron)

祝你好运 :)

于 2012-10-16T08:44:44.440 回答