PHP,检测水印图像?

PHP,检测水印图像?,php,image-processing,Php,Image Processing,我有一个大约100万张图像的库,其中大约一半的图像在同一点上用相同的、半透明的水印进行了水印处理 从哪里开始,检测带有水印的图像?是否有一些用于此目的的标准工具?如果没有用于此目的的工具,您可以尝试以下方法: 确定水印以像素百分比显示的位置,例如右下角40px x 100px 对于每个图像,制作临时副本并裁剪出水印将出现的位置。这将使带水印的版本和不带水印的版本保持相同 比较图像-例如,宽度x高度、文件大小、CRC或实际像素比较的组合,但是对于一百万个图像,您需要一些严重的CPU功率 检测图像中

我有一个大约100万张图像的库,其中大约一半的图像在同一点上用相同的、半透明的水印进行了水印处理


从哪里开始,检测带有水印的图像?是否有一些用于此目的的标准工具?

如果没有用于此目的的工具,您可以尝试以下方法:

  • 确定水印以像素百分比显示的位置,例如右下角40px x 100px

  • 对于每个图像,制作临时副本并裁剪出水印将出现的位置。这将使带水印的版本和不带水印的版本保持相同

  • 比较图像-例如,宽度x高度、文件大小、CRC或实际像素比较的组合,但是对于一百万个图像,您需要一些严重的CPU功率


  • 检测图像中的几乎任何特征称为对象检测。有一个被广泛使用的图书馆叫做。它有一个非常简单的SDK,尽管设置起来会很麻烦。C/C++和(几乎)Python都支持它。我花了3周的时间来训练自己,这是我第一次开始使用OpenCV


    但是我不会完全依赖这个解决方案,考虑我的优先事项。此外,使用自定义分类器很难获得良好的分类率。其他方法更耗时。

    简言之,并非完全准确

    充其量,您只能对图像应用启发式方法,以查看它是否与精确的水印匹配,并获得置信度评级——例如,如果水印覆盖了50%的白色,则以白色为主的场景可能会给出假阳性,当然,反之亦然


    如果图像使用有损压缩(如JPEG)作为边缘,也可能会出现问题,饱和可能会导致水印没有预期的饱和,或者精确定位。

    因为您知道水印始终位于何处,所以可以使用并获取水印内外像素的alpha值。我希望在没有水印的情况下,alpha值是相似的,而在有水印的情况下,alpha值是不同的(在您需要确定的某个阈值内)。当然,这可能不适用于所有图像,因此如果您需要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!";
            }
        }
    }
    
    $no\u of\u pixels=你得到了什么;
    $matched=0;
    $thumbpixels=数组();
    $wmark=imagecreatefrompng(“watermark.png”);
    列表($width,$height)=getimagesize(“watermark.png”);
    $tesimage=imagecreatefrompng(“test.png”);
    对于($h=0;$h<$height;$h++){
    对于($w=0;$w<$width;$w++){
    如果(imagecolorsforindex($testimage,imagecolorat($testimage,$w,$h))==$thumbpixels[0]){
    而($thumbpixels[$i++]==imagecolorsforindex($tesimage,imagecolorat($wmark,$w,$h))&&$no_像素!=$matched){
    $matched++;
    }
    如果($matched==$no\u像素)回声“瞧,我们找到了!”;
    }
    }
    }
    

    编辑 看看你的缩略图。如果您只想检测文本,可以尝试或


    你也可以考虑在你的情况下,你在一个可预测的位置寻找同一个标志,这是比较简单的。然而,匹配元数据中的版权声明要简单得多,也要快得多(根据我在别处的评论)

    水印不会对内容产生固定的更改-每个修改的像素将基于水印和图像本身获得一个新值。因此,你需要提取这些信息——我会对图像进行微分,只看导数的大小(而不是相位)

    然后,这仅仅是一个区别于其中一个水印(或水印和其他内容的批次)的问题

    除非您乐于编写自己的扩展,否则您真的不想在PHP中进行这种图像处理。大多数图像处理工具包将支持区分和关联


    顺便说一句:如果你不知道如何区分图像,和/或不知道如何关联图像,请不要问-这不是讨论的合适论坛

    你检查过元数据,看它们是否有机器可读的版权声明吗?是的,这些图像没有这样的元数据。水印有多大,它出现在图像中的什么位置?参见示例:在本例中,您从何处获得非水印图像?我是说,您可以裁剪水印出现的所有图像(或将区域设置为黑色或白色)。海报上说水印总是出现在同一个地方,所以这应该是可行的,如果水印是一条横跨图像的50%对角线白线,你什么也不裁剪(因为你知道水印会穿过对角线),看看它是否匹配什么?对-我从海报的措辞中假设水印很小“称为斑点”。但是,即使它是一条大对角线,你也可以从现有的带水印图像中提取水印,并将其应用于所有图像,这样你就可以对它们进行比较。如果它是半透明的(如上所述),你在这里向正确的方向踢了我一脚,谢谢。半透明的图像总是在同一个点上用更多的白色使图像变亮。一个简单的启发式方法是寻找文本亮度低于5的像素