我有一个包含大约 100 万张图像的库,其中大约一半在同一个位置带有相同的半透明水印。
我从哪里开始,检测带有水印的图像?为此目的是否有一些标准工具?
我有一个包含大约 100 万张图像的库,其中大约一半在同一个位置带有相同的半透明水印。
我从哪里开始,检测带有水印的图像?为此目的是否有一些标准工具?
如果根据您的问题,您只想检测带有水印的图像,您可以使用以下算法:
代码可能是这样的:
$no_of_pixels = what_you_got;
$matched = 0;
$thumbpixels = array();
$wmark = imagecreatefrompng("watermark.png");
list($width, $height) = getimagesize("watermark.png");
$tesimage = imagecreatefrompng("test.png");
for($h = 0; $h < $height; $h++){
for($w = 0; $w < $width; $w++){
if(imagecolorsforindex($testimage, imagecolorat($testimage, $w, $h)) == $thumbpixels[0]){
while($thumbpixels[$i++] === imagecolorsforindex($tesimage, imagecolorat($wmark, $w, $h)) && $no_of_pixels != $matched){
$matched++;
}
if($matched == $no_of_pixels) echo "Voila, we found it!";
}
}
}
只是看到您的缩略图示例。如果您只想检测文本,可以尝试tesseract-ocr或PhpOCR。
你也可以考虑PHPSane
检测图像中的几乎所有特征称为对象检测。有一个广泛使用的库,称为OpenCV。它有一个非常简单的 SDK,虽然设置起来很痛苦。它很好地支持 C/C++ 和(几乎很好地支持) Python。我花了 3 周时间来训练我自己的Classfier(训练),这是我第一次开始使用 OpenCV。
但我不会完全依赖这个解决方案并考虑我的优先事项。此外,使用自定义分类器很难达到良好的速率。其他方法更耗时。
简而言之,不完全准确。
充其量,您只能在图像上应用启发式方法以查看它是否与精确的水印匹配,并获得置信度等级——例如,如果水印覆盖了 50% 的白色,那么以白色为主的场景可能会给出误报,当然反之亦然。
如果图像使用有损压缩(例如 JPEG)作为边缘,也可能会出现问题,并且饱和度可能会导致水印不像预期的那样饱和,或者没有像预期的那样精确定位。
因为您知道水印始终在哪里,所以您可以使用imagecolorat和imagecolorsforindex来获取水印内部和外部像素的 alpha 值。我希望 alpha 值在没有水印时是相似的,而在有水印时是不同的(在您需要确定的某个阈值内)。当然,这可能不适用于所有图像,因此如果您需要 100% 的准确度,您可能需要更可靠的东西。
在您的情况下,您要在可预测的位置寻找相同的徽标,这相对简单。然而,匹配元数据中的版权声明要简单得多,也更快(根据我在其他地方的评论)!
水印不会对内容产生固定的变化——每个修改过的像素都会根据水印和图像本身获得一个新值。因此,您需要提取此信息 - 我将区分图像并仅查看导数的大小(而不是相位)。
然后,只需将差异与水印之一(或与水印和其他内容的批次)相关联即可。
除非您乐于编写自己的扩展,否则您真的不想在 PHP 中进行这种图像处理。大多数图像处理工具包将支持差异化和相关性。
顺便说一句:如果您不知道如何区分图像,和/或无法理解如何关联图像,请不要问 - 这不是该讨论的正确论坛
好吧,如果没有工具可以做到这一点,您可以尝试以下方法:
以像素百分比的形式确定水印出现的位置,例如右下角 40px x 100px
对于每张图像,制作一个临时副本并裁剪出水印出现的位置。这应该使水印版本和非水印版本保持相同
比较图像 - 例如宽度 x 高度、文件大小、CRC 或实际像素比较的组合,但对于一百万张图像,您需要一些强大的 CPU 能力。