Php 使用Imagick检测图像是灰度还是彩色

Php 使用Imagick检测图像是灰度还是彩色,php,colors,imagemagick,imagick,imagemagick-convert,Php,Colors,Imagemagick,Imagick,Imagemagick Convert,我试图根据图像的“饱和度”给图像赋值,看看图像是黑白还是彩色。我正在使用Imagick,并且找到了似乎是命令行的完美代码,并尝试使用PHP库复制它 我想我理解这个概念: 将图像转换为HSL 提取“g”通道(HSL中的S通道) 计算此通道的平均值 我的PHP代码 输出 不过,我的PHP代码输出的值与命令行代码不一样。例如,对于命令行代码,灰度图像给出0,而PHP代码给出[平均值]=>10845.39205182[标准偏差]=>7367.5888849872 类似地,另一灰度图像给出0与[平均

我试图根据图像的“饱和度”给图像赋值,看看图像是黑白还是彩色。我正在使用Imagick,并且找到了似乎是命令行的完美代码,并尝试使用PHP库复制它

我想我理解这个概念:

  • 将图像转换为HSL
  • 提取“g”通道(HSL中的S通道)
  • 计算此通道的平均值


  • 我的PHP代码

    输出 不过,我的PHP代码输出的值与命令行代码不一样。例如,对于命令行代码,灰度图像给出
    0
    ,而PHP代码给出
    [平均值]=>10845.39205182[标准偏差]=>7367.5888849872

    类似地,另一灰度图像给出
    0
    [平均值]=>31380.528443457[标准偏差]=>19703.501101904

    彩色图像给出
    0.565309
    [平均值]=>33991.552881892[标准偏差]=>16254.018540044


    不同的值之间似乎没有任何模式。我是不是做错了什么

    谢谢


    我还尝试了这个PHP代码

    $imagick = new Imagick($image_path);
    $imagick->setColorspace(imagick::COLORSPACE_HSL);
    $imagick->separateImageChannel(imagick::CHANNEL_GREEN);
    $imagick->setFormat('%[fx:mean]');
    
    但是当我尝试设置格式时,出现了一个
    无法设置格式的错误。我还尝试了
    setFormat('%[fx:mean]info:')
    setFormat('%[mean]'))
    setFormat('%mean')
    ,等等



    更新-修复! 感谢@danack发现我需要使用
    transformImageColorspace()
    而不是
    setColorspace()
    。工作代码如下

    $imagick = new Imagick($image_path);
    $imagick->transformImageColorspace(imagick::COLORSPACE_HSL);
    $saturation_channel = $imagick->getImageChannelMean(imagick::CHANNEL_GREEN);
    $saturation_level = $saturation_channel['mean']/65535;
    

    setFormat不复制命令行选项
    -format
    -Imagick中的选项尝试设置图像格式,应为png、jpg等。命令行中的选项正在设置
    info
    -Imagick中调用的最接近匹配项
    $Imagick->identifimage(true)
    并解析结果

    另外,您只是调用了错误的函数-它应该是transformImageColorspace而不是setColorSpace。如果您使用它,您可以使用getImageChannelMean中的统计信息

    在某些情况下,还有其他更适合测试灰色的方法。第一种方法是将图像的克隆转换为灰度,然后将其与原始图像进行比较:

    $imagick = new Imagick($image_path);
    $imagickGrey = clone $imagick;
    $imagickGrey->setimagetype(\Imagick::IMGTYPE_GRAYSCALE);
    
    $differenceInfo = $imagick->compareimages($imagickGrey, \Imagick::METRIC_MEANABSOLUTEERROR);
    
    if ($differenceInfo['mean'] <= 0.0000001) {
        echo "Grey enough";
    }
    
    如果你的图像有色彩。(以扫描仪为例)您应该在检测灰度之前为它们自动着色。 您应该
    normalizeImage(imagick::CHANNEL\u ALL)
    用于图像的所有单独通道<代码>分隔图像通道()

    但是

    我找到了一个命令行:


    它打印一个介于0和1之间的数字,其中0表示灰度。

    您是否可以详细说明“我的PHP版本输出的值与命令行版本不一样”的含义?您使用的是两个不同版本的PHP吗?对不起-我认为我的措辞不好!我会编辑的。这是同一版本的PHP,我只是指两个版本的代码,即命令行代码和PHP代码。@danack谢谢!我喜欢这个解决方案作为一种检测图像是否为灰度的方法,但我只是想知道您是否知道为什么
    $imagick->setColorspace(imagick::COLORSPACE_HSL)不起作用?理想情况下(这与我原来的问题略有不同),我希望根据图像的平均饱和度设置一个介于0.0和1.0之间的值。我在Photoshop中将图像的饱和度提高到最大值,命令行脚本给出了0.995(接近1.0),但上面的脚本给出了0.22-0.22代表什么?这似乎是迄今为止输出的最大数字。只是澄清一下,与其简单地将图像分类为灰度或非灰度,我更希望能够根据图像的颜色选择图像。虽然结果与计算平均饱和度略有不同,但您的代码可以做到这一点。如果不可能,我可以将代码的输出值除以0.25ish,得到一个归一化为1.0的值,但我很好奇。我真的很感谢你的帮助!“只是想知道你是否知道为什么$imagick->setColorspace(imagick::COLORSPACE\u HSL);不起作用?”看起来好像有问题。这是专业术语。setColorSpace似乎对图像没有任何影响-我将尝试进一步深入研究它,因为我应该知道它的作用。“理想情况下,我希望能够根据图像的颜色选择图像。”这是一个不同的问题。您现在可能不需要使用中断的setColorspace函数,可以通过i)将其拆分为rgb通道,ii)调用r+g和g+b之间的比较,并使用度量_MEANSQUAREERROR作为求和项。@Davey简单错误总是最好的。。。。transformImageColorspace未设置ImageColorSpace谢谢,此功能非常好!++convert../image\u bw.jpg-colorspace HSL-channel g-separate+channel-format“%$[fx:mean]”信息:+VALUE\u RAW=0.0348832++convert../image\u col.jpg-colorspace HSL-channel g-separate+channel-format“%$fx:mean]”信息:+VALUE\u RAW=0.435082,如果该值小于0.1,则图像为灰度图像。如果它是0.1-1,它就是颜色。
    
    $imagick = new Imagick($image_path);
    $imagick->transformImageColorspace(imagick::COLORSPACE_HSL);
    $saturation_channel = $imagick->getImageChannelMean(imagick::CHANNEL_GREEN);
    $saturation_level = $saturation_channel['mean']/65535;
    
    $imagick = new Imagick($image_path);
    $imagickGrey = clone $imagick;
    $imagickGrey->setimagetype(\Imagick::IMGTYPE_GRAYSCALE);
    
    $differenceInfo = $imagick->compareimages($imagickGrey, \Imagick::METRIC_MEANABSOLUTEERROR);
    
    if ($differenceInfo['mean'] <= 0.0000001) {
        echo "Grey enough";
    }
    
    $imageType = $imagick->getImageType();
    if ($imageType === \Imagick::IMGTYPE_GRAYSCALE || 
        $imageType === Imagick::IMGTYPE_GRAYSCALEMATTE) {
         //This is grayscale
    }
    
    convert image.png -colorspace HSL -channel g -separate +channel -format "%[fx:mean]" info: