我有两张图片(第一和第二个链接)。
第三张图片是由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();
我可以用不同的方式表示变化吗?例如,差异标记为红框。
答案 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
当然看起来会有所不同,这取决于你将轮廓合成到原始两张图片中的哪一张 - 我选择合成第一张,但你可以选择第二张。
我将掩码写入文件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
答案 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();
正如您所见,闪烁检测使其更容易看到: