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

时间:2014-05-28 22:04:15

标签: php colors imagemagick imagick imagemagick-convert

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

我想我理解这个概念:

  1. 将图片转换为HSL。
  2. 提取'g'通道(HSL中的S通道)。
  3. 计算此渠道的平均值。

  4. Command line code

    convert '$image_path' -colorspace HSL -channel g -separate +channel -format '%[fx:mean]' info:
    


    我的PHP代码

    $imagick = new Imagick($image_path);
    $imagick->setColorspace(imagick::COLORSPACE_HSL);
    print_r($imagick->getImageChannelMean(imagick::CHANNEL_GREEN));
    


    输出

    我的PHP代码不会输出与命令行代码相同的值。例如,灰度图像为命令行代码提供0,但PHP代码提供[mean] => 10845.392051182 [standardDeviation] => 7367.5888849872

    同样,另一个灰度图像提供0[mean] => 31380.528443457 [standardDeviation] => 19703.501101904

    彩色图片提供0.565309[mean] => 33991.552881892 [standardDeviation] => 16254.018540044


    在不同的值之间似乎没有任何类型的模式。我做了一件明显不对的事吗?

    感谢。


    刚才补充一下,我也试过这个PHP代码

    $imagick = new Imagick($image_path);
    $imagick->setColorspace(imagick::COLORSPACE_HSL);
    $imagick->separateImageChannel(imagick::CHANNEL_GREEN);
    $imagick->setFormat('%[fx:mean]');
    

    但是当我尝试设置格式时,我收到Unable to set format错误。我还尝试过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;
    

3 个答案:

答案 0 :(得分:2)

setFormat不复制命令行选项-format - Imagick中的一个尝试设置图像格式,应该是png,jpg等。命令行中的一个设置格式为info - Imagick中最接近的匹配$imagick->identifyImage(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";
}

如果您的图像的颜色区域也是透明的,那么这可能是合适的 - 所以它们理论上有颜色,但不明显。

或者,如果您只关心图像是否为灰度格式:

$imageType = $imagick->getImageType();
if ($imageType === \Imagick::IMGTYPE_GRAYSCALE || 
    $imageType === Imagick::IMGTYPE_GRAYSCALEMATTE) {
     //This is grayscale
}

答案 1 :(得分:1)

如果您的图片有色调。 (以扫描仪为例)你应该在检测灰度之前为它们做自动颜色。 对于所有单独的图像通道,您应该normalizeImage(imagick::CHANNEL_ALL)separateImageChannel()

但是

enter image description here

答案 2 :(得分:1)

我找到了命令行here

convert image.png -colorspace HSL -channel g -separate +channel -format "%[fx:mean]" info:

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