5

色で並べ替えて印刷したい画像が 10,000 枚あります。

私はかなり遠くまで来ています。色を平均化したので、2 つのディレクトリができました。1 つはすべての元の画像 (original_images/) で、もう 1 つは平均色の同じ名前の 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;
}

したがって、現在の質問は次のとおりです。

  1. rgb_to_hsv() 関数は正しいですか?
  2. キーが配列で上書きされないようにするにはどうすればよいですか? 例えば; 2 つの画像の $h-value が 0.01111111111 の場合、2 番目の画像が配列にプッシュされると、そのキーは 0.01111111112 になりますか?

(古い編集:) 編集:問題が発生するたびに 10,000 枚の画像を再アップロードする必要がないように変更rename()しました ;-)。copy()またini_set("max_execution_time", 300);、最大実行時間を 60 から 300 に増やしimagedestroy($image)、メモリ使用量を減らすために追加し、に変更$i < count($images)して for ループに改善しました$loop_limit = count($images)

編集 2:問題が見つかりました。画像の $h (色相) 値は時々同じです。したがって、使用sorted_images[$h] = $images[$i]すると、配列内のそのキーの値が上書きされます。実際には; 6000 を超える重複値があることが判明しました... $h 値をあまりいじらずに、どうすればそれを修正できますか?

4

2 に答える 2

1

エラーメッセージを有効にしてみましたか?

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

ローカルとマスターの値について。「ローカル」は、現在実行されているスクリプトが 300 秒のタイムアウトを使用していることを意味します。「マスター」は他のすべてのリクエストに適用されます (明示的に変更されない限り)

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 に答える
1

max_execution_time - スクリプトの実行が許可されている制限時間に達する可能性があります。より高い値を設定してみてください。

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

エラーメッセージは表示されませんか?

于 2012-10-16T07:46:31.817 に答える