Как проверить, является ли изображение уменьшенной версией другого изображения - PullRequest
4 голосов
/ 06 августа 2010

Я ищу ЛЕГКИЙ способ проверить, является ли изображение уменьшенной версией другого изображения. Оно не должно быть очень быстрым, оно должно быть «довольно» точным. И написано в .NET. И бесплатно.

Я знаю, желаемое за действительное: -)

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

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

Любая библиотека приходит в голову? Еще в университете у нас было несколько классов MPEG7, поэтому я думаю об использовании комбинации «статистики», такой как распределение тонов, яркость и т. Д.

Есть идеи или ссылки на эту тему?

Спасибо, Chris

Ответы [ 7 ]

3 голосов
/ 25 апреля 2013

Я думаю, это будет вашим лучшим решением.Сначала проверьте соотношение сторон.Затем масштабируйте изображения до меньшего из 2, если они не одинакового размера.Наконец, сделайте сравнение хеша из 2 изображений.Это намного быстрее, чем сравнение пикселей.Я нашел метод сравнения хешей в посте от кого-то другого и просто приспособил ответ здесь, чтобы соответствовать.Я пытался придумать лучший способ сделать это сам для проекта, в котором мне нужно будет сравнить более 5200 изображений.Прочитав несколько постов здесь, я понял, что у меня уже есть все необходимое для этого, и решил, что поделюсь.

public class CompareImages2
    {
        public enum CompareResult
        {
            ciCompareOk,
            ciPixelMismatch,
            ciAspectMismatch
        };

        public static CompareResult Compare(Bitmap bmp1, Bitmap bmp2)
        {
            CompareResult cr = CompareResult.ciCompareOk;

            //Test to see if we have the same size of image
            if (bmp1.Size.Height / bmp1.Size.Width == bmp2.Size.Height / bmp2.Size.Width)
            {
                if (bmp1.Size != bmp2.Size)
                {
                    if (bmp1.Size.Height > bmp2.Size.Height)
                    {
                        bmp1 = (new Bitmap(bmp1, bmp2.Size));
                    }
                    else if (bmp1.Size.Height < bmp2.Size.Height)
                    {
                        bmp2 = (new Bitmap(bmp2, bmp1.Size));
                    }
                }

                //Convert each image to a byte array
                System.Drawing.ImageConverter ic = new System.Drawing.ImageConverter();
                byte[] btImage1 = new byte[1];
                btImage1 = (byte[])ic.ConvertTo(bmp1, btImage1.GetType());
                byte[] btImage2 = new byte[1];
                btImage2 = (byte[])ic.ConvertTo(bmp2, btImage2.GetType());

                //Compute a hash for each image
                SHA256Managed shaM = new SHA256Managed();
                byte[] hash1 = shaM.ComputeHash(btImage1);
                byte[] hash2 = shaM.ComputeHash(btImage2);

                //Compare the hash values
                for (int i = 0; i < hash1.Length && i < hash2.Length && cr == CompareResult.ciCompareOk; i++)
                {
                    if (hash1[i] != hash2[i])
                        cr = CompareResult.ciPixelMismatch;

                }
            }
            else cr = CompareResult.ciAspectMismatch;
            return cr;
        }
    }
1 голос
/ 06 августа 2010

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

Затем можно установитьпорог для определения того, насколько близко вы должны быть, чтобы считать его совпадением, например, если 95% + пикселей находятся в пределах 5% значения цвета, у вас есть совпадение.

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

1 голос
/ 06 августа 2010

Одна идея для достижения этой цели:

Если изображение имеет размер 10x10, а ваш оригинал имеет размер 40x40

Зациклите каждый пиксель в 10x10, а затем извлеките 4 пикселя, представляющих этот зацикленный пиксель.

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

Затем можно взять средний цвет 4 пикселей и сравнить с пикселем.в меньшем изображении.Вы можете указать границы ошибок, IE -10% или + 10% границы считаются совпадением, другие считаются ошибками.

Создайте количество совпадений и отказов и используйте границы, чтобы определить, считается ли этосовпадение или нет.

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

0 голосов
/ 06 августа 2010

Не имея абсолютно никаких полномочий или опыта в этой области, я попытаюсь помочь вам.

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

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

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

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

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

Я знаю, что Microsoft (Photosynth) использует фильтры типа «контур» (что-то вроде Photoshop), чтобы удалять цвета изображения и оставлять только квадратные линии, которые оставляют только «компоненты» изображения для сопоставления (они соответствуют границам и пересекаться).

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

Процесс вкратце:

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

0 голосов
/ 06 августа 2010

Я бы сказал примерно то, что Том Гуллен, за исключением того, что я просто уменьшил бы большее изображение до меньшего, прежде чем сравнивать (иначе у вас просто будет сложная математика, если вы сравниваете 25x25 с 30x30 или чем-то еще).

Другая вещь, которую я мог бы рассмотреть в зависимости от размеров изображения, - это уменьшить их оба до меньшего изображения.т. е. если у вас есть один размером 4000x4000, а другой - 3000x3000, то вы можете уменьшить их оба до 200x200 и сравнить их с этим размером.

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

0 голосов
/ 06 августа 2010

Самый простой способ - просто увеличить самое большое изображение до меньшего размера и сравнить разницу в цвете.Поскольку вы не знаете, является ли масштабирование кубическим или линейным (или что-то еще), вы должны принять небольшую разницу.

Не забудьте взять абсолютное значение разности каждого пикселя.;)

0 голосов
/ 06 августа 2010

Вам придется перебирать пиксели в той или иной точке.Что-то, что легко реализовать, но достаточно эффективно, - это рассчитать разницу между отдельными компонентами цвета (RGB) для каждого пикселя, найти среднее значение и посмотреть, пересекает ли оно определенный порог.Это, конечно, не лучший метод, но для быстрой проверки он должен подойти.

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