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

时间:2015-09-03 08:43:07

标签: php image compare imagick

我有两张图片(第一和第二个链接)。

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();

我可以用不同的方式表示变化吗?例如,差异标记为红框。

2 个答案:

答案 0 :(得分:2)

这实际上是非平凡的:-)有几个问题,首先你需要确定差异 - 你可以通过差分(-compose difference)来做到这一点。然后,您需要根据它们的差异来确定差异的阈值,但由于您使用的是有损JPEG,因此每个像素都有量化结束编码差异。一旦你有差异,你需要勾画它们 - 但是如果你天真地勾勒出它们,你会在每个单个像素周围得到一个框,而不是每个形状周围的一个框,所以你需要做一些模糊和阈值处理(或者某些东西)否则)将附近的差异合并为单个肿块。一旦你找到肿块,你需要在它们周围放一个框架 - 你可以做一个“连接组件分析”或其他东西来找到肿块的边缘 - 我选择了一个 “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

enter image description here

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

我将掩码写入文件mask.png,这样你就可以看到我在括号内构建的内容,并在其周围放置一个边框,以便您可以在下面看到它:

enter image description here

以下是您尝试的另一种变体 - 很难知道哪些图片最适合您的所有图片: - )

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

答案 1 :(得分:1)

这个答案类似于上面的答案,除了它在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();

正如您所见,闪烁检测使其更容易看到:

enter image description here