我有2个包含大量图片的目录,比如: color / 和 gray / 。在 color / 中,图像命名为:image1.png image2.png等。
我知道 gray / 包含相同的图像,但是灰度级,文件名和文件顺序不同(例如:file_01.png,但这不是相同的图像as image1.png)。
是否可以对两个目录中的图像进行比较,并使用 gray / 文件将 color / 文件复制到结果 /目录名字?
示例:
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/*.jpg
复制到gray/*.jpg
文件夹中。
编辑(一些注释): 这三张图片的大小和内容都是IDENTICAL。唯一的区别是两个是彩色的,一个是灰度的。当然还有文件的名称。 2.我上传了一个带有一个样本图像及其当前名称的zip文件(文件夹“img1”是颜色文件夹和文件夹“img2”是灰度文件夹)和预期结果(“img3”是结果文件夹),这里:http://www.mediafire.com/?9ug944v6h7t3ya8
答案 0 :(得分:4)
如果我正确理解了要求,我们需要:
所以我建议的基本算法就是:
将文件夹 color / 中的所有图像转换为灰度,并将结果存储在 gray-reference / 文件夹中。保留原始名称:
mkdir gray-reference
convert color/img123.jpg -colorspace gray gray-reference/img123.jpg
对于 reference / 中的每个灰度图像,与 gray / 文件夹中的每个灰度图像进行比较。如果找到匹配项,请将相同名称的相应图像从 color / 复制到 results / 。一个可能的比较命令创建了差异的直观表示:
compare gray-reference/img123.jpg gray/imgABC.jpg -compose src delta.jpg
真正的技巧是两个灰度图像的比较(如步骤2)。 ImageMagick有一个方便的命令,可以逐个像素地比较两个(相似的)图像,并将结果写入一个' delta'图片:
compare reference.png test.png -compose src delta.png
如果比较适用于彩色图像,请在增量图像...
中有关此技术的说明示例,另请参阅我的回答"ImageMagick: 'Diff' an Image"。
如果我们直接逐个像素地比较灰度图像和彩色图像,我们当然会发现几乎每个像素都不同(导致全红色" delta&#34 ;图片)。因此,我从上面的步骤1提出的建议首先将彩色图像转换为灰度。
如果我们比较两个灰度图像,则生成的增量图像也是灰度图像。因此,默认的高亮颜色不能为红色。我们最好把它设置为黑色'为了更好地看待它。
现在,如果我们当前的颜色灰度转换会导致“不同”的颜色变化。比现有灰度图像具有的灰度级(由于应用了不同的颜色配置文件,我们当前生产的灰度可能比现有的灰度图像略微更浅或更暗),它可能仍然发生我们的delta图片全部是 - " red"或者更确切地说是全高亮颜色。但是,我用你的样本图像测试了这个,结果很好:
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兆像素),并且比较可能需要一段时间。
我在MacBook Pro上的计时结果如下:
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将大型彩色图像转换为灰度,再加上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
个不同的像素 - 这是我们可以在shell脚本中直接使用的结果!
以下是shell脚本进行自动比较的构建块:
转换彩色图像' 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
缩小' grey /'目录并将结果保存在< reference-grey /'目录:强>
# 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-grey /'使用目录中的图像' 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
警告:不要盲目依赖这些积木。他们没有经过考验。我没有可用于测试这个的多个合适图像的目录,我不想仅为此练习创建一个。谨慎行事!
答案 1 :(得分:2)
您应该尝试使用感知哈希技术(例如pHash)为您的具体数据提供一些好的结果。
感知哈希将为您提供可靠的相似性度量,因为基础算法足够强大,可以考虑更改/转换,例如对比度调整或不同的压缩/格式 - 这与标准加密哈希函数(如MD5)不同
此外,您可以在自己的图像上使用方便的基于网络的demo interface验证pHash是否有效。
答案 2 :(得分:1)
经过一些调整和摆弄-fuzz选项后,Kurt的解决方案非常有用! :)最终运作良好的-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格式压缩)
再次感谢!