imagick / php - 检查图片之间的差异和变化的判断

imagick / php - check the differences between the pictures and the determination of changes

我有两张图片(第一张和第二张 link)。

First image

Second image

Third image

第三张图片由imagick生成,代码:

$image1 = new \imagick(dirname(dirname(dirname(__DIR__))) . "/1.jpg");
$image2 = new \imagick(dirname(dirname(dirname(__DIR__))) . "/2.jpg");

$result = $image1->compareImages($image2, \Imagick::METRIC_MEANSQUAREERROR);
$result[0]->setImageFormat("jpg");

header("Content-Type: image/jpeg");
echo $result[0];
exit();

我可以用不同的方式表示更改吗?比如红框标出的差异。

这实际上很重要 :-) 有几个问题,首先您需要确定差异 - 您可以通过差分 (-compose difference) 来做到这一点。然后你需要根据它们的不同程度来对差异进行阈值处理,但是因为你使用的是有损的 JPEG,所以每个像素都有量化结束编码差异。一旦你有了差异,你需要勾勒出它们 - 但如果你天真地勾勒出它们,你会在每个不同的单个像素周围得到一个框,而不是每个形状周围都有一个框,所以你需要做一些模糊和阈值处理(或其他东西else) 将附近的差异合并为单个块。一旦你找到了这些块,你需要在它们周围放一个框架 - 你可以做一个 "Connected Components Analysis" 或其他东西来找到块的边缘 - 我选择了一个"Edge Out Morphology"。然后您需要为边缘着色并将它们合成回原始图像的顶部。该命令在命令行中如下所示:

convert a.jpg \
   \( +clone b.jpg -compose difference -composite                   \
      -threshold 1% -separate -evaluate-sequence Add                \
      -blur 0x5 -threshold 10%                                      \
      -morphology edgeout diamond:3                                 \
      -fill red -opaque white -transparent black -write mask.png \) \
      -compose srcover -composite  result.png

当然,它看起来会有所不同,具体取决于您将轮廓合成到原始两张图片中的哪一张上 - 我选择合成到第一张上,但您可以选择第二张。

我将掩码写入文件 mask.png 这样你就可以看到我在括号内实际构建的内容,我在它周围加了一个边框这样你就可以在下面看到它:

这是您可以尝试的另一种变体 - 很难知道什么最适合您的所有图像:-)

convert a.jpg \
   \( +clone b.jpg -compose difference -composite -threshold 1%    \
      -statistic maximum 25x25                                     \
      -morphology edgeout diamond:5                                \
      -fill red -opaque white -transparent black -write mask.png   \
   \) -compose srcover -composite  result.png

这个答案与上面的答案类似,只是它在 PHP 中实现。

此外,如果您要这样做,请将差异图像显示为动画。 Gif 或使用 javascript 在图像之间交换。将区域标记为闪烁使用户的生活变得更加轻松。

此外,通过进行两次较小的比较,一次垂直比较,一次水平比较,与一次大比较相比,可以稍微加快处理时间。

$image1 = new Imagick(__DIR__."/compare1.jpg");
$image2 = new Imagick(__DIR__."/compare2.jpg");

$image1->compositeImage($image2, \Imagick::COMPOSITE_DIFFERENCE, 0, 0);

$overlay = clone $image1;
$overlay->negateImage(false);
$overlay->setImageAlphaChannel(\Imagick::ALPHACHANNEL_DEACTIVATE);
$overlay->transformImageColorSpace(\Imagick::COLORSPACE_GRAY);

// Doing one big compare is slow
//$overlay->statisticImage(\Imagick::STATISTIC_MINIMUM, 20, 20);
// Doing a horizontal and vertical compare is faster
$overlay->statisticImage(\Imagick::STATISTIC_MINIMUM, 20, 2);
$overlay->statisticImage(\Imagick::STATISTIC_MINIMUM, 2, 20);

$overlay->statisticImage(\Imagick::STATISTIC_GRADIENT, 4, 4);

$red = new Imagick();
$red->newPseudoImage(
    $overlay->getImageWidth(),
    $overlay->getImageHeight(),
    'xc:red'
);

$red->compositeImage($overlay, \Imagick::COMPOSITE_COPYOPACITY, 0, 0);

$withOutline = clone $image2;
$withOutline->compositeImage($red, \Imagick::COMPOSITE_ATOP, 0, 0);

$outputGif = new Imagick();
$outputGif->addImage($image2);
$outputGif->addImage($withOutline);

$outputGif = $outputGif->deconstructImages();
$outputGif->setImageFormat('gif');    
header("Content-Type: image/gif");
echo $outputGif->getImagesBlob();

如您所见,闪烁检测使其更易于查看: