Код сравнения изображений не работает должным образом

  • Автор темы dbc-server
  • 53
  • Обновлено
  • 12, May 2024
  • #1
Я все еще новичок в программировании и столкнулся с проблемой с кодом Java.

Буду очень благодарен за предложения и комментарии.

Проблема заключается в следующем: Я нашел в Интернете Java-код, предназначенный для сравнения двух изображений и выделения различий между ними.

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

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

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

Что бы вы предложили изменить в коде? Заранее благодарим вас за помощь. Код: импортировать java.awt.image.BufferedImage; импортировать java.io.File; импортировать java.io.IOException; импортировать javax.imageio.ImageIO; общественный класс PictureOverlayTest { /*
  • Четыре переменных: три для нужных BufferedImages, одна строка для
  • Путь третьего изображения, которого еще нет.


*/ частное изображение BufferedImage1; частное изображение BufferedImage2; частное изображение BufferedImage3; частная строка pathImage3; public PictureOverlayTest (String filePathAndName1, String filePathAndName2, Строка filePathAndName3) выдает IOException { /*
  • Конструктор, чтобы этот метод можно было использовать повторно и в чистоте. Потребности
  • три струны. Пути и имена файлов всех трех изображений. Изображение 1
  • и 2 уже должны существовать, изображение 3 будет создано, если все
  • требования соблюдены. Конструктор создает первые два буферизованных
  • изображения, устанавливает все необходимые переменные и запускает функцию checkAndCompare().
  • метод


*/ Файл файл = новый файл (filePathAndName1); this.image1 = ImageIO.read(файл); файл = новый файл (filePathAndName2); this.image2 = ImageIO.read(файл); this.pathImage3 = filePathAndName3; проверитьИСравнить(); } Private void checkAndCompare() выдает IOException { /*
  • Эта функция создает синий цвет, сравнивает размеры обоих
  • изображения, и если они одинаковые, создается третье изображение. Затем это
  • циклически перебирает два изображения и сравнивает каждый пиксель. Если пиксели
  • одинаковы, третье изображение в этой точке получает синий пиксель


*/

Цвет синий = Цвет.синий;

Желтый цвет = Цвет.желтый;

если (image1.getHeight() == image2.getHeight()

& & image1.getWidth() == image2.getWidth()) {

image3 = новый BufferedImage(image1.getWidth(), image1.getHeight(),

изображение1.getType());

for (int y = 0; y < image1.getHeight(); y++) {

for (int x = 0; x < image1.getWidth(); x++) {

int colorImage1 = image1.getRGB(x, y);

int colorImage2 = image2.getRGB(x, y);

если (colorImage1 == colorImage2) {

image3.setRGB(x, y, blue.getRGB());

} еще {

image3.setRGB(x, y,жёлтый.getRGB());

// Какой бы цвет вы ни выбрали.

По умолчанию он черный. } } } сохранитьКартину3(); System.out.println("Сообщение: сравнение изображений завершено"); } еще {

System.out.println("Ошибка: размеры изображения не совпадают"); } } Private void savePicture3() выдает IOException { /*
  • Этот метод сохраняет созданное изображение в файл на вашем компьютере.
  • Оператор if() используется для проверки успешности файла.
  • создано во избежание нежелательных ошибок. Имейте в виду, что вы
  • необходимо изменить «bmp» в ImageIO.write() на любой формат, который вы хотите
  • на самом деле хочу


*/

Файл файл = новый файл (pathImage3);

если (file.createNewFile()) {

ImageIO.write(изображение3, «bmp», файл);

}

}

}

импортировать java.io.IOException;

общественный класс Main {

public static void main(String[] args) {

// TODO Автоматически сгенерированная заглушка метода

пытаться {

Тест PictureOverlayTest = новый PictureOverlayTest(

"C:\\Users\\Rabee Taha\\Desktop\\Java Test Pics\\test1.png",

"C:\\Users\\Rabee Taha\\Desktop\\Java Test Pics\\test2.png",

"C:\\Users\\Rabee Taha\\Desktop\\Java Test Pics\\test3.png");

} catch (IOException e) {

// TODO Автоматически сгенерированный блок catch

е.printStackTrace();

}

}

}

Вот ссылка на примеры изображений результата ( https://postimg.cc/gallery/rkXfPr7

)

dbc-server


Рег
27 Feb, 2011

Тем
1

Постов
2

Баллов
12
  • 19, May 2024
  • #2
«Код предназначен для сравнения двух изображений и выделения различий между ними.

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

Однако это приводит к проблеме, заключающейся в том, что даже малейшее смещение угла камеры или условий освещения между двумя изображениями приводит к разным значениям RGB пикселей, из-за чего код выделяет их как разные, даже если изображения в основном идентичны».

Код делает именно то, что должен.

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

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

vfrcbv2


Рег
04 Nov, 2011

Тем
0

Постов
2

Баллов
2
  • 09, Jun 2024
  • #3
Вместо того, чтобы делать двоичный вывод, я бы предложил использовать оттенки серого для различий между ними.

как бы тепловую карту.

Затем вы могли бы подать заявку.

использовали ли вы когда-нибудь радио CB / Ham? У них есть функция под названием «шумоподавитель», которая представляет собой ограничение уровня сигнала, предназначенное для подавления шума.

По сути, вы можете установить порог того, насколько сильно происходят изменения.

8-битная тепловая карта в оттенках серого или даже 10-битная тепловая карта RG была бы/могла бы быть гораздо более полезной, и, потеряв несколько битов, вы автоматически получите значительное уменьшение разницы, которое будет выброшено в мусор.

Java не мой конек — прошло уже полтора десятилетия с тех пор, как я писал на нем что-нибудь серьезное — но логика была бы примерно такой:

 final int

greyBitDepth = 8, // max reliable is 31 bits

greySHR = 31 - greyBitDepth,

squelch = 16, // ignore differences of 16 or less

width = image1.getWidth(),

height = image1.getHeight();

for (int y = 0; y < height; y++) {

for (int x = 0; x < width; x++) {

int

pixel1_temp = image1.getRGB(x, y),

pixel2_temp = image2.getRGB(x, y),

diff = Math.max(squelch, (

Math.abs(

(pixel1_temp & 0xFF) - (pixel2_temp & 0xFF)

) * 489626272 +

Math.abs(

((pixel1_temp >>= 8) &0xFF) - ((pixel2_temp >>= 8) & 0xFF)

) * 2521145802 +

Math.abs(

((pixel1_temp >>= 8) &0xFF) - ((pixel2_temp >>= 8) & 0xFF)

) * 1284195221

) >> greySHR);

/*

The multiplies above are the Luma component of YCrCb converted to

0..0x7FFFFFFF, allowing us to avoid expensive floating point divides

and multiplies.

*/

Color grey = new Color(diff, diff, diff);

image3.setRGB(x, y, grey.getRGB());

}

}
Код (разметка): Имейте в виду, я догадываюсь, что прошли годы.

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

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

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

huk


Рег
11 Feb, 2016

Тем
1

Постов
3

Баллов
13
Тем
49554
Комментарии
57426
Опыт
552966