Detect if image is grayscale or color using Imagick

a 夏天 提交于 2020-01-13 02:46:09

问题


I'm attempting to try and assign a value to an image based on its 'saturation level', to see if the image is black and white or color. I'm using Imagick, and have found what seems to be the perfect code for the command line and am trying to replicate it using the PHP library.

I think I understand the concept:

  1. Convert image to HSL.
  2. Extract the 'g' channel (which is the S channel in HSL).
  3. Calculate the mean of this channel.


Command line code

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


My PHP code

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


Output

My PHP code isn't outputting the same sort of values as the command line code, though. For example, a grayscale image gives 0 for the command line code, but the PHP code gives [mean] => 10845.392051182 [standardDeviation] => 7367.5888849872.

Similarly, another grayscale image gives 0 vs. [mean] => 31380.528443457 [standardDeviation] => 19703.501101904.

A colorful image gives 0.565309 vs. [mean] => 33991.552881892 [standardDeviation] => 16254.018540044.


There just doesn't seem to be any kind of pattern between the different values. Am I doing something obviously wrong?

Thanks.


Just to add, I've also tried this PHP code

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

But I get an Unable to set format error when I try and set the format. I've also tried setFormat('%[fx:mean] info:'), setFormat('%[mean]'), setFormat('%mean'), etc.



Update — FIXED!

Thanks to @danack for figuring out I needed to use transformImageColorspace() and not setColorspace(). The working code is below.

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

回答1:


setFormat doesn't replicate the command line option -format - the one in Imagick tries to set the image format, which should be png, jpg etc. The one in the command line is setting the format for info - the closest match for which in Imagick is calling $imagick->identifyImage(true) and parsing the results of that.

Also you're just calling the wrong function - it should be transformImageColorspace not setColorSpace. If you use that you can use the statistics from getImageChannelMean.

There are other ways to test for greyness which may be more appropriate under certain circumstances. The first is to convert the a clone of the image to grayscale, and then compare it to the original image:

$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";
}

That would probably be appropriate if you image had areas of color that were also transparent - so they theoretically have color, but not visibly.

Or if you only care about whether the image is of a grayscale format:

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



回答2:


I found a command line here:

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

It prints a number between 0 and 1, where zero means grayscale.




回答3:


If your images have tint. (from scanner as example) you should do auto color for them before detecting gray scale. You should normalizeImage(imagick::CHANNEL_ALL) for all separate channels of image. separateImageChannel()

But



来源:https://stackoverflow.com/questions/23922654/detect-if-image-is-grayscale-or-color-using-imagick

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!