Обнаружение почти повторяющихся изображений в Java. Проблемы с производительностьюJAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Обнаружение почти повторяющихся изображений в Java. Проблемы с производительностью

Сообщение Anonymous »

Я пытаюсь предотвратить дублирование изображений в моей системе. Но мне нужно сверить каждое входящее изображение со всеми существующими. Так что это не проверка на сходство 1-1. А иногда изображения не одинаковые, а почти идентичные. Например, посмотрите эти два изображения (обратите внимание на небольшую разницу в яркости): Поэтому я попытался сгенерировать хеш из изображение, которое хранится в базе данных, и каждое входящее изображение проверяется по базе данных.
Я реализовал решение на Java, которое работает нормально, но потребляет слишком много ресурсов ЦП. Я запускаю его на дроплете с 8 процессорами, и ожидаемая скорость обработки составляет 100 запросов в секунду. Но текущее решение достигает 100% загрузки ЦП с частотой 30-40 запросов в секунду и неприемлемо.
Есть ли у вас какие-либо предложения по более простому процессу или мне следует создать отдельный сервис на Python для обработки хеш изображения?
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import javax.imageio.ImageIO;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ImageUtil {
private static final int HASH_SIZE = 16;
private static final int INNER_SIZE = 8;
private static final int OFFSET = 4;

public static List computeHashesBatch(List urls) {
return urls.parallelStream()
.map(url -> {
try {
return new ImageHash(url, computePerceptualHash(url));
} catch (IOException e) {
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
}

public static String computePerceptualHash(String url) throws IOException {
BufferedImage img = ImageIO.read(URI.create(url).toURL());
if (img == null) {
return null;
}
String hash = computeHashFromImage(img);
return String.format("%s%s%s-%s", img.getType(), img.getWidth(), img.getHeight(), hash);
}

private static String computeHashFromImage(BufferedImage img) {
// Convert and resize
BufferedImage processed = new BufferedImage(HASH_SIZE, HASH_SIZE, BufferedImage.TYPE_BYTE_GRAY);
Graphics2D g = processed.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(img, 0, 0, HASH_SIZE, HASH_SIZE, null);
g.dispose();

byte[] pixels = ((DataBufferByte) processed.getRaster().getDataBuffer()).getData();
char[] hashBits = new char[INNER_SIZE * INNER_SIZE];
int hashIdx = 0;
long totalGradient = 0;

for (int y = OFFSET; y < OFFSET + INNER_SIZE; y++) {
int rowOffset = y * HASH_SIZE;
for (int x = OFFSET; x < OFFSET + INNER_SIZE; x++) {
int idx = rowOffset + x;
int gx = (pixels[idx + 1] & 0xFF) - (pixels[idx - 1] & 0xFF);
int gy = (pixels[idx + HASH_SIZE] & 0xFF) - (pixels[idx - HASH_SIZE] & 0xFF);
int gradient = Math.abs(gx) + Math.abs(gy);
totalGradient += gradient;
hashBits[hashIdx++] = (char) gradient;
}
}

int avgGradient = (int) (totalGradient / (INNER_SIZE * INNER_SIZE));
StringBuilder result = new StringBuilder(16);
int accumulator = 0;
int bitCount = 0;

for (char hashBit : hashBits) {
accumulator = (accumulator avgGradient ? 1 : 0);
bitCount++;

if (bitCount == 4) {
result.append(Integer.toHexString(accumulator));
accumulator = 0;
bitCount = 0;
}
}

if (bitCount > 0) {
accumulator

Подробнее здесь: https://stackoverflow.com/questions/793 ... e-problems
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»