Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011





НазваниеСписок основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011
страница12/13
Дата публикации24.02.2015
Размер0.54 Mb.
ТипОтчет
100-bal.ru > Право > Отчет
1   ...   5   6   7   8   9   10   11   12   13

4.3Реализация методов сжатия полутоновых растровых изображений


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

  1. #include

  2. #include

  3. #include

  4. #include "Image.h"



  5. const QStringList IMAGE_FORMATS = QStringList() << "jpg" << "png" << "bmp";



  6. Image loadFromQImage(QImage image);



  7. bool loadFromFile(QString filename, Image* res)

  8. {

  9. QImage img;

  10. foreach (QString format, IMAGE_FORMATS)

  11. {

  12. if (img.load(&in, format.toAscii()))

  13. {

  14. *res = loadFromQImage(img);

  15. return true;

  16. }

  17. }

  18. return false;

  19. }



  20. Image loadFromQImage(QImage image)

  21. {

  22. int width = image.width();

  23. int height = image.height();

  24. quint16* buf = new quint16[width * height];

  25. for (int y = 0; y < height; ++y)

  26. {

  27. for (int x = 0; x < width; ++x)

  28. {

  29. buf[y * width + x] = qGray(image.pixel(x, y)) * 256;

  30. }

  31. }

  32. return Image(width, height, buf);

  33. }


Метод load класса QImage пытается загрузить изображение из файла с учётом переданного ему формата (строка 15) [19]. В случае успешной загрузки изображения мы получаем не зависящее от исходного формата изображение в виде объекта QImage. Далее из этого объекта создаётся объект описанного выше класса Image (функция loadFromQImage, строки 24-37). В теле этой функции выделяется буфер, достаточный для хранения всех пикселей загружаемого изображения с использованием глубины цвета 16 бит на пиксель. В него копируется загружаемое изображение. При этом, так как все поддерживаемые форматы (см. определение IMAGE_FORMATS, строка 6) используют 8 бит на компоненту цвета, для преобразования в 16-битный формат осуществляется умножение на 256. По завершении копирования возвращается вновь созданный объект Image.

Сохранение изображения осуществляется по обратной схеме также за счёт использования возможностей класса QImage:

  1. void saveToFile(const Image& img, QString filename, QString format)

  2. {

  3. QImage res(img.getWidth(), img.getHeight(), QImage::Format_RGB32);

  4. for (int y = 0; y < img.getHeight(); ++y)

  5. {

  6. for (int x = 0; x < img.getWidth(); ++x)

  7. {

  8. quint16 i = img.getPixel(x, y) / 256;

  9. res.setPixel(x, y, qRgb(i, i, i));

  10. }

  11. }

  12. res.save(filename, format.toAscii());

  13. }


4.4Реализация методов улучшения, восстановления и морфологической обработки полутоновых растровых изображений


Как сказано в подразделе 2.3, для реализации методов преобразования изображения может использоваться библиотека ImageMagick (а точнее, её привязка к C++ – Magick++[20]) или CUDA.

Реализация любого рассматриваемого метода с помощью Magick++ состоит в вызове соответствующей функции из пространства имён Magick. Например, Magick::despeckleImage осуществляет пространственное подавление шумов, Magick::edgeImage выполняет выделение контуров,
Magick::equalizeImage производит эквализацию гистограммы и т.д. Таким образом, применение возможностей этой мощнейшей библиотеки не является трудоёмким.

Совсем иначе обстоит дело с реализацией рассматриваемых методов с использованием CUDA. Каждый из них должен быть рассмотрен с точки зрения параллельной обработки пикселей. Затем должна быть разработана схема параллельных вычислений и реализована посредством CUDA. При этом надо учитывать интенсивность обмена данными между оперативной памятью и памятью графического ускорителя, которая существенно сказывается на производительности создаваемой реализации. Кроме того, необходимо уложиться в налагаемые CUDA ограничения и т.д.

Рассмотрим CUDA-реализацию одного из методов улучшения полутоновых растровых изображений – линейной фильтрации.

Линейная фильтрация растровых изображений является частным случаем локальной пространственной фильтрации, с её помощью выполняются такие преобразования, как сглаживание, размытие, повышение чёткости (рисунок 4), выделение контуров и т.д. [2-5]. В процессе обработки каждого пикселя изображения оперируют одновременно как со значениями пикселей в его окрестности, так и с соответствующими им значениями некоторой матрицы, имеющей те же размеры, что и окрестность. Такую матрицу называют ядром или маской фильтра. Значения матрицы принято называть коэффициентами.

Схема линейной фильтрации приведена на рисунке 3. Процесс основан на простом перемещении маски фильтра от точки к точке изображения; в каждой точке (x, y) отклик фильтра задаётся суммой произведений коэффициентов фильтра на соответствующие значения пикселей в области, покрытой маской фильтра. При этом рассматриваются только маски нечётных размеров.





а)



б)

Рисунок 3 – Схема линейной фильтрации

Рисунок 4 – Пример линейной фильтрации (повышение чёткости): а) исходное изображение; б) результирующие изображение

Таким образом, линейная фильтрация изображения f, имеющего линейные размеры M×N, с помощью фильтра размером m×n задаётся выражением общего вида:

, (5)

где g(x, y) – отклик фильтра;

n = (2a + 1), m = (2b + 1);

w(s, t) – коэффициент маски фильтра;

f(x, y) – пиксель обрабатываемого изображения.

Стоит отдельно обратить внимание, что коэффициент w(0, 0) стоит при значении f(x, y), указывая тем самым, что маска центрирована в точке (x, y).

Предлагаемая реализация метода линейной фильтрации с использованием CUDA приведена ниже:

  1. __constant__ Mask filterMask;

  2. texture <u16, cudaTextureType2D, cudaReadModeElementType> input;



  3. __global__ void filterImage(Image out) {

  4. int row = blockIdx.y * blockDim.y + threadIdx.y;

  5. int col = blockIdx.x * blockDim.x + threadIdx.x;

  6. if (out.inside(row, col)) {

  7. const int hs = filterMask.size / 2;

  8. float sum = 0;

  9. for (int i = -hs; i <= hs; ++i) {

  10. for (int j = -hs; j <= hs; ++j) {

  11. sum += tex2D(input, col+j, row+i)*filterMask.value(i,j);

  12. }

  13. }

  14. out.setPixel(row, col, (int)sum);

  15. }

  16. }



  17. void filter(u16* pixels, int width, int height, float* mask,

  18. int maskSize)

  19. {

  20. const int imageSizeInBytes = width * height * sizeof(u16);

  21. cudaChannelFormatDesc desc = cudaCreateChannelDesc(16, 0, 0,

  22. 0, cudaChannelFormatKindUnsigned);

  23. cudaArray* inputArray;

  24. cudaMallocArray(&inputArray, &desc, width, height);

  25. cudaMemcpyToArray(inputArray, 0, 0, pixels, imageSizeInBytes, cudaMemcpyHostToDevice);

  26. input.normalized = false;

  27. input.filterMode = cudaFilterModePoint;

  28. input.addressMode[0] = input.addressMode[1] = cudaAddressModeClamp;

  29. cudaBindTextureToArray(&input, inputArray, &desc);

  30. Image out;

  31. out.width = width;

  32. out.height = height;

  33. cudaMalloc(&out.pixels, imageSizeInBytes);

  34. Mask k;

  35. k.size = maskSize;

  36. memcpy(k.values, mask, sizeof(float) * k.size * k.size);

  37. cudaMemcpyToSymbol(filterMask, &k, sizeof(Mask));

  38. dim3 threads(16, 16);

  39. dim3 blocks((width + threads.x - 1) / threads.x,

  40. (height + threads.y - 1) / threads.y);

  41. filterImage<<>>(out);

  42. cudaMemcpy(pixels, out.pixels, imageSizeInBytes,

  43. cudaMemcpyDeviceToHost);

  44. cudaUnbindTexture(&input);

  45. cudaFreeArray(inputArray);

  46. cudaFree(out.pixels);

  47. }

Для осуществления линейной фильтрации необходимо вызвать функцию filter, которая имеет следующие параметры:

  • pixels – указатель на пиксели обрабатываемого изображения;

  • width, height – соответственно длина и высота входного изображения;

  • mask – указатель на коэффициенты маски фильтра;

  • maskSize – размер одного измерения маски фильтра; в программе предполагается, что фильтр имеет квадратную маску.

В программе используются два вспомогательных класса: Image (не путать с Image, разработанным в 4.1) и Mask. Они представляют изображение и маску фильтра соответственно и обладают методами, упрощающими доступ к их элементам.

Приведённая выше реализация выполняет следующий алгоритм:

  1. загрузка входного изображения в текстурную память (строки 21-28);

  2. выделение в глобальной памяти графического ускорителя буфера, в который будет записано выходное изображение (строки 29-32);

  3. загрузка маски фильтра в область константной памяти (строки 33-36);

  4. запуск CUDA-ядра, выполняющего фильтрацию (строки 37-40);

  5. копирование выходного изображения из памяти графического ускорителя в оперативную память компьютера (строка 41);

  6. освобождение выделенных ресурсов (строки 42-44).

Перед описанием приведённых шагов алгоритма рассмотрим CUDA-ядро, выполняющее фильтрацию (строки 4-16).

CUDA-ядро – это функция, выполняемая всеми программными нитями графического ускорителя. В предлагаемой реализации ядро выполняет фильтрацию одного пикселя входного изображения. Сначала (строки 5-6) по положению нити в блоке и блока в сетке вычисляются координаты обрабатываемого пикселя [13]. Так как количество создаваемых программных нитей может превосходить количество обрабатываемых пикселей (см. далее), необходимо проверить, не выходит ли вычисленная позиция пикселя за границы изображения. Эта проверка осуществляется в строке 7.

Далее в строках 8-14 осуществляются вычисления по формуле 5. Счётчики циклов i и j перебирают элементы маски фильтра, а в теле второго цикла в переменной sum накапливается значение отклика (строка 12).

Наконец, в строке 16 вычисленное значение отклика записывается в выходное изображение.

Рассмотрев CUDA-ядро, перейдём к детальному описанию шагов приведённого выше алгоритма.

В архитектуре CUDA выделяются различные типы памяти: глобальная, константная, текстурная, разделяемая и локальная [13]. Они характеризуются различным объёмом и временем доступа, а также могут кэшироваться. Для хранения входного изображения может быть использована глобальная или текстурная память, остальные типы имеют слишком малый объём. Глобальная память поддерживает чтение и запись, не кэшируется и обладает самым высоким временем доступа. Текстурная память, напротив, кэшируется и доступна только для чтения. Следовательно, в некоторых ситуациях она обладает меньшей латентностью за счёт сокращения количества обращений. В частности, кэш текстурной памяти оптимизирован для обработки запросов, обладающих пространственной локальностью, которая проявляется, когда соседние программные нити обращаются к соседним элементам текстуры [13].

В процессе выполнения линейной фильтрации к отдельно взятому пикселю входного изображения происходят многократные обращения. Например, если маска фильтра имеет размер 3×3, то к одному пикселю может происходить до девяти обращений (рисунок 5). Кроме того, как следует из формул определения позиции обрабатываемого пикселя (строки 5-6), в рассматриваемой реализации соседние программные нити обрабатывают соседние пиксели изображения. Следовательно, текстурная память не только может быть применена для хранения входного изображения, но и даст существенный прирост производительности за счёт сокращения количества обращений к глобальной памяти.



Рисунок 5 – Количество обращений к пикселю в процессе линейной фильтрации. При размере ядра фильтра 3×3 к пикселю (2;2) происходят обращения при обработке всех пикселей, отмеченных серым

Загрузка входного изображения в текстуру осуществляется в строках 20-28. Сначала (строки 21-23) в глобальной памяти графического ускорителя выделяется CUDA-массив – специальная структура данных, оптимизированная для хранения текстур [13]. Затем в него копируется входное изображение. В строках 25-27 настраиваются параметры текстуры, и, наконец, в строке 28 текстурная ссылка input, связывается с выделенным CUDA-массивом.

Следует отметить, что при обработке пикселей, близких к границе изображения, некоторые строки и столбцы маски могут оказаться за его пределами. Существует несколько способов учесть это обстоятельство. Простейший способ состоит в ограничении перемещения центра маски по изображению. Результирующее изображение после фильтрации будет по размерам меньше оригинала, зато все его точки будут обработаны полной маской. Если результат должен иметь те же размеры, что и оригинал, то обычно применяется подход, при котором для фильтрации используется только та часть маски, которая полностью находится внутри изображения. При этом возле границ изображения образуется полоса точек, которые обрабатываются только частью маски фильтра. Другие подходы предусматривают расширение изображения за его границы добавлением строк и столбцов из нулей или же повторением строк и столбцов. После обработки добавленные строки и столбцы удаляются. Это позволяет сохранить размеры обработанного изображения равными размерам исходного, однако значения элементов, использовавшихся для расширения, будут оказывать влияние на значения элементов изображения внутри аналогичной полосы, которая тем шире, чем больше размеры маски [2, 3].

В рассматриваемой реализации неявно применяется метод повторения строк и столбцов изображения. Это достигается за счёт установки значения cudaAddressModeClamp в элементы текстурного атрибута addressMode (строка 27). Этот параметр указывает, что при обращении к пикселю, выходящему за пределы изображения, берётся ближайший пиксель на границе. Такой выбор обусловлен тем, что функция filter не предполагает изменение размеров изображения после фильтрации.

Из всех описанных выше типов памяти графического процессора для хранения выходного изображения подходит только глобальная память – она обладает достаточной ёмкостью и, в отличие от текстурной памяти, поддерживает запись. Кроме того, так как все программные нити обрабатывают разные пиксели, и позиция выходного пикселя совпадает с позицией входного, то каждый пиксель выходного изображения будет записан в выделенный буфер один раз. Следовательно, в процессе формирования результирующего изображения не возникает избыточных обращений к глобальной памяти, и она может быть применена для хранения выходного изображения (строки 30-33).

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

  • одно обращение к константной памяти может быть транслировано соседним 15 нитям;

  • константная память кэшируется, следовательно, последовательные обращения к одному и тому же адресу не порождают лишних обращений к памяти [13].

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

Эта операция осуществляется в строках 33-36 программы. Сначала необходимыми значениями инициализируется переменная k типа Mask, а затем с помощью специальной команды она записывается в область константной памяти, помеченную именем filterMask.

Для запуска CUDA-ядра необходимо сформировать структуру вычислительной сетки. Так как осуществляется обработка двумерного изображения, то сетка представляется в виде матрицы блоков, а блоки в свою очередь – в виде матрицы программных нитей. Количество нитей в блоке для данной задачи безразлично, так как они никак не взаимодействуют друг с другом, поэтому была выбрана рекомендуемая в таких случаях структура 16×16 [13]. Размеры матрицы блоков представляют собой частные от деления размеров изображения на количество нитей в соответствующем измерении блока, округлённые вверх (строки 38-39). При этом округление вверх гарантирует, что длина и высота вычислительной сетки будут не меньше, чем длина и высота изображения. Если одно из измерений сетки окажется больше соответствующего измерения изображения, то некоторым нитям будут соответствовать пиксели, выходящие за границы изображения. Чтобы исключить такие случаи, в CUDA-ядре стоит проверка на принадлежность обрабатываемого пикселя изображению (строка 7).

Другой важной особенностью является передача выходного изображения в качестве параметра filterImage (строка 41). Переменная out, используемая для обращения к выходному изображению, находится в оперативной памяти компьютера. Код, выполняющийся на графическом ускорителе, не может напрямую обращаться к ОЗУ, поэтому содержимое переменной out должно быть скопировано в память графического ускорителя. Передавая out в качестве фактического параметра ядра, мы неявно копируем её содержимое в локальную память программной нити, помещая тем самым необходимые данные в памяти графического ускорителя.

Копирование результирующего изображения и освобождение выделенных ресурсов осуществляются с помощью вызовов специальных функций CUDA (строки 42-45).
1   ...   5   6   7   8   9   10   11   12   13

Похожие:

Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 iconСписок основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011
Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 на выполнение поисковых научно-исследовательских работ для государственных...
Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 iconСписок основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011
Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 на выполнение поисковых научно-исследовательских работ для государственных...
Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 iconОтчет о выполненной работе по Государственному контракту №14. 741....
Государственное образовательное учреждение высшего профессионального образования "Российский экономический университет им. Г. В....
Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 iconОтчет о научно-исследовательской работе по Государственному контракту...
Этап второй: «Выбор направлений исследований и этап предварительных исследований по мембранным коллоидным системам»
Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 iconОтчет по Дополнительному соглашению №2 к Государственному контракту...
«Разработка проекта скиово бассейна реки Нарва и рек бассейна Псковско-Чудского озера» (С-10-01)
Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 iconОтчет о научно-исследовательской работе, выполняемой по государственному...
«Разработка алгоритмов для биоинформационного анализа комплексных метаболических и молекулярно-генетических сетей»
Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 iconОтчет о научно-исследовательской работе по государственному контракту...
Русский язык и культура речи: учебно-методический комплекс для студентов очной формы обучения / сост. И. А. Крым; Кузбасский институт...
Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 iconОтчет о выполнении 4 этапа Государственного контракта №14. 740. 11....
О выполнении 4 этапа Государственного контракта №14. 740. 11. 1071 от 24. 05. 2011 г
Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 iconОтчет по Дополнительному соглашению №4 от 27 февраля 2010 г к Государственному...

Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 iconОтчетные материалы по гос контракту №02. 740. 11. 0072 в рамках федеральной...
Учебно-методический комплекс по дисциплине «Биохимия молока и мяса» составлен на основе
Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 iconОтчет по Государственному контракту №
«Разработка концепции создания интеллектуальной транспортной системы на автомобильных дорогах федерального значения»
Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 iconОтчет по Государственному контракту на выполнение работ для государственных нужд
Организационно-техническое обеспечение работы российской экспозиции на осенней технической ярмарке
Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 iconОтчет по государственному контракту от 04. 06. 2012 №1102-01-41/06-12...
...
Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 iconРеферат отчета по государственному контракту от 20. 04. 2007 г. №8-07-Эко...
Фгун екатеринбургский медицинский научный центр профилактики и охраны здоровья рабочих
Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 iconСписок исполнителей
Содержание деятельности и результаты Мероприятия №10 «Москва – город грамотных людей»
Список основных исполнителей по Государственному контракту 14. 740. 11. 1258 от 17 июня 2011 iconСписок исполнителей
Федеральное государственное бюджетное учреждение науки институт программных систем им. А. К. Айламазяна


Школьные материалы


При копировании материала укажите ссылку © 2013
контакты
100-bal.ru
Поиск