Подтвердить что ты не робот

Как я могу различать графику и фотографии?

У меня есть каталог изображений, фотографий, веб-графики, логотипов и т.д.... все они вытащены из Интернета. Существуют файлы .jpg,.gif и .png.

Я хотел бы извлечь изображения, которые имеют реальные вещи (сохранить фотографии и удалить графику). Я не пытаюсь получить фактические/оригинальные фотографии, просто изображения реальной жизни и компьютерной графики (я не уверен, как сказать это более четко). Почти все эти изображения были обработаны, и информация exif будет недоступна.

Допустим большой (даже очень большой) погрешность.

Я уже:

  • удаленные изображения с низким количеством цветов с помощью imagecolorstotal()
  • удаленные изображения, которые имеют большие отношения высоты к ширине, и наоборот (соотношение 3+ работает потрясающе хорошо).
  • удаленные изображения, которые меньше определенного размера (50-75 пикселей хороши)

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

Как еще я могу улучшить эту фильтрацию изображений для извлечения (в основном) реальных фотографий? Я бы предпочел использовать PHP, но это не требуется.

ОБНОВЛЕНИЕ: Оказывается, что для моего приложения первые три вещи, которые я уже пробовал, были твердым 80% -ным решением. Дальнейшая фильтрация может быть выполнена с использованием некоторых из приведенных ниже ответов.

4b9b3361

Ответ 1

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

Я использовал IMagick (оболочка PHP для ImageMagick), чтобы выполнить работу при расчете следующих атрибутов изображения:

$Image      = new Imagick( $image_path );
$height     = $Image->getImageHeight();
$width      = $Image->getImageWidth();
$histogram  = $Image->getImageHistogram();              
$num_colors = $image->getImageColors();

Отношение высоты к ширине

Фильтрация изображений по соотношению высоты и ширины исключает большой процент нежелательной информации. Чем ближе установить фильтр к 1:1, тем лучше работает этот фильтр, но вы также начнете фильтровать множество хороших изображений. Это один из самых ценных фильтров, который я применил:

// max height to width ratio we allow on images before we junk them
$max_size_ratio = 3;
if( $size_ratio > $max_size_ratio )
    throw new Exception( "image height to width ratio exceeded max of $max_size_ratio" );

Число цветов

Фильтрация изображений ниже 32 цветов обычно удаляет только нежелательные изображения, однако я также потерял много черно-белых диаграмм и рисунков.

// min number of colors allowed before junking
$min_colors = 32;
if( $num_colors < $min_colors )
    throw new Exception( "image had less than $min_colors colors" );

Минимальная высота и ширина

Фильтрация изображений на основе абсолютной минимальной высоты и ширины, которые должны пройти оба измерения, а также несколько большее значение, которое должно пройти по крайней мере одно измерение, помогло фильтровать некоторые нежелательные сообщения.

// min height and width in pixels both dimensions must meet
$min_height_single = 50;
$min_width_single  = 50;
if(
    $width < $min_width_single
    OR $height < $min_height_single
)
    throw new Exception( "height or width were smaller than absolute minimum" );

// min height and width in pixels at least one dimension must meet
$min_height = 75;
$min_width  = 75;
if(
    $width < $min_width
    && $height < $min_height
)
    throw new Exception( "height and width were both smaller than minimum combo" );

Энтропия цвета изображения с использованием гистограммы изображения

Наконец, я вычисляю энтропию цвета изображения (как предложил @Jason в его ответе) для каждого изображения в моей системе. Когда я выбираю изображения для отображения, я обычно заказываю их, оценивая эту энтропию в порядке убывания. Чем выше энтропия, тем более вероятно, что изображение должно быть фотографией реальной вещи, а не графикой. Существуют три основные проблемы с этим методом:

  • Высоко стилизованная графика имеет тенденцию иметь более высокие энтропии из-за большой глубины цвета и цветовых вариаций.

  • Фотографии, которые были сделаны на фотошопе, чтобы иметь сплошные фоны и фоновые рисунки студии, имеют тенденцию к снижению энтропии из-за доминирующего сплошного цвета.

  • Это не работает как абсолютный фильтр из-за большого различия между изображениями в моем наборе, их типами файлов, глубинами цвета и т.д. Однако, когда это чрезвычайно полезно, это выбор лучшего изображения небольшого подмножества во всем моем наборе. Примером может быть выбор изображения, которое будет отображаться в качестве основного изображения из всех изображений, найденных на одной веб-странице.

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

function set_image_entropy()
{

    // create Imagick object and get image data
    $Image = new Imagick( $this->path );
    $histogram = $Image->getImageHistogram();               
    $height = $Image->getImageHeight();
    $width = $Image->getImageWidth();
    $num_pixels = $height * $width;

    // calculate entropy for each color in the image
    foreach( $histogram as $color )
    {
        $color_count = $color->getColorCount();
        $color_percentage = $color_count / $num_pixels;
        $entropies[] = $color_percentage * log( $color_percentage, 2 );
    }

    // calculate total image color entropy
    $entropy = ( -1 ) * array_sum( $entropies );

    return $entropy;

}

Ответ 2

Функция exif_read_data может предоставлять информацию о используемых камерах, она сильно отличается для каждой камеры. Это не будет идеальным решением, но оно должно добавить к тому, что вы уже используете.

Ответ 3

Entropy будет хорошей метрикой, чтобы отличать "настоящие" фотографии от компьютерной графики. Это действительно более структурированная версия вашей идеи гистограммы. Энтропия задается

H(X) = -sum(p[i] * log2(p[i]))

где p [i] - вероятность i-го цвета. p[i] - это в значительной степени значение гистограммы для каждого цвета (в процентах (0.0- > 1.0) пикселей - цвет i). Чем более распределены цвета, тем выше будет H(X). Если пиксели распределены только по нескольким цветам, H(X) будет небольшим.

Обратите внимание, что сжатый размер файла напрямую связан с энтропией (более высокая энтропия, более высокий размер файла), поэтому предложение в другом ответе на использование файлаize может быть косвенным способом получения этого.

Ответ 4

Графика и рисование линий обычно меньше при сохранении в виде png, а при меньших размерах при сохранении в формате jpg фотография меньше. Сохраните каждое изображение в каждом формате и сделайте обоснованное предположение, основанное на размере файла.