Быстро получить яркость/яркость изображений

Я работаю в php, и просматриваю каждое изображение попиксельно, чтобы получить среднюю яркость для каждого изображения, это будет интенсивно использовать процессор...

Я просмотрел документы GD и imagemagick, но не нашел способа вернуть среднюю яркость изображения... Можно ли это сделать быстро либо в этих библиотеках, либо в другом пакете, легко доступном для php?


person Eric    schedule 05.01.2012    source источник
comment
Используйте выбранную вами библиотеку, чтобы уменьшить размер изображения до 1x1 пикселя, а затем прочитайте значение этого пикселя.   -  person Mark Ransom    schedule 05.01.2012
comment
Чтобы было ясно, я ищу воспринимаемую яркость   -  person Eric    schedule 05.01.2012
comment
@MarkRansom спасибо, мне нравится это предложение.   -  person Eric    schedule 05.01.2012


Ответы (5)


Вот интересный пост с использованием ImageMagick для вычисления среднего уровня серого в изображении. В этом посте также обсуждается техника Марка Рэнсома по уменьшению размера до 1x1 с помощью ImageMagick.

person mevatron    schedule 05.01.2012
comment
Жаль, что в нем не обсуждаются преимущества и недостатки метода 1x1. Я предполагаю, что есть библиотеки, которые не используют подходящий метод выборки для изменения размера и дадут неточный результат. P.S. ваш ответ был бы сильнее, если бы он резюмировал ссылку. Ссылки умирают в конце концов. - person Mark Ransom; 06.01.2012

Образец? Просто выберите 10% случайных пикселей вместо 100%... Вероятность ошибок, очевидно, возрастет, но мне кажется, что 10% пикселей - это нормально, в большинстве случаев это должно давать отличные результаты!

person Mathieu Dumoulin    schedule 05.01.2012
comment
Интересно. У вас есть пример. - person Matt; 02.12.2017

В командной строке Imagemagick вы можете преобразовать в HSI или LAB и получить яркость (интенсивность или яркость) из среднего значения канала I или L. Любой из этих методов должен работать. Обратите внимание, что -scale 1x1 выполняет простое усреднение всего изображения/канала и сохраняет это значение в результате в 1 пиксель. -шкала очень быстрая. Это не похоже на -resize, который использует определенную функцию фильтра. В качестве альтернативы вы можете просто вычислить среднее значение изображения без записи в 1 пиксель.

convert image -colorspace HSI -channel b -separate +channel -scale 1x1 -format "%[fx:100*u]\n" info:

convert image -colorspace LAB -channel r -separate +channel -scale 1x1 -format "%[fx:100*u]\n" info:

convert image -colorspace HSI -channel b -separate +channel -format "%[fx:100*u.mean]\n" info:

convert image -colorspace LAB -channel r -separate +channel -format "%[fx:100*u.mean]\n" info:

convert image -colorspace HSI -channel b -separate +channel -format "%[mean]\n" info:

convert image -colorspace LAB -channel r -separate +channel -format "%[mean]\n" info:


Результат будет между 0 и 100%, где 0 означает черный, а 100 белый для всех, кроме последних двух, где диапазон fx находится между 0 и 1. Таким образом, коэффициент 100 дает процент. Для последних двух команд значения будут находиться в диапазоне от 0 до 255 для установки Q8 и от 0 до 65535 для установки Q16.

Обратите внимание, что каналы помечены в порядке, как если бы они были r, g, b. Но для современных версий Imagemagick можно использовать 0,1,2.

В качестве альтернативы вы можете получить цвет пикселя для канала, который будет иметь значение серого:

convert image -colorspace HSI -channel b -separate +channel -scale 1x1 -format "%[pixel:u.p{0,0}]\n" info:

convert image -colorspace LAB -channel r -separate +channel -scale 1x1 -format "%[pixel:u.p{0,0}]\n" info:


Извините, я не знаю Imagick, но см.

http://us3.php.net/manual/en/imagick.scaleimage.php

http://us3.php.net/manual/en/imagick.getimagepixelcolor.php

http://us3.php.net/manual/en/imagick.transformimagecolorspace.php

http://us3.php.net/manual/en/imagick.getimagechannelstatistics.php

или, возможно,

http://us3.php.net/manual/en/imagick.getimageproperty.php

Возможно, эксперт Imagick будет достаточно любезен, чтобы преобразовать одну из этих команд из командной строки в код Imagick.

person fmw42    schedule 13.07.2018

Кэшируйте значения, если используете их более одного раза, потому что это не быстрое решение. Сначала я попытался изменить размер изображения до 1x1 пиксель с помощью imagick, но результаты были не очень хорошими. Лучшие результаты я получил без изменения размера imagick, но он очень медленный с большими изображениями. Размер примера изменяется до 1000x1000 пикселей. Имейте в виду, что этот пример не охватывает изображения с альфа-каналом.

function getImageBrightness( $path )
{
    $width  = 1000;
    $height = 1000;

    try
    {
        $imagick = new imagick( $path );
        $imagick->resizeImage( $width, $height );

        $_brightness = 0;

        for( $i=0; $i < $width; $i++ )
            for( $j=0; $j < $height; $j++ )
                if( $pixel = $imagick->getImagePixelColor($i, $j) )
                    if( $colors = $pixel->getColor() AND isset($colors['r']) )
                    {
                        $brightness = ($colors['r'] + $colors['g'] + $colors['b']) / (3* 255);

                        $_brightness = $brightness + $_brightness;
                    }

        $_brightness = $_brightness / ( $height * $width );

        return $_brightness; // from 0 (black) to 1 (white)

    } catch( ImagickException $e )
    {}

    return 0.5;  // default
}
person Torben    schedule 13.07.2018

Imagick имеет функцию гистограммы для возврата цветов по количеству. Вы можете быстрее усреднять одну и ту же информацию без обработки попиксельно.

Производительность будет зависеть от количества цветов в изображении/гистограмме (например, одноцветное изображение будет очень быстрым).

<?php

$image = new Imagick('image.jpg');
$pixels = $image->getImageHistogram();  // Generate histogram of colors

$sumbright = 0;  // sum of brightness values
$cntbright = 0;  // count of pixels

foreach($pixels as $p){
  $color = $p->getColor();  // Get rbg pixel color
  $cnt = $p->getColorCount();  // Get number of pixels with above color

  $sumbright += (($color['r'] + $color['g'] + $color['b']) / (3*255)) * $cnt;  // Calculate 0.0 - 1.0 value of brightness (0=rgb[0] 1=rgb[255])

  $cntbright += $cnt;
}

$avgbright = $sumbright / $cntbright;  // Average 0-1 brightness of all pixels in the histogram

?>
person CPG    schedule 20.08.2020