Я пытаюсь предотвратить дублирование изображений в моей системе. Но мне нужно сверить каждое входящее изображение со всеми существующими. Так что это не проверка на сходство 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
Обнаружение почти повторяющихся изображений в Java. Проблемы с производительностью ⇐ JAVA
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Обнаружение того, что заданный элемент был удален из DOM, не жертвуя производительностью
Anonymous » » в форуме Html - 0 Ответы
- 6 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Как проверить количество повторяющихся строк в файле .txt с помощью Regex в Java?
Anonymous » » в форуме JAVA - 0 Ответы
- 172 Просмотры
-
Последнее сообщение Anonymous
-