Как я могу отличить графику от фотографий? - PullRequest
12 голосов
/ 09 августа 2011

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

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

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

Я уже:

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

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

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

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

Ответы [ 4 ]

7 голосов
/ 09 августа 2011

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

6 голосов
/ 09 августа 2011

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

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

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

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

2 голосов
/ 06 января 2012

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

Я использовал 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 в его ответе) для каждого изображения в моей системе.Когда я выбираю изображения для отображения, я обычно упорядочиваю их по этой энтропии в порядке убывания.Чем выше энтропия, тем больше вероятность, что изображение будет фотографией реальной вещи, а не графикой.У этого метода есть три основные проблемы:

  1. Из-за большой глубины цвета и вариации цвета графика с высокой степенью стилизации имеет большую энтропию.

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

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

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

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;

}
1 голос
/ 09 августа 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...