Размытие по Гауссу

Курсовая работа по предмету «Программирование»
Информация о работе
  • Тема: Размытие по Гауссу
  • Количество скачиваний: 122
  • Тип: Курсовая работа
  • Предмет: Программирование
  • Количество страниц: 19
  • Язык работы: Русский язык
  • Дата загрузки: 2014-12-29 06:03:21
  • Размер файла: 1592.5 кб
Помогла работа? Поделись ссылкой
Информация о документе

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

Если Вы являетесь автором текста представленного на данной странице и не хотите чтобы он был размешён на нашем сайте напишите об этом перейдя по ссылке: «Правообладателям»

Можно ли скачать документ с работой

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

Правительство Российской Федерации


Федеральное государственное автономное образовательное учреждение высшего образовательного образования

“Национальный исследовательский университет

“Высшая школа экономики”



Московский институт электроники и математики Национального исследовательского университета «Высшая школа экономики»


Факультет информационных технологий и вычислительной техники


Кафедра Информационно-коммуникационных технологий



Курсовая работа

Тема

Размытие по Гауссу






Выполнил:

Студент группы ИКТ-21

                                                                                           Проверил:

______________________

______________________


«»2014 г.

Оценка:_______________




Москва, 2014

Аннотация

Программная реализация фильтра «Размытие по Гауссу» с последующими примерами на изображениях. Представлена блок-схема действия этого фильтра.








Оглавление

Аннотация        2

Задание        4

План работы        5

Ход работы        6

Что такое Размытие по Гауссу.        6

Алгоритм работы фильтра        6

Блок-схема        7

Код программы        12

Результаты        18

Тесты        18

Источники        19






Задание

Программная реализация фильтра «Размытие по Гауссу». Написать и продемонстрировать работу фильтра. Программа должна уметь загружать изображения с диска и/или URL и сохранять результат. Все настройки должны быть в графическом интерфейсе программы.













План работы

  1. Что такое Размытие по Гауссу.
  2. Алгоритм работы
  3. Блок-схема программы
  4. Код программы






Ход работы

Что такое Размытие по Гауссу.

Размытие по Гауссу — это характерный фильтр размытия изображения, который использует  нормальное распределение (также называемое Гауссовым распределением,

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

Наиболее общая формула функция:

Рисунок 1. Функция Гаусса

Алгоритм работы фильтра

  1. Учитывая размер окна 2N+1, считаем точки опоры: xn= 3n/N, где n = -N, -N+1,…,N
  2. Рассчитываем значения G"n
  3. Рассчитываем коэффициент масштаба k'=∑G"n
  4. Рассчитываем размер окна G'n=G"n/k'
  5. Для каждого элемента:

А) Ищем его расположение относительно окна

Б) Берем все элементы

В) Умножаем элементы на соответствующийразмер окна

Г) Суммируем полученные результаты – это и есть отфильтрованное изображение


Блок-схема

Рисунок 2. Блок-схема функции "Размытие по Гауссу 1D"

Рисунок 3. Размытие по Гауссу 2D

Рисунок 4. Работа с памятью

Рисунок 5. Создание окна фильтра


Рисунок 6. Вставление данных

Рисунок 7. Создание фильтра





Код программы

gaussianblur.h


#ifndef _GAUSSIANBLUR_H_

#define _GAUSSIANBLUR_H_


template<class T = double> class TGaussianBlur

{

public:

       // РазмытиепоГауссу 1D


       bool Filter(T *pSignal, T *pResult, unsigned int N, unsigned int W) const;


       // РазмытиепоГауссу 2D


       bool Filter(T *pImage, T *pResult, unsigned int N, unsigned int M, unsigned int W) const;


protected:

       //   Структура массива данных

       structCSize

       {

               unsignedint x;   //   Ширина

               unsignedint y;   //   Высота


               //   Конструктор по умолчанию

               CSize(): x(0), y(0) {}

               //   Конструктор с инициализацией

               CSize(unsignedint _x, unsignedint _y): x(_x), y(_y) {}


               //   Инициализация

               void Set(unsigned int _x, unsigned int _y) { x = _x; y = _y; }

               //   Область

               unsignedint Area() const { return x * y; }

       };


       //   Дескриптормассива

       structCArray

       {

               CSize Size;   //   Размермассива

               T *Buffer;    //   элемент памяти


               //   Конструктор по умолчанию

               CArray(): Buffer(NULL) {}

               //   Конструктор с инициализацией

               CArray(T *_Buffer, constCSize&_Size): Buffer(_Buffer), Size(_Size) {}

               CArray(T *_Buffer, unsigned int _N): Buffer(_Buffer), Size(_N, 1) {}

       };


       //   Дескриптормассивафильтра

       structCExtension: public CArray

       {

               unsignedint Margin;


               enumEMode {ModeHorizontal, ModeVertical};


               //   Конструкторпоумолчанию

               CExtension(): Margin(0), Mode(ModeHorizontal) {}

               //   Деструктор

               ~CExtension() { if (Buffer) delete[] Buffer; }


               //   Установкарежимов

               voidSetMode(EMode _Mode) { Mode = _Mode; }

               bool Allocate(unsigned int _N, unsigned int _W) { return _Allocate(CSize(_N, 1), _W >> 1); }

               bool Allocate(constCSize&_Size, unsigned int _W) { return _Allocate(_Size, _W >> 1); }

               void Paste(const T * _Start);

               void Extend();


       protected:

               EMode Mode;


               bool _Allocate(constCSize&_Size, unsigned int _Margin);

       };


       //   Окнофильтра

       structCWindow

       {

               double *Weights;   //   Window weights

               unsignedint Size;   //   Window size


               //   Конструкторпоумолчанию

               CWindow(): Weights(NULL), Size(0), Correction(.5 - double(T(.5))) {}

               //   Деструктор

               ~CWindow() { if (Weights) delete[] Weights; }


               //   Созданиеокна

               bool Create(unsigned int _Size);


               //   Окноприложения

               T Apply(const T *_Element) const

               {

                       //   Нахождениепреобразования

                       double Sum = 0.;

                       const double *WeightIter = Weights;

                       const T *ElIter = _Element;

                       const double *const End = Weights + Size;

                       while (WeightIter< End)

                               Sum += *(WeightIter++) * double(*(ElIter++));

                       return T(Sum + Correction);

               }


       protected:

               const double Correction;

       };


       //   Проверкавходныхданных

       bool Consistent(const T *_Image, constCSize&_Size, unsigned int _W) const { return  _Image && _Size.x&& _Size.y&& _W && _Size.x> (_W >> 1) && _Size.y> (_W >> 1) && _W & 1; }

       bool Consistent(const T *_Signal, unsigned int _N, unsigned int _W) const { return  _Signal && _N && _W && _N > (_W >> 1) && _W & 1; }

};


#include "gaussianblur.cpp"


#endif


gaussianblur.cpp


#ifndef _GAUSSIANBLUR_CPP_

#define _GAUSSIANBLUR_CPP_

#include "gaussianblur.h"

#include <math.h>

// РазмытиепоГауссу 1D

template<class T>boolTGaussianBlur<T>::Filter(T *pSignal, T *pResult, unsigned int N, unsigned int W) const

{

       //   Проверкавходныхданных

       if (!Consistent(pSignal, N, W))

               return false;

       CExtension Extension;

       if (!Extension.Allocate(N, W))

               return false;

       //   Созданиедескрипторасигнала

       constCArray Signal(pSignal, N);

       //   Вставить сигнал в расширение

       Extension.Paste(Signal.Buffer);

       //   Продление сигнала

       Extension.Extend();

       //   Созданиеокнафильтра

       CWindow Window;

       if (!Window.Create(W))

               return false;

       const T *ExtIter = Extension.Buffer;

       const T *constExtStop = Extension.Buffer + Extension.Size.x;

       T *ResIter = pResult ?pResult :pSignal;

       //   Приминение фильтра к каждому элементу

       while (ExtIter<ExtStop)

               *(ResIter++) = Window.Apply(ExtIter++);

       returntrue;

}


// Размытие по Гауссу 2D

template<class T>boolTGaussianBlur<T>::Filter(T *pImage, T *pResult, unsigned int N, unsigned int M, unsigned int W) const

{

       //   Проверкавходныхданных

       if (!Consistent(pImage, CSize(N, M), W))

               return false;

       CExtension Extension;

       if (!Extension.Allocate(CSize(N, M), W))

               return false;

       //   Созданиедескриптораизображения

       CArrayImage(pImage, CSize(N, M));

       //   Создание окна фильтра

       CWindowWindow;

       if (!Window.Create(W))

               return false;

       const T * ExtStop = Extension.Buffer + Extension.Size.x;

       T *ResIter = pResult ?pResult :pImage;

       const T *ImIter = Image.Buffer;

       const T * ImStop = Image.Buffer + Image.Size.Area();

       //   Размываем по строкам

       while (ImIter<ImStop)

       {

               //   Берем изображение

               Extension.Paste(ImIter);

               //   Разбиваем его по линиям

               Extension.Extend();

               const T *ExtIter = Extension.Buffer;

               //   Применяем фильтр к каждому пикселю на линии

               while (ExtIter<ExtStop)

                       *(ResIter++) = Window.Apply(ExtIter++);

               //   Переходим к следующей линии

               ImIter += Image.Size.x;

       }

       //   Инициализируемизображение

       Image.Buffer = pResult ?pResult :pImage;

       //   Устанавливаемвертикальныйрежим

       Extension.SetMode(CExtension::ModeVertical);

       ExtStop = Extension.Buffer + Extension.Size.y;

       T *ResColumnIter = pResult ?pResult :pImage;

       ImIter = Image.Buffer;

       ImStop = Image.Buffer + Image.Size.x;

       //   Применяемфильтр к столбцам

       while (ImIter<ImStop)

       {

               //   Берем изображение

               Extension.Paste(ImIter++);

               //   Разбиваем изображение по столбцам

               Extension.Extend();

               const T *ExtIter = Extension.Buffer;

               ResIter = ResColumnIter;

               //   Применяем фильтр к каждому пикселю в столбце

               while (ExtIter<ExtStop)

               {

                       *ResIter = Window.Apply(ExtIter++);

                       ResIter += Image.Size.x;

               }

               //   переходим к следующему столбцу

               ++ResColumnIter;

       }

       return true;

}


// Работа с памятью

template<class T>boolTGaussianBlur<T>::CExtension::_Allocate(constCSize&_Size, unsigned int _Margin)

{

       //   Выделяемпамять

       Buffer = new T[(_Size.x> _Size.y ? _Size.x : _Size.y) + (_Margin << 1)];

       //   Проверямпамять

       if (!Buffer)

               return false;

       Size = _Size;

       Margin = _Margin;

       return true;

}


template<class T> void TGaussianBlur<T>::CExtension::Paste(const T *const _Start)

{

       if (Mode == ModeHorizontal)

       {

               memcpy(Buffer + Margin, _Start, Size.x * sizeof(T));

       }

       else

       {

               const T *const Stop = _Start + Size.Area();

               const T *ArrIter = _Start;

               T *ExtIter = Buffer + Margin;

               //   Берем массив столбцов элементов

               while (ArrIter<Stop)

               {

                       //   Копируем линию

                       *(ExtIter++) = *ArrIter;

                       //   Переходим к следующей линии

                       ArrIter += Size.x;

               }

       }

}


//   Созданиефильтра

template<class T> void TGaussianBlur<T>::CExtension::Extend()

{

       //   Длиналинии

       const unsigned int Line = Mode == ModeHorizontal ? Size.x :Size.y;

       const T *const Stop = Buffer - 1;

       T *ExtLeft = Buffer + Margin - 1;

       const T *ArrLeft = ExtLeft + 2;

       T *ExtRight = ExtLeft + Line + 1;

       const T *ArrRight = ExtRight - 2;

       //   Берем массив линий элементов

       while (ExtLeft>Stop)

       {

               *(ExtLeft--) = *(ArrLeft++);

               *(ExtRight++) = *(ArrRight--);

       }

}


//   Созданиеокнафильтра

template<class T>boolTGaussianBlur<T>::CWindow::Create(unsigned int _Size)

{

       //   Выделяемпамять

       Weights = new double[_Size];

       //   Проверка

       if (!Weights)

               return false;

       //   Устанавливаем размер окна

       Size = _Size;

       const unsigned int Half = Size >> 1;

       Weights[Half] = 1.;

       for (unsigned int Weight = 1; Weight < Half + 1; ++Weight)

       {

               //   Точкиопоры

               const double x = 3.* double(Weight) / double(Half);

               Weights[Half - Weight] = Weights[Half + Weight] = exp(-x * x / 2.);

       }

       // Суммирование всех результатов

       doublek = 0.;

       for (unsigned int Weight = 0; Weight < Size; ++Weight)

               k += Weights[Weight];

       //   Масштаб

       for (unsigned int Weight = 0; Weight < Size; ++Weight)

               Weights[Weight] /= k;

       return true;

}


#endif





Результаты

Был программно реализован фильтр «Размытие по Гауссу» и составлены блок схемы по работе программы. Ниже представлены результаты работы программы.

Тесты

Рисунок 8. До применения фильтра

Рисунок 9. После применения фильтра








Источники

http://en.wikipedia.org/wiki/Gaussian_blur

http://habrahabr.ru/post/151157/

http://www.interface.ru/home.asp?artId=31747

http://stackoverflow.com/questions/19413386/gaussian-blur-mean-filter-convolution

http://docs.gimp.org/en/plug-in-gauss.html