Проверьте последовательность изображений - PullRequest
5 голосов
/ 21 октября 2010

Проблема

Формирование проблемы

Последовательность изображения позиция и размер фиксированы и известны заранее (это не масштабируется ).Это будет довольно коротко, максимум 20 кадров и в замкнутом цикле.Я хочу проверить (событие, вызванное нажатием кнопки), что я видел это раньше.

Допустим, у меня есть некоторая последовательность изображений, например:

http://img514.imageshack.us/img514/5440/60372aeba8595eda.gif

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

Ограничения и использование

Я не пытаюсь воссоздать обнаружение авторских правсистема, подобная системе идентификации контента, реализованной на Youtube (Маргарет Гулд Стюарт из TED ( ссылка )).Последовательность изображений можно представить как файл (.gif), но это не так, и нет прямого способа получить двоичный файл.Подобный метод может быть использован, чтобы избежать дубликатов в «базе данных обмена изображениями», но это не то, что я пытаюсь сделать.

Мои усилия

Размытие по Гауссу

MathematicaФункция для генерации ядер размытия по Гауссу:

getKernel[L_] := Transpose[{L}].{L}/(Total[Total[Transpose[{L}].{L}]])
getVKernel[L_] := L/Total[L]

alt textalt textalt text
Оказывается, гораздо эффективнее использовать 2 прохода векторного ядра, чем ядра матрицы.Они основаны на Треугольник Паскаля неровных строках:

{1d/4, 1d/2, 1d/4}
{1d/16, 1d/4, 3d/8, 1d/4, 1d/16}
{1d/64, 3d/32, 15d/64, 5d/16, 15d/64, 3d/32, 1d/64}

Ввод данных, хэширование, масштабирование серого и лайтбокс

Пример исходных битов, которые могут быть полезны:

  • Лайтбокс вокруг известного прямоугольника: FrameX
  • Использование MD5CryptoServiceProvider для получения хеша md5 содержимого внутри известного прямоугольника atm.
  • Использование ColorMatrix для изображения в градациях серого

Исходный пример

Исходный пример ( GUI ; code ):

Получить текущее содержимое внутри определенного прямоугольника.

        private Bitmap getContentBitmap() {
            Rectangle r = f.r;
            Bitmap hc = new Bitmap(r.Width, r.Height);
            using (Graphics gf = Graphics.FromImage(hc)) {
                gf.CopyFromScreen(r.Left, r.Top, 0, 0, //
                    new Size(r.Width, r.Height), CopyPixelOperation.SourceCopy);
            }
            return hc;
        }

Получить md5 хэш растрового изображения.

        private byte[] getBitmapHash(Bitmap hc) {
            return md5.ComputeHash(c.ConvertTo(hc, typeof(byte[])) as byte[]);
        }

Получить оттенки серого изображения.

        public static Bitmap getGrayscale(Bitmap hc){
            Bitmap result = new Bitmap(hc.Width, hc.Height);
            ColorMatrix colorMatrix = new ColorMatrix(new float[][]{   
                new float[]{0.5f,0.5f,0.5f,0,0}, new float[]{0.5f,0.5f,0.5f,0,0},
                new float[]{0.5f,0.5f,0.5f,0,0}, new float[]{0,0,0,1,0,0},
                new float[]{0,0,0,0,1,0}, new float[]{0,0,0,0,0,1}});

            using (Graphics g = Graphics.FromImage(result)) {
                ImageAttributes attributes = new ImageAttributes();
                attributes.SetColorMatrix(colorMatrix);
                g.DrawImage(hc, new Rectangle(0, 0, hc.Width, hc.Height),
                   0, 0, hc.Width, hc.Height, GraphicsUnit.Pixel, attributes);
            }
            return result;
        }

Ответы [ 4 ]

3 голосов
/ 23 октября 2010

Я думаю, у вас есть несколько проблем с этим:

  1. Не все последовательности изображений [видео] одинаковы [но многие похожи]
  2. Откуда поступают ваши данные?
  3. Как вы будете представлять данные, относящиеся к вашим просмотрам?
  4. Размер данных

Выпуск № 1:

Многие изображения могут незначительно отличаться по сжатию, маркировке водой, отсутствию кадров и добавлению клипов.Я бы предложил попробовать видео.Например, вы можете рассмотреть возможность подвыборки небольших фрагментов изображений в видео.Кроме того, чтобы избежать шумных изображений и проблем с алгоритмами сжатия.Возможно, вы захотите рассмотреть оттенки серого для выбранных кадров и сделать размытие по Гауссу.[Guassian, потому что это «более естественно» (краткий ответ)] Как только у вас будет достаточно сэмплов, где у вас будет уверенность в сходстве с видео, сохраните его в базе данных.С примерами вы можете их хешировать или сохранить для последующего сходства в%.

Issue # 2

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

Issue # 3

Использование чего-то вроде Postgres [если есть много крупных объектов] или SQLLite настоятельно рекомендуется для индексации, хранения и вызова прошлых метаданных.

Выпуск № 4

Размер данных будет иметь огромное значение при отзыве, выборке, запросах к базе данных и т. Д.

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

Также обратите внимание на алгоритмы Computer Vision для получения дополнительной информации о представлении / вызове объекта.

2 голосов
/ 26 октября 2010

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

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

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

Если вы хотите сопоставить очень похожие, но не идентичные видео, и не хотите идтинаучный маршрут ультра-робуса, тогда я бы предложил следующий процесс:

  1. Сделайте размытие по Гауссу, которое вы уже делаете.
  2. Разделите каждое изображение нак нескольким прямоугольникам одинакового размера (вам нужно проверить на лучшее число, но я бы посоветовал вам начать с 9.
  3. Для каждого прямоугольника в каждом кадре вычислите полноцветную гистограмму, затем найдитесамый встречающийся цвет в этом прямоугольнике.Это дает вам 9 * 20 = 180 номеров.Это «отпечаток» этого фильма.
  4. Найдите наиболее похожий отпечаток в вашей базе данных, если он достаточно похож, вы уже знаете об этом, в противном случае - нет.

Шаг 4 немного расплывчатый, потому что я не очень в этой области.В настоящее время вы используете хеш-код MD5 в качестве своего рода отпечатка пальца, но в этом случае это неприемлемо, поскольку небольшие различия во входных данных хорошей криптографической функции хеширования приводят к очень большим различиям в хэше.Это будет означать, что два очень похожих кадра будут иметь совершенно другой хэш MD5, поэтому из хеша вы никогда не узнаете, что они похожи.

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

2 голосов
/ 23 октября 2010

Сам вопрос, безусловно, очень интересный и сложный, однако, как утверждает @ monksy, есть много практических вопросов.

Прагматик-оппортунист во мне сделал бы шаг назад, посмотрел на общую картину и увидел бы, есть ли другой способ решить проблему. Например, если вы создаете какое-то «сообщество по обмену изображениями» и хотите избежать дублирования в базе данных, вы можете сделать простой md5 для файла (анимированные GIF-файлы в Интернете, как правило, всегда одинаковы, люди редко изменяют их).

Еще один пример: если вы анализируете научные образцы (например, метео-последовательности), может быть проще встроить какой-либо хэш в каждый файл при их генерации.

1 голос
/ 21 октября 2010

Возможно, вы сможете найти способ получить двоичную копию данных изображения каждого кадра в переменной. Хешируйте эти данные (md5?) И сохраняйте каждый из хэшей. Тогда вы можете увидеть, видели ли вы когда-нибудь этот хеш раньше. Если нет, это новый кадр.

...