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