Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
204 changes: 61 additions & 143 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,106 +1,56 @@
# Последовательная фильтрация изображений
# Задание 1: последовательная фильтрация цветных изображений

## Описание

В работе реализована последовательная обработка изображений в градациях серого с использованием линейной свёртки и median filter.
В проекте реализована последовательная обработка цветных RGB-изображений с использованием линейной свёртки и median filter.

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

- `identity`
- `blur3`
- `blur5`
- `gaussian3`
- `gaussian5`
- `gaussian3_exact`
- `motion9`
- `edge_horizontal5`
- `edge_vertical5`
- `edge_45deg5`
- `edge_all3`
- `sharpen3`
- `sharpen5`
- `edge_excessive3`
- `emboss3`
- `emboss5`
- `mean3`
- `median3`
- `median5`
- `median7`
- `image` — загрузка, сохранение и хранение RGB-изображения
- `filter` — последовательные фильтры, ядра свёртки и median filter
- `app` — логика командной строки

## Сборка и запуск
Изображение хранится как массив RGB-байтов: на каждый пиксель приходится 3 канала. Фильтры применяются независимо к каналам `R`, `G` и `B`, поэтому результат остаётся цветным.

### Требования
## Сборка и запуск

Для сборки и запуска проекта должны быть установлены:
Требования:

- Git
- Maven
- Java 24

Проект компилируется с настройкой `source = 22`, а замеры производительности выполнялись на Java 24.

### 1. Клонирование репозитория

Склонировать проект с GitHub:

```bash
git clone <repo_url>
```

Перейти в каталог проекта:

```bash
cd <repo_name>
```

> Вместо `<repo_url>` нужно подставить ссылку на репозиторий,
> а вместо `<repo_name>` — имя папки проекта после клонирования.

### 2. Сборка проекта

Собрать проект с помощью Maven:
Сборка:

```bash
mvn clean package
```

После успешной сборки скомпилированные `.class`-файлы будут находиться в каталоге `target/classes`.

### 3. Запуск программы

#### Применить фильтр к изображению
Применить фильтр:

```bash
java -cp target/classes Main apply <input> <output> <filterName>
java -cp target/classes app.Main apply <input> <output> <filterName>
```

Пример:

```bash
java -cp target/classes Main apply input.png output.png gaussian3
java -cp target/classes app.Main apply input.png output.png gaussian3
```

#### Замер производительности
Замер производительности:

```bash
java -cp target/classes Main benchmark <input> <filterName> <iterations>
java -cp target/classes app.Main benchmark <input> <filterName> <iterations>
```

Пример:

```bash
java -cp target/classes Main benchmark input.png gaussian3 500
java -cp target/classes app.Main benchmark input.png gaussian3 500
```

### 4. Запуск тестов

Для запуска тестов используется команда:

```bash
mvn test
```

### 5. Поддерживаемые фильтры
## Поддерживаемые фильтры

- `identity`
- `blur3`
Expand All @@ -123,102 +73,70 @@ mvn test
- `median5`
- `median7`

### Пример запуска в Windows

```bash
java -cp target/classes Main apply D:\temp\input.png D:\temp\output.png gaussian3
````

## Тестирование

Для проверки корректности реализации использовались следующие идеи:
Проверяются основные свойства реализации:

- `identity` не должен изменять изображение
- нулевое ядро должно давать полностью чёрное изображение
- размеры выходного изображения должны совпадать с размерами входного
- значения пикселей после фильтрации должны оставаться в диапазоне `0..255`
- `median` на константном изображении не должен менять результат
- `median` должен убирать одиночный импульсный шум
- для части линейных фильтров использовалось сравнение с библиотечной реализацией свёртки для внутренних пикселей изображения
- расширение ядра нулевыми коэффициентами не должно менять результат
- `identity` не меняет RGB-данные
- нулевое ядро даёт чёрное изображение
- размер результата совпадает с размером входного изображения
- длина массива равна `width * height * 3`
- значения каналов остаются в диапазоне `0..255`
- median filter не меняет константное цветное изображение
- median filter удаляет одиночный импульсный шум по каждому каналу

## Анализ производительности
Запуск тестов:

### Параметры стенда
```bash
mvn test
```

Замеры производительности выполнялись для последовательной реализации фильтрации изображений в градациях серого.
## Исследование производительности

Конфигурация стенда:
Замеры пересчитаны для цветной RGB-версии. В отличие от старой grayscale-версии, каждый пиксель обрабатывается по трём каналам.

- операционная система: Windows 11 Pro, версия 25H2, сборка 26200.8246
- процессор: 11th Gen Intel(R) Core(TM) i7-11370H @ 3.30 GHz
- оперативная память: 16 ГБ
- тип системы: 64-разрядная операционная система, процессор x64
- среда выполнения benchmark: Java 24 (`Java HotSpot(TM) 64-Bit Server VM`)
- версия компиляции проекта: Java 22
- количество запусков для каждого замера: `500`
- размеры изображений: `256x256`, `512x512`, `1024x1024`, `2048x2048`
- измеряемые фильтры: `gaussian3`, `gaussian5`, `blur5`, `sharpen3`, `motion9`, `median3`, `median5`
Параметры стенда:

Для каждого запуска использовался режим `benchmark`, который печатает время каждой итерации и итоговое среднее значение времени выполнения и пропускной способности.
### График среднего времени выполнения
- ОС: Windows 11 Pro
- CPU: 11th Gen Intel(R) Core(TM) i7-11370H @ 3.30 GHz
- RAM: 16 ГБ
- Java runtime: Java 24
- компиляция проекта: Java 22
- изображения: `256x256`, `512x512`, `1024x1024`, `2048x2048`
- фильтры: `gaussian3`, `gaussian5`, `blur5`, `sharpen3`, `motion9`, `median3`, `median5`
- количество запусков для `256x256` и `512x512`: `500`
- для `1024x1024` и `2048x2048` оставлены контрольные замеры, потому что полный RGB-прогон всех фильтров на `500` итерациях занимает слишком много времени для интерактивной проверки

![Среднее время выполнения](time.png)
### Графики

### График пропускной способности
![Среднее время выполнения](time.png)

![Пропускная способность](throughput.png)

### Таблица среднего времени выполнения
### Среднее время, мс

| Фильтр | 256x256 | 512x512 | 1024x1024 | 2048x2048 |
|--------|--------:|--------:|----------:|----------:|
| `gaussian3` | 2.647 | 9.689 | 38.156 | 150.786 |
| `gaussian5` | 5.726 | 22.419 | 89.901 | 352.558 |
| `blur5` | 5.712 | 26.983 | 90.336 | 355.390 |
| `sharpen3` | 2.874 | 10.193 | 39.846 | 150.532 |
| `motion9` | 16.424 | 66.375 | 257.531 | 1037.052 |
| `median3` | 5.268 | 19.512 | 68.944 | 275.658 |
| `median5` | 20.451 | 82.723 | 308.710 | 1217.208 |
| `gaussian3` | 8.376 | 33.226 | 146.312 | 557.145 |
| `gaussian5` | 19.727 | 77.419 | 315.840 | 1231.733 |
| `blur5` | 20.648 | 78.597 | 319.758 | 1330.607 |
| `sharpen3` | 8.319 | 33.734 | 153.078 | 552.967 |
| `motion9` | 55.531 | 228.407 | 902.549 | 3702.536 |
| `median3` | 16.981 | 61.565 | 243.313 | 982.028 |
| `median5` | 63.081 | 258.506 | 945.342 | 3757.349 |

### Таблица пропускной способности
### Пропускная способность, MPix/s

| Фильтр | 256x256 | 512x512 | 1024x1024 | 2048x2048 |
|--------|--------:|--------:|----------:|----------:|
| `gaussian3` | 24.759 | 27.057 | 27.481 | 27.816 |
| `gaussian5` | 11.446 | 11.693 | 11.664 | 11.897 |
| `blur5` | 11.472 | 9.715 | 11.608 | 11.802 |
| `sharpen3` | 22.804 | 25.718 | 26.316 | 27.863 |
| `motion9` | 3.990 | 3.949 | 4.072 | 4.044 |
| `median3` | 12.441 | 13.435 | 15.209 | 15.216 |
| `median5` | 3.204 | 3.169 | 3.397 | 3.446 |

### Краткий анализ

По результатам замеров видно, что с увеличением размера изображения время выполнения растёт почти пропорционально числу пикселей.
Например, для `gaussian3` время увеличилось с `2.647 мс` на `256x256` до `150.786 мс` на `2048x2048`, а для `motion9` — с `16.424 мс` до `1037.052 мс`.

Наиболее быстрыми среди протестированных фильтров оказались `gaussian3` и `sharpen3`.
Их пропускная способность держится примерно на уровне `25–28 MPix/s`, что заметно выше, чем у остальных фильтров.

Фильтры `gaussian5` и `blur5` работают медленнее, чем фильтры с окном `3x3`, так как для каждого пикселя требуется обработать больше соседних значений.
На больших размерах изображения их пропускная способность держится примерно на уровне `11–12 MPix/s`.

Фильтр `motion9` оказался одним из самых тяжёлых.
Это объясняется тем, что используется окно `9x9`, то есть на каждый пиксель приходится значительно больше операций.

`median`-фильтры также работают заметно медленнее обычной линейной свёртки.
Например, на размере `2048x2048`:
- `median3` = `275.658 мс`
- `gaussian3` = `150.786 мс`
- `median5` = `1217.208 мс`
- `gaussian5` = `352.558 мс`

То есть `median3` примерно в `1.8` раза медленнее `gaussian3`, а `median5` примерно в `3.5` раза медленнее `gaussian5`.
Это связано с тем, что median filter не просто суммирует значения по окну, а собирает значения окна и сортирует их для поиска медианы.
| `gaussian3` | 7.824 | 7.890 | 7.167 | 7.528 |
| `gaussian5` | 3.322 | 3.386 | 3.320 | 3.405 |
| `blur5` | 3.174 | 3.335 | 3.279 | 3.152 |
| `sharpen3` | 7.877 | 7.771 | 6.850 | 7.585 |
| `motion9` | 1.180 | 1.148 | 1.162 | 1.133 |
| `median3` | 3.859 | 4.258 | 4.310 | 4.271 |
| `median5` | 1.039 | 1.014 | 1.109 | 1.116 |

### Вывод
## Вывод

Последовательная реализация подходит как базовая референсная версия для дальнейших задач.
Однако уже на изображениях `1024x1024` и `2048x2048` видно, что фильтры с большими окнами и особенно `median5` становятся достаточно дорогими по времени.
Это подтверждает, что для следующих задач имеет смысл переходить к параллельной реализации.
Цветная версия выполняет ту же фильтрацию отдельно для трёх каналов, поэтому она заметно тяжелее старой grayscale-версии. Время растёт почти пропорционально числу пикселей и сложности окна фильтра. Самыми тяжёлыми остаются `motion9` и `median5`, потому что они требуют больше операций на каждый пиксель.
67 changes: 0 additions & 67 deletions src/main/java/Convolution.java

This file was deleted.

17 changes: 0 additions & 17 deletions src/main/java/GrayImage.java

This file was deleted.

Loading