Обнаружить, если изображение в оттенках серого или в цвете, используя Imagick
Я пытаюсь попытаться присвоить значение изображению на основе его "уровня насыщенности", чтобы увидеть, является ли изображение черно-белым или цветным. Я использую Imagick, и нашел то, что кажется идеальным кодом для командной строки, и пытаюсь воспроизвести его с помощью библиотеки PHP.
Я думаю, что понимаю концепцию:
- преобразование изображения в HSL.
- извлеките канал " g " (который является каналом S в HSL).
- вычислите среднее значение этого канал.
Код командной строки
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 ответа:
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 }
Я нашел командную строку здесь:
Он выводит число от 0 до 1, где ноль означает оттенки серого.convert image.png -colorspace HSL -channel g -separate +channel -format "%[fx:mean]" info: