Идентификация 2 тех же изображений с помощью Java

Функции обычно относятся к процедурному программированию. В ООП у вас есть методы, которые на самом деле являются функциями по своей природе, работают так же, как функции, но они всегда работают по отношению к некоторому объекту. Вы не можете объявить метод / функцию, не создав для нее класс, аналогично, вы всегда должны вызывать функции, используя их объект. Таким образом, подход к созданию функций и простому вызову их в OOP не работает одинаково. Вы должны связать их с классом здесь и обычно с конструктором для этого класса.

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

int add(int a, int b){
    return a+b;
}

Теперь для Java метод в ООП выглядит следующим образом,

class NumberAdder{
    int num1;
    int num2;
    NumberAdder(int num1, int num2){
        this.num1=num1;
        this.num2=num2;
    }
    public int getSum(){
        return num1+num2;
    }
}
10
задан starblue 26 March 2009 в 06:48
поделиться

8 ответов

Я сделал что-то очень похожее на это прежде в Java, и я нашел, что класс PixelGrabber в java.awt.image пакете API чрезвычайно полезен (если не совершенно необходимый).

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

При обнаружении подобия необходимо использовать некоторую форму метода усреднения, как упомянуто в ответе на этот вопрос

Если Вы можете, также проверить Объем 2 главы 7 Базового Java Horstman (8-й редактор), потому что существует целый набор примеров на преобразованиях изображений и т.п., но снова, удостоверьтесь, что ввели по абсолютному адресу вокруг java.awt.image пакета, потому что необходимо найти, что у Вас есть почти все подготовленное к Вам :)

G'luck!

8
ответ дан 3 December 2019 в 18:00
поделиться

Вы могли также генерировать подпись MD5 файла и проигнорировать дублирующиеся записи. Не поможет Вам найти подобные изображения все же.

2
ответ дан 3 December 2019 в 18:00
поделиться

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

Если, конечно, Вы не интересуетесь идентификацией подобных изображений также.

1
ответ дан 3 December 2019 в 18:00
поделиться

В зависимости от того, как подробный Вы хотите добраться с ним:

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

Независимо от того, если Вы хотите сделать все это, или не Вы должны:

  • загрузите изображения
  • сделайте сравнение байта байтом изображений

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

5
ответ дан 3 December 2019 в 18:00
поделиться

вычислите MD5s с помощью чего-то вроде этого:

MessageDigest m=MessageDigest.getInstance("MD5");
m.update(image.getBytes(),0,image.length());
System.out.println("MD5: "+new BigInteger(1,m.digest()).toString(16));

Поместите их в hashmap.

1
ответ дан 3 December 2019 в 18:00
поделиться

Хеширование уже предлагается и распознающий, идентичны ли два файла, очень легко, но Вы сказали пиксельный уровень. Если Вы хотите распознать два изображения, даже если они находятся в различных форматах (.png/.jpg/.gif/..) и даже если они масштабировались, я предлагаю: (использование библиотеки изображений и если изображение является средними/большими значками № 16x16):

  1. масштабируйте изображение к некоторому фиксированному размеру, оно зависит от образцов
  2. преобразуйте его к шкале полутонов с помощью преобразования RGB-YUV для примера и беря Y оттуда (очень легкие) 3 Делают расстояние Хемминга каждого изображения и устанавливают порог, чтобы решить, являются ли они тем же или нет.

Вы сделаете сумму различия всех серых пикселей обоих изображений, Вы получаете число, если различие <T, Вы считаете оба изображения идентичными

--

0
ответ дан 3 December 2019 в 18:00
поделиться

Посмотрите на класс MessageDigest. По существу Вы создаете экземпляр его, затем передаете его ряд байтов. Байты могли быть байтами, непосредственно загруженными из URL, если Вы знаете, что два изображения, которые являются "тем же", будут тем же самым файлом/потоком байтов. Или при необходимости, Вы могли создать BufferedImage из потока, затем вытащить пиксельные значения, что-то как:

  MessageDigest md = MessageDigest.getInstance("MD5");
  ByteBuffer bb = ByteBuffer.allocate(4 * bimg.getWidth());
  for (int y = bimg.getHeight()-1; y >= 0; y--) {
    bb.clear();
    for (int x = bimg.getWidth()-1; x >= 0; x--) {
      bb.putInt(bimg.getRGB(x, y));
    }
    md.update(bb.array());
  }
  byte[] digBytes = md.digest();

Так или иначе MessageDigest.digest () в конечном счете дает Вам массив байтов, который является "подписью" изображения. Вы могли преобразовать это в шестнадцатеричную строку, если это полезно, например, для включения HashMap или таблицы базы данных, например:

StringBuilder sb = new StringBuilder();
for (byte b : digBytes) {
  sb.append(String.format("%02X", b & 0xff));
}
String signature = sb.toString();

Если содержание/изображение от двух URL дает Вам ту же подпись, то они - то же изображение.

Править: Я забыл упоминать, что при хешировании пиксельных значений Вы, вероятно, хотели бы включать размеры изображения в хеше также. (Только к подобной вещи - пишут два ints в 8-байтовый ByteBuffer, затем обновляют MessageDigest с соответствующим 8 массивами байтов.)

Другая вещь состоит в том, что кто-то упомянул, то, что MD5 не является коллизией-resistent. Другими словами, существует техника для построения нескольких последовательностей байта с тем же хешем MD5, не имея необходимость использовать метод проб и ошибок "грубой силы" (где в среднем, Вы ожидали бы должными быть пробовать о 2^64 или 16 миллиардов миллиардов файлов прежде, чем совершить нападки на коллизии). Это делает MD5 неподходящий, где Вы пытаетесь защитить от этой модели угрозы. Если Вы не обеспокоены случаем, где кто-то мог бы сознательно попытаться одурачить Вашу дублирующуюся идентификацию, и Вы просто взволнованы по поводу возможностей дублирующегося хеша "случайно", то MD5 прекрасен абсолютно. На самом деле это не прекрасно только, это на самом деле немного чрезмерно - как я говорю, в среднем, Вы ожидали бы один "ложный дубликат" приблизительно после 16 миллиардов миллиардов файлов. Или помещенный иначе, у Вас мог быть, скажем, миллиард файлов и шанс коллизии быть чрезвычайно близко к нулю.

Если Вы волнуетесь по поводу обрисованной в общих чертах модели угрозы (т.е. Вы думаете, что кто-то мог бы сознательно выделять процессорное время построению файлов для одурачивания системы), то решение состоит в том, чтобы использовать более сильный хеш. Java поддерживает SHA1 из поля (просто заменяют "MD5" "SHA1"). Это теперь даст Вам, более длинные хеши (160 битов вместо 128 битов), но с современными знаниями делает нахождение коллизии неосуществимым.

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

4
ответ дан 3 December 2019 в 18:00
поделиться

Осмотрите заголовки ответа и опросите значение Завершающего тега HTTP-заголовка, если существующий. (RFC2616: Завершающий тег) Они, возможно, то же для идентичных изображений, прибывающих из Вашего целевого веб-сервера. Это вызвано тем, что значение Завершающего тега часто является дайджестом сообщения как MD5, который позволил бы Вам использовать в своих интересах уже завершенные вычисления веб-сервера.

Это может потенциально позволить Вам даже не загружать изображение!

for each imageUrl in myList
    Perform HTTP HEAD imageUrl
    Pull ETag value from request
    If ETag is in my map of known ETags
       move on to next image
    Else
       Download image
       Store ETag in map

Конечно, Завершающий тег должен присутствовать, и в противном случае хорошо идея является тостом. Но возможно у Вас есть получение по запросу с администраторами веб-сервера?

0
ответ дан 3 December 2019 в 18:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: