获取一张图片在另一张图片中的位置

时间:2015-04-26 21:29:47

标签: node.js image image-processing imagemagick frontend

我的浏览器屏幕截图显示了一个网站。 现在我想找出网站(视口)的位置(相对于整个屏幕截图)。在此图像中看到带有黑色边框的矩形:

Image showing a sample screenshot with a viewport

我可以在开始图像处理之前向网站的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 ),这样我就可以从节点或者它执行它直接节点模块。

我的优势是我可以在更大的图像中选择我想要搜索的图像。我想对所发现内容的确切知识可以是加速过程的有用信息(但我不知道如何使用这些信息)。

1 个答案:

答案 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;

enter image description here

以下是&#34; 结果&#34; ImageMagick认为&#34; &#34;位于:

enter image description here

<强> 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