按颜色排序10,000张图像

Rei*_*ein 5 php sorting image-processing

我有10,000张图像,我想按颜色排序以进行打印.

我已经走得很远了.我已经平均了他们的颜色,所以现在我有两个目录:一个包含所有原始图像(original_images /),另一个包含平均颜色(平均值/)的同名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);
Run Code Online (Sandbox Code Playgroud)

编辑问题的是键的$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;
}
Run Code Online (Sandbox Code Playgroud)

所以现在的问题是:

  1. rgb_to_hsv() - 函数是否正确?
  2. 如何确保数组中的键没有被覆盖,但值是否(密切)保持?例如; 如果两个图像的$ h值为0.01111111111,当第二个图像被推送到数组时,它的关键应该是0.01111111112?

(旧编辑:) 编辑:我已经改为rename(),copy()所以每次出错时我都不必重新上传10,000张图片;-).我还习惯ini_set("max_execution_time", 300);将max exec时间从60增加到300,增加imagedestroy($image)内存使用量并通过更改$i < count($images)为for循环进行改进$loop_limit = count($images).

编辑2:好的,所以我发现了一个问题.图像的$ h(Hue)值时不时相同.因此,使用sorted_images[$h] = $images[$i]覆盖数组中该键的值.事实上; 结果是超过6000个重复值...我怎么去解决这个问题,而不会过多地贬低$ h值?

Tji*_*irp 1

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

error_reporting(E_ALL);
ini_set('display_errors', 1);
Run Code Online (Sandbox Code Playgroud)

至于本地值与主值。“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)

祝你好运 :)