Классификация изображений - обнаружение изображения похоже на мультфильм - PullRequest
5 голосов
/ 05 октября 2009

У меня есть большое количество миниатюрных изображений JPEG размером от 120x90 до 320x240, и я хотел бы классифицировать их как реальные или как мультфильм.

Как можно это сделать с помощью ImageMagick утилит: convert, compare, identify? Или есть другие программы, которые помогут?

Ответы [ 4 ]

16 голосов
/ 05 октября 2009

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

Вы можете использовать

COLORS=`convert picture.jpg  -format %c histogram:info:- | wc -l`

для подсчета количества цветов на картинке. И используйте команду вроде:

WIDTH=`jpeginfo picture.jpg | sed -r "s/.* ([0-9]+) x.*/\1/"`

и

HEIGHT=`jpeginfo picture.jpg | sed -r 's/.*x ([0-9]+)  .*/\1/'`

для извлечения ширины и высоты.

Затем используйте эту команду, чтобы найти соотношение:

echo $WIDTH $HEIGHT $COLORS | awk '{ print $3/($1 * $2);}'

Тогда вам решать, какое соотношение квалифицируется как мультипликационное, а какое нет. Для мультяшного типа это соотношение в основном ниже, чем в реальном.

Просто мысль.

РЕДАКТИРОВАТЬ: Я только что видел ваш комментарий, что вы не хотите знать, как просто выход. Поэтому просто проигнорируйте мой ответ.

РЕДАКТИРОВАТЬ 2: Я немного изменяю его, чтобы было легче видеть.

ПРИМЕЧАНИЕ 1: Вы должны заметить, что я меняю соотношение, так как количество пикселей всегда намного больше количества цветов, поэтому предыдущая программа приводит к меньшее число. Вот почему их трудно различить.

ПРИМЕЧАНИЕ2: Я также изменяю с "jpeginfo" на "identity", поскольку jpeginfo может выполнять только jpg и не является частью ImageMagick.

~ / тест / CheckCartoon.sh

<code>#!/bin/sh</p>

<p>IMAGE=$1
COLORS=<code>convert $IMAGE -format %c histogram:info:- | wc -l</code>
WIDTH=<code><b>identify</b> $IMAGE | sed -r "s/.* ([0-9]+)x[0-9]+ .*/\1/"</code>
HEIGHT=<code><b>identify</b> $IMAGE | sed -r 's/.* [0-9]+x([0-9]+) .*/\1/'</code>
RATIO=<code>echo $WIDTH $HEIGHT $COLORS | awk '{ print <b>($1 * $2)/$3</b>;}'</code>
echo $RATIO  | awk '{ printf "%020.5f",$1 }'

~ / тест / CheckAll.sh

#!/bin/sh</p>

<p>cd images
FILES=<code>ls</code>
for FILE in $FILES; do
    IsIMAGE=<code>identify $FILE 2>&1 | grep " no decode delegate " | grep -o "no"</code>
    if [ "$IsIMAGE" = "no" ]; then continue; fi</p>

<pre><code>IsIMAGE=`identify $FILE 2>&1 | grep " Improper image header " | grep -o "Improper"`
if [ "$IsIMAGE" = "Improper" ]; then continue; fi

echo `.././CheckCartoon.sh $FILE` $FILE

сделано

кд ..

Теперь для тестирования скопируйте файлы здесь.

Рис 1: ~ / test / images / Cartoon-01.jpg

Рисунок 2: ~ / test / images / Cartoon-02.png

Рис. 3: ~ / test / images / Cartoon-03.gif

Рис. 4: ~ / test / images / Real-01.jpg

Рис. 5: ~ / test / images / Real-02.jpg

Рис 6: ~ / test / images / Real-03.jpg

http://dl.getdropbox.com/u/1961549/StackOverflow/SO1518347/Images.png

Затем я запускаю ./CheckAll.sh | sort (в папке test). Вот хочу меня достать.

00000000000003.31362 Real-03.jpg
00000000000004.61574 Real-02.jpg
00000000000009.89920 Cartoon-01.jpg
00000000000013.05870 Real-01.jpg
00000000000020.55470 Cartoon-03.gif
00000000000032.21900 Cartoon-02.png

Как видите, результат в целом хороший. Вы можете использовать число как 15 как разделение.

Cartoon-01.jpg - рисунок, но выглядит он довольно реалистично, поэтому его легко спутать. Также Real-01.jpg - изображение моей подруги, стоящей перед океаном, поэтому количество цветов меньше обычного. Это неудивительно, почему возникает путаница.

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

Надеюсь, это поможет.

11 голосов
/ 05 октября 2009

В теории:

Один из способов различить изображения мультфильмов и естественных сцен - сравнить данное изображение с его "сглаженным" я . Мотивация этого заключается в том, что «сглаженное» мультипликационное изображение статистически будет не сильно меняться, тогда как в качестве естественного изображения сцены будет . Другими словами, возьмите изображение, карикатурируйте (т.е. сгладьте) его и вычтите результат из оригинала :

isNotACartoonIndex = mean( originalImage - smooth(originalImage) )

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

В SO вопросе уже обсуждается, как карикатурировать изображения .

На практике:

Я бы предложил выполнить сглаживание / карикатуру с помощью двусторонней фильтрации : Original Filtered

Двустороннюю фильтрацию можно выполнить с помощью OpenCV с использованием функции cvSmooth с параметром CV_BILATERAL .

Что касается вычитания мультяшного изображения из оригинала, я бы сделал это с каналом Хюэ изображений HSV. Это означает, что вам нужно сначала преобразовать оба изображения из RGB в HSV.

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

5 голосов
/ 08 декабря 2009

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

Это похоже на то, что предложил NawaMan, но этот метод идет еще дальше. Количество цветов по количеству пикселей может быть недостаточно. Например, могут быть артефакты JPEG, которые искусственно увеличивают количество цветов в изображении, но только на несколько пикселей. В этом случае большинство пикселей на изображении будет иметь очень мало цветов, что соответствует низкой энтропии.

Допустим, вы начинаете с изображения RGB. Для каждого пикселя значения R, G и B находятся в диапазоне от 0 до 255.
Вы можете разделить этот диапазон на n бинов, где n может быть 16, например. Вы бы посчитали, сколько пикселей попадает в каждый из этих 3-мерных контейнеров. Тогда вам нужно будет разделить значения бункеров на общее количество пикселей, так что ваша гистограмма суммирует до 1. Затем вычислите энтропию, которая is - sum_i p_i * log (p_i), где p_i - значение i-го бина.

Попробуйте это с другими значениями для n, и посмотрите, можете ли вы отделить реальные изображения от мультфильмов.

0 голосов
/ 05 октября 2009

Это проблема классификации изображений, которую AFAIK ImageMagick сможет НЕ решить.

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

...