我的浏览器屏幕截图显示了一个网站。 现在我想找出网站(视口)的位置(相对于整个屏幕截图)。在此图像中看到带有黑色边框的矩形:
我可以在开始图像处理之前向网站的DOM添加任何内容。
我已经尝试生成QR码,将其添加到视口的左上角和右下角,然后使用 imagemagick 以确定更大的QR码的位置图像:
compare -metric "rmse" -subimage-search -dissimilarity-threshold "0.1" -virtual-pixel "edge" "haystack.png" "needle.png" "results.png"
然而,这需要很长时间。事实上,我在40分钟后退出了。
我使用了QR码,因为通过使用时间戳,我可以确定在网站上的任何其他地方都找不到这张图片。
此外,屏幕截图中QR码的大小是原始QR码的两倍,但我想这是因为我的mac屏幕有144dpi。
我正在使用 node.js 所以我需要一些可以通过命令行执行的东西(比如 imagemagick ),这样我就可以从节点或者它执行它直接节点模块。
我的优势是我可以在更大的图像中选择我想要搜索的图像。我想对所发现内容的确切知识可以是加速过程的有用信息(但我不知道如何使用这些信息)。
答案 0 :(得分:3)
如果您发现子图像搜索速度太慢,我会提出一些建议,您可以考虑加快搜索速度。
<强> 1。缩小图像尺寸
我进行了一项小实验来测试在不同大小的草垛中搜索各种尺寸的针,如下所示:
#!/bin/bash
# Create a range of haystack sizes
for h in 200 400 800; do
# And a range of needle sizes
for n in 10 20 40; do
# Create haystack to search in, containing two needles
convert -size ${h}x${h}! gradient:red-black -fill white \
-draw "rectangle 100,100 139,139" \
-draw "rectangle 150,150 189,189" \
haystack.png
# Create a needle this size to search for
convert -size ${n}x${n}! xc:white needle.png
cp haystack.png haystack_${h}x${h}.png
cp needle.png needle${n}x${n}.png
# Search, measuring the time
start=$SECONDS
compare -dissimilarity-threshold 1.0 -metric rmse -subimage-search haystack.png needle.png null: > /dev/null 2>&1
end=$SECONDS
((elapsed=end-start))
echo Haystack:${h}x${h}, needle:${n}x${n}, time:$elapsed
done
done
并找到尺寸如何影响搜索时间,如下所示:
Haystack:200x200, needle:10x10, time:2
Haystack:200x200, needle:20x20, time:2
Haystack:200x200, needle:40x40, time:2
Haystack:400x400, needle:10x10, time:8
Haystack:400x400, needle:20x20, time:8
Haystack:400x400, needle:40x40, time:10
Haystack:800x800, needle:10x10, time:33
Haystack:800x800, needle:20x20, time:36
Haystack:800x800, needle:40x40, time:47
如您所见,图像的大小有很大差异。
以下是三个不同大小的草垛,每个草垛包含2个白色&#34; 针&#34;
以下是&#34; 结果&#34; ImageMagick认为&#34; 针&#34;位于:
<强> 2。尽快停止
如果您添加参数-similarity-threshold
并将其设置为合理值,则可以在找到第一个匹配项后立即停止搜索 - 例如grep -m 1
。
如此设置将使其在第一次完美匹配时停止(相似度为零差异):
-similarity-threshold 0.0
或者设置为这样会使它停在第一个&#34;相当不错的匹配&#34;
-similarity-threshold 0.05
,默认设置为1.0
,它永远不会匹配,从而导致搜索在整个图像上继续。
现在我知道你想找到视口的顶部和底部,这是 两个 匹配,看起来很快就找到第一个匹配是没有使用。但孔子,他说&#34;旋转你的形象&#34; : - )
所以,找到你的第一个(即顶部)匹配,然后将你的图像(和针)旋转180度并再次搜索,但这次你从底部搜索并且可以在第一场比赛时再次停止。 (也可以旋转你的结果。)
第3。使用您付费的所有可爱核心 - 并行化!
您可以将图像拆分为多个部分并进行并行搜索,以充分利用您为此付出的所有可爱的英特尔核心。您需要稍微小心重叠一点,这样您的针头就不会跨越您切割的边界,但您只需要将针头的宽度添加到搜索区域的条子上......像这样
#!/bin/bash
# Create a range of haystack sizes
for h in 200 400 800; do
# And a range of needle sizes
for n in 10 20 40; do
# Create haystack to search in, containing two needles
convert -size ${h}x${h}! gradient:red-black -fill white \
-draw "rectangle 100,100 139,139" \
-draw "rectangle 150,150 189,189" \
haystack.png
# Create a needle this size to search for
convert -size ${n}x${n}! xc:white needle.png
cp haystack.png haystack_${h}x${h}.png
cp needle.png needle${n}x${n}.png
# Search, measuring the time
start=$SECONDS
compare -dissimilarity-threshold 1.0 -metric rmse -subimage-search haystack.png needle.png null: > /dev/null 2>&1
end=$SECONDS
((elapsed=end-start))
echo Haystack:${h}x${h}, needle:${n}x${n}, time:$elapsed
((a=h/2))
((b=h/2))
((c=a+n))
((d=b+n))
((e=a-n))
((f=b-n))
# Measure time for parallel search, including dividing up image
start=$SECONDS
convert haystack.png -crop ${c}x${d}+0+0 +repage h1.png
convert haystack.png -crop ${a}x${b}+${a}+0 +repage h2.png
convert haystack.png -crop ${a}x${b}+0+${b} +repage h3.png
convert haystack.png -crop ${c}x${d}+${e}+${f} +repage h4.png
for p in 1 2 3 4; do
compare -dissimilarity-threshold 1.0 -metric rmse -subimage-search h${p}.png needle.png null: > /dev/null 2>&1 &
done
wait
end=$SECONDS
((elapsed=end-start))
echo Parallel Haystack:${h}x${h}, needle:${n}x${n}, time:$elapsed
done
done
你可以看到,与单线程时间相比,并行时间几乎加快了4倍:
Haystack:200x200, needle:10x10, time:2
Parallel Haystack:200x200, needle:10x10, time:0
Haystack:200x200, needle:20x20, time:2
Parallel Haystack:200x200, needle:20x20, time:1
Haystack:200x200, needle:40x40, time:2
Parallel Haystack:200x200, needle:40x40, time:1
Haystack:400x400, needle:10x10, time:8
Parallel Haystack:400x400, needle:10x10, time:2
Haystack:400x400, needle:20x20, time:8
Parallel Haystack:400x400, needle:20x20, time:3
Haystack:400x400, needle:40x40, time:10
Parallel Haystack:400x400, needle:40x40, time:4
Haystack:800x800, needle:10x10, time:33
Parallel Haystack:800x800, needle:10x10, time:10
Haystack:800x800, needle:20x20, time:36
Parallel Haystack:800x800, needle:20x20, time:11
Haystack:800x800, needle:40x40, time:47
Parallel Haystack:800x800, needle:40x40, time:14