Skip to content

germanganys/mvc_1

Repository files navigation

Мобильные системы компьютерного зрения

Лабораторная работа №1 (Вариант 3)

Выполнили: Ганыс, Реккубрацкий, Сидуков

Преподаватель Денисов А.К.

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

Задание:

  1. Реализовать программу согласно варианту задания. Базовый алгоритм, используемый в программе, необходимо реализовать в 2 вариантах: с использованием встроенных функций какой-либо библиотеки (OpenCV, PIL и др.) и нативно на Python с использованием циклов.
  2. Сравнить быстродействие реализованных вариантов.
  3. Сделать отчёт в виде readme на GitHub, там же должен быть выложен исходный код.

Отчёт должен содержать следующие пункты:

  1. Теоретическая база
  2. Описание разработанной системы (алгоритмы,принципы работы, архитектура)
  3. Результаты работы и тестирования системы(скриншоты,изображения, графики, закономерности)
  4. Выводы
  5. Использованные источники

Теоретическая база:

Медиа́нный фи́льтр — один из видов цифровых фильтров, широко используемый в цифровой обработке сигналов и изображений для уменьшения уровня шума. Медианный фильтр является нелинейным КИХ-фильтром.

Значения отсчётов внутри окна фильтра сортируются в порядке возрастания (убывания); и значение, находящееся в середине упорядоченного списка, поступает на выход фильтра. В случае чётного числа отсчётов в окне выходное значение фильтра равно среднему значению двух отсчётов в середине упорядоченного списка. Окно перемещается вдоль фильтруемого сигнала, и вычисления повторяются.

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

Описание разработанной системы

Требовалось реализовать медианный фильтр для устранения шумов, для реализации пункта 1 при реализации с помощью готовой библиотеки была выбрана библиотека PIL, предназначенная для работы с изображениями В данной библиотеке уже есть готовая реализация медианного фильтра.

В качестве образца для тестирования было выбрано следующее изображение: balloons_noisy.png

Применить медианный фильтр с помощью библиотеки PIL не составило труда

im = Image.open('./balloons_noisy.png')
im.filter(ImageFilter.MedianFilter(3))
im.save('./balloons_noisy_pil_filtered.png')

В результате получилось следующее изображение: balloons_noisy_pil_filtered.png

После применения стало гораздо проще различить объекты

Далее был реализован самописный медианный фильтр

def median_filter_diy(data, filter_size: int):
    indexer = filter_size // 2

    for x in range(data.size[0]):
        for y in range(data.size[1]):
            temp = []

            for k in range(filter_size):
                if x + k - indexer < 0 or x + k - indexer > data.size[0] - 1:
                    for c in range(filter_size):
                        temp.append((0, 0, 0))
                else:
                    if y + k - indexer < 0 or y + indexer > data.size[1] - 1:
                        temp.append((0, 0, 0))
                    else:
                        for z in range(filter_size):
                            temp.append(data.getpixel((x + k - indexer, y + z - indexer)))
            pixel = [0, 0, 0]
            for i in range(3):
                temp.sort(key=lambda x: x[i])
                pixel[i] = temp[len(temp) // 2][i]
            data.putpixel((x, y), tuple(pixel))
    return data

Особенность данной реализации - для каждого пиксела сортируется каждый канал по отдельности

После применения данного фильтра было получено следующее изображение

balloons_noisy_diy_filtered.png

Далее был написан драйвер для замера скорости работы 2х вариантов

if __name__ == '__main__':
    im = Image.open('./balloons_noisy.png')

    sum_time_diy = 0
    for i in range(100):
        im2 = im.copy()
        start = time.process_time()
        median_filter_diy(im2, 3)
        sum_time_diy += (time.process_time() - start)

    sum_time_pil = 0
    for i in range(100):
        im2 = im.copy()
        start = time.process_time()
        im2.filter(ImageFilter.MedianFilter(3))
        sum_time_pil += (time.process_time() - start)

    print(f'{sum_time_diy=}, {sum_time_pil=}')

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

В результате получились следующие замеры (в секундах):

  • (самописная реализация) 146.73271800000006
  • (реализация PIL) 5.470951000000184

Выводы

Как видно код PIL работает в 30 раз быстрее чем наша реализация, скорее всего что во первых код PIL написан на C что сильно ускоряет процесс и в коде C используются векторные инструкции которые позволяют гораздо быстрее справлятся с матричными вычислениями

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages