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

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

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 23.09.2012
Размер файла 8,0 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Рис. 5.17 - Визуальная оценка границы совмещения

Сравнение с эталонным изображением

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

Рис. 5.18 - Профили яркостей для эталонного и сформированного алгоритмом 3 изображения панорамы

Заключение по результатам исследования.

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

5.3 Разработка лабораторного практикума

Название лабораторного практикума:

«Лабораторный практикум по курсу «Обработка изображений» ».

Цели и задачи лабораторного практикума:

Изучение принципов работы алгоритмов совмещения фрагментов при формировании панорамного изображения;

Изучение скорости работы алгоритмов совмещения фрагментов на примере реализованных в программном обеспечении PanoramaMaker.

Детальное изучение принципов работы алгоритма с средними профилями.

Структура лабораторного практикума:

Лабораторный практикум

Лабораторная работа №1 «Быстродействие различных алгоритмов совмещения фрагментов при построении панорамного изображения»

Цель работы: оценка скорости различных алгоритмов совмещения фрагментов.

Теоретическая часть: Основные принципы алгоритмов совмещения фрагментов, основные шаги алгоритмов реализованных в программном продукте PanoramaMaker

Практическое задание: Формирование панорамных изображений 4 алгоритмами реализованными в программном продукте PanoramaMaker, оценка времени работы каждого алгоритма.

Лабораторная работа № 2 «Изучение алгоритма совмещения фрагментов со средними профилями»

Цель работы: «Изучение зависимости алгоритма со средними профилями от параметров»

Теоретическая часть: Детальное описание основных шагов алгоритма со средними профилями. Описание реализации фрагментов содержащих основные параметры работы алгоритма.

Практическое задание: Оценка работы алгоритма при изменении параметров минимального перекрытия, порога бинаризации, порогового значения дифференса после обработки маской.

6. Экспериментальные исследования

6.1 Эксперимент № 1. Оценка качества совмещения фрагментов алгоритмом с бинаризацией на основе гистограмм

Этапы проведения эксперимента:

Выборка фрагментов панорамного изображения;

Совмещение фрагментов алгоритмом с бинаризацией;

Совмещение фрагментов алгоритмом с бинаризацией;

Сравнение полученных изображений с эталонным изображением;

Заключение по результатам исследования.

Выборка фрагментов панорамного изображения;

В качестве экспериментальной выборки фрагментов была взята выборка фрагментов размером 2*3 фрагмента.

Совмещение фрагментов

На данном этапе были получено панорамное изображение с помощью базового алгоритма и алгоритма с бинаризацией

Сравнение обработанного изображения с эталонным изображением;

Были построены графики (см рис.5.1 и 5.2) «профили яркостей» полученных изображения и эталонного.

Рис. 6.1 - Профили яркостей панорамы собранной алгоритмом с бинаризацией и эталонного изображения

Рис. 6.2 - Профили яркостей панорамы собранной базовым алгоритмом и эталонного изображения

Заключение по эксперименту

Из рис. 6.1 и 6.2 отчетливо видно, что результат работы алгоритма с бинаризацией корректней аналогичного результата для базового алгоритма.

6.2 Эксперимент № 2. Оценка скорости работы алгоритма со средними профилями

Этапы проведения эксперимента:

Выборка фрагментов панорамного изображения;

Совмещение фрагментов алгоритмом со средними профилями;

Совмещение фрагментов базовым алгоритмом;

Сравнение времени работы алгоритмов;

Заключение по результатам исследования;

Выборка фрагментов панорамного изображения;

В качестве экспериментальной выборки фрагментов были взяты две выборки фрагментов 2*3 фрагментов и 2*5 фрагментов, такой маленький размер панорамы обусловлен низкой скоростью работы базового алгоритма.

Совмещение фрагментов

Были построены панорамные изображения алгоритмом со средними профилями и базовым алгоритмом.

Сравнение времени работы алгоритмов.

Таблица 6.1

Размер панорамного изображения

Время работы базового алгоритма

Время работы алгоритма со степенями жесткости

2*3

56 сек

4 сек

2*5

117 сек

10 сек

Заключение по результатам эксперимента

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

6.3 Эксперимент № 3. Оценка работы алгоритма с средними профилями на малоконтрастных участках

Этапы проведения эксперимента:

Выборка фрагментов панорамного изображения;

Совмещение фрагментов выбранным алгоритмом;

Анализ работы алгоритма;

Экспертная оценка границы;

Сравнение обработанного изображения с эталонным изображением;

Заключение по результатам исследования.

Выборка фрагментов панорамного изображения;

В качестве экспериментальной выборки фрагментов была взята область панорамы размером 2*17 кадров содержащая более 50% фрагментов которой - малоконтрастные. Из этих фрагментов было получено эталонное изображение путем ручной сборки панорамного изображения.

Совмещение фрагментов выбранным алгоритмом;

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

Анализ работы алгоритма;

Были проанализированы рабочие графики алгоритма, из которых очевидно, что алгоритм отработал корректно.

Рис. 6.3 - Участок графика «дифференс»

Экспертная визуальная оценка границ совмещения;

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

Сравнение обработанного изображения с эталонным изображением;

Были построены графики (см рис. 6.4) «профилей яркостей» полученного изображения и эталонного, из которых видно, что полученное изображение значительно отличается от эталонного

Рис. 6.4 - Фрагмент графика сравнения «профилей яркости»

6.4 Эксперимент № 4. Оценка работы алгоритма с средними профилями на малоконтрастных участках

Этапы проведения эксперимента:

Выборка фрагментов панорамного изображения;

Совмещение фрагментов выбранным алгоритмом;

Анализ работы алгоритма;

Экспертная оценка границы;

Сравнение обработанного изображения с эталонным изображением;

Заключение по результатам исследования.

Выборка фрагментов панорамного изображения;

В качестве экспериментальной выборки фрагментов была взята таже выборка фрагментов, что и в эксперименте №1

Совмещение фрагментов выбранным алгоритмом;

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

Анализ работы алгоритма;

Были проанализированы рабочие графики алгоритма, из которых очевидно, что алгоритм отработал корректно.

Рис. 6.5 - Участок графика «дифференс»

Стоит отметить, что данный алгоритм в случае малой контрастности фрагмента не пытается найти оптимальное положение, а накладывает его со средним наложением.

Экспертная визуальная оценка границ совмещения;

Была проведена визуальная оценка границ совмещения, которая показала корректное совмещение фрагментов на границах.

Сравнение обработанного изображения с эталонным изображением;

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

Рис. 6.6 - Фрагмент графика «профили яркостей»

Заключение по эксперименту

Из рис. Отчетливо видно, что график «профиля яркости» полученного изображения незначительно отличается от графика эталонного изображения.

Заключение

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

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

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

Программная система может применяться как инструмент для проведения лабораторных работ по курсу «Обработка изображений». Благодаря алгоритмической базе, реализованной в программе и средствам исследования эффективности их работы, система предоставляет возможность изучения вопросов корректности совмещения фрагментов алгоритмами при формировании панорамного изображения микропрепарата.

Список использованной литературы

1. Введение в компьютерную графику. Лекция 4 (http://graphics.cs.msu.ru/courses/cg03b/lectures/)

2. Б. Страуструп «Язык программирования С++» специальное издание

3. У.Прэтт «Цифровая Обработка Изображений»

4. http://www.cgm.computergraphics.ru/content/view/49

5. Р.Гонсалес, Р. Вудс «Цифровая обработка изображений»

6. Сайт профессора Хельмута Дерша www.fh-furtwangen.de/~dersch

Приложение 1

Лабораторный практикум

Лабораторная работа 1 «Быстродействие различных алгоритмов совмещения фрагментов при построении панорамного изображения»

Цель работы: оценка быстродействия различных алгоритмов совмещения фрагментов.

Теоретическая часть

Процесс составления из ряда кадров единого изображения называется ститчингом (stitching - склеивание).

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

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

Данный алгоритм используется в следующих программных продуктах CANON PhotoStitch, FlamingPearFlexify, PanoramaComposer, PanoramaMaker, PhotovistaPanorama, PixMakerPro,Pixtra, 3dPhotoBuilderProfessional, EasyPano Tourweaver, Panorama Factory

Все приведенные выше программы пасуют при необходимости сшивать сложные многорядные панорамы.

Революция в алгоритмах сшивания панорам произошла в 1998 году, когда профессор физики Хельмут Дерш (Helmut Dersch) из Технического Университета города Фюртванген (ФРГ) выложил на своем сайте www.fh-furtwangen.de/~dersch ряд разработанных им программ, которые и по сей день являются самым известным и популярным среди фотографов инструментом создания панорамных изображений. Главное достоинство подхода, лежащего в основе этих программ, заключалось в том, что он позволял получать панорамы любых типов из снимков, полученных с помощью практически любого объектива. С их помощью можно сшивать как однорядные, так и многорядные панорамы. Наличие на исходных снимках всякого рода геометрических искажений также не является препятствием для получения панорам хорошего качества. Еще одним немаловажным достоинством разработки Х.Дерша являлось то, что она распространялась и распространяется до сих пор совершенно бесплатно. Более того автор сделал свой проект открытым и теперь любой может внести свою лепту в дальнейшее совершенствование его программ и методик.

В основе подхода Х.Дерша к решению задачи сшивания панорам лежит простая и весьма продуктивная идея. Вместо того, чтобы и дальше развивать и совершенствовать способы совмещения смежных областей изображений по контурам рисунков, затирать фантомные элементы и т.п., автор разработки решил трансформировать исходные изображения целиком так, чтобы минимизировать различие в рисунках этих смежных областей. Делается это по контрольным точкам (маркерам), расставляемым вручную. При этом трансформации подвергаются такие параметры изображений, как фокусное расстояние объектива, с помощью которого получено исходное изображение, параметры радиального смещения, присущие данному объективу, углы наклона объектива от кадра к кадру, линейные смещения изображений. В результате работы программы получается многослойный файл, состоящий из маркированных трансформированных изображений, смещенных друг относительно друга и образующих при этом панораму.

Первоначально пакет программ Х.Дерша получил название Panorama Tools и представлял собой 4 плагина к Фотошопу или любому другому растровому графическому редактору, работающему со слоями. В дальнейшем, по мере совершенствования, пакет пополнился несколькими самостоятельными программами. В состав пакета входит также т.н. PTViewer - программа просмотра панорамный изображений. Сегодня весь этот пакет, состоящий из плагинов Panorama Tools, 8-ми самостоятельных программ и PTViewer'а, носит название PanoTools.

Пакет PanoTools мог бы, претендовать на роль той самой 'универсально-идеальной' программы сшивания, если бы не одно весьма существенное обстоятельство. Работа с PanoTools предусматривает весьма тщательную расстановку контрольных точек на одинаковых элементах смежных областей исходных изображений. Причем выходное качество, весьма чувствительно к количеству и точности их расстановки. В настоящее время предпринимаются попытки создания программ автоматического определения координат контрольных точек, но, но полностью обойтись без ручного вмешательства в работу этих программ (проблема ложных точек) вряд ли удастся. Изначально пакет не предусматривал наличие вообще какого-либо графического интерфейса пользователя (GUI). Однако сегодня эта проблема успешно решена как самим автором PanoTools (программа PTPicker), так другими разработчиками (программы PTGui, PTAssembler и PTMac). 3 последних программы уже не являются бесплатными. Следует отметить, что эти 3 программы не содержат какие-либо дополнения или усовершенствования к программам и методикам профессора Дерша. Они лишь предоставляют графический интерфейс для работы с созданными им средствами.

Алгоритмы реализованные в программе

Алгоритм 1 базовый алгоритм системы Атлант Микро

Основные шаги алгоритма:

Формируется цикл, в каждом шаге которого уменьшается зона перекрытия от W-10 до W-300, где W - ширина кадра.

По зоне перекрытия считается суммарный попиксельный дифференс, который потом делится на площадь перекрытия, тем самым получается средний дифференс по зоне перекрытия изображений по оси X (высота перекрытия остаётся постоянной и равна H - высоте изображения).

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

Алгоритм 2 с бинаризацией на основе гистограмм

Основные шаги алгоритма:

При загрузке изображений на вход алгоритма, они обрабатываются маской:

|-1 0 0 0 1|

|-1 0 0 0 1|

|-1 0 0 0 1|

|-1 0 0 0 1|

|-1 0 0 0 1|

Тем самым выделяя границы объектов для сшивки по горизонтали.

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

Далее рассчитывается порог бинаризации, при котором на изображении не более 70% черных пикселей.

Сшиваемые изображения бинаризируются с найденным порогом бинаризации.

Рассчитывается средний дифференс по зоне перекрытия для бинаризованной картинки

Алгоритм 3 с средними профилями

Основные шаги алгоритма:

При загрузке изображений в программу обрабатываем каждое изображение маской:

|-1 0 0 0 1|

|-1 0 0 0 1|

|-1 0 0 0 1|

|-1 0 0 0 1|

|-1 0 0 0 1|

Тем самым выделаем границы объектов для сшивки по горизонтали.

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

Сшиваемые изображения бинаризируются с порогом бинариазции = 7, чтобы убрать шум на изображении после обработки его маской. Бинаризация осуществляется по следующему принципу: значение ниже порога приравнивается к нулю, значения выше пороге бинаризации приравниваются к среднему из 3-х компонент.

Строится средний профиль изображений по оси X, т.е. X=(?p(x,j))/H, где j меняется от 0 до H - высота изображения.

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

Полученный средний дифференс обрабатывается маской [-1 0 2 0 -1], чтобы выделить резкие перепады на графике среднего дифференса.

На полученной графике ищется максимальное значение, индекс которого соответствует истинному положению второго кадра в первом по оси X

Алгоритм 4 с степенями жесткости

Основные шаги алгоритма:

При загрузке изображений в программу обрабатываем каждое изображение маской:

|-1 0 0 0 1|

|-1 0 0 0 1|

|-1 0 0 0 1|

|-1 0 0 0 1|

|-1 0 0 0 1|

Тем самым выделаем границы объектов для сшивки по горизонтали.

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

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

Сшиваемые изображения бинаризируются с порогом бинаризации = 7, чтобы убрать шум на изображении после обработки его маской. Бинаризация осуществляется по следующему принципу: значение ниже порога приравнивается к нулю, значения выше пороге бинаризации приравниваются к среднему из 3-х компонент.

Если у сшиваемых изображений площадь контрастных структур на зоне перекрытия больше 1000 (значение получено экспериментально), то считается, что сшивка будет выполнена корректно.

Строится средний профиль изображений по оси X, т.е. X=(?p(x,j))/H, где j меняется от 0 до H - высота изображения.

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

Полученный средний дифференс обрабатывается маской [-1 0 2 0 -1], чтобы выделить резкие перепады на графике среднего дифференса.

На полученной графике ищется максимальное значение, индекс которого соответствует истинному положению второго кадра в первом по оси X

Контрольные вопросы:

Чем обусловлена скорость работы алгоритмов?

Как увеличить скорость работы алгоритмов?

Какой алгоритм корректнее всего справляется с совмещением малоконтрастных фрагментов?

Подготовка к работе

Для работы понадобится архив с файлами проекта PanoramaMaker, 2 набора фрагментов(2*2 фрагмента и 4*4 фрагмента) с наличием контрастных структур на каждом фрагменте в формате.bmp

Задание № 1

1.Загрузить набор фрагментов панорамного изображения размером 2 на 2 фрагмента в программу.

2. Построить панорамное изображение всеми 4 алгоритмами, заполняя таблицу

Алгоритм

Время сшивки

1

2

3

4

3. Сделать заключение о максимально быстром алгоритме.

4.Загрузить набор фрагментов панорамного изображения размером 4 на 4 фрагмента в программу.

5. Построить панорамное изображение всеми 4 алгоритмами, заполняя таблицу

Алгоритм

Время сшивки

1

2

3

4

6. Построить график зависимости скорости алгоритма от числа кадров.

Лабораторная работа 2: «Изучение алгоритма со средними профилями»

Цель работы: Изучение зависимости алгоритма со средними профилями от параметров

Теоретическая часть

Алгоритм со средними профилями изначально разрабатывался для повышения скорости и точности работы базового алгоритма системы Атлант-Микро. Результаты экспериментов показали, что с поставленной задачей алгоритм справился.

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

Основные шаги алгоритма:

При загрузке изображений в программу обрабатываем каждое изображение маской:

|-1 0 0 0 1|

|-1 0 0 0 1|

|-1 0 0 0 1|

|-1 0 0 0 1|

|-1 0 0 0 1|

Тем самым выделаем границы объектов для сшивки по горизонтали.

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

Сшиваемые изображения бинаризируются с порогом бинариазции = 7, чтобы убрать шум на изображении после обработки его маской. Бинаризация осуществляется по следующему принципу: значение ниже порога приравнивается к нулю, значения выше порога бинаризации приравниваются к среднему из 3-х компонент.

Строится средний профиль изображений по оси X, т.е. X=(?p(x,j))/H, где j меняется от 0 до H - высота изображения.

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

Полученный средний дифференс обрабатывается маской [-1 0 2 0 -1], чтобы выделить резкие перепады на графике среднего дифференса.

На полученной графике ищется максимальное значение, индекс которого соответствует истинному положению второго кадра в первом по оси X

Далее изображения обрабатываются маской

|-1 -1 -1 -1 -1|

| 0 0 0 0 0 |

| 0 0 0 0 0 |

| 0 0 0 0 0 |

| 1 1 1 1 1 |

Строится средний профиль по Y (аналогично среднему профилю по X)

Полученные профили вычитаются друз из друга с заданным перекрытием и ищется минимум, который соответствует истинному положению второго кадра в первом по оси Y

После сшивки всех кадров по полосам оценивается значение максимума при сшивке по оси X. Если значение максимума больше 0,11 (значение получено опытным путём), то сшивка считается правильной и остаётся без изменений, если значение меньше, то сшивка считается неудачной и положение кадра в предыдущем кадре приравнивается среднему значению всех положений кадров в предыдущих.

Далее ищется кадр с максимальным значением коэффициента, который характеризует наличие контрастных структур в верхней половине кадра.

Найденный кадр и кадр над ним обрабатывается маской для сшивки по оси X

Далее изображения бинаризируются с порогом 7

Формируется цикл, в котором для нижнего кадра строится средний профиль по X для полоски шиной в 90 пикселей от верхней границы кадра, а для верхнего кадра рассчитывается средний профиль по X для полоски шириной в 50 пикселей от нижней границы кадра. В каждом следующем шаге цикла полоска для верхнего кадра поднимается вверх на 25 пикселей и средний профиль строится для неё.

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

Далее эта же пара изображений обрабатывается маскрой для вертикальной сшивки и бинаризируется с порогом 7

Рассчитывается средний профиль по оси Y для обоих изображений

Рассчитывается средний дифференс, который потом обрабатывается маской.

Ищется максимальное значение, которое соответствует правильному положению нижнего кадра в верхнем по оси Y

Все остальные кадры выстраиваются относительно новых координат только что сшитых кадров

Минимальное перекрытие - минимальное наложение кадра 2 на кадр 1.

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

Например: если известно, что зона перекрытия - середина кадра, то не имеет смысла искать оптимальное положение до 1/5 кадра.

int right=100;

for(size_t x=0;x<vbin10_1.size()-right;++x) // расчёт дифференса между соседними изображениями

{

double sdifbin10=0;

for(size_t i=x;i<vbin10_1.size();++i)

{

sdifbin10+=abs(vbin10_1[i]-vbin10_2[i-x]);

}

sdifbin10/=(double)(vbin10_1.size()-x);

vbin10_dif.push_back(sdifbin10);

Form6->allg1_differens.push_back(sdifbin10);

vdx.push_back(x);

}// конец расчёта дифференса между соседними изображениями

За минимальное наложение кадра отвечает параметр right.

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

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

f.Binarization(VPP[k].L,Ltmp,7);

f.Binarization(VPP[k+1].L,Ltmp1,7);

Пороговое значение дифференса после обработки маской - параметр, отвечающий за оценку качества сшивки двух фрагментов.

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

for(size_t i=0;i<vpic.size();++i)

{

if(vpic[i]<0.011)

VPan[n*y_idx+i+1]->Left=VPan[n*y_idx+i]->Left+mid;

else

VPan[n*y_idx+i+1]->Left=VPan[n*y_idx+i]->Left+vdeltax[i];

}

Контрольные вопросы:

Принцип работа алгоритма с расчетом средних профилей.

От каких параметров зависит алгоритм с расчетом средних профилей?

Чему равно оптимальное пороговое значение дифференса после обработки маской?

Подготовка к работе

Для работы понадобится архив с файлами проекта PanoramaMaker, набор фрагментов с наличием контрастных структур на каждом фрагменте в формате.bmp

Задание № 1

Изменяя значение минимального перекрытия(параметр right) от 1 / 2 до 1/5 собрать панорамное изображение алгоритмом

Заполнить таблицу и построить график зависимости времени работы алгоритма от минимальной области перекрытия

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

Время работы алгоритма.

0.5 от ширины кадра

0.4 от ширины кадра

0.3 от ширины кадра

0.2 от ширины кадра

Изменяя порог бинаризации 2 до 150 оценить степень корректности работы алгоритма и заполнить таблицу, оценивая корректность работы алгоритма по 5 бальной системе.

Порог бинаризации

Корректность сборки панорамного изображения

2

7

15

25

150

Изменяя пороговое значение дифференса после обработки маской в диапазоне 0.005 до 0.05 подобрать оптимальное значение.

Сделать заключение о правильности выбора оптимального значения равного 0.11.

Приложение 2

Описание алгоритмов формирования панорамных изображений

Описание алгоритма №1. Листинг функции PanoramMake1

void TForm1::PanoramMake1(int Overlap,vector<PanoramPart> VPP)

{

TDateTime t=GetTime();

Form7->allg2_differens.clear();

size_t H=VPP[0].L.H;

size_t W=VPP[0].L.W;

// задаём положение первого фрагмента панорамы

VPan[0]->Left=30;

VPan[0]->Top=30;

// объявление переменных для хранения расчётных значений алгоритма

double mindif1=99999999;

double mindif2=99999999;

size_t sumdif;

int x1,y1;

int x2,y2;

ProgressBar1->Max=VPP.size()-1;

ProgressBar1->Position=0;

for(int y_idx=0;y_idx<RowCount;++y_idx)

{

if(y_idx>0)

{

VPan[y_idx*ColCount]->Left=30;

VPan[y_idx*ColCount]->Top=15+VPan[(y_idx-1)*ColCount]->Top+

VPan[(y_idx-1)*ColCount]->Height;

}

for(int x_idx=0;x_idx<ColCount-1;++x_idx)// цикл по X в панорамной сетке

{

size_t idx=y_idx*ColCount+x_idx;

size_t yi=VPP[idx].L.H-5;

for(size_t xi=10;xi<(W-200);++xi)

{

sumdif=0;

//цикл расчёта разницы между изображениями по зоне перекрытия

for(size_t j=0;j<yi;++j)

for(size_t i=xi;i<W-5;++i)

{

sumdif+=abs(VPP[idx].L(i,j).comp[lyr::g_rgb]-

VPP[idx+1].L(i-xi+5,j).comp[lyr::g_rgb]

+VPP[idx].L(i,j).comp[lyr::g_rgb]-

VPP[idx+1].L(i-xi+5,j).comp[lyr::g_rgb]

+VPP[idx].L(i,j).comp[lyr::b_rgb]-

VPP[idx+1].L(i-xi+5,j).comp[lyr::b_rgb]);

}

double t=((double)sumdif/(double)((W-xi)*yi));

Form7->allg2_differens.push_back(t);

// поиск минимума при смещении изображений по X

if(t<mindif1)

{

mindif1=t;

x1=xi;

y1=yi;

}

}

Form7->allg2_differens.push_back(99999999);

mindif2=mindif1;

size_t sumdif2;

x2=x1;

y2=H-y1-5;

// смещение изображений по оси Y

for(int dy=0;dy<6;++dy)

{

for(int xi=x1-6;xi<x1+6;++xi)

{

sumdif=0;

sumdif2=0;

for(size_t j=dy;j<H-5;++j)

for(size_t i=xi;i<W-5;++i)

{

sumdif+=abs(VPP[idx].L(i,j).comp[lyr::r_rgb]-

VPP[idx+1].LB(i-xi,j-dy).comp[lyr::r_rgb]+

VPP[idx].L(i,j).comp[lyr::g_rgb]-

VPP[idx+1].LB(i-xi,j-dy).comp[lyr::g_rgb]+

VPP[idx].L(i,j).comp[lyr::b_rgb]-

VPP[idx+1].LB(i-xi,j-dy).comp[lyr::b_rgb]);

sumdif2+=abs(VPP[idx].L(i,j-dy).comp[lyr::r_rgb]-

VPP[idx+1].LB(i-xi,j).comp[lyr::r_rgb]+

VPP[idx].L(i,j-dy).comp[lyr::g_rgb]-

VPP[idx+1].LB(i-xi,j).comp[lyr::g_rgb]+

VPP[idx].L(i,j-dy).comp[lyr::b_rgb]-

VPP[idx+1].LB(i-xi,j).comp[lyr::b_rgb]);

}

double t=((double)sumdif/(double)((W-xi)*(H-dy)));

double t2=((double)sumdif2/(double)((W-xi)*(H-dy)));

// поиск минимума при смещении изображений по Y

if(t<mindif2)

{

mindif2=t;

x2=xi;

y2=dy;

}

if(t2<mindif2)

{

mindif2=t2;

x2=xi;

y2=-dy;

}

}

}

VPan[idx+1]->Left=VPan[idx]->Left+x2;

VPan[idx+1]->Top=VPan[idx]->Top+y2;

VPan[idx+1]->Refresh();

ScrollBox1->Refresh();

++ProgressBar1->Position;

ProgressBar1->Refresh();

}

}

// сшивка по кадру между полосами

mindif1=99999999;

mindif2=99999999;

sumdif=0;

size_t sumdif2=0;

for(int y_idx=1;y_idx<RowCount;++y_idx)

{

size_t idx;

size_t idx1;

// если первая полоса, то берём последний кадр, если вторая, то первый

if((y_idx*5)%2!=0)

{

idx1=ColCount*y_idx+ColCount-1;

idx=idx1-ColCount;

}

else

{

idx1=ColCount*y_idx;

idx=idx1-ColCount;

}

// определяем начальное положение сшиваемого кадра

int dTop=VPan[idx1]->Top;

int dLeft=VPan[idx1]->Left;

Ltmp=VPP[idx].L;

Ltmp1=VPP[idx1].L;

size_t xi=VPP[idx].L.W-5;

for(size_t yi=10;yi<(H-150);++yi)

{

sumdif=0;

for(size_t j=yi;j<H-5;++j)

for(size_t i=5;i<W-5;++i)

{

// расчёт дифференса между изображениями

sumdif+=abs(VPP[idx].L(i,j).comp[lyr::g_rgb]-

VPP[idx1].L(i,j-yi+5).comp[lyr::g_rgb]+VPP[idx].L(i,j).comp[lyr::g_rgb]-

VPP[idx1].L(i,j-yi+5).comp[lyr::g_rgb]

+VPP[idx].L(i,j).comp[lyr::b_rgb]-

VPP[idx1].L(i,j-yi+5).comp[lyr::b_rgb]);

}

double t=((double)sumdif/(double)(xi*(H-yi)));

Form7->allg2_differens.push_back(t);

// поиск минимума разницы между двумя изображениями по зоне перекрытия

if(t<mindif1)

{

mindif1=t;

x1=xi;

y1=yi;

}

}

mindif2=mindif1;

size_t sumdif2;

x2=W-x1-5;

y2=y1;

// цикл расчёта разницы между изображениями при смещении по X

for(int yi=y2-6;yi<y2+6;++yi)

{

for(int dx=0;dx<6;++dx)

{

sumdif=0;

sumdif2=0;

for(int j=yi;j<H-5;++j)

for(int i=dx;i<W-5;++i)

{

sumdif+=abs(VPP[idx].L(i,j).comp[lyr::r_rgb]-

VPP[idx1].LB(i-dx,j-yi).comp[lyr::r_rgb]+

VPP[idx].L(i,j).comp[lyr::g_rgb]-VPP[idx1].LB(i-dx,j-yi).comp[lyr::g_rgb]+

VPP[idx].L(i,j).comp[lyr::b_rgb]-VPP[idx1].LB(i-dx,j-yi).comp[lyr::b_rgb]);

sumdif2+=abs(VPP[idx].L(i-dx,j).comp[lyr::r_rgb]-

VPP[idx1].LB(i,j-yi).comp[lyr::r_rgb]+VPP[idx].L(i-dx,j).comp[lyr::g_rgb]-VPP[idx1].LB(i,j-yi).comp[lyr::g_rgb]+

VPP[idx].L(i-dx,j).comp[lyr::b_rgb]-VPP[idx1].LB(i,j-yi).comp[lyr::b_rgb]);

}

double t=((double)sumdif/(double)((W-dx)*(H-yi)));

double t2=((double)sumdif2/(double)((W-dx)*(H-yi)));

// поиск минимума разницы

if(t<mindif2)

{

mindif2=t;

x2=dx;

y2=yi;

}

if(t2<mindif2)

{

mindif2=t2;

x2=-dx;

y2=yi;

}

}

}

// задаём новое положение кадра

VPan[idx1]->Left=VPan[idx]->Left+x2;

VPan[idx1]->Top=VPan[idx]->Top+y2;

// рассчитываем изменение относительно старого положения

dTop-=VPan[idx1]->Top;

dLeft=VPan[idx1]->Left-dLeft;

VPan[idx1]->Refresh();

ScrollBox1->Refresh();

//положения всех остальных кадров полосы меняем на изменения в положении сшиваемого кадра

for(size_t i=y_idx*ColCount;i<idx1;++i)

{

VPan[i]->Top=VPan[i]->Top-dTop;

VPan[i]->Left=VPan[i]->Left+dLeft;

}

for(int i=idx1+1;i<(y_idx+1)*ColCount;++i)

{

VPan[i]->Top=VPan[i]->Top-dTop;

VPan[i]->Left=VPan[i]->Left+dLeft;

}

}

TDateTime t1=GetTime();

Form1->Caption="Создание панорамных изображений Время работы алгоритма №1 = "+(t1-t);

}

//---------------------------------------------------------------------------

Описание алгоритма №2. Листинг функции PanoramMake2

void TForm1::PanoramMake2(int Overlap,vector<PanoramPart> VPP)

{

TDateTime t=GetTime();

Form8->allg3_differens.clear();

size_t H=VPP[0].L.H;

size_t W=VPP[0].L.W;

//задаём положение первого кадра панорамы

VPan[0]->Left=30;

VPan[0]->Top=30;

// объявление переменных для хранения расчётных значений алгоритма

double mindif1=99999999;

double mindif2=99999999;

size_t sumdif;

int x1,y1;

int x2,y2;

ProgressBar1->Max=VPP.size()-1;

ProgressBar1->Position=0;

for(int y_idx=0;y_idx<RowCount;++y_idx)

{

if(y_idx>0)

{

VPan[y_idx*ColCount]->Left=30;

VPan[y_idx*ColCount]->Top=15+VPan[(y_idx-1)*ColCount]->Top+

VPan[(y_idx-1)*ColCount]->Height;

}

for(int x_idx=0;x_idx<ColCount-1;++x_idx)// цикл по X в панорамной сетке

{

size_t idx=y_idx*ColCount+x_idx;

MyFilter::Filter f;

vector<int> g;

Ltmp=VPP[idx].LB;

Ltmp1=VPP[idx+1].LB;

size_t yi=VPP[idx].L.H-5;

for(size_t xi=10;xi<(W-100);++xi)

{

// расчёт гистограммы для зоны перекрытия

g=f.Gistogr(VPP[idx].LB,g,xi,W-5,5,yi);

//определение порога бинаризации

double c=static_cast<double>(yi*(W-5-xi))*0.7;

size_t i=0,s=0;

while(s<c)

{

s+=g[i];

++i;

}

f.Binarization(VPP[idx].LB,Ltmp,i-1);

f.Binarization(VPP[idx+1].LB,Ltmp1,i-1);

sumdif=0;

// расчёт разницы между изображениями по зоне перекрытия при смещении по X

for(size_t j=5;j<yi;++j)

for(size_t i=xi;i<W-5;++i)

{

sumdif+=abs(VPP[idx].LB(i,j).comp[lyr::r_rgb]-

VPP[idx+1].LB(i-xi,j).comp[lyr::r_rgb]);

}

double t=((double)sumdif/(double)((W-xi)*yi));

Form8->allg3_differens.push_back(t);

// поиск минимума

if(t<mindif1)

{

mindif1=t;

x1=xi;

y1=yi;

}

}

Form8->allg3_differens.push_back(99999999);

mindif2=mindif1;

size_t sumdif2;

// расчёт разницы между изображениями по зоне перекрытия при смещении по Y

x2=x1;

y2=H-y1-5;

for(int dy=0;dy<6;++dy)

{

for(int xi=x1-6;xi<x1+6;++xi)

{

sumdif=0;

sumdif2=0;

for(size_t j=dy;j<H-2;++j)

for(size_t i=xi;i<W-2;++i)

{

sumdif+=abs(VPP[idx].LB(i,j).comp[lyr::r_rgb]-

VPP[idx+1].LB(i-xi,j-dy).comp[lyr::r_rgb]);

sumdif2+=abs(VPP[idx].LB(i,j-dy).comp[lyr::r_rgb]-

VPP[idx+1].LB(i-xi,j).comp[lyr::r_rgb]);

}

double t=((double)sumdif/(double)((W-xi)*(H-dy)));

double t2=((double)sumdif2/(double)((W-xi)*(H-dy)));

// поиск минимума

if(t<mindif2)

{

mindif2=t;

x2=xi;

y2=dy;

}

if(t2<mindif2)

{

mindif2=t2;

x2=xi;

y2=-dy;

}

}

}

VPan[idx+1]->Left=VPan[idx]->Left+x2;

VPan[idx+1]->Top=VPan[idx]->Top+y2;

VPan[idx+1]->Refresh();

ScrollBox1->Refresh();

++ProgressBar1->Position;

ProgressBar1->Refresh();

}

}

// сшивка по кадру между полосами

mindif1=99999999;

mindif2=99999999;

sumdif=0;

size_t sumdif2=0;

for(int y_idx=1;y_idx<RowCount;++y_idx)

{

size_t idx;

size_t idx1;

// если нечётная строка - берём последний кадр

if((y_idx*5)%2!=0)

{

idx1=ColCount*y_idx+ColCount-1;

idx=idx1-ColCount;

}

// если чётная строка - берём первый кадр

else

{

idx1=ColCount*y_idx;

idx=idx1-ColCount;

}

int dTop=VPan[idx1]->Top;

int dLeft=VPan[idx1]->Left;

Ltmp=VPP[idx].L;

Ltmp1=VPP[idx1].L;

size_t xi=VPP[idx].L.W-5;

for(size_t yi=10;yi<(H-150);++yi)

{

sumdif=0;

//расчёт разницы

for(size_t j=yi;j<H-5;++j)

for(size_t i=5;i<W-5;++i)

{

sumdif+=abs(VPP[idx].L(i,j).comp[lyr::g_rgb]-

VPP[idx1].L(i,j-yi+5).comp[lyr::g_rgb]+VPP[idx].L(i,j).comp[lyr::g_rgb]-VPP[idx1].L(i,j-yi+5).comp[lyr::g_rgb]+VPP[idx].L(i,j).comp[lyr::b_rgb]-VPP[idx1].L(i,j-yi+5).comp[lyr::b_rgb]);

}

double t=((double)sumdif/(double)(xi*(H-yi)));

Form8->allg3_differens.push_back(t);

//поиск минимума

if(t<mindif1)

{

mindif1=t;

x1=xi;

y1=yi;

}

}

mindif2=mindif1;

size_t sumdif2;

x2=W-x1-5;

y2=y1;

for(int yi=y2-6;yi<y2+6;++yi)

{

for(int dx=0;dx<6;++dx)

{

sumdif=0;

sumdif2=0;

for(int j=yi;j<H-5;++j)

for(int i=dx;i<W-5;++i)

{

sumdif+=abs(VPP[idx].L(i,j).comp[lyr::r_rgb]-

VPP[idx1].LB(i-dx,j-yi).comp[lyr::r_rgb]+VPP[idx].L(i,j).comp[lyr::g_rgb]-VPP[idx1].LB(i-dx,j-yi).comp[lyr::g_rgb]+VPP[idx].L(i,j).comp[lyr::b_rgb]-VPP[idx1].LB(i-dx,j-yi).comp[lyr::b_rgb]);

sumdif2+=abs(VPP[idx].L(i-dx,j).comp[lyr::r_rgb]-

VPP[idx1].LB(i,j-yi).comp[lyr::r_rgb]+VPP[idx].L(i-dx,j).comp[lyr::g_rgb]-VPP[idx1].LB(i,j-yi).comp[lyr::g_rgb]+VPP[idx].L(i-dx,j).comp[lyr::b_rgb]-VPP[idx1].LB(i,j-yi).comp[lyr::b_rgb]);

}

double t=((double)sumdif/(double)((W-dx)*(H-yi)));

double t2=((double)sumdif2/(double)((W-dx)*(H-yi)));

if(t<mindif2)

{

mindif2=t;

x2=dx;

y2=yi;

}

if(t2<mindif2)

{

mindif2=t2;

x2=-dx;

y2=yi;

}

}

}

VPan[idx1]->Left=VPan[idx]->Left+x2;

VPan[idx1]->Top=VPan[idx]->Top+y2;

dTop-=VPan[idx1]->Top;

dLeft=VPan[idx1]->Left-dLeft;

VPan[idx1]->Refresh();

ScrollBox1->Refresh();

for(size_t i=y_idx*ColCount;i<idx1;++i)

{

VPan[i]->Top=VPan[i]->Top-dTop;

VPan[i]->Left=VPan[i]->Left+dLeft;

}

for(int i=idx1+1;i<(y_idx+1)*ColCount;++i)

{

VPan[i]->Top=VPan[i]->Top-dTop;

VPan[i]->Left=VPan[i]->Left+dLeft;

}

}

TDateTime t1=GetTime();

Form1->Caption="Создание панорамных изображений Время работы алгоритма №2 = "+(t1-t);

}

//---------------------------------------------------------------------------

Описание алгоритма №3. Листинг функции PanoramMake3

void TForm1::PanoramMake3(int Overlap,vector<PanoramPart> VPP)

{

TDateTime t= GetTime();

Form6->allg1_profilX_left.clear();

Form6->allg1_profilX_right.clear();

Form6->allg1_differens.clear();

Form6->allg1_differens_mask.clear();

MyFilter::Filter f;

size_t H=VPP[0].L.H;

size_t W=VPP[0].L.W;

VPan[0]->Left=30;

VPan[0]->Top=30;

// объявление переменных алгоритма

vector<double> vbin10_1;

vector<double> vbin10_2;

vector<double> vbin10_1_y;

vector<double> vbin10_2_y;

vector<double> vbin10_1_down;

vector<double> vbin10_2_down;

vector<double> vbin10_dif;

vector<double> vbin10_dif_up;

vector<double> vbin10_dif_down;

vector<double> vbin10_dif_mask;

vector<double> vbin10_dif_mask_up_down;

vector<int> vdx;

vector<int> vdy_up;

vector<int> vdy_down;

size_t sumdif;

int x1=0,y1=0;

int x2,y2;

int S_obj;

ProgressBar1->Max=RowCount*(ColCount-1);

ProgressBar1->Position=0;

// цикл по Y в панорамной сетке

for(int y_idx=0;y_idx<RowCount;++y_idx)

{

if(y_idx>0)

{

VPan[y_idx*ColCount]->Left=30;

VPan[y_idx*ColCount]->Top=15+

VPan[(y_idx-1)*ColCount]->Top+VPan[(y_idx-1)*ColCount]->Height;

}

vpic.clear();

vdeltax.clear();

vdeltay.clear();

for(int x_idx=0;x_idx<ColCount-1;++x_idx)// цикл по X в панорамной сетке

{

vdx.clear();

vdy_up.clear();

vdy_down.clear();

vbin10_1.clear();

vbin10_2.clear();

vbin10_1_y.clear();

vbin10_2_y.clear();

vbin10_1_down.clear();

vbin10_2_down.clear();

vbin10_dif.clear();

vbin10_dif_up.clear();

vbin10_dif_down.clear();

vbin10_dif_mask.clear();

vbin10_dif_mask_up_down.clear();

size_t k=y_idx*ColCount+x_idx;

Ltmp=VPP[k].LB;

Ltmp1=VPP[k+1].LB;

// бинаризация изображений

f.Binarization(Ltmp,VPP[k].LB,7);//7 порог

f.Binarization(Ltmp1,VPP[k+1].LB,7);//7

for(size_t i=5;i<(W-5);++i)// средний профиль по X

{

double c_bin1=0,c_bin2=0;

for(size_t j=5;j<H-5;++j)

{

c_bin1+=(double)(Ltmp(i,j).comp[lyr::r_rgb]+Ltmp(i,j).comp[lyr::g_rgb]+

Ltmp(i,j).comp[lyr::b_rgb])/3.0;

c_bin2+=(double)(Ltmp1(i,j).comp[lyr::r_rgb]+Ltmp1(i,j).comp[lyr::g_rgb]+

Ltmp1(i,j).comp[lyr::b_rgb])/3.0;

}

vbin10_1.push_back(c_bin1/(double)(H-10));

vbin10_2.push_back(c_bin2/(double)(H-10));

Form6->allg1_profilX_left.push_back(c_bin1/(double)(H-10));

Form6->allg1_profilX_right.push_back(c_bin2/(double)(H-10));

}// конец цикла подсчёта среднего профиля по X

Form6->allg1_profilX_left.push_back(99999999);

Form6->allg1_profilX_right.push_back(99999999);

int right=100;

for(size_t x=0;x<vbin10_1.size()-right;++x) // расчёт дифференса между соседними изображениями

{

double sdifbin10=0;

for(size_t i=x;i<vbin10_1.size();++i)

{

sdifbin10+=abs(vbin10_1[i]-vbin10_2[i-x]);

}

sdifbin10/=(double)(vbin10_1.size()-x);

vbin10_dif.push_back(sdifbin10);

Form6->allg1_differens.push_back(sdifbin10);

vdx.push_back(x);

}// конец расчёта дифференса между соседними изображениями

Form6->allg1_differens.push_back(99999999);

vbin10_dif_mask.resize(vbin10_dif.size(),0);

double max=0;

for(size_t i=2;i<vbin10_dif_mask.size()-2;++i) // маска дифференса и поиск максимума

{

vbin10_dif_mask[i]=abs(-vbin10_dif[i-2]+vbin10_dif[i]*2-vbin10_dif[i+2]);

Form6->allg1_differens_mask.push_back(vbin10_dif_mask[i]);

if(vbin10_dif_mask[i]>max)

{

max=vbin10_dif_mask[i];

x1=vdx[i];

}

}// конец расчёта маски дифференса и поиска максимума

Form6->allg1_differens_mask.push_back(99999999);

vpic.push_back(max);

// обработка маской для сшивки по вертикали

Mask5x5vert(Ltmp,VPP[k].L);

Mask5x5vert(Ltmp1,VPP[k+1].L);

f.Binarization(VPP[k].L,Ltmp,7);

f.Binarization(VPP[k+1].L,Ltmp1,7);

Ltmp=VPP[k].LB;

Ltmp1=VPP[k+1].LB;

size_t sumdif2;

x2=x1;

y2=0;

for(size_t j=5;j<H-5;++j)// средний профиль по оси Y

{

double c_bin1=0,c_bin2=0;

for(size_t i=x2;i<(W-5);++i)

{

c_bin1+=(double)(Ltmp(i,j).comp[lyr::r_rgb]+Ltmp(i,j).comp[lyr::g_rgb]+

Ltmp(i,j).comp[lyr::b_rgb])/3.0;

c_bin2+=(double)(Ltmp1(i-x2+5,j).comp[lyr::r_rgb]+

Ltmp1(i-x2+5,j).comp[lyr::g_rgb]+Ltmp1(i-x2+5,j).comp[lyr::b_rgb])/3.0;

}

vbin10_1_y.push_back(c_bin1/(double)(W-5-x2));

vbin10_2_y.push_back(c_bin2/(double)(W-5-x2));

}// конец расчёта среднего профиля по оси Y

double min=99999999;

for(int x=0;x<5;++x)// расчёт дифференса при смещении картинок отнсительно друг друга вверх и вниз

{

double sdifbin10=0;

double sdifbin10_1=0;

for(size_t i=x;i<vbin10_1_y.size();++i)

{

sdifbin10+=abs(vbin10_1_y[i]-vbin10_2_y[i-x]);

sdifbin10_1+=abs(vbin10_1_y[i-x]-vbin10_2_y[i]);

}

sdifbin10/=(double)(vbin10_1_y.size()-x);

sdifbin10_1/=(double)(vbin10_1_y.size()-x);

vbin10_dif_up.push_back(sdifbin10);

vbin10_dif_down.push_back(sdifbin10_1);

vdy_up.push_back(x);

vdy_down.push_back(-x);

if(sdifbin10<min)

{

min=sdifbin10;

y2=x;

}

if(sdifbin10_1<min)

{

min=sdifbin10_1;

y2=-x;

}

}// конец расчёта дифференса при смещении картинок отнсительно друг друга вверх и вниз

vdeltax.push_back(x2);

vdeltay.push_back(y2);

VPan[k+1]->Left=VPan[k]->Left+x2;

VPan[k+1]->Top=VPan[k]->Top+y2;

VPan[k+1]->Refresh();

ScrollBox1->Refresh();

++ProgressBar1->Position;

ProgressBar1->Refresh();

}// конец цикла по x_idx

double mid=0;

size_t count=0;

double mid_y=0;

size_t count_y=0;

for(size_t i=0;i<vdeltax.size();++i)

{

if(vpic[i]>0.011)

{

mid+=vdeltax[i];

++count;

mid_y+=vdeltay[i];

++count_y;

}

}

if(count==0)++count;

if(count_y==0)++count_y;

mid/=static_cast<double>(count);

mid_y/=static_cast<double>(count_y);

size_t n=ColCount;

for(size_t i=0;i<vpic.size();++i)

{

if(vpic[i]<0.011)

VPan[n*y_idx+i+1]->Left=VPan[n*y_idx+i]->Left+mid;

else

VPan[n*y_idx+i+1]->Left=VPan[n*y_idx+i]->Left+vdeltax[i];

}

} // конец цикла по y_idx

//---------------------------------------------

// сшивка по кадру между полосами

vector<double> vbin101;

vector<double> vbin102;

vector<double> vdif;

vector<double> vdif1;

vector<double> vdif_mask;

vector<int> vdx1;

vector<int> vdx2;

vector<int> vdy;

for(int y_idx=1;y_idx<RowCount;++y_idx)

{

size_t max_top_idx=y_idx*ColCount;

int max_top=0;

for(int idx=y_idx*ColCount;idx<(y_idx+1)*ColCount;++idx)

if(VPP[idx].idxTop>max_top)

{

max_top=VPP[idx].idxTop;

max_top_idx=idx;

}

vbin101.clear();

vbin102.clear();

vdif.clear();

vdif_mask.clear();

vdy.clear();

size_t idx=max_top_idx-ColCount;

size_t idx1=max_top_idx;

int dTop=VPan[idx1]->Top;

int dLeft=VPan[idx1]->Left;

Ltmp=VPP[idx].L;

Ltmp1=VPP[idx1].L;

Mask5x5(VPP[idx].LB,Ltmp);

Mask5x5(VPP[idx1].LB,Ltmp1);

f.Binarization(Ltmp,VPP[idx].LB,7);//7 порог

f.Binarization(Ltmp1,VPP[idx1].LB,7);//7

double max=0;

for(size_t k=0;k<451;k+=25)

{

vbin101.clear();

vbin102.clear();

vdif.clear();

vdif_mask.clear();

vdx1.clear();

vdx2.clear();

for(size_t i=5;i<(W-5);++i)

{

double c_bin1=0;

for(size_t j=H-5-50-k;j<H-5-k;++j)

c_bin1+=(double)(Ltmp(i,j).comp[lyr::r_rgb]+

Ltmp(i,j).comp[lyr::g_rgb]+Ltmp(i,j).comp[lyr::b_rgb])/3.0;

vbin101.push_back(c_bin1/(double)(45));

}

for(size_t i=5;i<(W-5);++i)

{

double c_bin2=0;

for(size_t j=5;j<90;++j)

c_bin2+=(double)(Ltmp1(i,j).comp[lyr::r_rgb]+

Ltmp1(i,j).comp[lyr::g_rgb]+Ltmp1(i,j).comp[lyr::b_rgb])/3.0;

vbin102.push_back(c_bin2/(double)(45));

}

for(int x=0;x<vbin101.size()-150;++x)

{

double sdifbin10=0;

double sdifbin10_1=0;

for(size_t i=x;i<vbin101.size();++i)

{

sdifbin10+=abs(vbin101[i]-vbin102[i-x]);

sdifbin10_1+=abs(vbin101[i-x]-vbin102[i]);

}

sdifbin10/=(double)(vbin101.size()-x);

sdifbin10_1/=(double)(vbin101.size()-x);

vdif.push_back(sdifbin10);

vdif1.push_back(sdifbin10_1);

vdx1.push_back(x);

vdx2.push_back(-x);

}

vdif_mask.resize(vdif.size(),0);

for(size_t i=3;i<vdif_mask.size()-3;++i)

{

double t=abs(-vdif[i-3]+vdif[i]*2-vdif[i+3]);

double t1=abs(-vdif1[i-3]+vdif1[i]*2-vdif1[i+3]);

if(t>max)

{

max=t;

y1=0;

x1=vdx1[i];

vdif_mask[i]=t;

}

if(t1>max)

{

max=t1;

y1=0;

x1=vdx2[i];

vdif_mask[i]=t1;

}

}

}

x2=x1;

y2=y1;

//----конец поиска минимума по Х

vbin101.clear();

vbin102.clear();

vdif.clear();

vdif1.clear();

vdif_mask.clear();

vdx1.clear();

vdx2.clear();

vbin101.reserve(100);

vbin102.reserve(100);

vdif.reserve(100);

vdif1.reserve(100);

vdif_mask.reserve(100);

vdx1.reserve(100);

vdx2.reserve(100);

Ltmp=VPP[idx].L;

Ltmp1=VPP[idx1].L;

Mask5x5vert(VPP[idx].LB,Ltmp);

Mask5x5vert(VPP[idx1].LB,Ltmp1);

f.Binarization(Ltmp,VPP[idx].LB,7);//7 порог

f.Binarization(Ltmp1,VPP[idx1].LB,7);//7

if(x1>=0)

for(size_t j=H/4;j<H-5;++j)// средний профиль по оси Y

{

double c_bin1=0,c_bin2=0;

for(size_t i=x1;i<(W-5);++i)

{

c_bin1+=(double)(Ltmp(i,j).comp[lyr::r_rgb]+

Ltmp(i,j).comp[lyr::g_rgb]+Ltmp(i,j).comp[lyr::b_rgb])/3.0;

c_bin2+=(double)(Ltmp1(i-x1+5,j-H/4+5).comp[lyr::r_rgb]+

Ltmp1(i-x1+5,j-H/4+5).comp[lyr::g_rgb]+Ltmp1(i-x1+5,j-H/4+5).comp[lyr::b_rgb])/3.0;

}

vbin101.push_back(c_bin1/(double)(W-5-x1));

vbin102.push_back(c_bin2/(double)(W-5-x1));

}// конец расчёта среднего профиля по оси Y

else

for(size_t j=H/4;j<H-5;++j)// средний профиль по оси Y

{

double c_bin1=0,c_bin2=0;

for(size_t i=5;i<(W-5)+x1;++i)

{

c_bin1+=(double)(Ltmp(i,j).comp[lyr::r_rgb]+

Ltmp(i,j).comp[lyr::g_rgb]+Ltmp(i,j).comp[lyr::b_rgb])/3.0;

c_bin2+=(double)(Ltmp1(i-x1,j-H/4+5).comp[lyr::r_rgb]+

Ltmp1(i-x1,j-H/4+5).comp[lyr::g_rgb]+Ltmp1(i-x1,j-H/4+5).comp[lyr::b_rgb])/3.0;

}

vbin101.push_back(c_bin1/(double)(W-10+x1));

vbin102.push_back(c_bin2/(double)(W-10+x1));

}// конец расчёта среднего профиля по оси Y

for(size_t x=0;x<vbin101.size()-20;++x)// дифференс

{

double sdifbin10=0;

for(size_t i=x;i<vbin101.size();++i)

sdifbin10+=abs(vbin101[i]-vbin102[i-x]);

sdifbin10/=(double)(vbin101.size()-x);

vdif.push_back(sdifbin10);

vdy.push_back(x+H/4-5);

}// конец расчёта дифференса

vdif_mask.resize(vdif.size(),0);

max=-100;

for(size_t i=3;i<vdif_mask.size()-3;++i)// маска и поиск максимума

{

double t=abs(-vdif[i-3]+vdif[i]*2-vdif[i+3]);

vdif_mask[i]=abs(-vdif[i-3]+vdif[i]*2-vdif[i+3]);

if(t>max)

{

max=t;

vdif_mask[i]=t;

y2=vdy[i];

}

} // конец поиска максимума

size_t sumdif2;

vdeltax.push_back(x2);

vdeltay.push_back(y2);

vpic.push_back(max);

VPan[idx1]->Left=VPan[idx]->Left+x2;

VPan[idx1]->Top=VPan[idx]->Top+y2;

dTop-=VPan[idx1]->Top;

dLeft=VPan[idx1]->Left-dLeft;

VPan[idx1]->Refresh();

ScrollBox1->Refresh();

for(size_t i=y_idx*ColCount;i<idx1;++i)

{

VPan[i]->Top=VPan[i]->Top-dTop;

VPan[i]->Left=VPan[i]->Left+dLeft;

}

for(int i=idx1+1;i<(y_idx+1)*ColCount;++i)

{

VPan[i]->Top=VPan[i]->Top-dTop;

VPan[i]->Left=VPan[i]->Left+dLeft;

}

}

TDateTime t1=GetTime();

Form1->Caption="Создание панорамных изображений Время работы алгоритма №3 = "+(t1-t);

}

//---------------------------------------------------------------------------

Описание алгоритма №4. Листинг функции PanoramMake4

void TForm1::PanoramMake4(int Overlap,vector<PanoramPart> VPP)

{

TDateTime t=GetTime();

Form12->allg4_profilX_left.clear();

Form12->allg4_profilX_right.clear();

Form12->allg4_differens.clear();

Form12->allg4_differens_mask.clear();

MyFilter::Filter f;

size_t H=VPP[0].L.H;

size_t W=VPP[0].L.W;

VPan[0]->Left=30;

VPan[0]->Top=30;

vector<double> vbin10_1;

vector<double> vbin10_2;

vector<double> vbin10_1_y;

vector<double> vbin10_2_y;

vector<double> vbin10_1_down;

vector<double> vbin10_2_down;

vector<double> vbin10_dif;

vector<double> vbin10_dif_up;

vector<double> vbin10_dif_down;

vector<double> vbin10_dif_mask;

vector<double> vbin10_dif_mask_up_down;

vector<int> vdx;

vector<int> vdy_up;

vector<int> vdy_down;

size_t sumdif;

int x1=0,y1=0;

int x2,y2;

int S_obj;

ProgressBar1->Max=RowCount*(ColCount-1);

ProgressBar1->Position=0;

// цикл по Y в панорамной сетке

for(int y_idx=0;y_idx<RowCount;++y_idx)

{

vpic.clear();

vdeltax.clear();

vdeltay.clear();

for(int x_idx=0;x_idx<ColCount-1;++x_idx)// цикл по X в панорамной сетке

{

vdx.clear();

vdy_up.clear();

vdy_down.clear();

vbin10_1.clear();

vbin10_2.clear();

vbin10_1_y.clear();

vbin10_2_y.clear();

vbin10_1_down.clear();

vbin10_2_down.clear();

vbin10_dif.clear();

vbin10_dif_up.clear();

vbin10_dif_down.clear();

vbin10_dif_mask.clear();

vbin10_dif_mask_up_down.clear();

size_t k=y_idx*ColCount+x_idx;

if(Vfixed[k])

{

continue;

}

if(VPP[k].idxRight>1000)

{

VPP[k].StitchedRight=true;

VPP[k+1].StitchedLeft=true;

if(y_idx==0)

Vfixed[k]=true;

}

Ltmp=VPP[k].LB;

Ltmp1=VPP[k+1].LB;

f.Binarization(Ltmp,VPP[k].LB,7);//7 порог

f.Binarization(Ltmp1,VPP[k+1].LB,7);//7

for(size_t i=5;i<(W-5);++i)// средний профиль по X

{

double c_bin1=0,c_bin2=0;

for(size_t j=5;j<H-5;++j)

{

c_bin1+=(double)(Ltmp(i,j).comp[lyr::r_rgb]+Ltmp(i,j).comp[lyr::g_rgb]+

Ltmp(i,j).comp[lyr::b_rgb])/3.0;

c_bin2+=(double)(Ltmp1(i,j).comp[lyr::r_rgb]+

Ltmp1(i,j).comp[lyr::g_rgb]+Ltmp1(i,j).comp[lyr::b_rgb])/3.0;

}

vbin10_1.push_back(c_bin1/(double)(H-10));

vbin10_2.push_back(c_bin2/(double)(H-10));

Form12->allg4_profilX_left.push_back(c_bin1/(double)(H-10));

Form12->allg4_profilX_right.push_back(c_bin2/(double)(H-10));

}// конец цикла подсчёта среднего профиля по X

Form12->allg4_profilX_left.push_back(99999999);

Form12->allg4_profilX_right.push_back(99999999);

int right=100;

for(size_t x=0;x<vbin10_1.size()-right;++x) // расчёт дифференса между соседними изображениями

{

double sdifbin10=0;

for(size_t i=x;i<vbin10_1.size();++i)

{

sdifbin10+=abs(vbin10_1[i]-vbin10_2[i-x]);

}

sdifbin10/=(double)(vbin10_1.size()-x);

vbin10_dif.push_back(sdifbin10);

Form12->allg4_differens.push_back(sdifbin10);

vdx.push_back(x);

}// конец расчёта дифференса между соседними изображениями

Form12->allg4_differens.push_back(99999999);

vbin10_dif_mask.resize(vbin10_dif.size(),0);

double max=0;

for(size_t i=2;i<vbin10_dif_mask.size()-2;++i) // маска дифференса и поиск максимума

{

vbin10_dif_mask[i]=abs(-vbin10_dif[i-2]+vbin10_dif[i]*2-vbin10_dif[i+2]);

Form12->allg4_differens_mask.push_back(vbin10_dif_mask[i]);


Подобные документы

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.