要件を正しく理解した場合は、次のことを行う必要があります。
- フォルダgray/ ..にあるXYZという名前のグレースケール画像ごとに検索します。
- ...フォルダcolor/にあるABCという名前の一致するカラー画像と...
- ...ABCをフォルダresults/に新しい名前XYZでコピーします
したがって、私が提案する基本的なアルゴリズムは次のとおりです。
フォルダcolor/のすべての画像をグレースケールに変換し、結果をフォルダgray-reference/に保存します。元の名前を保持します。
mkdir gray-reference
convert color/img123.jpg -colorspace gray gray-reference/img123.jpg
参照/内の各グレースケール画像について、フォルダ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
、ピクセルが異なることを意味します。これは、シェルスクリプト内で直接使用できる結果です。
シェルスクリプトの構成要素
したがって、自動比較を行うためのシェルスクリプトの構成要素は次のとおりです。
カラー画像を「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
'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
一致するものが見つかるまで、ディレクトリ'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
警告:これらのビルディングブロックに盲目的に依存しないでください。それらはテストされていません。これをテストするために利用できる複数の適切なイメージのディレクトリがありません。この演習のためだけに自分で作成したくありません。注意して進んでください!