Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
imagick/php-检查图片之间的差异并确定更改_Php_Image_Compare_Imagick - Fatal编程技术网

imagick/php-检查图片之间的差异并确定更改

imagick/php-检查图片之间的差异并确定更改,php,image,compare,imagick,Php,Image,Compare,Imagick,我有两个图像(第一个和第二个链接) 第三幅图像由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_MEA

我有两个图像(第一个和第二个链接)

第三幅图像由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,因此每个像素都存在量化结束编码差异。一旦你有了差异,你就需要对它们进行轮廓化——但是如果你简单地对它们进行轮廓化,你会在每个不同的像素周围得到一个盒子,而不是在每个形状周围有一个盒子,因此你需要做一些模糊和阈值化(或其他事情)来将附近的差异合并成单个块。一旦你找到了肿块,你需要在它们周围放一个框架——你可以做一个“连接组件分析”或者别的什么来找到肿块的边缘——我选择了一个“边缘形态学”。然后你需要给边缘上色,并把它们合成回原始图像的顶部。命令行中的命令如下所示:

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
,这样你就可以看到我在括号里实际构建了什么,我在它周围加了一个边框,这样你就可以在下面看到它:

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


这个答案与上面的答案类似,只是它是用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();
正如您所看到的,闪烁检测使您更容易看到:


嗯?差异已经是红色的。只有红色边框:)@edit:和100%不透明度的图像。这是一个非常好的解决方案。它就像我想要的那样工作。但是它需要很长的时间并且消耗CPU资源。你可以试着将图像缩小到原来大小的一半或四分之一来制作面具,然后再将其放大。
25x25
非常昂贵。我已将此代码添加到bash脚本中。当我通过命令exec运行它时,它不是create。控制台上的代码本身工作得很好。我只能想象当您通过
exec()
-或引用
%
符号或括号调用它时,您的路径或其他一些环境变量是错误的。
$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();