1

たくさんの画像を含む2つのディレクトリがあります。たとえば、color/gray/です。カラー/画像の名前は、image1.pngimage2.pngなどです。

グレー/には同じ画像が含まれていますが、グレースケールであり、ファイル名とファイルの順序が異なります(例:file_01.pngですが、これはimage1.pngと同じ画像ではありません)。

両方のディレクトリの画像を比較し、color /ファイルをgray/ファイル名のresults /ディレクトリにコピーすることは可能ですか?

例:

directory        | directory           | directory
   "color/"      |     "gray/"         |      "results/" 
(color images)   | (grayscale images)  | (color images with gray-scale names)   
-----------------+---------------------+----------------------------------------
color/image1.png | gray/file324.png    | results/file324.png  (in color: ==>
                                       | this and image1.png are the same image)

これがそれほど混乱しないことを願っていますが、それをよりよく説明する方法がわかりません。

imagemagickを試してみましたが、-compareオプションでうまくいくようですが、bashスクリプトなどをうまく作成できません。

別の言い方をすれば、正しく一致する名前を使用して、すべてをフォルダーcolor/*.jpgにコピーする必要があります。results/*.jpggray/*.jpg

編集(いくつかのメモ): 1。3つの画像はサイズと内容が同じです。唯一の違いは、2つがカラーで、1つがグレースケールであるということです。そしてもちろん、ファイルの名前。2.現在の名前(フォルダー"img1"カラーフォルダー、フォルダー"img2"グレースケールフォルダー)と期待される結果("img3"結果フォルダー)を含む1つのサンプル画像を含むzipファイルをここにアップロードしました。 http://www.mediafire.com/?9ug944v6h7t3ya8

4

3 に答える 3

4

要件を正しく理解した場合は、次のことを行う必要があります。

  • フォルダgray/ ..にあるXYZという名前のグレースケール画像ごとに検索します。
  • ...フォルダcolor/にあるABCという名前の一致するカラー画像と...
  • ...ABCをフォルダresults/に新しい名前XYZでコピーします

したがって、私が提案する基本的なアルゴリズムは次のとおりです。

  1. フォルダcolor/のすべての画像をグレースケールに変換し、結果をフォルダgray-reference/に保存します。元の名前を保持します。

    mkdir gray-reference
    convert  color/img123.jpg  -colorspace gray  gray-reference/img123.jpg
    
  2. 参照/内の各グレースケール画像について、フォルダgray/内の各グレースケール画像と比較します。一致するものが見つかった場合は、同じ名前のそれぞれの画像をcolor/からresults/にコピーします。違いの視覚的表現を作成する1つの可能な比較コマンドは次のとおりです。

    compare  gray-reference/img123.jpg  gray/imgABC.jpg  -compose src delta.jpg
    

本当の秘訣は、2つのグレースケール画像の比較(ステップ2のように)です。ImageMagickには、2つの(類似した)画像をピクセルごとに比較し、その結果を「デルタ」画像に書き込むための便利なコマンドがあります。

compare  reference.png  test.png  -compose src  delta.png

比較がカラー画像の場合、デルタ画像では...

  • ...等しい各ピクセルは白で表示されますが...
  • ...異なる各ピクセルはハイライトカラーで表示されます(デフォルトは赤)。

この手法の図解例については、私の回答「ImageMagick:'Diff'aImage」も参照してください。

グレー画像とカラー画像をピクセルごとに直接比較すると、もちろん、ほぼすべてのピクセルが異なることがわかります(結果として、すべて赤の「デルタ」画像になります)。したがって、最初にカラー画像をグレースケールに変換するという上記のステップ1からの私の提案。

2つのグレースケール画像を比較すると、結果のデルタ画像もグレースケールになります。したがって、デフォルトのハイライト色を赤にすることはできません。見やすくするために、「黒」に設定することをお勧めします。

ここで、現在の色のグレースケール変換により、既存のグレー画像とは「異なる」種類のグレースケールが生成される場合(現在生成されているグレーは、カラープロファイルが異なるため、既存のグレースケール画像よりもわずかに明るいまたは暗い可能性があります)適用された後でもデルタ画像がすべて「赤」、またはむしろすべてハイライトカラーである可能性があります。ただし、これをサンプル画像でテストしたところ、結果は良好です。

 convert  color/image1.jpg  -colorspace gray  image1-gray.jpg  
 compare                  \
    gray/file324.jpg      \
    image1-gray.jpg       \
   -highlight-color black \
   -compose src           \
    delta.jpg

delta.jpgは98%の白いピクセルで構成されています。何千ものグレースケール画像の他のすべてが、元のカラーから派生したときに同じ設定を使用したかどうかはわかりません。そのため、コマンドを実行するときに小さなファズファクターを追加compareします。これにより、2つのピクセルを比較したときに色が多少ずれることがあります。

compare  -fuzz 3%  reference.png  test.png  -compose src  delta.png

このアルゴリズムは何千回も実行されるため(話している画像の数を考えると、おそらく数百万回)、パフォーマンスを考慮し、コマンドの実行時間を計る必要がありcompareます。サンプル画像はかなり大きく(3072x2048ピクセル-6メガピクセル)、比較には時間がかかる可能性があるため、これは特に懸念事項です。

私のタイミングは、MacBookProで次のようになります。

time (convert  color/image1.jpg  -colorspace gray  image1-gray.jpg ;
      compare                   \
         gray/file324.jpg       \
         image1-gray.jpg        \
        -highlight-color black  \
        -fuzz 3%                \
        -compose src            \
         delta100-fuzz.jpg)

  real  0m6.085s
  user  0m2.616s
  sys   0m0.598s

6秒:大きなカラー画像からグレースケールへの1回の変換、および2つの大きなグレースケール画像の1回の比較。

あなたは「何千もの画像」について話しました。このタイミングに基づいて3000枚の画像を想定すると、すべての画像の処理には(3000*3000)/2比較(450万)と(3000*3000*6)/2秒(2700万秒)が必要になります。すべての比較を完了するのに合計312日かかります。あなたが私に尋ねれば、長すぎます。

パフォーマンスを向上させるために何ができるでしょうか?

さて、私の最初のアイデアは、画像のサイズを小さくすることです。3072x2048サイズの画像ではなく、小さい画像を比較すると、比較の結果が早く返されるはずです。(ただし、テスト画像の最初の縮小にも追加の時間を費やしますが、後で小さい画像を比較するときに節約するよりもはるかに短い時間であることが望まれます。

time (convert color/image1.jpg  -colorspace gray  -scale 6.25%  image1-gray.jpg  ;
      convert gray/file324.jpg                    -scale 6.25%  file324-gray.jpg ;
      compare                  \
         file324-gray.jpg      \
         image1-gray.jpg       \
        -highlight-color black \
        -fuzz 3%               \
        -compose src           \
         delta6.25-fuzz.jpg)

   real  0m0.670s
   user  0m0.584s
   sys   0m0.074s

それははるかに良いです!処理時間のほぼ90%を削減しました。これにより、MacBook Proを使用すれば、35日で作業を完了することができます。

改善は論理的です。画像のサイズを元の画像の6.25%に縮小すると、結果の画像は192x128ピクセルになります。つまり、600万ピクセルから24.5千ピクセルに、256:1の比率で縮小されます。

注:およびパラメーターは-thumbnail-resizeよりも少し速く-scale動作します。ただし、この速度の向上は、品質の低下とのトレードオフです。その品質の低下により、比較の信頼性が大幅に低下する可能性があります...)

比較した画像から視覚的に検査可能なデルタ画像を作成する代わりに、ImageMagickにいくつかの統計を出力するように指示できます。異なるピクセルの数を取得するには、AEメトリックを使用できます。その結果を含むコマンドは次のとおりです。

time (convert color/image1.jpg -colorspace gray -scale 6.25% image1-gray.jpg  ;
     convert gray/file324.jpg                   -scale 6.25% file324-gray.jpg ;
     compare -metric AE  file324-gray.jpg image1-gray.jpg -fuzz 3% null: 2>&1 )
0 

  real  0m0.640s
  user  0m0.574s
  sys   0m0.073s

これは0、ピクセルが異なることを意味します。これは、シェルスクリプト内で直接使用できる結果です。

シェルスクリプトの構成要素

したがって、自動比較を行うためのシェルスクリプトの構成要素は次のとおりです。

  1. カラー画像を「color/」ディレクトリからグレースケール画像に変換し、6.25%に縮小して、結果を「reference-color/」ディレクトリに保存します。

    # Estimated time required to convert 1000 images of size 3072x2048:
    #   500 seconds
    mkdir reference-color
    for i in color/*.jpg; do
        convert  "${i}"  -colorspace gray  -scale 6.25%  reference-color/$(basename "${i}")
    done
    
  2. 'gray /'ディレクトリから画像を縮小し、結果を'reference-gray/'ディレクトリに保存します。

    # Estimated time required to convert 1000 images of size 3072x2048:
    #    250 seconds
    mkdir reference-gray
    for i in gray/*.jpg; do
        convert  "${i}"  -scale 6.25%  reference-gray/$(basename "${i}")
    done
    
  3. 一致するものが見つかるまで、ディレクトリ'reference-gray/'の各画像をディレクトリ'reference-color'の画像と比較します。

    # Estimated time required to compare 1 image with 1000 images:
    #    300 seconds
    # If we have 1000 images, we need to conduct a total of 1000*1000/2
    # comparisons to find all matches;
    #    that is, we need about 2 days to accomplish all.
    # If we have 3000 images, we need a total of 3000*3000/2 comparisons
    # to find all matches;
    #    this requires about 20 days.
    #
    for i in reference-gray/*.jpg ; do
    
        for i in reference-color/*.jpg ; do
    
            # compare the two grayscale reference images
            if [ "x0" == "x$(compare  -metric AE  "${i}"  "${j}" -fuzz 3%  null: 2>&1)" ]; then
    
                # if we found a match, then create the copy under the required name
                cp color/$(basename "${j}"  results/$(basename "${i}") ;
    
                # if we found a match, then remove the respective reference image (we do not want to compare again with this one)
                rm -rf "${i}"
    
                # if we found a match, break from within this loop and start the next one
                break ;
    
            fi
    
        done
    
    done
    

警告:これらのビルディングブロックに盲目的に依存しないでください。それらはテストされていません。これをテストするために利用できる複数の適切なイメージのディレクトリがありません。この演習のためだけに自分で作成したくありません。注意して進んでください!

于 2012-10-04T23:11:13.003 に答える
2

pHashなどの知覚的ハッシュ手法が具体的なデータに良い結果をもたらすかどうかを試してみてください。

基礎となるアルゴリズムは、コントラスト調整やさまざまな圧縮/形式などの変更/変換を考慮に入れるのに十分堅牢であるため、知覚ハッシュは信頼性の高い類似性の尺度を提供します。これは、MD5などの標準的な暗号化ハッシュ関数には当てはまりません。

さらに、独自の画像で便利なWebベースのデモインターフェイスを使用して、pHashが機能するかどうかを検証できます。

于 2012-09-29T10:18:14.977 に答える
1

Kurtのソリューションは、-fuzzオプションを微調整していじった後でも非常に機能します。:)最終的にうまく機能した-fuzzの最終的な値は50%です!3、10、19、20、24、25、30、40%で試しましたが、成功しませんでした。おそらく、グレー画像が以前に別の方法で生成されたため、グレーが異なります。また、すべての画像のサイズが異なり、一部の画像は比較的小さいため、パーセンテージによるスケーリング方法では悪い結果が生じます。私が使用-resize 200xしたので、すべての参照画像はほぼ同じサイズでした。最後に、これは私が使用したbashスクリプトでした。

    # this bash assumes the existence of two dirs: color/ and gray/ 
    # each one with images to compare

    echo Starting...
    echo Checking directories...
    if [ ! -d color ]; then
        echo Error: the directory color does not exist!
        exit 1;
    fi
    if [ ! -d gray ]; then
        echo Error: the directory gray does not exist!
        exit 1;
    fi

    echo Directories exist. Proceeding...

    mkdir reference-color
    echo creating reference-color...
    for i in color/*.png; do
        convert  "${i}"  -colorspace gray  -resize 200x  reference-color/$(basename "${i}")
    done
    echo reference-color created...

    mkdir reference-gray
    echo creating reference-gray...
    for i in gray/*.png; do
        convert  "${i}"  -resize 200x  reference-gray/$(basename "${i}")
    done
    echo reference-gray created...

    mkdir results
    echo created results directory...

    echo ...ready.

    echo "-------------------------"
    echo "|  starting comparison  |"
    echo "-------------------------"

    for i in reference-gray/*.png; do
        echo comparing image $i 

        for j in reference-color/*.png; do

            # compare the two grayscale reference images

            if [ "x0" == "x$(compare  -metric AE "${i}"  "${j}" -fuzz 50% null: 2>&1)" ]; then

                # if we found a match, then create the copy under the required name
                echo Founded a similar one. Copying and renaming it...
                cp color/$(basename "${j}")  results/$(basename "${i}")

                # if we found a match, then remove the respective reference image (we do not want to compare again with this one)
                echo Deleting references...
                rm -rf "${i}"
                rm -rf "${j}"
                echo "--------------------------------------------------------------"

                # if we found a match, break from within this loop and start the next one
                break ;

            fi

        done

    done
    echo Cleaning...
    rm -rf reference-color
    rm -rf reference-gray
    echo Finished!

時間の尺度は次のとおりです(180の画像の場合、cygwinでimagemagickを使用しているため、ネイティブのLinux imagemagickの方がおそらく優れていますが、まだわかりません)。

real    5m29.308s
user    2m25.481s
sys     3m1.573s

興味があれば、スクリプトとテスト画像のセットを含むファイルをアップロードしました。http://www.mediafire.com/?1ez0gs6bw3rqbe4(7z形式で圧縮されています)

再度、感謝します!

于 2012-10-08T15:37:55.133 に答える