Вы находитесь на странице: 1из 201

Аннотация

В настоящей работе выполнен обзор существующих способов кодирования


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

1
Оглавление
1. Введение.....................................................................................................................................4
1.1. Представление изображений в цифровом виде...............................................................4
1.2. Кодирование видеоизображений с предсказанием.........................................................9
1.3. Кодирование видеоизображений с помощью преобразований....................................11
1.4. Стандарт цифрового сжатия MPEG-2............................................................................14
1.4.1. Пространственное сжатие.........................................................................................14
1.4.2. Временное сжатие.....................................................................................................16
2. Разработка имитационной модели.........................................................................................21
3. Разработка программных модулей........................................................................................28
3.1. Выбор сторонних компонент..........................................................................................28
3.2. Разработка функционала программы.............................................................................28
3.2.1. Разработка функционала работы с ДИКМ..............................................................28
3.2.2. Разработка функционала работы с преобразованием Адамара............................29
3.2.3. Разработка функционала работы с MPEG...............................................................30
3.2.4. Разработка функционала работы с шумами канала...............................................31
4. Разработка тестов....................................................................................................................32
4.1. Тесты в режиме отладки..................................................................................................32
4.2. Функциональные тесты....................................................................................................33
5. Разработка методики и проведение эксперимента на имитационной модели..................36
5.1. Исследование способов кодирования изображений.....................................................36
5.2. Исследование реакции различных кодеров на шум......................................................44
5.3. Завершение работы...........................................................................................................45
6. Экономическое обоснование НИР.........................................................................................46
6.1. Оценка прогрессивности НИР.........................................................................................46
6.2. Оценка новизны НИР.......................................................................................................47
6.3. Календарное планирование работ...................................................................................48
6.4. Определение показателей экономического обоснования.............................................49
6.5. Определение цены на НТПр............................................................................................51
6.6. Оценка экономической эффективности НТПр..............................................................51
7. Охрана труда и окружающей среды. Обеспечение условий труда при компьютерном
моделировании.............................................................................................................................53
7.1. Анализ условий труда при работе с ПЭВМ...................................................................53
7.2. Вентиляция помещения...................................................................................................55
7.2.1. Расчет выделения тепла............................................................................................55
7.2.2. Расчет потребного воздухообмена...........................................................................57
7.2.3. Определение поперечных размеров воздуховода..................................................58
7.2.4. Определение сопротивления сети............................................................................58
7.2.5. Подбор вентилятора и электродвигателя................................................................59
7.3. Расчет кондиционирования.............................................................................................59
7.4. Требования по шуму и вибрации....................................................................................60
7.5. Противопожарные мероприятия.....................................................................................60
8. Вывод........................................................................................................................................63
9. Список использованной литературы.....................................................................................64
Приложение 1. Алгоритмы работы программы.......................................................................65
Приложение 2. Образцы работы ДИКМ и преобразования Адамара....................................74
П2.1. ДИКМ..............................................................................................................................74
П2.2. Преобразование Адамара..............................................................................................75
Приложение 3. Текст программы...............................................................................................78
П3.1. Transforms.dpr.................................................................................................................78
П3.2. Unit1.pas..........................................................................................................................79
П3.3. Unit1.dfm.......................................................................................................................126
2
П3.4. Unit2.pas........................................................................................................................163
П3.5. Unit2.dfm.......................................................................................................................164
Приложение 4. Результаты функционального тестирования................................................165
П4.1. ДИКМ............................................................................................................................165
П4.2. Преобразование Адамара............................................................................................170
П4.3. MPEG-кодирование.....................................................................................................174
Приложение 5. Слайды.............................................................................................................175

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

1.1. Представление изображений в цифровом виде


Видеоизображения в общем случае могут быть представлены как непрерывные случайные
функции B ( x, y , t ) , зависящие от двух пространственных координат и времени. На
ограниченном отрезке и времени, и пространства в общем случае аргументы имеют
несчетное множество значений, а значит, несчетно и общее количество возможных
изображений. Для хранения в цифровом виде и передачи по цифровому каналу
необходимо перейти от несчетного множества изображений к счетному, а значит, и к
представлению изображений в цифровом виде.
Эта задача теоретически может решаться путем обобщенного квантования. При
обобщенном квантовании все пространство возможных изображений разбивается на
конечное множество подпространств, которые пронумеровываются. Далее все
изображения, попадающие в одно подпространство, заменяются одним представителем,
которому присваивается номер подпространства, и храниться и передаваться может
только номер изображения-представителя. При этом возникают ошибки представления,
которые характеризуются мерой отличия реальных изображений от изображений-
представителей. Обобщенное квантование позволяет решать задачи хранения и передачи
по цифровому каналу наиболее эффективно с точки зрения наименьшей требуемой
скорости передачи при заданном критерии точности воспроизведения. Однако технически
это решение труднореализуемо, за исключением некоторых особых случаев, поэтому на
практике используют менее эффективную, но более легко реализуемую процедуру
преобразования изображения в цифровую форму, включающую пространственную и
временную дискретизацию изображения, а также поэлементное квантование.
Задача пространственной дискретизации заключается в преобразовании непрерывной
функции B ( x, y ) , описывающей неподвижное изображение, в дискретную B ( xi , y j ) ,
заданную на дискретном множестве точек с координатами xi и y j , где в общем случае
   i   ,    j   . Множество этих точек образует решетку, которую называют
растром, а B ( xi , y j ) - выборочными элементами или отсчетами изображения.
Дополнительным ограничением для решения этой задачи являются необходимость
возможности восстановления непрерывной функции B ( x, y ) по значениям B ( xi , y j ) с
допустимой величиной ошибок при минимальном количестве элементов изображения,
приходящихся на единицу поверхности изображения. Это условие диктуется
необходимостью получения минимально возможного объема данных, описывающего
изображение с допустимой точностью.
Элементы изображения располагаются в узлах регулярной решетки с равными
интервалами между точками, что вытекает из конструкционных требований аппаратуры.
Наибольшее распространение для дискретизации сигналов получил подход, основанный
на теореме Котельникова.
4
Пусть изображение – непрерывная и неограниченная в пространстве функция двух
координат B ( x, y ) , для которой можно найти пространственный спектр S ( x ,  y ) :
 
S ( x ,  y )    B( x, y )  exp 
  
j ( x  x   y  y ) dxdy ,

(1.1)
где  x и  y - пространственные круговые частоты по оси x и y , j   1 .
В силу инерционности устройств, формирующих оптические изображения, а также
статистических свойств источников визуальных сообщений, можно считать, что для
большого класса изображений этот спектр спадает с ростом пространственных частот и за
пределами некоторой области становится равен нулю. Эту область можно ограничить
прямоугольником, стороны которого равны 2W x и 2W y , где W x и W y - значение
пространственных частот по осям  x и  y , выше которых S ( x ,  y )  0 . Модуль
спектра (1.1) показан на рис. 1.1.

Рис. 1.1. Модуль спектра S ( x ,  y )

Рассмотрим простой ортогональный растр с элементами, расположенными в узлах


прямоугольной решетки. Дискретизированное изображение B ( xi , y j ) в трехмерном
пространстве можно представить в виде пространственных  -импульсов, расположенных
в узлах ортогонального растра, амплитуда которых равна B ( xi , y j ) (см. рис. 1.2).
Модулирующей функцией является изображение B ( x, y ) , показанное на рис. 1.2
пунктиром.

5
Рис. 1.2. Изображение B ( xi , y j ) в трехмерном пространстве в виде  -импульсов

Аналитически продискретизированное изображение B ( xi , y j ) можно записать в


следующем виде:
B ( xi , y j )  B( x, y )  ( x  xi , y  y j ) ,
i j

(1.2)
где  ( x, y ) - двухмерная  -функция.
Спектр произведения двух функций есть свертка спектров исходных функций. Спектр
исходного изображения S ( x ,  y ) задается формулой (1.1), а спектр пространственных
 -функций, показанный на рис. 3, представляет собой периодическую структуру из
двухмерных  -функций в области пространственных частот, имеющую период по оси
2 2
 x , равный , а по оси  y - y , где x  xi  xi 1 ; y  y j  y j 1 . Аналитически
x
его можно записать в следующем виде:
2i 2j
S  ( x ,  y )  ( 2 ) 2   ( x  , y  )
i j x y
(1.3)
Используя фильтрующее свойство  -функций, после свертки спектров (1.1) и (1.3)
получается спектр дискретизированного изображения S g ( x ,  y ) , который отличается от
(1.3) тем, что на месте каждой из  -функций в области пространственных частот
появился спектр исходного непрерывного изображения S ( x ,  y ) (на рис. 1.3 изображен
пунктиром).

Рис. 1.3. Спектр дискретизированного изображения S g ( x ,  y )


Если спектральные компоненты не перекрываются, то есть при условии
 
 Wx ,  Wy ,
x y
(1.4)
то из дискретизированного изображения можно точно восстановить исходное
непрерывное изображение путем удаления высокочастотных компонент спектра.
С учетом сказанного можно сформулировать обобщенную теорему Котельникова. Любое
непрерывное изображение, имеющее конечный пространственный спектр, полностью
определяется своими элементами, расположенными в узлах прямоугольной решетки,
интервалы между узлами которой удовлетворяют условию

6
 
x  , y  .
Wx Wy
(1.5)
Реальные изображения никогда не удовлетворяют условиям теоремы Котельникова,
поскольку они имеют ограниченные в пространстве размеры, а значит, бесконечный
спектр. Кроме того, для идеального восстановления B ( x, y ) нужно иметь бесконечное
число отсчетов, что реально невозможно. Поэтому в процессе дискретизации и
восстановления изображения всегда появляются ошибки.
При дискретизации реальных изображений и при использовании практически
реализуемых восстанавливающих фильтров возникают ошибки следующих видов:
стробоскопические, ошибки ограничения спектра, муаровые, частотные и ошибки типа
«ложных узоров».
За дискретизацией аналогового изображения следует квантование его по уровню. Весьма
часто используется импульсно-кодовая модуляция (ИКМ), называемая также кодово-
импульсной (КИМ). Примером формата хранения изображений, использующего КИМ,
является bmp. При использовании ИКМ каждый отсчет изображения представляется
кодовым словом, состоящим из m символов (для двоичных кодов, естественно, символов
два – нуль и единица). В этом случае общее число возможных m-символьных кодовых
комбинаций, равное числу уровней квантования ТВ-сигнала, будет
N  2m (1.6)
Очевидно, что качество воспроизводимых изображений зависит от выбранного
количества уровней квантования, причем чем выше уровней квантования, тем выше
качество. С другой стороны, увеличение числа символов m увеличивает объем данных,
необходимых для представления изображения фиксированного размера, увеличивает
требования к доступной скорости передачи по цифровому каналу R. Поэтому возникает
задача такого выбора числа уровней квантования, при котором заданное качество
воспроизводимых изображений достигается при минимальных требованиях к R.
В измерительных системах качество изображения оценивается величиной ошибок
квантования. В этом случае число m выбирается исходя из допустимой максимальной
ошибки квантования, или из допустимого среднеквадратического значения ошибки
квантования. Указанные ошибки зависят от закона распределения мгновенных значений
сигнала яркости, а также от типа преобразователя аналог-цифра (АЦП). Плотность
вероятности сигнала яркости хорошо аппроксимируется равномерным законом
распределения, и ошибки квантования минимальны, если используется АЦП с
равномерным шагом квантования.
Такой подход неоптимален для систем, в которых получателем информации является
человек, и поэтому при выборе числа m учитывают особенности субъективного
восприятия квантованных изображений. Ошибки квантования незаметны наблюдателю,
если их величина меньше яркостного порога B , под которым понимается минимальная
разность между яркостью цветового пятна и яркостью фона Bф , различимая глазом.
Экспериментально установлена закономерность, называемая законом Вебера-Фехнера,
утверждающая, что в большом диапазоне яркостей остается постоянным пороговый
контраст   B / Bф . Тогда для незаметности ошибок квантования шаг квантования
нужно выбирать соответствующим Bmin  Bфmin   . В этом случае
 Bфmax 
 1
Bфmax  Bфmin  B фmin 
m  log 2  log 2   (1.7)
Bmin   
 
 
При больших размерах тестового пятна пороговый контраст равен примерно 0,02. При
близком к реальности отношении Bфmax / Bф min  100 получим m=15. В этом случае
ошибки квантования будут незаметны даже при минимальной яркости фона, при больших

7
значениях яркости яркостный порог во много раз больше. Используя неравномерную
шкалу квантования яркости, например, логарифмическую, можно добиться снижения m
до 8.
Использованное значение порогового контракта, однако, достигается только в условиях
длительной адаптации глаза к выбранной освещенности фона и при длительном
рассматривании изображения. Эти условия почти никогда не соблюдаются для
видеоизображений; прямой эксперимент показывает, что высокое качество
восстановленного изображения обеспечивается уже при m=7 для логарифмической шкалы
квантования или m=8 для равномерной шкалы.
Величина  также увеличивается приблизительно на два порядка при уменьшении
тестового пятна до размеров, соответствующих пропускной способности человеческого
зрения. Существует взаимозависимость между разрешающей способностью восприятия
деталей  д , градационной разрешающей способностью  г и чувствительностью зрения
к восприятию движения  дв . Приблизительно ее можно записать в виде  д  г  дв  const ,
так что взаимосвязь этих параметров можно представить в виде гиперболической
поверхности (см. рис. 1.4). При этом предполагается, что пропускная способность зрения
ограничена и конечна. Поэтому при передаче быстрого движения допустима пониженная
разрешающая способность при передаче мелких деталей и уменьшенное число
воспроизводимых градаций, передача контрастных деталей изображения ограничивает
требования к скорости движения и числу градаций и, наконец, передача изображений
большой площади с большим числом различимых градаций ограничивает требования к
скорости движения и передаче мелких деталей. Число уровней квантования при передаче
мелких деталей, а также резких перепадов яркости, можно уменьшать до 2-3.

Δ
Рис. 1.4. Идеализированная пространственная модель пропускной способности зрения.
Ошибки квантования яркости видеоизображения являются сильно коррелированными, и
воспринимаются зрителем как ложные контуры. Для снижения их заметности
используется введение в сигнал частотных предыскажений, а также псевдошумовое
квантование.
Квантование цветности соответствует разбиению цветового треугольника на
элементарные участки так, чтобы внутри каждого различия в цветности не были видны
для глаза. Экспериментально установлено, что число таких участков составляет от одной
до нескольких тысяч. Аналогично, экспериментально установлены приемлемые нормы на
квантование разностных сигналов – по шесть разрядов на каждый при нелинейной шкале
квантования, учитывающей величину зрительных порогов.
Чувствительность зрения к цвету мелких деталей существенно меньше, чем к цвету
крупных. Поэтому ширина полосы сигналов цветности при кодировании

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

1.2. Кодирование видеоизображений с предсказанием


Элементы видеоизображения сильно коррелированы как в горизонтальном и
вертикальном направлениях, так и во времени. Наличие этой корреляционной связи
обуславливает большую статистическую избыточность КИМ-кодированного
представления изображения. Первым способом кодирования, который позволяет
сократить эту избыточность, стало кодирование с предсказанием. В этом случае по
одному или нескольким предшествующим отсчетам предсказывается величина
последующего. Затем предсказанное значение сравнивается с истинным, и хранится или
передается разность между предсказанным и истинным значением. Этот метод
кодирования получил название дифференциальной импульсно-кодовой модуляции
(ДИКМ). Частным случаем ДИКМ является дельта-модуляция, при которой разностный
сигнал квантуется всего на два уровня.
Все системы с ДИКМ разделяются на три основные группы в зависимости от того, как
выбираются элементы, по которым ведется предсказание. В одномерных системах
предсказание ведется по одному измерению – например, межэлементное, межстрочное
или межкадровое предсказание. В двухмерных системах используется предсказание по
двум координатам, а в трехмерных – сразу по трем: по горизонтали, вертикали и времени.
Алгоритм предсказания случайного процесса, обеспечивающий минимальные ошибки,
может быть найден методами математического синтеза. Наибольшее распространение
получил метод линейного предсказания, в соответствии с которым предсказываемое
~
значение S ц (t r 1 ) формируется в виде взвешенной суммы нескольких предыдущих
~ ~ ~
отсчетов S ц (t ), S ц (t ),..., S ц (t ) . Для одномерной системы с ДИКМ алгоритм работы
r r 1 r n
линейного предсказателя (экстраполятора) определяется следующим выражением:
~ n
S ц (t r 1 )   ai S ц (t r -i )
i 0
(1.8)
где ai - весовые коэффициенты, n – величина, называемая порядком предсказания.
При этом предсказание аналогично при использовании в качестве предыдущих отсчетов
предыдущих элементов строки, элементов предыдущих строк или предыдущих кадров.
Изменяются лишь весовые коэффициенты и время задержки.
Наиболее простым является кодирование с предсказателем нулевого порядка (n=0), для
которого a 0  1 . Очевидно, предсказанное значение в этом случае совпадет со значением
предыдущего отсчета, и хранится или передается разность между текущим отсчетом и
предыдущим. Простота подобного предсказателя привела к его широкому использованию.
Двухмерный и трехмерный предсказатели более сложны. В аналоговой технике для их
работы необходимы линии задержки, равные длительности строки и кадра,
соответственно; в цифровом случае они сложнее алгоритмически.
Уменьшение избыточности в ДИКМ-кодировании основано на том, что, как правило,
диапазон значений разностного сигнала значительно меньше диапазона значений
исходного сигнала, что позволяет при сохранении неизменным шага квантования
сократить число уровней квантования. Кроме того, плотность распределения мгновенных
значений разностного сигнала является существенно неравномерной (распределение
имеет форму, близкую к гауссовой кривой), что позволяет использовать АЦП с
нелинейной шкалой квантования, то есть в области вероятных значений разностного
сигнала выбирать шаг квантования малым, а в области маловероятных значений,
соответствующих резким перепадам яркости, увеличивать его. При сохранении

9
субъективного качества восстановленного изображения в таком случае требуется меньше
уровней квантования, чем при использовании АЦП с равномерным шагом квантования.
Кроме шума квантования в системе с ДИКМ присутствуют специфические искажения:
шум перегрузки по крутизне и гранулярный шум (шум зернистой структуры). Природа
возникновения этих искажений проиллюстрирована на рис. 1.5.

Рис. 1.5. Специфические искажения ДИКМ: шум перегрузки по крутизне и гранулярный


шум

Шум перегрузки по крутизне возникает при кодировании резких изменений сигнала


яркости. При этом величина разностного сигнала оказывается больше динамического
диапазона и ограничивается. Шум перегрузки по крутизне проявляется на изображении
как нелинейные искажения.
Гранулярный шум возникает при кодировании сигнала с медленно изменяющимся
уровнем. При этом кодированное представление имеет вид колебания, размах которого
равен минимальному шагу квантования. Гранулярный шум приводит к возрастанию
уровня шумов на изображении и появлению муара на больших поверхностях постоянного
уровня яркости.
Особенностью систем ДИКМ, как и других систем дифференциального кодирования,
является накопление ошибки. Ошибки в одномерной системе с межэлементным
предсказанием проявляются на декодированном изображении в виде горизонтальных
полос. Для борьбы с этим уменьшают коэффициент a 0 предсказателей кодера и декодера
или же время от времени передают вместо разностного сигнала непосредственное
значение отсчета. Переход к двухмерному предсказателю также ведет к резкому
улучшению субъективного качества изображения благодаря улучшению передачи
вертикально ориентированных перепадов яркости.
Экспериментально установлено, что использование для устранения избыточности
одномерного линейного предсказания по элементам строки позволяет сократить с 8 до 4
число разрядов кодовых слов при неизменном субъективном качестве изображения. При
использовании же одномерного предсказания по элементам изображения предыдущих
кадров оказывается возможным кодировать видеоизображение даже так, что на каждый
элемент изображения приходится в среднем один двоичный разряд, что обусловлено
сильной корреляцией элементов изображения соседних кадров.

1.3. Кодирование видеоизображений с помощью преобразований


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

10
Метод кодирования изображений с помощью преобразований является по существу
практическим приближением к реализации метода обобщенного квантования. При
кодировании с помощью преобразований изображение представляется многомерным
вектором в некотором пространстве, координатами которого являются базисные
изображения. Очевидно, что любой многомерный вектор однозначно определяется
своими проекциями на координатные оси, то есть может быть представлен в виде суммы
взвешенных с весовыми коэффициентами базисных векторов (изображений). Весовые
коэффициенты вычисляются в результате преобразования и хранятся, что эквивалентно
хранению номера изображения-представителя при обобщенном квантовании.
В настоящее время наиболее разработанными являются линейные ортогональные
преобразования, при которых, как правило, выполняются следующие операции:
- изображение разделяется на фрагменты прямоугольной или квадратной формы;
- производится линейное преобразование групп отсчетов каждого фрагмента;
- кодируются коэффициенты, вычисленные в результате преобразования сигнала.
Для обработки фрагментов изображений в основном используются ортогональные
преобразования следующих типов: преобразования Фурье, Хаара, Адамара, наклонное
преобразование, преобразование Карунена-Лоэва и синусно-косинусное преобразование.
Возможность сокращения избыточности при кодировании изображения с помощью
преобразований обусловлена тем, что большое число вычисленных коэффициентов
разложения при правильно выбранной системе базисных изображений имеет малую
величину и может не храниться. На восстановленном изображения это будет практически
незаметно.
При выполнении преобразования исходный фрагмент изображения представляется в виде
матрицы s   s (i, j )
s (1,1), s (1,2), ..., s (1, n)
s ( 2,1) s ( 2,2) ..., s ( 2, n)
s 
... ... ... ...
s ( n,1) s ( n,2) ... s ( n, n)
(1.9)
Каждый элемент матрицы (1.9) s (i, j ) есть просто отсчет яркости соответствующего
элемента изображения. В результате преобразования вычисляется матрицы
коэффициентов преобразования c   c ( k , l ) :
c (1,1), c (1,2), ..., c (1, n )
c ( 2,1) c ( 2,2) ..., c ( 2, n)
c 
... ... ... ...
c ( n,1) c ( n, 2) ... c ( n, n )
(1.10)
n n
где c (k , l )   a klij s (i, j ) ,
i 1 j 1

aklij - элементы матрицы преобразования Akl , имеющей смысл базисного


изображения. Базисные изображения для преобразования Адамара показаны на рис. 1.6.

11
Рис. 1.6. Базисные изображения для преобразования Адамара

Каждый из элементов матрицы (1.10) определяется всеми элементами исходного


изображения. Декодированию изображения соответствует обратное преобразование, в
результате которого восстанавливаются элементы исходного изображения
n n
s (i, j )   a klij c (*k ,l )
*

k 1 l 1
(1.11)
*
Звездочкой в (1.11) отмечено то, что восстановленные коэффициенты c( k ,l ) могут
отличаться от исходных из-за квантования коэффициентов матрицы, а при передаче
изображения – из-за помех в канале передачи.
Линейное преобразование само по себе не устраняет избыточности, однако в результате
преобразования энергия элементов s (i, j ) существенно перераспределяется между
элементами матрицы c , что создает предпосылки для сокращения объема хранимой
информации. Число уровней квантования для коэффициентов преобразования c ( k , l ) ,
имеющих малую величину, можно резко уменьшить или вовсе отбросить их.
Методы квантования коэффициентов преобразования разделяются на адаптивные и
неадаптивные. К неадаптивным методам относится метод зонального отбора. В
соответствии с этим методом передают только те коэффициенты преобразования, которые
принадлежат определенной зоне. Зона определяется для множества передаваемых изоб-
ражений, причем в зону входят те коэффициенты, которые оказывают существенное
влияние на субъективное качество изображения. На рис. 1.7 показаны зоны матрицы c ,
которые обычно сохраняются при использовании преобразования Адамара. Эти зоны
соответствуют "низкочастотным" коэффициентам преобразования и коэффициентам
вертикальных и горизонтальных пространственных частот. Необходимость сохранения
последних обусловлена анизотропией спектров изображений и пространственно-
частотных характеристик зрительной системы.

12
Рис. 1.7. Зоны матрицы коэффициентов преобразования c , которые обычно
сохраняются при использовании преобразования Адамара

Применимость метода зонального отбора ограничена тем, что выбор границ зоны может
быть оптимальным только для некоторого класса изображений. В связи с этим более
широкое распространение получал адаптивный метод порогового отбора, в соответствии с
которым коэффициент преобразования c ( k , l ) не сохраняется, если его величина меньше
некоторого порога.
С точки зрения степени сокращения избыточности передаваемого сигнала наиболее
эффективными являются преобразования Карунена - Лоэва, наклонное и синусно-
косинусное преобразования. Несколько уступают им преобразования Фурье и Хаара.
Преобразование Адамара проигрывает всем остальным, однако на применимость
преобразования зачастую более существенно влияет не его эффективность, а
вычислительные трудности, связанные с выполнением преобразования. Для преоб-
разования Карунена - Лоэва не существует быстрого алгоритма вычисления
коэффициентов преобразования, и при преобразовании фрагмента из n  n отсчетов
необходимо выполнить n 4 операций. В случае быстрого преобразования Фурье требуется
выполнять 2n 2 log 2 n перемножений и такое же число сложений, а для преобразования
Адамара - только 2n 2 log 2 n сложений. Поэтому реализация преобразования Адамара
является наиболее простой.
Сложность преобразования зависит также от размеров фрагмента. Субъективные
экспертизы качества изображений показали, что при размерах фрагментов, больших 4x4,
субъективное качество изображения улучшается медленно. Это объясняется тем, что
базисные изображения рассмотренных преобразований недостаточно согласованы со
статистическими свойствами изображений.
Результаты экспериментов по кодированию изображений с помощью преобразований
показали, что сокращение цифрового потока до двух разрядов на элемент изображения
достигается при кодировании с преобразованием Адамара фрагментов изображения
размером 16х16 элементов. При уменьшении фрагмента до 8х8 цифровой поток
уменьшается только лишь до 2,5 разрядов на элемент при той же оценке качества
восстановленного изображения.
Для сравнения различных типов преобразования на рис. 8 приведены зависимости
среднеквадратической ошибки восстановления исходного изображения для различных
преобразований от размера группы отсчетов, полученные в предположении, что
изображение описывается двумерным марковским процессом с коэффициентами
корреляции между соседними элементами по горизонтали Rэ=0,95 и по вертикали Rс=0,95.

13
Рис. 1.8. Зависимость среднеквадратической ошибки от размера группы отсчетов для
различных видов преобразований

Как видно из рис. 1.8, с точки зрения обеспечения малых среднеквадратических ошибок
размер группы отсчетов целесообразно брать не меньшим, чем 8 x 8 . Для указанной
модели изображения лучшим преобразованием является синусно-косинусное, которое по
среднеквадратической ошибке совпадает с преобразованием Карунена-Лоэва. Однако в
отличие от последнего синусно-косинусное преобразование имеет алгоритм быстрого
преобразования и поэтому более просто реализуется.
В системах с кодированием изображения с помощью линейных преобразований
проявляются характерные искажения, связанные с заметностью разбиения его на
фрагменты. Цифровые ошибки, обусловленные искажением цифрового сигнала в канале
связи, в таких системах горазда меньше заметны на восстановленном изображена, чем при
использовании ДИКМ, поскольку при обратном преобразовании искажения переданного
коэффициента распределяются по всему фрагменту изображения.

1.4. Стандарт цифрового сжатия MPEG-2


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

1.4.1. Пространственное сжатие


На рис. 1.9 показаны три основных этапа пространственного сжатия.

Рис. 1.9. Этапы пространственного сжатия


14
1.4.1.1. Пространственное преобразование
Вначале изображение разбивается на макроблоки 16х16 отсчетов, каждый из которых
содержит по 4 блока отсчетов яркости Y размером 8x8 пикселов и блоков сигналов
цветности СB и CR размером также 8 х 8 пикселов. Количество блоков сигналов цветности
определяется форматом дискретизации (рис. 1.10).

Рис. 1.10. Форматы дискретизации MPEG-2

На вход дискретного косинусного преобразователя DCT поступают 8x8 массивы


пикселов изображения с различными значениями интенсивности по яркости и цвету. На
выходе преобразователя - уже другой массив чисел размером 8x8. Пространственное
преобразование преобразует блок изображения размером 8x8 элементов в блок
коэффициентов того же размера, который может быть закодирован с использованием
значительно меньшего количества бит, чем оригинальный блок, который мы имели на
первом этапе.
Первый коэффициент преобразования, имеющий индекс (0,0), особенный. Он
представляет среднее значение всех 64 входящих пикселов матрицы 8x8. При движении
коэффициента слева направо по горизонтали или вниз по вертикали преобразования
говорят о росте пространственной частоты. DCT преобразование эффективно из-за того,
кто оно имеет тенденцию концентрировать энергию преобразования в коэффициентах
преобразования, расположенных в верхнем левом углу матрицы, где наименьшая
пространственная частота.
1.4.1.2. Квантование
Второй этап пространственного сжатия - квантование коэффициентов преобразования,
которое уменьшает число бит для представления DCT коэффициентов. Квантование
выполняется путем деления коэффициентов преобразования на целое число с
последующим округлением до ближайшего целого числа.
Целый делитель каждого DCT коэффициента состоит из двух частей, первая часть
уникальна для каждого коэффициента в DCT матрице 8x8. Набор этих уникальных чисел
также является матрицей и называется матрицей квантования. Вторая часть делителя
(quantizer_scale) - это целое число, которое фиксировано для каждого следующего
макроблока. В частности, существуют две матрицы квантования с фиксированными
коэффициентами для I-кадров и не I-кадров. Эти две матрицы показаны в таблицах 1.1 и
1.2.

0 1 2 3 4 5 6 7
0 8 16 19 22 26 27 29 34

15
1 16 16 22 24 27 29 34 37
2 19 22 26 27 29 34 34 38
3 22 22 26 27 29 34 37 40
4 22 26 27 29 32 35 40 48
5 26 27 29 32 35 40 48 58
6 26 27 29 34 38 46 56 69
7 27 29 35 38 46 56 69 83
Таблица 1.1. Матрица квантования для I-кадров
0 1 2 3 4 5 6 7
0 16 16 16 16 16 16 16 16
1 16 16 16 16 16 16 16 16
2 16 16 16 16 16 16 16 16
3 16 16 16 16 16 16 16 16
4 16 16 16 16 16 16 16 16
5 16 16 16 16 16 16 16 16
6 16 16 16 16 16 16 16 16
7 16 16 16 16 16 16 16 16
Таблица 1.2. Матрица квантования для не I-кадров

1.4.1.3. Коды переменной длины


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

1.4.2. Временное сжатие


В отличие от пространственного сжатия, которое обеспечивается техникой
преобразования изображений, временное сжатие достигается компенсацией движения
(см. рис. 1.11).

Рис. 1.11. Удаление избыточности по трем осям

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


удалена в трех направлениях: двух пространственных и временном. С этой целью для
удаления избыточности по времени изображение передается в виде последовательности
I-, Р- и В-кадров (см. рис. 1.12).

16
Рис. 1.12. Типовая группа изображений в MPEG-2.

На рисунке выше представлена типовая группа изображений GOP (Group of Pictures) -


это набор изображений, который включает в себя:
- кадры, не требующие информации от других кадров, приходящих раньше или позже
(так называемые Intra или I-кадры);
- кадры с однонаправленным предсказанием по предыдущим кадрам (Р-кадры);
- кадры с двунаправленным предсказанием по предыдущим и следующим кадрам (В-
кадры).
Группа изображений - серия изображений, содержащих один I-кадр (см. рис. 1.12), где
стрелками показаны направления предсказания в пределах одной группы изображений.
С информационной точки зрения каждое изображение представляет собой три
прямоугольных матрицы отсчетов изображений: яркостную Y и две матрицы цветности
С. Соотношение между количеством отсчетов яркости и цветности определяется
форматом дискретизации (рис. 1.10):
- 4:2:0 — размеры матриц СB и СR в два раза меньше, чем Y и в горизонтальном, и в
вертикальном направлении;
- 4:2:2 — все три матрицы имеют одинаковые размеры по вертикали, но в
горизонтальном направлении матрицы цветности имеют в два раза меньшее количество
элементов;
- 4:4:4 — все матрицы одинаковы.
Р- и В-кадры используются для достижения временного сжатия. Опыты показывают, что
Р-кадрам требуется только 40%, а В-кадрам 10% от количества бит, требуемых для I-
кадров.
Преобразование, изображенное на рис. 8, обычно называют гибридым кодированием, в
основном из-за того, что пространственное сжатие достигается техникой
преобразования, а временное сжатие — компенсацией движения.
Так как В-кадры должны быть получены из I- и Р-кадров, декодер должен сначала
получить те и другие кадры, прежде чем будет декодирован В-кадр. Поэтому порядок
передачи не может быть IBBP IBBP. Порядок передачи кадров должен быть следующий:
IPBB IPBB.
Это вносит ограничения для кодера, так как он должен хранить кадры, которые должны
стать В-кадрами. Это ведет к росту задержки — времени от момента начала кодирования
кадра до момента его воспроизведения.
17
Изображения (I-, Р- или В-кадры) делятся на слайсы (slices), макроблоки (macroblocks) и
блоки (blocks), каждый из которых имеет свой заголовок. Следует отметить, что в
литературе слайсы иногда принято переводить как срезы.
Р- и В-кадры используются для достижения временного сжатия. Опыты показывают, что
Р-кадрам требуется только 40%, а В-кадрам 10% от количества бит, требуемых для I-
кадров.
Структуру, показанную на рис. 1.11, обычно называют гибридым кодированием, в
основном из-за того, что пространственное сжатие достигается техникой
преобразования, а временное сжатие — компенсацией движения.
Так как В-кадры должны быть получены из I- и Р-кадров, декодер должен сначала
получить те и другие кадры, прежде чем будет декодирован В-кадр. Поэтому порядок
передачи не может быть IBBP IBBP. Порядок передачи кадров должен быть следующий:
IPBBIPBB.
Это вносит ограничения для кодера, так как он должен хранить кадры, которые должны
стать В-кадрами. Это ведет к росту задержки — времени от момента начала кодирования
кадра до момента его воспроизведения.
Изображения (I-, Р- или В-кадры) делятся на слайсы (slices), макроблоки (macroblocks) и
блоки (blocks), каждый из которых имеет свой заголовок. Название слайсы также
переводят как срезы.

Рис. 1.13. Деление изображения на слайсы и макроблоки в MPEG-2.

Слайсом называется группа последовательных макроблоков в видеокадре (рис. 1.13),


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

18
Рис. 1.14. Варианты внутренней организации макроблока в MPEG-2

В стандарте MPEG-2 возможны два варианта внутренней организации макроблока (см.


рис. 1.14):
- кадровое кодирование, при котором каждый блок яркости образуется из
чередующихся строк двух полей (рис. 1.14а);
- полевое кодирование, при котором каждый блок яркости образуется из строк только
одного из двух полей (рис. 1.14б)
Макроблок яркости — это область, имеющая размер 16x16 пикселей. Цветовая часть
макроблока зависит от выборки отсчетов яркости. (Структура макроблока с форматом
4:2:0 показана на рис. 1.11). Из этого рисунка видно, что макроблок формата 4:2:0
состоит из шести блоков. Яркостная составляющая представляет из себя квадрат из
четырех блоков размером 8х8, а каждая из цветовых составляющих состоит из одного
блока 8x8 пикселов. Векторы для компенсации движения определяются по яркостной
составляющей макроблока.
Блоки имеют размер 8x8 пикселей и являются наименьшим синтаксическим элементом
MPEG-2. Блоки являются основными элементами для DCT кодирования.
Набор операций такого кодирования:
- дискретное косинусное преобразование;
- взвешенное квантование, определяемое элементами матрицы квантования;
- энтропийное кодирование серии коэффициентов косинусного преобразования,
полученной в результате диагонального сканирования матрицы коэффициентов.

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

20
2. Разработка имитационной модели
Имитационная модель для исследования алгоритмов цифрового сжатия изображений
программно симулирует процесс кодирования видеоизображений, их передачи, а зачем
декодирования. Имитационная модель состоит из нескольких функциональных блоков,
соответствующих программным блокам реализации в коде (см. рис.2.1).

Система
Источник данных Кодер Канал передачи Декодер
отображения
2 3 4 5 6

Данные изображения
Система
АРМ управления статистического
Команды управления анализа
1 7

Рис. 2.1. Функциональная структура имитационной модели.

1) Автоматизированное рабочее место управления – пользовательский интерфейс


имитационной модели. Именно с АРМ управления задаются параметры работы
других компонент модели. Программно АРМ управления представляет собой ряд
видимых пользователю модели окон, элементы управления на которых реализуют
функциональность управления моделью, отображения исходного изображения,
результатов его декодирования и статистических данных о них.
2) Источник данных – компонент, выступающий в качестве отправной точки для
работы остальных симуляционных компонент модели. В качестве источника
данных используется изображение, представленное в формате без сжатия, -
например, формате bmp. Команды управления с АРМ управления указывают,
какое именно из доступных изображений будет использоваться для работы
имитационной модели.
3) Кодер – компонент, симулирующий работу кодера. В этом программном модуле
осуществляется кодирование изображения, полученного из источника данных, при
помощи одного из доступных алгоритмов сжатия. Выбор алгоритма сжатия и его
параметров осуществляется с АРМ управления.
4) Канал передачи – компонент, симулирующий условия передачи данных. По
команде с АРМ управления он вносит в изображение помехи с указанными
характеристиками, симулируя действительные помехи, вносимые в сигнал при
передаче.
5) Декодер – компонент, симулирующий обратное к сжатию преобразование
соответствующего выбранному на стороне кодера алгоритма. Параметры его
работы, таким образом, определяются параметрами, указанными с АРМ
управления для кодера.
6) Система отображения – конечная точка симулируемого канала передачи данных.
Получая данные от декодера, она преобразует их в формат, пригодный для
отображения их на АРМ управления.
7) Система статистического анализа – аналитический модуль, который обрабатывает
данные, получаемые от источника данных, кодера и системы отображения
информации. Задача системы статистического анализа – в соответствии с
командами с АРМ управления сформировать наглядные численные и графические
представления качества работы алгоритма сжатия, дать пользователю
имитационной модели возможность получить информацию о сравнительных
21
достоинствах различных алгоритмов, продемонстрировать существование или
отсутствие разницы между исходным изображением и изображением после
прохождения симулируемого канала передачи данных.
В качестве способа воплощения имитационной модели в программный код был
выбран объектно-ориентированный язык программирования Delphi. Его важные
преимущества – хорошо развитая объектная модель, статическая типизация,
интуитивный, подробный код, который в большинстве случаев близок к
самодокументированному, широкие функциональные возможности, в том числе
наличие множества уже существующих программных компонент для решения
стандартных задач программирования, высокая скорость прототипирования,
использование его в качестве основного языка курса информатики факультета
радиоэлектроники летательных аппаратов.
Теперь рассмотрим алгоритмы работы каждого из функциональных блоков
имитационной модели более подробно. Поскольку формирование алгоритмов на
уровне индивидуальных команд выливается даже для сравнительно простых
алгоритмов в создание сложных схем большого размера, чтение которых значительно
затруднено, а полезность ограниченна, будем оперировать алгоритмами из более
подробных функциональных блоков.
АРМ управления
АРМ управления – система из нескольких взаимосвязанных визуальных окон,
предназначенных для ввода параметров работы имитационной модели и вывода
результатов этой работы, а также для работы со статистическими данными. Алгоритм
работы АРМ управления типичен для визуальных интерфейсных систем:
функциональный блок ждет команды от пользователя, и, получив ее, принимает
параметры и осуществляет другой свойственный ей функционал. Аналогично, по
команде на выход блок завершает свою работу, а вместе с ней и работу всей
имитационной модели. Алгоритм работы АРМ управления см. на рис. 2.2.
Источник данных
Источник данных – функциональный блок без графического интерфейса. Он
принимает на вход от АРМ управления параметры изображения, над которым будет
работать имитационная модель, и загружает его в память, представляя в таком виде,
который позволит взаимодействовать с ним остальным функциональным блокам
модели. На этом работа источника данных завершается. Алгоритм его работы см. на
рис. 2.3.
Кодер
Кодер – функциональный блок без графического интерфейса. Получив на вход данные
изображения от источника данных и параметры его сжатия от АРМ управления, он
запускает процедуру сжатия соответствующего типа соответствующими параметрами,
а затем завершает свою работу. Алгоритм работы кодера изображен на рис. 2.4.
Канал передачи
Канал передачи – функциональный блок без графического интерфейса. Получив на
вход данные изображения от кодера и параметры шума от АРМ управления, он вносит
в данные изображения шум с заданными параметрами, а затем завершает работу.
Алгоритм его работы изображен на рис. 2.5.

22
Начало

Начать работу
модели?

Да

Выбор исходного изображения и передача


параметров источнику данных

Выбор алгоритма кодирования и его


параметров, передача параметров кодеру

Выбор уровня искажений в канале,


передача параметров каналу

Получение результатов от системы


отображения, вывод их на экран
Нет

Отобразить Нет
статистическую
информацию?

Да

Выбор параметров отображения


статистических данных, передача
параметров системе статистического
анализа

Нет

Получение результатов от системы


статистического анализа, вывод их на Нет
экран

Завершить
работу со
статистикой?

Да

Выход?

Да

Выход

Рис. 2.2. Алгоритм работы АРМ управления.


23
Начало

Получить параметры загружаемого


изображения от АРМ управления

Загрузить изображение

Вывести
Загрузка прошла
Нет сообщение
штатно?
об ошибке

Да

Конец

Рис. 2.3. Алгоритм работы источника данных.

Рис. 2.4. Алгоритм работы кодера.


24
Начало

Получить закодированное сообщение от


кодера и параметры шума от АРМ
управления

Внести в данные изображения шум с


заданными параметрами

Конец

Рис. 2.5. Алгоритм работы канала передачи.

Декодер
Декодер – функциональный блок без графического интерфейса. Получив данные
изображения от канала передачи, он выполняет преобразование, обратное
выполненному кодером, проверяет, что это преобразование успешно (поскольку
искажения, внесенные в канале передачи, могут сделать изображение нечитаемым,
повредив, например, служебные области данных), и завершает свою работу. Алгоритм
работы декодера изображен на рис. 2.6.
Система отображения
Система отображения – функциональный блок, взаимодействующий с элементами
графического интерфейса. Получив от декодера данные изображения, система
отображения представляет их в виде, доступном для графического отображения с
помощью визуальных элементов АРМ управления, и завершает свою работу.
Алгоритм работы системы отображения изображен на рис. 2.7.
Система статистического анализа
Система статистического анализа – функциональный блок, взаимодействующий с
элементами графического интерфейса. По запросу с АРМ управления, получив данные
от системы отображения, система статистического анализа проводит над ними
аналитические операции, в общем случае специфические для каждого алгоритма
преобразования, а затем использует визуальные элементы интерфейса АРМ
управления для вывода их на экран. Алгоритм работы системы статистического
анализа изображен на рис. 2.8.

25
Рис. 2.6. Алгоритм работы декодера

26
Начало

Получить декодированное сообщение от


декодера

Преобразовать его к виду,


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

Передать результаты преобразования на


АРМ управления

Конец

Рис. 2.7. Алгоритм работы системы отображения.

Рис. 2.8. Алгоритм работы системы статистического анализа.

27
3. Разработка программных модулей
3.1. Выбор сторонних компонент
В соответствии с причинами, изложенными в разделе 2, для разработки программы,
реализующей заданную имитационную модель, выбран язык Delphi. Он обладает
встроенными возможностями, позволяющими реализовать подавляющее большинство
функционала, необходимого для заданной модели, но есть области, где этих встроенных
возможностей недостаточно.
В первую очередь, затруднения возникают при отображении видео, – возможности языка
в этой области рудиментарны. Для компенсации данной проблемы существует множество
дополнительных сторонних компонентов, из которых выбран набор DSPack, как
реализующий необходимый функционал наиболее полно, и в то же время
фокусирующийся именно на нем.
Поскольку язык лишен средств отображения видео, очевидно, он лишен и возможностей
более глубокого взаимодействия с ним: редактирования, изменения способа кодирования,
и так далее. Для компенсации этой недостаточности функционала был выбран пакет
программ ffmpeg, являющийся стандартом де-факто в области кодирования
видеоизображений. Этот пакет состоит из трех приложений: кодировщика ffmpeg,
проигрывателя ffplay и сборщика информации о видеофайлах ffprobe. Управление
компонентами пакета осуществляется через командную строку ОС, методы доступа к
которой входят в стандартные возможности языка Delphi.

3.2. Разработка функционала программы


Основными функциональными частями программы станут симуляция ДИКМ,
преобразования Адамара, MPEG-кодирование, симуляция работы шумов. Все эти
функции разместим на панелях основной вкладке основного окна программы. В
зависимости от выбора пользователя, будем показывать только те панели, которые
относятся к текущему используемому способу кодирования. Кроме того, сделаем в
основном окне еще две вкладки: для отображения изображений до и после симуляции
передачи, и для отображения статистики.

3.2.1. Разработка функционала работы с ДИКМ


Для того, чтобы пользователь программы мог получить адекватное представление о
работе ДИКМ, кодер делается настраиваемым. Всегда используем в качестве
предсказателя на приемной стороне линейный интерполятор нулевого порядка. Тогда
определяющим параметром работы алгоритма является количество бит, доступных для
передачи одного цветового отсчета. В соответствии с ним определяется доступное
количество уровней квантования разностных отсчетов. Различные же методы ДИКМ,
которые мы реализуем в программе, в первую очередь отличаются именно методом
выбора этих уровней квантования.
Наиболее очевидным методом выбора уровней квантования является линейный. В этом
случае уровни квантования, чье число задается числом бит, доступным для кодирования
каждого цветового отсчета, равномерно распределяется по множеству возможных
разностных отсчетов
Другим методом, столь же простым, является метод распределения уровней квантования с
заданным интервалом. Зная из количества доступных бит число уровней квантования,
запрашиваем у пользователя интервал между ними, и располагаем их с заданным таким
образом постоянным шагом по обе стороны от нуля.

28
Подметодом предыдущего метода является метод с отсечкой: заданное числом доступных
бит количество уровней квантования распределяется по обе стороны от нуля с единичным
шагом.
Несколько более сложным и требующим простейшего анализа является метод
значимости. Для его работы не требуется указание пользователем доступного для
передачи каждого цветового отсчета числа бит, только пороговый уровень значимости,
определяющий количество раз, которое разностный отсчет должен встретиться при
кодировании изображения для того, чтобы получить свой собственный уровень
квантования. Определив простейшим анализом изображения необходимое количество
уровней квантования, очевидным логарифмическим преобразованием можем найти
количество бит, необходимое для кодирования каждого цветового отсчета.
Наиболее распространенным адаптивным методом является равномерное заполнение
околонулевого максимума. У подавляющего большинства реальных изображений
большинство разностных отсчетов – нулевые или близкие к нулю. Исходя из этого
предположения, заданное числом доступных для кодирования одного цифрового отсчета
бит количество уровней квантования равномерно распределяется по околонулевому
максимуму, сформированному этими небольшими разностными отсчетами. Данный метод
хорошо работает для большинства реальных изображений (картин, фотографий), но для
изображений высокой контрастности (например, содержащих тексты) основания
информация об изображении содержится не в околонулевом максимуме, и результаты
кодирования значительно ухудшаются (вплоть до срыва обнаружения околонулевого
максимума и полностью ошибочного кодирования изображения).
Более сложным адаптивным методом является метод максимумов. При его использовании
проводится несколько более сложный анализ изображения, и уровни квантования
распределяются по разностным отсчетам, встречающимся наиболее часто. Этот метод, с
одной стороны, лишен недостатков предыдущего; с другой стороны, для типичных
изображений уровни квантования могут быть распределены чересчур близко к нулю, что
приводит к некоторому ухудшению качества декодированного изображения.
Для ДИКМ предоставим пользователю статистику по распределению цветовых и
разностных отсчетов по исходному изображению и изображению после преобразования, а
также распределение разностей между цветовым отсчетом и его средним значением.
Алгоритмы работы с ДИКМ см. в Приложении 1, Рис. П1.1-П1.3.

3.2.2. Разработка функционала работы с преобразованием Адамара


Аналогично необходимости использования настраиваемого кодера для наглядности
работы ДИКМ, для преобразования Адамара также необходимо обеспечить способ
взаимодействия с пользователем. В первую очередь, естественным кажется дать ему
возможность выбора размера кодируемого фрагмента, хотя бы потому, что для небольших
размеров фрагментов преобразование Адамара легко повторить другими средствами
(например, табличным редактором), что крайне полезно на этапе отладки. В качестве
доступных для выбора размеров кодируемого фрагмента установим 4х4 и 8х8 пикселов,
использующиеся наиболее часто. Опорные изображения преобразования представим так
же, как они представляются в литературе – в виде квадратов, соответствующих опорным
матрицам и содержащих соответствующее размеру фрагмента количество элементов-
пикселей, чей цвет соответствует значению элемента матрицы. Представление этих
опорных матриц в виде командных операторов только для преобразования фрагментов
размером 8х8 потребовало бы использования N  8  8  8  8  4096 строк кода. Поэтому
вместо этого будем использовать парсер, подгружающий данные опорных матриц в
память, доступную программе, интерпретируя графические файлы.
Следующим параметром для преобразования Адамара должен стать выбор метода
исключения избыточности. Реализуем оба основных метода – пороговый, при котором
трансформанты, меньшие указанного пользователем числа, опускаются, и позиционный,
29
при котором опускаются те трансформанты, которые стоят за заданных пользователем
местах.
Предоставим пользователю статистику по работе преобразования Адамара. Поскольку
отбрасывание коэффициентов влияет на динамический диапазон в границах кодируемого
фрагмента, выведем график распределения этого параметра для всех фрагментов
исходного изображения и изображения после симуляции передачи.
Алгоритмы работы с преобразованием Адамара см. в Приложении 1, Рис. П1.4-П1.6.
Для обоих упомянутых способов преобразования статических изображений предусмотрим
также способ наглядно видеть разницу между исходным изображением и изображением
после симуляции передачи: построим разностное изображение. Алгоритм его построения
см. в Приложении 1, Рис. П1.8.
Результаты работы модели будем сохранять в отдельные файлы на файловой системе, с
названиями, соответствующими параметрам кодера, результатом использования которых
стал каждый из этих файлов. Таким образом, пользователь получает возможность
наглядно сравнить между собой результаты кодирования с различными параметрами.
Кроме того, для обоих упомянутых способов соберем статистику сжатия. Сначала оценим
размер исходного изображения, исходя из предположения, что на каждый его пиксель
уходит по три байтовых цветовых отсчета основных цветов (стандартный способ
представления несжатых изображений), и объем потока данных при передаче тридцати
таких кадров в секунду (для дальнейшего сравнения с кодированием MPEG). Затем,
исходя в случае ДИКМ из заданного количества бит на цветовой отсчет, а в случае
преобразования Адамара – из количества опускаемых трансформант, на основе ли
позиционного или порогового уровня, оценим размер, занимаемый изображением после
кодирования. Аналогично предыдущему, также вычислим размер потока при передаче
тридцати таких кадров в секунду. Сравнение этих показателей для различных параметров
кодирования позволяет пользователю наглядно видеть не только влияние на качество
изображения после декодирования, но и получаемую этой ценой разность в степени
сжатия.

3.2.3. Разработка функционала работы с MPEG


В соответствии с решением, принятым в пункте 3.1, для реализации MPEG-кодирования
будем использовать стороннее приложение-кодер, являющееся стандартом в данной
области. Среди прочих очевидных преимуществ подобного решения – возможность
реализовать кодирование не только в MPEG-2, но и в более современный MPEG-4, в том
числе с кодеком h264.
Для того, чтобы показать пользователю различия в результатах кодирования различными
кодеками с различными параметрами, сделаем значительную часть основных из этих
параметров задаваемыми, в том числе форматы дискретизации, размер группы
изображений, частота B-кадров в нем, параметры треллис-квантования. Поскольку
кодирование видео – весьма ресурсоемкий процесс, даем пользователю возможность
ограничить длительность кодируемого фрагмента. В отсутствие необходимости звука,
исключаем из исходного видео все звуковые дорожки.
После завершения кодирования показываем пользователю оба видеоизображения,
исходное и результирующее, бок о бок. Используем для этого проигрыватель ffplay,
входящий в состав пакета ffmpeg, поскольку большинство других доступных
проигрывателей оказываются неспособны воспроизвести видео с параметрами
кодирования, отличными от наиболее часто употребимых.
Для демонстрации степени сжатия запрашиваем утилитой ffprobe, входящей в состав
пакета ffmpeg, фреймрейт и битрейт кодированного видео, что позволяет оценить размер
кадра и поток при тридцати кадрах в секунду (что, в свою очередь, делает кодирование
MPEG сравнимым с методами кодирования, использующимися для статических
изображений.
30
Алгоритм работы с MPEG см. в Приложении 1, рис. П1.9.

3.2.4. Разработка функционала работы с шумами канала


Будем симулировать равномерные и гауссовы шумы канала. Позволим пользователю
выбрать интенсивность, указав вероятность появления шумовых искажений, раз на
пиксель. Затем, таким же образом узнаем матожидание распределения шумовых
искажений, а также широту разброса значений шумовых отсчетов. По требованию,
построим график шумового распределения, чтобы наглядно показать его.
Поскольку в Delphi доступен только генератор случайных чисел с равномерным
распределением, для получения гауссова шума будем использовать нормированную
сумму трех случайных отсчетов, созданных этим генератором.
Будем добавлять шумовые отсчеты к случайно выбранному цвету случайно выбранного
цветового отсчета после кодирования. Повторим эту процедуру заданное пользователем
число раз на каждый пиксель изображения.
Попиксельно сравним исходное изображение и изображение после кодирования и
декодирования. Долю пикселей, цвет которых изменился, покажем пользователю, приведя
к процентам. Затем введем количественную оценку степени изменения: помятуя, что
каждый байт, кодирующий базовый цвет в пикселе, может принимать значения от 0 до
256, и зная разницу в этих значениях между исходным изображением и изображением
после симуляции передачи, получаем возможность оценить процент цветовых искажений.
Эта характеристика более представительна, чем предыдущая, поскольку значительные
изменения малого числа пикселей гораздо заметнее для человеческого глаза, чем
незначительные изменения большого.
Для зашумления при кодировании MPEG будем использовать один из эффектных
фильтров кодировщика – фильтр Шум. Указывая параметры командной строки, получаем
возможность регулировать распределение добавляемого шума, его влияние на яркость или
цвета картинки, временное постоянство.

31
4. Разработка тестов
Создав программные модули, реализующие заданные алгоритмы преобразования,
зададимся вопросом проверки правильности их работы. Основных методов тестирования
будем использовать два: тесты в режиме отладки и функциональные тесты.
Тестами в режиме отладки будем называть тестирование программы, проводимое с
помощью среды разработки и ее средств, в том числе точек остановки (breakpoints) и
наблюдателей (watches). Выбрав точки прерывания в основных процедурах, и подготовив
программный код так, чтобы средствами отладки было удобно пользоваться, будем
тестировать программу с использованием ее исходных кодов.
Функциональными тестами будем называть тестирование на основе стандартных входных
изображений, передача которых с использованием выбранного типа кодирования
приводит к заведомо известным результатам: характерным искажениям, известным типам
помех, заведомо знаемым степеням сжатия, и так далее.

4.1. Тесты в режиме отладки


Как описано выше, тесты в режиме отладки предполагают тестирование программного
исходного кода с использованием среды разработки. Основные инструменты: точки
остановки, наблюдатели и пошаговое выполнение. Конечно, эти инструменты бесполезны
без знания того, какие именно значения должны принимать переменные в каждый момент
времени. Для того, чтобы иметь способ независимой проверки, преобразование ДИКМ и
преобразование Адамара рассчитаны для простого случая (изображение 4х4 пиксела
Test.bmp, поставляющееся с программой в директории Pictures, содержащей стандартные
изображения и результаты ее работы) в табличном редакторе. Результаты вычисления см.
в Приложении 2.
Рассмотрим теперь набор точек остановки, отмеченных в коде.
BP1. Точка остановки стоит после процедур формирования уровней квантования для
ДИКМ. При помощи наблюдателей возможно перехватить значения переменной diff_used
(в которой хранится число уровней квантования, использующееся в текущей симуляции) и
матрицы difftable (в которой хранятся, собственно, уровни квантования). Зная
распределение разностных отсчетов (например, из графика в основной вкладке основного
окна, в панелях работы с ДИКМ), легко понять, верно ли программой распределены
уровни квантования.
ВР2. Точка остановки установлена в цикле кодирования изображения ДИКМ. При
помощи наблюдателей легко определить, правильно ли цветовой отсчет разбирается на
составляющие базовые цвета. Используя пошаговое выполнение, также убедимся, что
разностные отсчеты верно вычисляются, и им ставятся в соответствие правильные уровни
квантования; что цветовые отсчеты считываются в верном порядке.
ВР3. Точки остановки – в цикле зашумления ДИКМ. Соответственно, при включенном
шуме канала передачи с использованием пошагового выполнения легко убедиться, что
программная реализация зашумления соответствует алгоритму.
ВР4. Следующая точка остановки – в цикле декодирования ДИКМ. Наблюдая за
переменными, использующимися в нем, и пошагово выполняя его, убеждаемся, что
декодирование происходит штатно.
ВР5. Эта точка остановки – в цикле кодирования преобразованием Адамара. Отслеживая
значения переменных, регулирующих значение текущего обрабатываемого фрагмента и
элемента в нем, можно убедиться, что они обрабатываются в правильном порядке.
ВР6. Удостоверимся, что цветовой отсчет верно разбирается на составляющие, а
трансформанты H преобразования Адамара при кодировании принимают корректные
значения. С помощью пошагового исполнения проследим работу порогового или
позиционного метода устранения избыточности и убедимся, что они работают верно.

32
ВР7. Эта точка остановки – в цикле зашумления процедуры кодирования
преобразованием Адамара. Поскольку выполняются сходные вычислительные задачи, код
и возможности его наблюдения аналогичны с ВР3.
ВР8. Точка остановки установлена непосредственно после оператора, который декодирует
базовый цвет восстановленного цветового отсчета в рамках кодирования преобразованием
Адамара. При помощи наблюдателя убеждаемся, что цветовые отсчеты
восстанавливаются правильно; а наблюдая переменные, управляющие циклами, также
имеем возможность удостовериться, что цветовой отсчет восстанавливается на верное,
исходное место.
ВР9а и ВР9b. Эти две точки остановки установлены в процедуре формирования
разностного изображения, с той лишь разницей, что (а) – в процедуре кодирования
ДИКМ, а (b) – в процедуре кодирования преобразованием Адамара. Пошагово выполняя
код, можно увидеть, как цветовые отсчеты вычитаются друг из друга, формируя шаг за
шагом, собственно, разностное изображение.
ВР10. Точка остановки – в процедуре подготовки к кодированию видеоизображения
кодером MPEG. Установив наблюдатель на переменную tmpstr, можно увидеть, верно ли
программа отдает команды приложению ffprobe, чтобы узнать доступные в системе
кодеки. Сделав шаг без захода, в той же переменной можно увидеть выходной поток этого
приложения.
ВР11. Аналогично предыдущей точке остановки, в этой можно узнать, верно ли
формируется команда приложению ffprobe на получение свойств выбранного
пользователем видеофайла; опять-таки аналогично через шаг без захода в ней можно
увидеть выходной поток этого приложения.
ВР12. Эта команда остановки – в процедуре кодирования видеоизображения кодером
MPEG. Установив наблюдатель на переменную tmpstr, можно увидеть, верно ли
программа отдает команды приложению-кодеру ffmpeg; верно ли считались и
превратились в параметры команды введенные пользователем настройки кодирования.
Сделав шаг без захода, в той же переменной можно увидеть выходной поток этого
приложения.
Во всех тестах на всех перечисленных точках остановки все наблюдаемые параметры
соответствовали ожидаемому; программная реализация соответствовала алгоритму.

4.2. Функциональные тесты


Под функциональным тестированием, в соответствии с определением, данным в разделе
4, пониманием тесты на специально подобранных изображениях, приводящие к заведомо
известным результатам: характерным искажениям, известным типам помех, заведомо
знаемым степеням сжатия, и так далее.
В качестве тестовых изображений выберем реальную черно-белую и реальную цветную
фотографии, таблицу из малоконтрастных цветных блоков, шахматную доску (таблицу
высококонтрастных блоков), изображения с высококонтрастным и низкоконтрастным
текстом.
Теперь будем последовательно кодировать их различными кодерами с различными
параметрами, а также протестируем реакцию кодеров на шум. Изображения, полученные
в результате функционального тестирования, см. в Приложении 4.
Протестируем ДИКМ. Возьмем линейный квантователь с равномерным распределением, 3
бита на разностный отсчет. Для наибольшей наглядности в качестве исходного
изображения будем использовать изображение шахматной доски (см. рис. П4.1). На
результирующем изображении хорошо виден гранулярный шум, характерный для ДИКМ.
Протестируем на том же материале теперь адаптивный метод заполнения максимума. Еще
на этапе предварительного просмотра видно, что центральный максимум на пространстве
разностных отсчетов не обнаруживается – в специально подобранном изображении

33
разностные отсчеты со значениями только лишь 0, -255 и 255. В результате этого срыва
изображение не удается восстановить вовсе (см. рис. П4.2).
Сменим метод квантования на критерий значимости или метод максимумов. Несмотря на
столь же жесткие ограничения, - три бита на разностный отсчет, - этот метод гораздо
лучше справляется с поставленной задачей, и искажений на полученном изображении не
заметно (см. рис. П4.3).
Теперь кодируем то же изображение, выбрав метод квантования с отсечкой или линейный
метод интервалов с малым интервалом. На полученном изображении отлично виден
характерный для ДИКМ шум перегрузки по крутизне (см. рис. П4.4).
Убедимся теперь, что предыдущий провал метода равномерного заполнения центрального
максимума был вызван особенностями изображения, а не метода или реализации.
Загрузим в качестве тестового изображения реальную фотографию, и кодируем ее с
линейным квантователем с равномерным распределением, а затем с адаптивным
квантователем с равномерным заполнением центрального максимума (см. рис. П4.5). В
обоих случаях отведем на кодирование одного цветового отсчета 4 бита. Разница между
результатами более чем наглядна – в случае с равномерным распределением уровней
квантования двухкратная экономия цифрового потока стоила верной передачи цветов и
повсеместного гранулярного шума; адаптивный же метод лишь слегка исказил
изображение шумом перегрузки по крутизне – искажение, которое в реальном
видеоизображении не было бы заметно совершенно.
Посмотрим, как на ДИКМ влияет появление шумов канала. Включим равномерный шум с
матожиданием 0 и отклонением 510 интенсивностью в 1 искаженный байт из 1000. Легко
посчитать, что для цифрового представления изображения без сжатия процент пикселей с
ошибкой будет составлять в среднем 0,1%. Из-за особенностей алгоритма ДИКМ, однако,
как и следовало ожидать для этого алгоритма, каждый искаженный отсчет исказил кроме
себя еще и все лежащие за ним на горизонтали (см. рис. П4.6). В результате доля пикселей
с искажениями – 62%.
Перейдем к тестированию преобразования Адамара. Для этого возьмем реальное цветное
изображение.
Попробуем провести преобразование без устранения избыточности. Видно, что
изображение после преобразования восстанавливается без ошибок, то есть что
преобразование работает штатно (см. рис. П4.6-7).
Применим теперь метод устранения избыточности – зональный отбор для кодируемых
фрагментов размером 8 на 8. Оставим набор передающихся трансформант по умолчанию,
таким, каковой наиболее частно используется при реальных применениях метода. На
полученном изображении видно, что уменьшение требований к каналу почти в три раза не
привело к значительному ухудшению качества или доле цветовых искажений, к которым
привело бы, например, использование ДИКМ с неадаптивным квантователем и подобным
уровнем сжатия (рис. П4.8).
Сменим теперь метод устранения избыточности на пороговый, и установим порог в 30
при кодировании фрагментов размером 4 на 4. Глядя на рис. П4.9, видим, что, хотя
качество изображения значительно ухудшилось, оно все еще легко распознается;
экономия потока при этом составляет более 14 раз.
Теперь посмотрим на типичную проблему при использовании преобразования Адамара:
работу с текстом. Возьмем изображение с контрастным текстом и кодируем его с
устранением избыточности методом зонального отбора, с настройками аналогичными
предыдущему его применению (см. рис. П4.10). Хорошо видно, что на исходном
изображении текст легко распознается до 8го размера шрифта, и с некоторым
напряжением – до 6го размера. На изображении же после преобразования проблематично
различить уже текст 12го размера.
Рассмотрим теперь влияние на преобразование Адамара шумов канала. Включим
равномерный шум с матожиданием 0 и отклонением 510 интенсивностью в 1 искаженный

34
байт из 1000. Таким образом, шум полностью аналогичен предыдущему случаю. Выберем
метод преобразования с кодируемыми фрагментами размером 8 на 8 без устранения
избыточности. На изображении, полученном в результате симуляции передачи через
канал с шумом, отлично видны ожидаемые последствия внесенного шума (см. рис. П4.11)
– цветовые искажения, повторяющие по форме опорные изображения преобразования.
Каждый искаженный трансформант, таким образом, искажает данные в 64 цветовых
отсчетах.
Наконец, проверим работу MPEG-кодера. Для этого выберем динамичное
видеоизображение высокого разрешения и закодируем его при помощи MPEG-2
кодирования. На видеоизображении, полученном в результате преобразования, хорошо
различимы многие из шумов, характерных для MPEG-2: мозаичный и блокинг-эффект,
размывание изображения и окантовки на границах, «эффект комаров» (см. рис. П4.12).
При этом битрейт видео снизился по сравнению с исходным (wmv-кодированным) более
чем в два раза.
Подключим к кодеру генератор шума канала, выставив на нем настройки, аналогичные
предыдущим случаям тестирования. На видеоизображении человеческим глазом
дополнительные искажения, вносимые шумом в добавление к искажениям, создаваемым
процессом кодирования, не заметны.
Проанализируем результаты функционального тестирования. Для всех протестированных
вариантов всех выбранных методов кодирования изображения симуляция процесса
кодирования происходила ожидаемо, с теоретически предсказанными степенью сжатия,
искажениями, и реакциями на шум, соответствующими особенностям алгоритмов
кодирования. Таким образом, полученные реальные результаты соответствуют
теоретически предсказанным, а значит, модель работает верно.

35
5. Разработка методики и проведение эксперимента на
имитационной модели
Основное назначение разрабатываемой имитационной модели – служить в качестве
наглядного пособия для студентов, изучающих методы кодирования видеоизображений,
будь то в виде стенда для лабораторной работы или пособия для лекции. Поэтому в
качестве эксперимента на имитационной модели проведем исследование, аналогичное
лабораторной работе, посвященной описанному предмету.

5.1. Исследование способов кодирования изображений


1) Исследование работы ДИКМ. Ознакомьтесь с теоретическими принципами работы
метода кодирования, различными способами квантования разностных отсчетов и
ошибками, вносимыми методом.
А) Сравнение линейных и адаптивных методов квантования.
В выпадающем списке выберите метод кодирования «Дифференциальная импульсно-
кодовая модуляция». Выберите реально изображение для кодирования и нажмите
«Загрузить». Выберите настройки кодера: «Линейный квантователь», «Равномерное
заполнение». Изменяя количество бит на разностный отсчет, постройте таблицу
зависимости доли пикселов с искажениями от этого параметра. Для каждого запуска
рассмотрите также доступные виды статистики для исходного изображения и
изображения после преобразования.
Результаты выполнения этого пункта работы собраны в таблицу 5.1.

Число бит на отсчет Пикселов с искажением, %


2 100
4 100
6 100
8 96
Таблица 5.1. Зависимость процента искажений от числа бит на отсчет при линейном
квантовании с равномерным распределением.

Переключите квантователь в адаптивный режим: «Адаптивный», «Равномерное


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

Число бит на отсчет Пикселов с искажением, %


2 100
4 100
6 2
8 2
Таблица 5.2. Зависимость процента искажений от числа бит на отсчет при линейном
квантовании с равномерным распределением.

По полученным таблицам постройте графики зависимости искажений от числа бит на


отсчет.
Результаты выполнения этого пункта работы представлены на рис. 5.1.

36
Линейный квантователь Адаптивный квантователь

120

100
Пикселей с искажениями, %

80

60

40

20

0
2 4 6 8
Бит на разностный отсчет

Рис. 5.1. Графики зависимости доли искажений от типа используемого квантователя

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


максимума и дайте объяснение, почему процент искажений для адаптивного квантователя
остается постоянным при увеличении числа бит на каждый разностный отсчет.
Результат выполнения этого пункта работы: поскольку для представленного в работе
стандартного цветного изображения, для которого построен график на рис. 5.1, ширина
центрального максимума – 43 различных разностных отсчета, для его полного заполнения
уровнями квантования требуется всего 6 бит на разностный отсчет. Поэтому дальнейшее
увеличение количества доступных квантователю разрядов не улучшает выходные
результаты.
Рассмотрим теперь случаи, в которых использование адаптивного квантователя дает сбои.
Выберите в качестве передаваемого изображения «Шахматная доска» или
«Высококонтрастный текст», и снова укажите в качестве используемого алгоритма
квантователя «Адаптивный», «Равномерное заполнение околонулевого максимума».
Укажите произвольное количество бит на отсчет и симулируйте передачу. Объясните
полученный результат.
Результат выполнения этого пункта работы: как рассмотрено выше, в случаях,
отличающихся от реальных изображений, у которых большинство разностей между
цветовыми отсчетами имеет значения, близкие к нулю, алгоритм поиска центрального
максимума дает сбой. Срываясь таким образом, он делает корректное декодирование
изображений невозможным.
Б) Исследование ошибок при кодировании ДИКМ.
Выберите в качестве передаваемого изображения изображение шахматной доски,
«Линейный» квантователь и «Равномерное заполнение» при трех битах на разностный
отсчет. Изучите результат, увеличив его щелчком по изображению после преобразования,
и объясните наблюдаемое искажение (см. рис. П4.1б).
Результат выполнения этого пункта работы: характерный паттерновый шум, разбивающий
области сплошного цвета на цветные полосы – пример гранулярного шума, характерного
для ДИКМ. Причины его возникновения приведены в главе 1.2.
Переключите режим работы линейного квантователя на режим с равными интервалами
между уровнями квантования. Укажите в качестве доступного количества бит любое
достаточно большое (например, 6), а в качестве интервала - любое разумно большое
число, не позволяющее распределению уровней квантования покрыть все пространство
37
разностных отсчетов, но и не удерживающее их у центрального нулевого максимума
(примером такого значения может быть 4). Изучите результат симуляции передачи,
увеличив его, если необходимо, и объясните наблюдаемое искажение (см. рис. П4.4.).
Результат выполнения этого пункта работы: характерный протяженный шум,
растягивающий области резких цветовых переходов – пример перегрузки по крутизне,
характерной для ДИКМ и объясненной в главе 1.2.
Рассмотрите результаты предыдущих симуляций на реальных изображений, открыв их из
директории Pictures в директории программы, или же запустив симуляцию повторно.
Укажите, какие вы можете увидеть ошибки кодирования ДИКМ в этих изображениях.
Результат выполнения этого пункта работы: на реальных изображениях, в зависимости от
конкретной настройки квантователя, можно увидеть оба упомянутых типа шума:
растяжение резких цветовых границ и гранулярный шум на равномерно окрашенных
фрагментах, а также цветовые искажения, вызванные большим расстоянием между
уровнями квантователя.
2) Исследование работы преобразования Адамара. Ознакомьтесь с теоретическими
принципами работы метода кодирования, базисными изображениями, различными
способами избавления от избыточности и ошибками, вносимыми методом.
А) Изучение порогового метода.
Выберите в качестве метода кодирования «Кодирование с использованием
преобразования Адамара», в качестве исходного изображения возьмите реальную ч/б
картинку и загрузите ее в имитационную модель. Выберите размер кодируемого
фрагмента в 4 пикселя на 4 пикселя, а метод избавления от избыточности – «Метод
порогового отбора». Теперь, изменяя критерий значимости отсчета-трансформанта от 1 до
5, постройте таблицу зависимости доли пикселов с искажением от этого параметра. Для
каждого порогового значения, которое вы исследуете, также запишите получившийся
размер кадра.
Затем повторите построение таблицы для фрагментов размером 8х8 пикселов. Размеры
получившихся кадров также запишите.
По данным из таблиц постройте график этой зависимости.
Результаты выполнения этого пункта работы: таблицы 5.3 и 5.4, рис. 5.2.

Пороговое значение Пикселов с искажением, %


5 19
10 31
20 43
30 50
40 54
50 57
Таблица 5.3. Зависимость процента искажений от порогового значения трансформанта
в преобразовании Адамара с фрагментом 4х4 и устранением избыточности пороговым
методом
Пороговое значение Пикселов с искажением, %
5 32
10 42
20 54
30 60
40 63
50 66
Таблица 5.4. Зависимость процента искажений от порогового значения трансформанта
в преобразовании Адамара с фрагментом 8х8 и устранением избыточности пороговым
методом

38
4x4 8x8

70

60
пикселей с искажениями, %

50

40

30

20

10

0
0 5 10 20 30 40 50
пороговое значение

Рис. 5.2. Зависимость процента искажений от порогового значения трансформанта в


преобразовании Адамара при устранении избыточности пороговым методом
Б) Изучение позиционного метода.
Переключите кодер на использование метода позиционного отбора и фрагментов 4х4.
Постройте таблицу и график зависимости доли пикселей с искажениями от количества
передаваемых трансформант, постепенно удаляя трансформанты, и приближаясь тем
самым к трансформанту (0,0) в левом верхнем углу.
Результаты выполнения этого пункта работы: таблица 5.5 и рис. 5.3.

Число переданных Пикселов с искажением, %


трансформант
8 5
6 17
4 19
3 22
Таблица 5.5. Зависимость процента искажений от числа переданных трансформант
преобразования Адамара при позиционном методе устранения избыточности для
фрагментов 4х4.

39
25

20
пикселей с искажениями, %

15

10

0
3 4 6 8
число переданных трансформант

Рис. 5.3. Зависимость процента искажений от числа переданных трансформант


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

Повторите сделанное для фрагментов 8х8.


Результаты выполнения этого пункта работы: таблица 5.6 и рис. 5.4.

Число переданных Пикселов с искажением, %


трансформант
19 16
16 22
14 22
11 25
9 34
6 35
3 38
Таблица 5.6. Зависимость процента искажений от числа переданных трансформант
преобразования Адамара при позиционном методе устранения избыточности для
фрагментов 8х8.

40
40

35

30
пикселей с искажениями, %

25

20

15

10

0
3 6 9 11 14 16 19
число переданных трансформант

Рис. 5.4. Зависимость процента искажений от числа переданных трансформант


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

В) Используя полученные в предыдущих пунктах данные, постройте зависимость доли


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

Позиц. метод 8х8 Позиц. метод 4х4 Порог. метод 8х8 Порог. метод 4х4
Размер Искаж, Размер Искаж, Размер Искаж, Размер Искаж,
% % % %
74 38 296 22 18 66 70 57
148 35 395 19 20 63 75 54
222 34 593 17 22 60 82 50
271 25 791 5 27 54 95 43
296 23 43 42 129 31
346 22 80 32 192 19
395 22
469 16
Таблица 5.7. Зависимость доли пикселей с искажениями от размера кадра при различных
методах устранения избыточности в преобразовании Адамара.

41
8х8 позиционный метод 4х4 позиционный метод 4х4 пороговый метод 8х8 пороговый метод

70

60
Пикселов с искажениями, %

50

40

30

20

10

0
18 20 22 27 43 70 74 75 80 82 95 129 148 192 222 271 296 346 395 469 593 791
Размер кадра, кБ

Рис. 5.5. Зависимость доли пикселей с искажениями от размера кадра при различных
методах устранения избыточности в преобразовании Адамара.

3) Исследование кодирования MPEG.


Выберите метод кодирования «Кодирование с использованием протокола MPEG»,
выберите исходное видео (например, Shuttle.avi в поддиректории Pictures директории
программы) и загрузите его для работы с имитационной моделью.
Исследуйте зависимость между размером группы изображений и средним размером кадра.
Результаты занесите в таблицу и постройте на основе этих данных график.
Результаты выполнения этого пункта работы: таблица 5.8 и рис. 5.6.

Размер группы изображений Средний размер кадра, кбайт


15 98
25 90
50 85
75 83
100 82
150 81
300 80
Таблица 5.8. Зависимость среднего размера кадра видеоизображения от размера группы
изображений при MPEG-2 кодировании.

42
100

95
Средний размер кадра

90

85

80

75
15 25 50 75 100 150 300
Размер группы изображений

Рис 5.6. Зависимость среднего размера кадра видеоизображения от размера группы


изображений при MPEG-2 кодировании.

Установите теперь размер группы изображений 150 и исследуйте влияние количества B-


кадров между P-кадрами на средний размер кадра. Результаты занесите в таблицу и
постройте по ним график.
Результаты выполнения этого пункта работы: таблица 5.9 и рис. 5.7.

Размер группы изображений Средний размер кадра, кбайт


0 55
1 77
2 81
3 87
4 91
5 95
6 98
7 99
8 103
9 106
10 108
Таблица 5.9. Зависимость среднего размера кадра видеоизображения от числа B-кадров
между P-кадрами при MPEG-2 кодировании.

43
120

100
Средний размер кадра

80

60

40

20

0
0 1 2 3 4 5 6 7 8 9 10
Число B-кадров

Рис 5.7. Зависимость среднего размера кадра видеоизображения от числа B-кадров


между P-кадрами при MPEG-2 кодировании.

Обратите внимание на искажения, вносимые в видеоизображение процессом MPEG-


кодирования.

5.2. Исследование реакции различных кодеров на шум


Сравните реакции различных алгоритмов кодирования на шум в канале передачи данных.
А) Выберите в качестве метода кодирования «Дифференциальная импульсно-кодовая
модуляция». Загрузите для обработки любое стандартное изображение, а в качестве
настроек квантователя выберите «Адаптивный» режим с критерием значимости. Укажите
критерий значимости 1 для того, чтобы все разностные отсчеты были переданы.
Очевидно, процент искажений, если симулировать передачу при этих настройках, будет
нулевым.
Включите шум канала передачи: переключите переключатель в положение «Равномерный
шум». Оставьте остальные настройки по умолчанию и запустите симуляцию.
Сравните процент искажений с процентом искажений, который бы наблюдался при той же
интенсивности шума в изображении, передающемся без сжатия. Объясните вид шума,
полученный на изображении после декодирования.
Результаты выполнения этого пункта работы: искажения появляются на 30% пикселов
выходного изображения вместо 0,1%, который был бы искажен у несжатого изображения.
Характерный шум из полос искаженного цвета объясняется алгоритмом кодирования:
после одного искаженного разностного отсчета не происходит никакой коррекции
ошибок, а все цветовые отсчеты после него зависимы от его значения.
Б) Выберите теперь в качестве метода кодирования «Кодирование с использованием
преобразования Адамара». Аналогично, загрузите стандартное изображение и включите
генератор шума с теми же настройками. Сравните долю цветовых отсчетов, переданных
ошибочно, с долей цветовых отсчетов, которая была бы передана ошибочно для
изображения без кодирования, и объясните вид получаемого шума.
Результаты выполнения этого пункта работы: характерный рисунок шума, подобный
базовым изображениям преобразования Адамара, вызывается искажением только лишь
одной из трансформант из отсчетов фрагмента, что и приводит к появлению
соответствующего ему базового изображения в виде неверно восстановленного. Доля
44
пикселов с искажениями – 2%, что примерно в 16 (4х4) раза больше, чем было бы в
изображении, передаваемом без сжатия.
В) Наконец, выберите в качестве метода кодирования «Кодирование с использованием
протокола MPEG», выберите и загрузите видео. Переключите используемый вариант
кодека с MPEG-2. Включите генератор шума. Оставьте настройки кодера по умолчанию,
за исключением продолжительности кодируемого фрагмента. Уменьшите ее, в
зависимости от мощности вашей ЭВМ, до небольшого значения, порядка 10 секунд.
Изменяя интенсивность генерируемого шума, добейтесь его видимости в кадре видео.
Результаты выполнения этого пункта работы: едва заметный шум появляется в кадре при
интенсивности в 1 изменение на 200 отсчетов.

5.3. Завершение работы


На основании проделанной работы сделайте выводы об оптимальном кодере для
представления видеоизображений с минимальными ошибками от шума в канале и
минимальным потоком данных. Предложите для него оптимальные настройки.
Результаты выполнения этого пункта работы: по совокупности параметров ожидаемо
превзошло остальные наиболее современное кодирование MPEG. Исходя из данных,
полученных в ходе работы, оптимальный режим его работы – с размерами группы
изображений порядка 200, с минимизацией количества B-кадров.

45
6. Экономическое обоснование НИР
В дипломной работе была разработана имитационная модель для исследования
алгоритмов цифрового сжатия изображений. Таким образом обеспечена возможность
наглядно исследовать различия между способами кодирования, устраняющими
избыточность передаваемых данных, и таким образом в перспективе обеспечить более
эффективное использование радиочастотного спектра.

6.1. Оценка прогрессивности НИР


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

Для определения индекса технического уровня требуется:


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

Для сравнения выбраны существующие системы аналогового телевизионного вещания в


формате SECAM и цифровые системы вещания DVB-T2, использующие исследованные
способы кодирования MPEG.

Основные характеристики базовой и новой НТПр приведены в таблице 6.1.

Существенные свойства Уровень свойств Уровень свойств Значимость (вес)


НТПр новой НТПр базовой НТПр признака
Научно-технический 7 2 40%
уровень
Перспективность 8 2 40%
Возможность применения 6 10 20%
результатов
Таблица 6. 1. Основные характеристики базовой и новой НТПр.

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


радиосистемы. Для этого воспользуемся формулой (6.1):
Н

J НТП  Б (6.1)

46
где J НТП - индекс эксплуатационной прогрессивности результатов НТПр,
Н
HЭ - обобщенный количественный показатель эксплуатационного уровня НТПр,
являющийся результатом дипломной работы.
Б
HЭ - обобщенный количественный показатель эксплуатационного уровня
базовой НТПр.
Обобщенный количественный показатель как для базовой НТПр, так и для
разрабатываемой НТПр определяется с помощью средневзвешенной оценки (6.2):
i j
  QЭij  RЭi
HЭ  i (6.2)
 RЭi

где QЭij - значение j-го показателя i-го признака НТПр, выраженного в баллах;
RЭi - значение «весового коэффициента» i-го признака НТПр, выраженного в

процентах.
Тогда обобщенный показатель эксплуатационного уровня для аналогового вещания:
Б 2 * 0,4  2 * 0,4  10 * 0,2
HЭ =  3,6
1
Обобщенный показатель эксплуатационного уровня для нового комплекса:
Н 7 * 0,4  8 * 0,4  6 * 0,2
HЭ =  7,2
1
Оценим индекс эксплуатационной прогрессивности результатов НТПр:
7,2
J НТП  2
3,6

Полученный индекс эксплуатационной прогрессивности показывает целесообразность


разработки нового комплекса.

6.2. Оценка новизны НИР


Новизна НИР определяется с использованием метода балльных оценок. Оценки НТПр
приведены в таблице 6.2.

Критерий новизны Новизна Оценка новизны, баллы


Функциональный Принципиально новое 5
Технологический Улучшенное 2
Производственный Новое 3
Социальный Принципиально новое 5
Юридический Принципиально новое 5
Таблица 6.2. Оценки НТПр методом балльных оценок
Новизна определяется соотношением БК/БМ, где

47
БК – сумма набранных баллов по таблице 6.2,
БМ – максимальная сумма баллов по всем категориям.
5  2  3  5  5 20 4
Таким образом, новизна НТПр есть    0,8
5  5  5  5  5 25 5

6.3. Календарное планирование работ


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

№ Наименование Удельный Трудоемк Количе Производствен Длительность


этапов вес этапа в ость ство ный цикл этапа этапа в
% этапа, исполн календарных
чел*ч ителей днях
1 Анализ исх. 5% 25 1 3,125 4,375
данных,
разработка ТЗ
2 Обзор рынка 20% 100 2 6,25 8,75
существующих
систем
3 Обзор рынка 20% 100 2 6,25 8,75
комплектующих
4 Выбор и 25% 125 2 7,8125 10,9375
обоснование
компоненты
спектра
5 Выбор и 10% 50 2 3,125 4,375
обоснование
комплектующих
6 Разработка и 15% 75 2 4,6875 6,5625
проверка
эксперементальн
ой модели
7 Доработка 5% 25 2 1,5625 2,1875
системы с учетом
данных
эксперимента
ИТОГО 100% 500 32,8125 45,9375
Таблица 6.3. Структура трудоемкости этапов работ
Общая трудоемкость работы 500 чел-часов. В графе «удельный вес этапа» приведена
длительность этапа в процентах от полной длительности. В графе «трудоемкость этапа»
приведена трудоемкость этапа в чел-часах, рассчитанная с помощью предыдущей графы.

48
В графе «производственный цикл этапа» приведено количество рабочих дней,
требующееся для выполнения этапа. Производственный цикл этапа TЦ рассчитывается
по формуле (6.3):
ТЭ
TЦ 
t РД q

(6.3)

где Т Э - это трудоемкость этапа в чел-ч., t РД = 8 часов – продолжительность


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

№ этапа
7
6
5
4
3
2
1 Календарные
дни
5 10 15 20 25 30 35 40 45

Рис. 6.1. Директивный график работ.

6.4. Определение показателей экономического обоснования


Определим сначала затраты на НТПр. Затраты на выполняемую НТПр определяются по
следующим статьям расходов:
 Заработная плата разработчиков
 Страховые взносы на обязательное пенсионное, медицинское и социальное
страхование.
 Накладные расходы
 Прочие расходы
Оплата труда персонала определяется на основе общей трудоемкости создания
радиосистемы и формах оплаты труда, расценок и тарифов.
Оплата труда определяется по формуле (6.4):

49
k
З   Т Эi  i
i 1

(6.4)

где k – количество этапов, Т Эi - трудоёмкость i-го этапа,  i - средняя часовая


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

Категория исполнителей Месячный оклад (р.)

Инженер 30000
Техник 15000
Таблица 6.4. Месячный оклад разработчиков

Исходя из того, что количество рабочих часов за день t РД = 8 часов и среднее количество
рабочих дней в месяце d = 23 дня, получим величину часовой ставки инженера и техника:
30000 30000
 инж    163 р
t РД d 8 * 23

15000 15000
 тех    81,5 р
t РД d 8 * 23

Величина премии не превышает 40% (по данным с предприятия) от рассчитанной


заработной платы. Величина заработной платы с учетом премии рассчитывается по
формуле (6.5):
Пр
З осн  З  (1  )
100 (6.5)

Расчет заработной платы сводится в таблицу 6.5.

№ Трудоемкость Исполнители Часовая Средняя Зарплата Зарплата


Стадии ставка ставка с учетом
(чел-ч.) Должность Численност (р.) (р.) премии
ь
1 25 Инженер 1 163 163 4075 5705
2 100 Инженер 1 163 122,25 12225 17115
Техник 1 81,5
3 100 Инженер 1 163 122,25 12225 17115
Техник 1 81,5
4 125 Инженер 1 163 122,25 15281,2 21393,75
Техник 1 81,5 5
5 50 Инженер 1 163 122,25 6112,5 8557,5
Техник 1 81,5
50
6 75 Инженер 1 163 122,25 9168,75 12836,25
Техник 1 81,5
7 25 Инженер 1 163 122,25 3056,25 4275,75
Техник 1 81,5
ИТОГО 500 62143,75 87001,25
Таблица 6.5. Расчет заработной платы разработчиков

Затраты на проектирования по сведены в таблицу 6.6. При этом учтено, что отчисления в
ЕСФ составляют 30% от заработной платы, накладные расходы составляют 150% от
заработной платы (по данным предприятия); прочие расходы составляют 5% от
заработной платы; размер заработной платы берется с учетом премии.

№ Наименование статей затрат Затраты в р. Удельный вес в %


1 Заработная плата 87001,25 35,09
2 Отчисления в ЕСФ 26100,38 10,53
3 Накладные расходы 130501,9 52,63
4 Прочие расходы 4350,06 1,75
ИТОГО З затр = 247953,6 100%
Таблица 6.6. Затраты на проектирование

6.5. Определение цены на НТПр


Цена разработки комплекса определяется исходя из принципа обеспечения
безубыточности деятельности предприятия, получения прибыли, позволяющей выплатить
обязательные платежи в бюджет и инвестировать расширение ее деятельности. Цена
п
Ц НТПр
первоначальной продажи определяется по формуле (6.6):
 ЗП
п
Ц НТПр  З затр  Зосн , (6.6)
100

где З затр - текущие затраты на создание НТПр,


Зосн
- оплата труда персонала в общих текущих затратах с учетом премии,
 ЗП - уровень рентабельности, обеспечивающий безубыточность деятельности,

 ЗП =200%
п
Ц НТПр  247953,6  87001,25  2  421956,1

6.6. Оценка экономической эффективности НТПр


Экономическая эффективность оценивается путем расчета годового экономического

эффекта Э НТПр . Величина Э НТПр определяется по следующей формуле (6.7):

51
З НТПрБ J НТП  З НТПрН
Э НТПр 

(6.7)
ЗНТПрБ
- затраты на выполнение темы прототипа, руб.;

- продолжительность разработки новой темы, лет;
J НТП - уровень технической прогрессивности техники и технологического процесса;

Таким образом, годовой экономический эффект составляет (6.8):


200000  2  247953,6
ЭНТПр   1206717,76
0,126

(6.8)
Характеристикой эффективности работы является уровень эффективности затрат на
создание новой системы, рассчитываемый по формуле (6.9):
Э НТПр 1206717,76
E п
  2,86
Ц НТПр 421956,1

(6.9)
Полученная величина Е =2,86 свидетельствует об эффективности проведенной
разработки. Экономия достигается за счет повышения качества проектирования и
использования более совершенных технологий.

52
7. Охрана труда и окружающей среды. Обеспечение
условий труда при компьютерном моделировании
7.1. Анализ условий труда при работе с ПЭВМ.
При работе на оператора ЭВМ воздействуют сразу несколько вредных факторов:
радиация и мерцание монитора, шум и вибрация работы вентиляторов блока питания,
корпуса, видеокарты, а также шум принтеров и многофункциональных устройств,
монотонность работы, длительное нахождение в сидячем положении и постоянное
напряжение органов зрительной системы. Ввод данных в ПЭВМ может осуществляться
множеством способов: с помощью устройств управления (клавиатуры, мыши и прочих),
считыванием с различных накопителей (CD/DVD дисков, дискет, Flash накопителей,
мобильных жестких дисков и других), с помощью сканеров и другого оборудования.
Большую часть времени применяется ввод данных посредством клавиатуры, который
является самым утомительным. Если оператор не обладает навыками печати вслепую
десятипальцевым методом, то ввод большого объёма информации является тяжёлой и
сложной задачей. При этом усталость может появляться уже через достаточно короткий
промежуток времени. И на протяжении длительного периода это может привести к
неблагоприятным последствиям, изменениям в костной ткани, болезням суставов.
Проблема уменьшения воздействия радиации актуальна при работе с ЭЛТ- мониторами,
процент использования которых относительно ЖК-дисплеев в настоящее время
снижается, но все равно еще довольно высок. Для решения этой проблемы, раньше
применяли стеклянные или сеточные фильтры, уменьшающие мерцание, повышающие
контрастность и чёткость изображения, но со временем все ЭЛТ-дисплеи стали
соответствовать спецификации «low radiation» и выпускаться со специальным
антибликовым составом для лучшего восприятия изображения и для уменьшения
отражения внешнего освещения.
Для уменьшения воздействия нагрузки на зрительную систему и для уменьшения
воздействия монотонности работы дисплей размещается на столе так, чтобы расстояние
от глаз до экрана составляло 500-1000 мм (в зависимости от диагонали дисплея). В общем
случае расстояние наблюдения выбирается в зависимости от высоты и угловых размеров
знака. Угловой размер знака - угол между линиями, соединяющими крайние точки знака
по высоте и глаз наблюдателя. Угловой размер знака определяется по формуле:

h
a  arctg  
 2l 

где а - угловой размер знака; h — высота знака; l — расстояние от знака до глаза


наблюдателя.

Рекомендуемое значение углового размера знака должно входить в диапазон от 16 до 60.


Яркость знака, измеренная в темноте, должна находиться в диапазоне от 35 до 120 кд/м 2.
Внешняя освещенность экрана ПК должна составлять от 100 до 250 кд/м 2. Дисплей
должен предусматривать наличие регулировок яркости и контраста, обеспечивающих
возможность изменения этих параметров от минимальных до максимальных значений.
Конструкция клавиатуры должна предусматривать:
- исполнение в виде отдельного устройства с возможностью свободного
перемещения;
- опорное приспособление, позволяющее изменить угол наклона
поверхности клавиатуры в пределах от 5 до 15 градусов;

53
- высоту среднего ряда клавиш не более 30 мм;
- выделение цветом, размером, формой и местом расположения функциональных
групп клавиш;
- минимальный размер клавиш — 13 мм, оптимальный - 15 мм;
- клавиши с углублением в центре и шагом 19 ± 1 мм;
- расстояние между клавишами не менее 3 мм;
- одинаковый ход для всех клавиш с минимальным сопротивлением нажатию 0,25
Н и максимальным - не более 1,5 Н.
Кроме утомления зрительной системы, из-за длительного сохранения сидячего
положения идёт утомление мышц шеи и спины. Для уменьшения воздействия этих
факторов следует периодически (через каждые час — полтора работы) делать
короткие перерывы для отдыха и/или разминки.
Размещение технических средств и кресла оператора в рабочей зоне должно
обеспечивать удобный доступ к основным функциональным узлам и блокам
аппаратуры для проведения технической диагностики, профилактического осмотра и
ремонта. Подразумевается также возможность быстро приходить в рабочую зону и
покидать ее, должно быть исключено случайное приведение в действие средств
управления и ввода информации, также рекомендуется наличие удобной позы для
работы и отдыха.
При размещении пульта на стандартном столе высотой 750 мм необходимо
использовать кресло с регулируемой высотой сидения и желательно с жёсткой спинкой
вместо мягкого, во избежание сутулости оператора.
При вводе данных с какого-либо бумажного носителя путем набора на клавиатуре,
бумаги должны располагаться на расстоянии 450-500 мм от глаз оператора,
преимущественно слева, при этом угол между экраном дисплея и документом в
горизонтальной плоскости должен составлять 30-40 градусов. Угол наклона
клавиатуры следует установить в значении 15 градусов.
Экран дисплея, документы и клавиатура должны быть расположены так, чтобы перепад
яркостей поверхностей, зависящий от их расположения относительно источника света,
не превышал 1:10 (рекомендуемое значение 1:3). При номинальных значениях яркостей
изображения на экране 50-100 кд/м2 освещённость документа должна составлять 300-
500 люкс.
Устройства документирования и другие нечасто используемые технические средства
должны располагаться справа от оператора в зоне максимальной досягаемости, а
средства связи слева, чтобы освободить правую руку для записей.
Рабочий стол и клавиатура должны иметь возможность освещения сбоку настольной
лампы, помимо основного потолочного или настенного освещения помещения и
рабочего места, которое должно оставаться включенным для уменьшения резкости.

54
7.2. Вентиляция помещения
Для предотвращения неблагоприятного воздействия на оператора ПЭВМ повышенной
(или пониженной) температуры, повышенной относительной влажности и скорости
движения воздуха, запыленности, загазованности - следует предусмотреть системы
отопления, теплоснабжения, вентиляции и кондиционирования воздуха. Устройство,
содержание и эксплуатация систем должны соответствовать требованиям:
СНиП 2.04.05-91 «Отопление, вентиляция и кондиционирование воздуха»;
ГОСТ 12.4.021-75 «ССБТ. Системы вентиляционные. Общие требования»;
«Правил технической эксплуатации теплоиспользующих установок и тепловых сетей».
Отопительные приборы должны быть размещены в местах, доступных для осмотра,
ремонта и очистки, на расстоянии 100 мм от поверхностей стен. Не допускается
размещать отопительные приборы в нишах стен.
Вентиляция и кондиционирование воздуха должны обеспечивать оптимальные нормы
микроклиматических параметров на рабочих местах, оснащенных ПК, и содержание
вредных веществ в воздухе рабочей зоны не должно превышать 0,3 от предельно
допустимой концентрации.
Микроклимат помещения оказывает значительное влияние на оператора. Отклонение
его отдельных параметров от рекомендованных значений снижают работоспособность,
ухудшают самочувствие и могут привести к профессиональным заболеваниям.
В зависимости от энергозатрат организма ГОСТ 12.1.005-88 ССБТ "Воздух рабочей
зоны, общие санитарно-гигиенические требования" предусматривает три категории
работ. В соответствии ним, работа оператора ЭВМ может быть отнесена к лёгкой
физической работе категории 1Б, с энергозатратами организма, примерно равными
138-172 Дж/с или 120-150 ккал/час. Следует помнить, что в тёплый период года
среднесуточная температура наружного воздуха - выше +10°С, а в холодный период
года—10°С и ниже. Оптимальная относительная влажность колеблется в пределах 40-
60%.

7.2.1. Расчет выделения тепла


7.2.1.1. Тепловыделение от людей
Тепловыделение человека зависят от тяжести работы, температуры окружающего
воздуха и скорости движения воздуха. В расчете используется явное тепло, т.е. тепло,
воздействующее на изменение температуры воздуха в помещении. Для умственной
работы количество явного тепла, выделяемое одним человеком, составляет 140 ВТ при
10°С и 16 ВТ при 35°С. Для нормальных условий (20°С) явные тепловыделения одного
человека составляют около 55 Вт. Считается, что женщина выделяет 85%, а ребенок -
75% тепловыделения взрослого мужчины. В рассчитываемом помещении (5x10x3,5 м)
находится 4 человека. Тогда суммарное тепловыделение от людей будет:
Q1  4  55  220[ Вт]
7.2.1.2. Тепловыделение от солнечной радиации.
Расчет тепла, поступающего в помещение от солнечной радиации, Qост и QП ,
производится по следующим формулам:
- для остекленных поверхностей Qост  Fост  q ост  Aост
- для покрытий Q П  FП  q П
где F ост и FП - площади поверхности остекления и покрытия, м2;
qост и q П - тепловыделения от солнечной радиации, Вт/м2, через 1 м2 поверхности
остекления (таблицы 7.1 и 7.2 соответственно);
Aост - коэффициент учета характера остекления (таблица 7.3).

55
Характер При ориентации остекления по географической широте
остекления Ю ЮВ и ЮЗ ВиЗ СВ и СЗ
35 45 55 65 35 45 55 65 35 45 55 65 35 45 55 65
Окна с двойным остеклением с переплетами:
деревянными 128 145 145 170 100 128 145 170 145 145 170 170 75 75 75 75
металлическими 165 185 185 120 128 165 185 210 185 185 200 210 95 95 95 95
Фонари с двойным вертикальным остеклением с переплетами:
деревянными 140 170 170 175 115 145 175 175 170 170 185 185 87 87 87 80
металлическими 150 185 185 200 128 165 200 200 185 185 210 210 100 100 100 95
Таблица 7.1: Тепловыделение от солнечной радиации через остекление qост

Для остекленных поверхностей, ориентированных на север, принимаются равным 0.

Характер покрытия При географической широте

35 45 55 65
Плоское бесчердачное 24 21 17 14
с чердаком 6 6 6 6

Таблица 7.2: Тепловыделения от солнечной радиации через покрытие q П


Солнечную радиацию следует учитывать при наружной температуре от 10 °С и выше.
Характер остекления, его состояние Аост

Двойное остекление в одной раме 1,15


Одинарное остекление 1,45
Обычное загрязнение 0,8
Сильное загрязнение 0,7
Забелка окон 0,6
Остекление с матовыми стеклами 0,7
Внешнее зашторивание окон 0,25

Таблица 7.3: Значение коэффициента Aост

В помещении имеется 2 окна размером 2x1,2 м2. Тогда Focm= 4,8 м2.
Географическую широту примем равной 55°, окна выходят на юго-восток, характер
оконных рам - с двойным остеклением и деревянными переплетами. Тогда,

q ост  145 Вт / м 2 
Аост  1,15
Q ост  4,8  145  1,15  800 Вт
Площадь покрытия FП =20 [м2]. Характер покрытия - с чердаком. Тогда,

q П  6 Вт / м 2 
Q П  20  6  120 Вт
Суммарное тепловыделение от солнечной радиации:
Q 2  Q ост  Q П  800  120  920 Вт
7.2.1.3. Тепловыделение от источников искусственного освещения
56
Расчет тепловыделений от источников искусственного освещения проводится по формуле
Q3  N  n  1000 Вт
где N - суммарная мощность источников освещения, кВт;
п - коэффициент тепловых потерь (0,9 для ламп накаливания и 0,55 для
люминесцентных ламп).
У нас имеется 20 светильников с двумя лампами ЛД30 (30Вт) и 2 местных светильника
с лампами Б215-225-200 или Г215-225-200. Тогда получаем:
Q 3   20  2  0,03  0,55  2  0,2  0,9  1000  1020 Вт
7.2.1.4. Тепловыделение от устройств вычислительной техники
Расчет выделений тепла проводится аналогично расчету тепловыделений от источников
искусственного освещения:
Q4  N  n  1000 Вт
Коэффициент тепловых потерь для устройств вычислительной техники составляет п = 0,5.
В помещении находятся: 3 персональных компьютера на основе процессора Intel
Pentium Core i7 по 500 Вт, 3 монитора Samsung TFT 21" по 42 Вт и 2 сканера Canon
CanoScan LiDE 25 по 2,5 Вт.
Q 4  (3  0,5  3  0,042  2  0,0025)  0,5  1000  815,5 Вт
Суммарное тепловыделение составит:
Q С  Q 1  Q 2  Q 3  Q 4  220  920  1020  815,5  2975,5 Вт

Qизб - избыточная теплота в помещении, определяемая как разность между Qc - теплом,


выделяемым в помещении и Qрасх - теплом, удаляемым из помещения.
Qизб  QС  Q расх
Q расх  0,1  QС  0,1  2975,5  297,55 Вт
Q изб  2975,5  297,55  2677,95 Вт

7.2.2. Расчет потребного воздухообмена


Объем приточного воздуха, необходимого для поглощения тепла, G (м3/ч), рассчитывают
по формуле:
3600  Q
G
c p  q   t уд  t пр 
где Q - теплоизбыток, Вт;
ср - массовая удельная теплоемкость воздуха;
 
q  1,2  1,29 кг / м 3 - плотность приточного воздуха;
tуд, tпр- температура удаляемого и приточного воздуха
Температура приточного воздуха определяется по СНиП-П-33-75 для холодного и теплого
времени года. Поскольку удаление тепла сложнее провести в теплый период, то расчет
проведем именно для него, приняв tпр= 18° С .
Температура удаляемого воздуха определяется по формуле:
t уд  t рз  а Н  2 
где t- температура в рабочей зоне по ГОСТ 12.1.005-76;
а=1[С/м] - нарастание температуры на каждый 1 м высоты;
Н=3.5[м] - высота помещения.
t уд  20  1  (3,5  2)  21,5 o  C 

G  2160 м 3 / с 

57
7.2.3. Определение поперечных размеров воздуховода
Исходными данными для определения поперечных размеров воздуховода являются
расходы воздуха G=2160 [м3/с] и допустимые скорости его движения на участке сети
V= 3 [ м / с ] .
Необходимая площадь воздуховода f определяется по формуле:
G 2160
f    0,2[ м 2 ]
3600  V 3600  3
Для дальнейших расчетов (при определении сопротивления сети, подборе вентилятора
и электродвигателя) площадь воздуховода принимается равной ближайшей большей
стандартной величине, т. е. f = 0.246[м2]. В офисах рекомендуется использовать
круглые металлические воздуховоды. Тогда расчет сечения воздуховода заключается в
определении диаметра трубы.
По справочнику находим, что для площади f = 0.246[м2] условный диаметр
воздуховода d = 560 [мм] .

7.2.4. Определение сопротивления сети


Определим потери давления в вентиляционной сети. При расчете сети необходимо учесть
потери давления в вентиляционном оборудовании. Естественным давлением в системах
механической вентиляции пренебрегают. Для обеспечения запаса вентилятор должен
создавать в воздуховоде давление, превышающее не менее чем на 10% расчетное
давление.
Для расчета сопротивления участка сети используется формула:
Y
P  R  L  Ei  V 2
2
где R - удельные потери давления на трение на участках сети;
L - длина участка воздуховода, м;
Ei - сумма коэффициентов местных потерь на участке воздуховода;
V - скорость воздуха на участке воздуховода, м/с;
Y - плотность воздуха (принимаем 1,2 кг/м3).
Значения R определяются по справочнику (R - по значению диаметра воздуховода на
участке d=560[мм] и F = 3 [м/с]). Ei - в зависимости от типа местного сопротивления.
Результаты расчета воздуховода и сопротивления сети приведены в таблице 7.4, для сети,
приведенной на рисунке 7.1 ниже.

Рис. 7.1: Вентиляционная сеть

58
№ G L V d м R R*L Е W Р
уч. м3/ч м м/с мм Па Па/м Па Па Па

1 2160 5 2,8 560 4,7 0,018 0,09 2,1 9,87 9,961


2 2160 3 2,8 560 4,7 0,018 0,054 2,4 11,28 11,334
3 4320 3 4,5 630 12,2 0,033 0,099 0,9 10,98 11,079
4 2160 3 2,8 560 4,7 0,018 0,054 2,4 11,28 11,334
5 6480 2 6,7 630 26,9 0,077 0,154 0,9 24,21 24,264
6 2160 3 2,8 560 4,7 0,018 0,054 2,4 11,28 11,334
7 8640 3 8,9 630 47,5 0,077 0,531 0,6 28,50 29,031
Таблица 7.4: Расчет воздуховодов сети

Y
M V2
где 2 ; W  M  Ei
Pmax  P1  P3  P5  P7  74,334[ Па ]
Таким образом, потери давления в вентиляционной сети составляют Р = 74.334[Па]

7.2.5. Подбор вентилятора и электродвигателя


Требуемое давление, создаваемое вентилятором, с учетом запаса на непредвиденное
сопротивление в сети в размере 10% составит:
Pтр  1,1  P  81,7674[ Па ]

В вентиляционной установке для данного помещения необходимо применить


вентилятор низкого давления, т. к. Ртр< 1 [кПа].
Выбираем осевой вентилятор (для сопротивлений сети до 200 Па) по аэродинамическим
характеристикам, т.е. зависимостям между полным давлением Ртр, создаваемым
вентилятором, и производительностью Vтр [м/ч].
С учетом возможных дополнительных потерь или подсоса воздуха в воздуховоде
необходимая производительность вентилятора увеличивается на 10%:
Vтр  1,1  G  9504 м / ч 
По справочнику выбираем осевой вентилятор типа 06-300N4 с КПД пв=0.65 первого
исполнения. КПД ременной передачи вентилятора nрп=1.0. Мощность электродвигателя
рассчитывается по формуле:
Vтр  Pтр
N  10 6  Вт
3,6  nв  n рп
в
N  332 Вт
По мощности выбираем электродвигатель AOЛ-22-2 с мощностью N = 0.6[кВт] и частотой
вращения 2830 об/мин.

7.3. Расчет кондиционирования


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

59
протекания технологического процесса. На промышленных предприятиях
кондиционирование воздуха применяется либо для обеспечения комфортных
(оптимальных) санитарно-гигиенических условий, создание которых обычной
вентиляцией невозможно, либо как составная часть технологического процесса.
Расчет кондиционирования проведем используя формулу для нахождения
кратности воздухообмена:
L
k
s
где L - количество воздуха, подаваемого (+) или удаляемого (-) из помещения;
s - объем помещения.
По этой формуле определим необходимый объем удаляемого воздуха, выбрав
кратность из справочника (должно быть не менее 3, примем k = 3 ).
Выразим
L  ks
s  5  10  3,5  175 м 3  
 
L  3  175  525 м 3 / ч
Теперь, используя формулу
L  3600  v  Fn
где L - количество воздуха, удаляемого в течение часа вытяжным шкафом или зонтом
(колпаком);
v - средняя скорость всасывания воздуха в открытый проем шкафа (зонта) [м/с] (0.5 -
1.7 м/с в зависимости от токсичности и летучести газов и паров, примем v =0.8[м/с] );
Fn - площадь открытого проема.
Следовательно,
Fn 
L

525
3600  v 3600  0,8
 
 0,182 м 2

В результате этого расчета получаем, что количество воздуха, удаляемого в течение часа
вытяжным шкафом, для нашего помещения должно быть 525 м 3/ч, а площадь открытого
проема - 0.182 м2. По справочным данным выбираем кондиционер КТЦ2-200.
В результате расчета кондиционирования нашли значение количества воздуха, которое
необходимо удалять из помещения в течение часа, и площадь открытого проема,
необходимую для удаления этого количества воздуха.

7.4. Требования по шуму и вибрации


При работе оператора на него действуют различные шумы, создаваемые системным
блоком (корпусными, процессорными и другими вентиляторами, а также жестким
диском), периферийными устройствами (принтерами, многофункциональными
устройствами, блоками бесперебойного питания), а также кондиционерами и прочим
оборудованием. Для уменьшения воздействия шума на организм оператора следует
производить своевременную профилактику оборудования.
Производственные помещения, в которых для работы используются ПЭВМ, не должны
граничить с помещениями, в которых уровни шума и вибрации превышают
нормируемые значения (печатные, механические цеха).
При выполнении основной работы на ПК уровень шума на рабочем месте не должен
превышать 50 дБа (в соответствии с санитарными нормами 2.2.4/2.1.8.562-96 «Шумы на
рабочих местах, в помещениях жилых, общественных зданий и на территории жилой
застройки»).
Уровни вибрации в производственных помещениях при работе на ПК (согласно
санитарным нормам СН 2.2.4/2.1.8.566-96 «Производственная вибрация, вибрация в

60
помещениях жилых и общественных зданий») не должны превышать следующих
значений: на частотах 2, 4, 8, 16, 31.5, 63 Гц соответственно 79, 73, 67, 67, 67, 67 дБ

7.5. Противопожарные мероприятия


Согласно СНИП JI-M-2-72 в зависимости от характера используемых в производстве
веществ и их количества, по пожарной и взрывной опасности производства
подразделяются по категориям А, Б, В, Г, Д. Помещение, где установлены компьютеры
чаще всего можно отнести к категории Д пожарной опасности с третьей степенью
огнестойкости - здания с несущими и ограждающими конструкциями из естественных
или искусственных материалов, бетона или железобетона.
Пожары в вычислительных центрах и центрах хранения данных представляют особую
опасность, так как сопряжены с большими материальными потерями. Как известно,
пожар может возникнуть при взаимодействии горючих веществ, окислителя и
источника зажигания. Все эти факторы актуальны для рассматриваемой ситуации.
Начало пожара в данных обстоятельствах наиболее вероятно по причинам
неисправности электрооборудования, к которым относятся: искрение в местах
соединения электропроводки, короткие замыкания в цепи, перегрузки проводов и
обмоток трансформаторов, перегрев источников бесперебойного питания и другие
факторы. Поэтому подключение компьютеров к сети необходимо производить через
распределительные щиты или сетевые фильтры, позволяющие производить
автоматическое отключение нагрузки при аварии или опасном отклонении параметров
питания от нормы.
Особенностью современных ЭВМ является очень высокая плотность расположения
элементов электронных схем, высокая рабочая температура процессора, северного
моста и микросхем памяти. Следовательно, вентиляция и система охлаждения,
предусмотренные в системном блоке компьютера, должны быть постоянно в исправном
состоянии, в противном случае возможен перегрев элементов, не исключающий их
воспламенение. Рекомендуется регулярная проверка, и очистка внутренних элементов
ПК от пыли и загрязнений, а также консультация специалиста, при подборе
комплектующих и охлаждения к ним.
Надёжная работа отдельных элементов и электронных схем в целом обеспечивается
только в определённых интервалах температуры, влажности и при заданных
электрических параметрах. При отклонении реальных условий эксплуатации от
расчётных также могут возникнуть пожароопасные ситуации.
Поскольку в рассматриваемом случае при возгораниях электроустройства могут
находиться под напряжением, то использовать воду и пену для тушения пожара
недопустимо, так как это может привести к электрическим травмам. Другой причиной,
по которой нежелательно использование воды, является то, что на некоторые элементы
ЭВМ недопустимо попадание влаги. Поэтому для тушения пожаров в рассматриваемом
помещении можно использовать либо порошковые составы, либо установки
углекислотного тушения. Но поскольку последние предназначены только для тушения
небольших очагов возгорания, то область их применения ограничена. Поэтому для
тушения пожаров в данном случае применяются порошковые составы, так как они
обладают следующими свойствами: диэлектрики, практически не токсичны, не
оказывают коррозийного воздействия на металлы, не разрушают диэлектрические лаки.
Установки порошкового пожаротушения могут быть как переносными, так и
стационарными, причем стационарные могут быть с ручным, дистанционным и
автоматическим включением. Автоматическая установка и установка с механическим
включением отличается только средствами открытия запорного крана. В
автоматических установках используются различные датчики обнаружения пожара (по

61
дыму, тепловому и световому излучению), а в механических специальные тросовые
системы с легкоплавкими замками.
В случае вычислительных центров и центров хранения данных целесообразно
использовать, например, автоматическую стационарную установку порошкового
пожаротушения УПС-500. В качестве тепловых и дымовых датчиков, подходят
извещатели ИП 104, которые срабатывают при превышении температуры в помещении
+60°С и извещатели ИП 212, которые срабатывают при скоплении дыма.
При составлении плана эвакуации в случае пожара необходимо учитывать, что он
должен быть составлен таким образом, чтобы за кратчайшее время люди могли
покинуть здание, не создавая заторов во время движения. Путь от дверей каждого
помещения до выхода из здания должен быть по возможности минимальным, для этого
необходимо учесть расположение комнат и всех выходов из здания, включая
аварийные.

62
8. Вывод
Как видно из тестов и эксперимента, представленная имитационная модель способна
адекватно моделировать процессы кодирования изображений при помощи ДИКМ,
преобразования Адамара и MPEG, что означает возможность ее использования в качестве
демонстрационного стенда для демонстрации студентам особенностей различных
способов кодирования, специфичных для них ошибок и искажений, характерных для них
достоинств и недостатков; а также в качестве стенда для лабораторных работ.
Как показано в экономической части работы, использование представленных цифровых
методов, выбор между которыми позволяет осуществить представленная модель (в
особенности MPEG), для кодирования телевизионных сигналов вместо существующих
аналоговых, позволяет сэкономить значительную долю радиэлектронного спектра, и
таким образом является экономически обоснованным.
У имитационной модели широкие перспективы расширения. Открытая программная
архитектура модели и гибкость языка Delphi, построенного на принципах объектно-
ориентированного программирования, позволяют при необходимости значительно
расширить функциональность модели. Основными возможными направлениями
улучшения видятся модификация пользовательского интерфейса и добавление новых
средств, повышающих наглядность сравний между работой различных алгоритмов
кодирования с различными настройками, добавление функционала работы с ДИКМ
(например, использование экстраполяторов вместо линейного интерполятора нулевого
порядка, использование двухмерного ДИКМ), расширение списка доступных для
исследования алгоритмов кодирования с преобразованием (как то ДКП или использование
БПФ, некоторые из функций которых в применении к изображениям реализованы в
сторонних компонентах для Delphi), расширение диапазона настроек различных видов
MPEG-кодеров.

63
9. Список использованной литературы
1. Загнетов П.П., Марков С.С. Применение цифровых методов при передаче и
обработке телевизионной информации. М. МАИ 1984.
2. Карякин В.Л. Цифровое телевидение. М. Солон-Пресс 2008.
3. Птачек М. Цифровое телевидение. Теория и техника. М. Радио и связь 1990.
4. Под ред. проф. Панагушина В.П. Экономическое обоснование дипломных
проектов (работ) по приборо- и радиоприборостроению. Методические указания.
М. МАИ 2008.
5. СНиП 2.04.05-86. Отопление, вентиляция и кондиционирование. М.
Государственный строительный комитет. 1987
6. Кострюков В.А. Сборник примеров расчета по отоплению и вентиляции. М.
Госстройиздат, 1962.
7. Инструкция по организации работ, охране труда и экологической безопасности
при работе на ПЭВМ (ПК), Госкомпечати России, 1998.
8. Бобков Н.И. и др. Охрана труда на ВЦ МАИ 1998
9. ССБТ ГОСТ 12.4.021-75 Сборник общих требований М. 1980
10. Яров В.Н., Малько Л.И. Защита от шума и вибраций. МАИ 1978

64
Приложение 1. Алгоритмы работы программы
Начало

Составить таблицу количества


разностных отсчетов различных
значений в изображении

Линейный
Да Нет
квантователь?

Таблица разностных отсчетов


Равномерное Режим с
Да Да содержит ближайшие к нулю
заполнение? отсечкой?
Нет последовательные целые

Нет

Разностные отсчеты Разностные отсчеты Таблица разностных отсчетов


равномерно распределены от 0 в Критерий содержит все отсчеты,
Да
распределены от 0 до обе стороны с значимости? встречающиеся чаще
255 и до -255. заданным шагом заданного числа раз

Нет

Таблица разностных отсчетов


Разностные отсчеты
Метод содержит заданное число
равномерно делят Нет Да
максимумов? наиболее часто
центральный максимум
встречающихся отсчетов

Строка 0

Столбец 0

Да Столбец 0? Нет

Из таблицы разностных отсчетов


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

Запомнить для
передачи номер
элемента в
таблице

Следующий
столбец

Следующая Номер столбца больше


Да
строка ширины изображения?

Номер строки больше


Конец Да
высоты изображения?

Рис. П1.1. Алгоритм работы кодера ДИКМ.

65
Рис. П1.2. Алгоритм работы декодера ДИКМ.

66
Рис. П1.3. Алгоритм работы систем сбора статистики для ДИКМ.

67
Рис. П1.4. Алгоритм работы кодера, преобразование Адамара.
68
Рис. П1.5. Алгоритм работы декодера, преобразование Адамара.
69
Рис. П1.6. Алгоритм сбора статистики. Преобразование Адамара.
70
Рис. П1.7. Алгоритм работы генератора шумовых искажений.

71
Рис. П1.8. Алгоритм формирования разностного изображения

72
Рис. П1.9. Алгоритм работы с MPEG
73
Приложение 2. Образцы работы ДИКМ и преобразования Адамара
П2.1. ДИКМ.
Исходный цветовой фрагмент Разностные отсчеты Восстановленные значения

255 255 255 125 255 0 0 -130 255 255 255 125
255 255 0 255 255 0 -255 255 255 255 0 255
255 125 255 255 255 -130 130 0 255 125 255 255
0 255 255 255 0 255 0 0 0 255 255 255

П2.2. Преобразование Адамара


Исходный цветовой фрагмент

255 255 255 125 255 255 255 125 255 255 255 125 255 255 255 125
255 255 0 255 255 255 0 255 255 255 0 255 255 255 0 255
255 125 255 255 255 125 255 255 255 125 255 255 255 125 255 255
0 255 255 255 0 255 255 255 0 255 255 255 0 255 255 255

Базисные изображения
phi00 phi01 phi02 phi03
1 1 1 1 1 1 -1 -1 1 -1 -1 1 1 -1 1 -1
1 1 1 1 1 1 -1 -1 1 -1 -1 1 1 -1 1 -1
1 1 1 1 1 1 -1 -1 1 -1 -1 1 1 -1 1 -1
1 1 1 1 1 1 -1 -1 1 -1 -1 1 1 -1 1 -1

phi10 phi11 phi12 phi13


1 1 1 1 1 1 -1 -1 1 -1 -1 1 1 -1 1 -1
1 1 1 1 1 1 -1 -1 1 -1 -1 1 1 -1 1 -1
-1 -1 -1 -1 -1 -1 1 1 -1 1 1 -1 -1 1 -1 1
-1 -1 -1 -1 -1 -1 1 1 -1 1 1 -1 -1 1 -1 1

phi20 phi21 phi22 phi23


1 1 1 1 1 1 -1 -1 1 -1 -1 1 1 -1 1 -1
-1 -1 -1 -1 -1 -1 1 1 -1 1 1 -1 -1 1 -1 1
-1 -1 -1 -1 -1 -1 1 1 -1 1 1 -1 -1 1 -1 1
1 1 1 1 1 1 -1 -1 1 -1 -1 1 1 -1 1 -1

phi30 phi31 phi32 phi33


1 1 1 1 1 1 -1 -1 1 -1 -1 1 1 -1 1 -1
-1 -1 -1 -1 -1 -1 1 1 -1 1 1 -1 -1 1 -1 1
1 1 1 1 1 1 -1 -1 1 -1 -1 1 1 -1 1 -1
-1 -1 -1 -1 -1 -1 1 1 -1 1 1 -1 -1 1 -1 1

74
Кодируем
255 255 255 125 255 255 -255 -125 255 -255 -255 125 255 -255 255 -125
255 255 0 255 255 255 0 -255 255 -255 0 255 255 -255 0 -255
255 125 255 255 255 125 -255 -255 255 -125 -255 255 255 -125 255 -255
0 255 255 255 0 255 -255 -255 0 -255 -255 255 0 -255 255 -255
3310 206,875 H00 0 0 H01 0 0 H02 -250 -15,625 H03
Суммируем Нормируем
255 255 255 125 255 255 -255 -125 255 -255 -255 125 255 -255 255 -125
255 255 0 255 255 255 0 -255 255 -255 0 255 255 -255 0 -255
-255 -125 -255 -255 -255 -125 255 255 -255 125 255 -255 -255 125 -255 255
0 -255 -255 -255 0 -255 255 255 0 255 255 -255 0 255 -255 255
0 0 H10 770 48,125 H11 250 15,625 H12 0 0 H13

255 255 255 125 255 255 -255 -125 255 -255 -255 125 255 -255 255 -125
-255 -255 0 -255 -255 -255 0 255 -255 255 0 -255 -255 255 0 255
-255 -125 -255 -255 -255 -125 255 255 -255 125 255 -255 -255 125 -255 255
0 255 255 255 0 255 -255 -255 0 -255 -255 255 0 -255 255 -255
0 0 H20 -250 -15,625 H21 -770 -48,125 H22 0 0 H23

255 255 255 125 255 255 -255 -125 255 -255 -255 125 255 -255 255 -125
-255 -255 0 -255 -255 -255 0 255 -255 255 0 -255 -255 255 0 255
255 125 255 255 255 125 -255 -255 255 -125 -255 255 255 -125 255 -255
0 -255 -255 -255 0 -255 255 255 0 255 255 -255 0 255 -255 255
250 15,625 H30 0 0 H31 0 0 H32 770 48,125 H33

75
Декодируем
206,875 206,875 206,875 206,875 0 0 0 0 0 0 0 0 -15,625 15,625 -15,625 15,625
206,875 206,875 206,875 206,875 0 0 0 0 0 0 0 0 -15,625 15,625 -15,625 15,625
206,875 206,875 206,875 206,875 0 0 0 0 0 0 0 0 -15,625 15,625 -15,625 15,625
206,875 206,875 206,875 206,875 0 0 0 0 0 0 0 0 -15,625 15,625 -15,625 15,625

0 0 0 0 48,125 48,125 -48,125 -48,125 15,625 -15,625 -15,625 15,625 0 0 0 0


0 0 0 0 48,125 48,125 -48,125 -48,125 15,625 -15,625 -15,625 15,625 0 0 0 0
0 0 0 0 -48,125 -48,125 48,125 48,125 -15,625 15,625 15,625 -15,625 0 0 0 0
0 0 0 0 -48,125 -48,125 48,125 48,125 -15,625 15,625 15,625 -15,625 0 0 0 0

0 0 0 0 -15,625 -15,625 15,625 15,625 -48,125 48,125 48,125 -48,125 0 0 0 0


0 0 0 0 15,625 15,625 -15,625 -15,625 48,125 -48,125 -48,125 48,125 0 0 0 0
0 0 0 0 15,625 15,625 -15,625 -15,625 48,125 -48,125 -48,125 48,125 0 0 0 0
0 0 0 0 -15,625 -15,625 15,625 15,625 -48,125 48,125 48,125 -48,125 0 0 0 0

15,625 15,625 15,625 15,625 0 0 0 0 0 0 0 0 48,125 -48,125 48,125 -48,125


-15,625 -15,625 -15,625 -15,625 0 0 0 0 0 0 0 0 -48,125 48,125 -48,125 48,125
15,625 15,625 15,625 15,625 0 0 0 0 0 0 0 0 48,125 -48,125 48,125 -48,125
-15,625 -15,625 -15,625 -15,625 0 0 0 0 0 0 0 0 -48,125 48,125 -48,125 48,125

Суммируем
255 255 255 125
255 255 0 255
255 125 255 255
0 255 255 255

76
Приложение 3. Текст программы.
П3.1. Transforms.dpr
program Transcode;

uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2};

{$R *.res}

begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.Run;
end.

77
П3.2. Unit1.pas
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls, TeEngine, Series, TeeProcs, Chart,
Spin, Math, idGlobal, XPMan, Grids, DSPack, ToolWin, ImgList, ShellApi, DirectShow9;

type
TBasisImage = record
loaded : Boolean;
values : Array[0..7,0..7] of Integer;
end;
TBasisImages = Array[0..7,0..7] of TBasisImage;
TForm1 = class(TForm)
PageSourceControl1: TPageControl;
ParametersTabSheet: TTabSheet;
ImageTabSheet: TTabSheet;
StatTabSheet: TTabSheet;
GroupBox1: TGroupBox;
ComboBox1: TComboBox;
GroupBox2: TGroupBox;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
Edit1: TEdit;
Button1: TButton;
Button2: TButton;
Panel1: TPanel;
RadioButton3: TRadioButton;
RadioButton4: TRadioButton;
RadioButton5: TRadioButton;
RadioButton6: TRadioButton;
RadioButton7: TRadioButton;
RadioButton8: TRadioButton;
RadioButton9: TRadioButton;
OpenDialog1: TOpenDialog;
GroupBox3: TGroupBox;
Image1: TImage;
Chart1: TChart;
Series1: TLineSeries;
RadioButton10: TRadioButton;
RadioButton11: TRadioButton;
SpinEdit1: TSpinEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;

78
Label4: TLabel;
SpinEdit2: TSpinEdit;
Series2: TLineSeries;
RadioButton12: TRadioButton;
Label5: TLabel;
Label6: TLabel;
GroupBox4: TGroupBox;
GroupBox5: TGroupBox;
RadioButton13: TRadioButton;
RadioButton14: TRadioButton;
RadioButton15: TRadioButton;
RadioButton16: TRadioButton;
Chart2: TChart;
Label7: TLabel;
SpinEdit3: TSpinEdit;
Label8: TLabel;
SpinEdit4: TSpinEdit;
Label9: TLabel;
SpinEdit5: TSpinEdit;
Label10: TLabel;
RadioButton17: TRadioButton;
RadioButton18: TRadioButton;
SpinEdit6: TSpinEdit;
Panel2: TPanel;
RadioButton19: TRadioButton;
RadioButton20: TRadioButton;
Label12: TLabel;
SpinEdit7: TSpinEdit;
SpinEdit8: TSpinEdit;
Label13: TLabel;
Button3: TButton;
Image2: TImage;
Image3: TImage;
RadioButton21: TRadioButton;
RadioButton22: TRadioButton;
RadioButton23: TRadioButton;
Image4: TImage;
GroupBox6: TGroupBox;
RadioButton25: TRadioButton;
RadioButton24: TRadioButton;
ComboBox2: TComboBox;
GroupBox7: TGroupBox;
Label14: TLabel;
Label15: TLabel;
Label16: TLabel;
Label17: TLabel;
Label18: TLabel;
Label19: TLabel;
Label20: TLabel;
Label21: TLabel;

79
Label22: TLabel;
Label23: TLabel;
GroupBox8: TGroupBox;
Label24: TLabel;
Label26: TLabel;
Label25: TLabel;
Label27: TLabel;
Chart3: TChart;
Series4: TLineSeries;
GroupBox9: TGroupBox;
GroupBox10: TGroupBox;
Image5: TImage;
Label28: TLabel;
Panel3: TPanel;
RadioButton26: TRadioButton;
RadioButton27: TRadioButton;
XPManifest1: TXPManifest;
Label29: TLabel;
Panel4: TPanel;
RadioButton28: TRadioButton;
RadioButton29: TRadioButton;
Label30: TLabel;
SpinEdit9: TSpinEdit;
StringGrid1: TStringGrid;
Label31: TLabel;
RadioButton30: TRadioButton;
Series3: TLineSeries;
Panel5: TPanel;
RadioButton31: TRadioButton;
SpinEdit10: TSpinEdit;
RadioButton32: TRadioButton;
SpinEdit11: TSpinEdit;
RadioButton33: TRadioButton;
SpinEdit12: TSpinEdit;
Button4: TButton;
GroupBox11: TGroupBox;
Edit2: TEdit;
Button5: TButton;
Button6: TButton;
OpenDialog2: TOpenDialog;
GroupBox12: TGroupBox;
GroupBox13: TGroupBox;
Memo1: TMemo;
Label11: TLabel;
Label32: TLabel;
Panel6: TPanel;
RadioButton34: TRadioButton;
RadioButton35: TRadioButton;
RadioButton36: TRadioButton;
FilterGraph: TFilterGraph;

80
VideoWindow1: TVideoWindow;
ImageList1: TImageList;
ToolBar1: TToolBar;
ToolButton1: TToolButton;
ToolButton2: TToolButton;
ToolButton3: TToolButton;
ToolButton4: TToolButton;
ToolButton5: TToolButton;
ToolButton6: TToolButton;
ToolButton7: TToolButton;
Label33: TLabel;
SpinEdit13: TSpinEdit;
Label34: TLabel;
SpinEdit14: TSpinEdit;
Label35: TLabel;
ComboBox3: TComboBox;
Label36: TLabel;
SpinEdit15: TSpinEdit;
Label37: TLabel;
SpinEdit16: TSpinEdit;
Button7: TButton;
Label38: TLabel;
DSTrackBar1: TDSTrackBar;
Button8: TButton;
Memo2: TMemo;
RadioButton37: TRadioButton;
procedure ComboBox1Change(Sender: TObject);
procedure RadioButton1Click(Sender: TObject);
procedure RadioButton2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure RadioButton11Click(Sender: TObject);
procedure RadioButton10Click(Sender: TObject);
procedure SpinEdit1Change(Sender: TObject);
procedure SpinEdit2Change(Sender: TObject);
procedure RadioButton12Click(Sender: TObject);
procedure RadioButton14Click(Sender: TObject);
procedure RadioButton15Click(Sender: TObject);
procedure RadioButton16Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure SpinEdit4Change(Sender: TObject);
procedure SpinEdit5Change(Sender: TObject);
procedure Label12Click(Sender: TObject);
procedure RadioButton17Click(Sender: TObject);
procedure RadioButton18Click(Sender: TObject);
procedure SpinEdit6Change(Sender: TObject);
procedure SpinEdit8Change(Sender: TObject);
procedure RadioButton19Click(Sender: TObject);
procedure RadioButton20Click(Sender: TObject);
procedure SpinEdit7Change(Sender: TObject);

81
procedure Button3Click(Sender: TObject);
procedure RadioButton21Click(Sender: TObject);
procedure RadioButton22Click(Sender: TObject);
procedure RadioButton23Click(Sender: TObject);
procedure RadioButton24Click(Sender: TObject);
procedure RadioButton25Click(Sender: TObject);
procedure ComboBox2Change(Sender: TObject);
procedure RadioButton29Click(Sender: TObject);
procedure RadioButton28Click(Sender: TObject);
procedure RadioButton26Click(Sender: TObject);
procedure RadioButton27Click(Sender: TObject);
procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
procedure Image2Click(Sender: TObject);
procedure Image3Click(Sender: TObject);
procedure Image4Click(Sender: TObject);
procedure Chart2Click(Sender: TObject);
procedure Chart2ClickAxis(Sender: TCustomChart; Axis: TChartAxis;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure Chart2ClickBackground(Sender: TCustomChart;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure Chart2ClickLegend(Sender: TCustomChart; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Chart2ClickSeries(Sender: TCustomChart; Series: TChartSeries;
ValueIndex: Integer; Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
procedure Chart2Enter(Sender: TObject);
procedure Chart2MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure RadioButton30Click(Sender: TObject);
procedure SpinEdit10Change(Sender: TObject);
procedure SpinEdit11Change(Sender: TObject);
procedure RadioButton31Click(Sender: TObject);
procedure RadioButton32Click(Sender: TObject);
procedure RadioButton33Click(Sender: TObject);
procedure SpinEdit12Change(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure ToolButton1Click(Sender: TObject);
procedure ToolButton3Click(Sender: TObject);
procedure ToolButton5Click(Sender: TObject);
procedure ToolButton7Click(Sender: TObject);
procedure Button7Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button8Click(Sender: TObject);
procedure VideoWindow1Click(Sender: TObject);
procedure RadioButton37Click(Sender: TObject);

82
private
{ Private declarations }
public
differences:array [0..511] of Integer;
DiffSum:LongInt;
threshold,needed:Integer;
width,height:Integer;
DiffTable:array [0..512] of integer;
Diff_used:Integer;
Reds,Greens,Blues:Array [0..1600,0..1600] of Integer;
dropped:Array[0..15,0..15] of Integer;
AdamarImages:TBasisImages;
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}
//Задаем значения по умолчанию для матриц опускаемых коэф.преобразования Адамара
procedure DefaultDropped(total:Integer;moved:Boolean);
var
i,j:Integer;
begin
For i:=0 to 15 do
For j:=0 to 15 do Form1.dropped[i,j]:=0;
//Для фрагмента размером 8х8
If (total=8) and (moved=False) then begin
Form1.dropped[0,0]:=1;
Form1.dropped[1,0]:=1;
Form1.dropped[2,0]:=1;
Form1.dropped[3,0]:=1;
Form1.dropped[0,1]:=1;
Form1.dropped[1,1]:=1;
Form1.dropped[2,1]:=1;
Form1.dropped[3,1]:=1;
Form1.dropped[5,0]:=1;
Form1.dropped[6,0]:=1;
Form1.dropped[7,0]:=1;
Form1.dropped[0,2]:=1;
Form1.dropped[1,2]:=1;
Form1.dropped[2,2]:=1;
Form1.dropped[0,3]:=1;
Form1.dropped[1,3]:=1;
Form1.dropped[0,5]:=1;

83
Form1.dropped[0,6]:=1;
Form1.dropped[0,7]:=1;
end;
//И для фрагмента 4х4, со смещением. В коде преобразования это смещение учитывается.
If (total=4) and (moved=True) then begin
Form1.dropped[4,4]:=1;
Form1.dropped[4,5]:=1;
Form1.dropped[4,6]:=1;
Form1.dropped[4,7]:=1;
Form1.dropped[5,4]:=1;
Form1.dropped[5,5]:=1;
Form1.dropped[6,4]:=1;
Form1.dropped[7,4]:=1;
end;
end;

//Запускаем стороннее приложение в командной строке ОС и получаем его вывод


function GetDosOutput(CommandLine: string; Work: string = 'C:\'): string;
var
SA: TSecurityAttributes;
SI: TStartupInfo;
PI: TProcessInformation;
StdOutPipeRead, StdOutPipeWrite: THandle;
WasOK: Boolean;
Buffer: array[0..255] of AnsiChar;
BytesRead: Cardinal;
WorkDir: string;
Handle: Boolean;
begin
Result := '';
with SA do begin
nLength := SizeOf(SA);
bInheritHandle := True;
lpSecurityDescriptor := nil;
end;
CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SA, 0);
try
with SI do
begin
FillChar(SI, SizeOf(SI), 0);
cb := SizeOf(SI);
dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
wShowWindow := SW_HIDE;
hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin
hStdOutput := StdOutPipeWrite;
hStdError := StdOutPipeWrite;
end;
WorkDir := Work;
Handle := CreateProcess(nil, PChar('cmd.exe /C ' + CommandLine),
nil, nil, True, 0, nil,

84
PChar(WorkDir), SI, PI);
CloseHandle(StdOutPipeWrite);
if Handle then
try
repeat
WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
if BytesRead > 0 then
begin
Buffer[BytesRead] := #0;
Result := Result + Buffer;
end;
until not WasOK or (BytesRead = 0);
WaitForSingleObject(PI.hProcess, INFINITE);
finally
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
end;
finally
CloseHandle(StdOutPipeRead);
end;
end;

//Загружаем базисные изображения преобразования Адамара. Чтобы не забивать их руками, они хранятся в виде, собственно, изображений.
procedure LoadAdamarBasisImage(size,x,y:Integer);
var
Bitmap:TBitmap;
tmpstr:String;
i,j:Integer;
currclr:TColor;
begin
Bitmap:=TBitmap.Create;
tmpstr:=ExtractFileDir(Application.ExeName)+'\Adamar_basis_images\'+IntToStr(size)+'x'+IntToStr(size)+'\phi'+IntToStr(x)+IntToStr(y)+'.bmp';
Bitmap.LoadFromFile(tmpstr);
For i:=0 to size-1 do
For j:=0 to size-1 do begin
currclr:=Bitmap.Canvas.Pixels[i,j];
If currclr=0 then Form1.AdamarImages[y,x].Values[i,j]:=-1
else Form1.AdamarImages[y,x].Values[i,j]:=1;
end;
Form1.AdamarImages[x,y].Loaded:=True;
Bitmap.Destroy;
end;

//Сортировка массива, стандартный алгоритм быстрой сортировки.


procedure QuickSort(var A: array of Integer; iLo, iHi: Integer) ;
var
Lo, Hi, Pivot, T: Integer;
begin
Lo := iLo;
Hi := iHi;

85
Pivot := A[(Lo + Hi) div 2];
repeat
while A[Lo] < Pivot do Inc(Lo) ;
while A[Hi] > Pivot do Dec(Hi) ;
if Lo <= Hi then
begin
T := A[Lo];
A[Lo] := A[Hi];
A[Hi] := T;
Inc(Lo) ;
Dec(Hi) ;
end;
until Lo > Hi;
if Hi > iLo then QuickSort(A, iLo, Hi) ;
if Lo < iHi then QuickSort(A, Lo, iHi) ;
end;

//возвращаем номер элемента в difftable - таблице доступных значений разностей для кодирования
function FindClosestDiff(Diff:Integer):Integer;
var
i:Integer;
opt:Integer;
resultf:Integer;
begin
opt:=600;
resultf:=-1;
for i:=0 to Length(Form1.DiffTable)-1 do if Abs(Form1.difftable[i]-diff)<opt then begin
opt:=Abs(Form1.difftable[i]-diff);
resultf:=i;
end;
FindClosestDiff:=resultf;
end;

//Выбор способа кодирования


procedure TForm1.ComboBox1Change(Sender: TObject);
begin
GroupBox3.Visible:=False;
GroupBox4.Visible:=False;
GroupBox5.Visible:=False;
GroupBox9.Visible:=False;
GroupBox10.Visible:=False;
GroupBox11.Visible:=False;
GroupBox12.Visible:=False;
GroupBox13.Visible:=False;
Button6.Enabled:=False;
FilterGraph.ClearGraph;
If Combobox1.ItemIndex<2 then Groupbox2.Visible:=True
else begin
Groupbox2.Visible:=False;
GroupBox11.Visible:=True;

86
end;
If Combobox1.ItemIndex=0 then begin
Label13.Caption:='Линейный квантователь не отсечет наиболее резкие изменения цветов.'+#10+#13+'Разностные отсчеты передадутся точно, но информации будет передано больше, чем без
ДИКМ.';
end;
end;

//Загрузка изображений - включаем-выключаем подпункты меню


procedure TForm1.RadioButton1Click(Sender: TObject);
begin
If RadioButton1.Checked then begin
RadioButton3.Enabled:=True;
RadioButton4.Enabled:=True;
RadioButton5.Enabled:=True;
RadioButton6.Enabled:=True;
RadioButton7.Enabled:=True;
RadioButton8.Enabled:=True;
RadioButton9.Enabled:=True;
RadioButton13.Enabled:=True;
Edit1.Enabled:=False;
Button1.Enabled:=False;
end
else begin
RadioButton3.Enabled:=False;
RadioButton4.Enabled:=False;
RadioButton5.Enabled:=False;
RadioButton6.Enabled:=False;
RadioButton7.Enabled:=False;
RadioButton8.Enabled:=False;
RadioButton9.Enabled:=False;
RadioButton13.Enabled:=True;
Edit1.Enabled:=True;
Button1.Enabled:=True;
end;
end;

//Загрузка изображений - включаем-выключаем подпункты меню


procedure TForm1.RadioButton2Click(Sender: TObject);
begin
If RadioButton2.Checked=false then begin
RadioButton3.Enabled:=True;
RadioButton4.Enabled:=True;
RadioButton5.Enabled:=True;
RadioButton6.Enabled:=True;
RadioButton7.Enabled:=True;
RadioButton8.Enabled:=True;
RadioButton9.Enabled:=True;
RadioButton13.Enabled:=True;
Edit1.Enabled:=False;
Button1.Enabled:=False;

87
end
else begin
RadioButton3.Enabled:=False;
RadioButton4.Enabled:=False;
RadioButton5.Enabled:=False;
RadioButton6.Enabled:=False;
RadioButton7.Enabled:=False;
RadioButton8.Enabled:=False;
RadioButton9.Enabled:=False;
RadioButton13.Enabled:=False;
Edit1.Enabled:=True;
Button1.Enabled:=True;
end;
end;

//Подгружаем имя выбранного пользователем в стандартном диалоге изображения


procedure TForm1.Button1Click(Sender: TObject);
begin
If OpenDialog1.Execute then Edit1.Text:=OpenDialog1.FileName;
end;

//Собственно, загружаем изображения для работы с ДИКМ


procedure TForm1.Button2Click(Sender: TObject);
var
ratio:Real;
i,j:Integer;
diff:Integer;
currclr:TColor;
r,g,b: Byte;
pr,pg,pb:Byte;
begin
If Combobox1.ItemIndex=0 then begin
Image1.AutoSize:=True;
//Стандартные изображения.
If RadioButton1.Checked then begin
//If RadioButton3.Checked then Image1.Picture.LoadFromFile();
If RadioButton4.Checked then Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\BW Picture.bmp');
If RadioButton5.Checked then Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Color Picture.bmp');
If RadioButton7.Checked then Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Color Stripes.bmp');
If RadioButton6.Checked then Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Checkers.bmp');
If RadioButton13.Checked then Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Checkers-small.bmp');
If RadioButton8.Checked then Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\High-contrast Letters.bmp');
If RadioButton9.Checked then Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Low-contrast Letters.bmp');
end
else begin
try
Image1.Picture.LoadFromFile(Edit1.Text);
except
Application.MessageBox('Ошибка при загрузке изображения','Ошибка',mb_ok or MB_ICONERROR);
end;

88
end;
Image1.Visible:=False;
RadioButton10.Checked:=True;
width:=Image1.Width;
height:=Image1.Height;
ratio:=width/height;
If (width>1599) or (height>1599) then begin
Application.MessageBox('Максимальный размер изображения для обработки - 1600х1600!','Ошибка',mb_ok or MB_ICONERROR);
exit;
end;

//Готовим статистику в панель справа


for i:=0 to 511 do differences[i]:=0;
For i:=0 to Image1.Height-1 do begin
currclr:=Image1.Picture.Bitmap.Canvas.Pixels[0,i];
pr := currclr and $FF;
pg := (currclr shr 8) and $FF;
pb := (currclr shr 16) and $FF;
For j:=1 to Image1.Width-1 do begin
currclr:=Image1.Picture.Bitmap.Canvas.Pixels[j,i];
r := currclr and $FF;
g := (currclr shr 8) and $FF;
b := (currclr shr 16) and $FF;
diff:=r-pr;
differences[diff+255]:=differences[diff+255]+1;
diff:=b-pb;
differences[diff+255]:=differences[diff+255]+1;
diff:=g-pg;
differences[diff+255]:=differences[diff+255]+1;
pr:=r;
pg:=g;
pb:=b;
end;
end;
//усредняем значения по цветам
for i:=0 to 511 do differences[i]:=Trunc(differences[i]/3);
DiffSum:=0;
for i:=0 to 511 do diffsum:=diffsum+differences[i];
SpinEdit1.MaxValue:=DiffSum;
Chart1.Series[0].Clear;
Chart1.Series[1].Clear;
for i:=0 to 511 do Chart1.Series[0].AddXY(i-255,differences[i]);

Image1.AutoSize:=False;
Image1.Stretch:=True;
If ratio<4/3 then begin
Image1.width:=300;
Image1.height:=Round(300/ratio);
end
else begin

89
Image1.height:=200;
Image1.width:=Round(ratio*200);
end;
Image1.Visible:=True;
GroupBox3.Visible:=True;
GroupBox4.Visible:=True;
GroupBox5.Visible:=True;
RadioButton30.Checked:=True;
RadioButton30Click(Self);
end;

//загружаем превью изображения


If Combobox1.ItemIndex=1 then begin
Image5.AutoSize:=True;
If RadioButton1.Checked then begin
//If RadioButton3.Checked then Image1.Picture.LoadFromFile();
If RadioButton4.Checked then Image5.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\BW Picture.bmp');
If RadioButton5.Checked then Image5.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Color Picture.bmp');
If RadioButton7.Checked then Image5.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Color Stripes.bmp');
If RadioButton6.Checked then Image5.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Checkers.bmp');
If RadioButton13.Checked then Image5.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Checkers-small.bmp');
If RadioButton8.Checked then Image5.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\High-contrast Letters.bmp');
If RadioButton9.Checked then Image5.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Low-contrast Letters.bmp');
end
else begin
try
Image5.Picture.LoadFromFile(Edit1.Text);
except
Application.MessageBox('Ошибка при загрузке изображения','Ошибка',mb_ok or MB_ICONERROR);
end;
end;
Image1.Visible:=False;
RadioButton10.Checked:=True;
width:=Image1.Width;
height:=Image1.Height;
ratio:=width/height;
If (width>1599) or (height>1599) then begin
Application.MessageBox('Максимальный размер изображения для обработки - 1600х1600!','Ошибка',mb_ok or MB_ICONERROR);
exit;
end;
Image5.AutoSize:=False;
Image5.Stretch:=True;
If ratio<4/3 then begin
Image5.width:=364;
Image5.height:=Round(364/ratio);
end
else begin
Image5.height:=273;
Image5.width:=Round(ratio*273);
end;

90
Image5.Visible:=True;
GroupBox9.Visible:=True;
GroupBox10.Visible:=True;
GroupBox5.Visible:=True;
RadioButton26Click(Self);
end;
end;

//настройки превью - линия минимальной значимости


procedure TForm1.RadioButton11Click(Sender: TObject);
begin
If Radiobutton11.Checked then SpinEdit1.Enabled:=True
else SpinEdit1.Enabled:=False;
Spinedit1Change(Self);
end;

//настройки превью - показ всего пространства разностных отсчетов


procedure TForm1.RadioButton10Click(Sender: TObject);
var
i:Integer;
begin
If Radiobutton11.Checked then SpinEdit1.Enabled:=True
else SpinEdit1.Enabled:=False;
Chart1.Series[0].Clear;
for i:=0 to 511 do Chart1.Series[0].AddXY(i-255,differences[i]);
Label3.Caption:='Сейчас на графике отображены 100% разностных отсчетов.';
end;

//настройки превью - линия минимальной значимости


procedure TForm1.SpinEdit1Change(Sender: TObject);
var
i:Integer;
first,last:Integer;
cursum:LongInt;
begin
try
Chart1.Series[0].Clear;
last:=-1;
first:=512;
For i:=0 to 511 do If differences[i]>SpinEdit1.Value then last:=i;
For i:=511 downto 0 do If differences[i]>SpinEdit1.Value then first:=i;
If last>=0 then begin
cursum:=0;
If last=511 then last:=510;
for i:=first to last+1 do If differences[i]>SpinEdit1.Value then begin
Chart1.Series[0].AddXY(i-255,differences[i]);
cursum:=cursum+differences[i];
end
else Chart1.Series[0].AddXY(i-255,0);
Label3.Caption:='Сейчас на графике отображены '+IntToStr(Trunc(cursum/diffsum*100))+'% разностных отсчетов.';

91
end
else begin
Label3.Caption:='В выбранном изображении ни один разностный отсчет не'+#10+#13+'появляется заданное число раз.';
end;
except
end;
end;

//настройки превью - линия минимальной значимости


procedure TForm1.SpinEdit2Change(Sender: TObject);
var
max:Integer;
i,j:Integer;
cursum:LongInt;
begin
try
max:=0;
j:=Trunc(Power(2,SpinEdit2.Value)/2);
For i:=0 to 511 do If differences[i]>max then max:=differences[i];
Chart1.Series[1].Clear;
Chart1.Series[1].AddXY(j,max);
Chart1.Series[1].AddXY(j+1,0);
Chart1.Series[1].AddXY(-1*j-1,0);
Chart1.Series[1].AddXY(-1*j,max);
If Spinedit2.Value<9 then begin
cursum:=0;
for i:=255-j to 255+j do cursum:=cursum+differences[i];
Label6.Caption:=IntToStr(Trunc(cursum/diffsum*100))+'% разностных отсчетов';
end
else Label6.Caption:='100% разностных отсчетов';
except
end;
end;

//дикм - оценка нужного числа уровней квантования


procedure TForm1.RadioButton12Click(Sender: TObject);
begin
RadioButton10Click(Self);
SpinEdit2Change(Self);
end;

//Канал передачи - без шума


procedure TForm1.RadioButton14Click(Sender: TObject);
begin
If RadioButton14.Checked then begin
SpinEdit3.Enabled:=False;
SpinEdit4.Enabled:=False;
SpinEdit5.Enabled:=False;
Chart2.Series[0].Clear;
end;

92
end;

//равномерный шум
procedure TForm1.RadioButton15Click(Sender: TObject);
begin
If RadioButton15.Checked then begin
SpinEdit3.Enabled:=True;
SpinEdit4.Enabled:=True;
SpinEdit5.Enabled:=True;
SpinEdit4Change(Self);
end;
end;

//гауссовский шум
procedure TForm1.RadioButton16Click(Sender: TObject);
begin
If RadioButton16.Checked then begin
SpinEdit3.Enabled:=True;
SpinEdit4.Enabled:=True;
SpinEdit5.Enabled:=True;
SpinEdit4Change(Self);
end;
end;

procedure TForm1.FormCreate(Sender: TObject);


begin
randomize;
//инициализируем генератор случайных чисел - он нужен для шума
end;

// генерим пример распределения шума


procedure TForm1.SpinEdit4Change(Sender: TObject);
var
randres:array [-255..255] of Integer;
i:Integer;
temp:Integer;
rand:Integer;
begin
If Chart2.AnimatedZoom then
try
Chart2.Series[0].Clear;
for i:=-255 to 255 do randres[i]:=0;
If RadioButton15.Checked then begin
temp:=SpinEdit4.Value-Trunc(SpinEdit5.Value/2);
//равномерный
for i:=0 to 1000000 do begin
rand:=temp+Random(SpinEdit5.Value);
if (rand>=-255) and (rand<=255) then randres[rand]:=randres[rand]+1;
end;
end;

93
If RadioButton16.Checked then begin
temp:=Round(SpinEdit4.Value-SpinEdit5.Value/2);
//гауссовский
for i:=0 to 100000 do begin
rand:=temp+Round((Random(SpinEdit5.Value)+Random(Spinedit5.Value)+Random(Spinedit5.Value))/3);
if (rand>=-255) and (rand<=255) then randres[rand]:=randres[rand]+1;
end;
end;
for i:=-254 to 254 do Chart2.Series[0].AddXY(i,Round((randres[i-1]+randres[i]+randres[i+1])/3));
except
end;
end;

procedure TForm1.SpinEdit5Change(Sender: TObject);


begin
SpinEdit4Change(Self);
end;

procedure TForm1.Label12Click(Sender: TObject);


begin
RadioButton20.Checked:=True;
end;

//отключаем подменю: выбрано кодирование ДИКМ с отсечкой


procedure TForm1.RadioButton17Click(Sender: TObject);
begin
If RadioButton17.Checked then begin
SpinEdit6.Enabled:=True;
RadioButton19.Enabled:=False;
RadioButton20.Enabled:=False;
label12.enabled:=False;
SpinEdit7.Enabled:=False;
SpinEdit8.Enabled:=False;
SpinEdit10.Enabled:=False;
RadioButton31.Enabled:=False;
RadioButton32.Enabled:=False;
SpinEdit11.Enabled:=False;
RadioButton33.Enabled:=False;
SpinEdit12.Enabled:=False;
Spinedit6Change(Self);
end;
end;

//ДИКМ - адаптивный метод, включаем-отключаем подменю в зависимости от выбранного подметода.


procedure TForm1.RadioButton18Click(Sender: TObject);
begin
If RadioButton18.Checked then begin
SpinEdit6.Enabled:=False;
RadioButton19.Enabled:=True;
RadioButton20.Enabled:=True;

94
SpinEdit10.Enabled:=False;
RadioButton31.Enabled:=False;
RadioButton32.Enabled:=False;
SpinEdit11.Enabled:=False;
RadioButton33.Enabled:=True;
If RadioButton19.Checked then begin
SpinEdit7.Enabled:=True;
SpinEdit7Change(Self);
end;
If RadioButton20.Checked then begin
label12.enabled:=True;
SpinEdit8.Enabled:=True;
SpinEdit8Change(Self);
end;
If RadioButton33.Checked then begin
SpinEdit12.Enabled:=True;
SpinEdit12Change(Self);
end;
end;
end;

//ДИКМ - метод с отсечкой, меняем число бит на разностный отсчет


procedure TForm1.SpinEdit6Change(Sender: TObject);
var
i,j:Integer;
cursum:Longint;
begin
Radiobutton12.Checked:=True;
SpinEdit2.Value:=0;
SpinEdit2.Value:=SpinEdit6.Value;
If Spinedit2.Value<9 then begin
cursum:=0;
j:=Trunc(Power(2,SpinEdit2.Value)/2);
for i:=255-j to 255+j do cursum:=cursum+differences[i];
Label13.Caption:='Линейный квантователь отсечет наиболее резкие изменения цветов.'+#10+#13+'Точно будет передано '+IntToStr(Trunc(cursum/diffsum*100))+'% разностных отсчетов';
end
else Label13.Caption:='Линейный квантователь не отсечет наиболее резкие изменения цветов.'+#10+#13+'Разностные отсчеты передадутся точно, но информации будет передано больше, чем без
ДИКМ.';
end;

//ДИКМ - критерий значимости, меняем пороговое значение


procedure TForm1.SpinEdit8Change(Sender: TObject);
var
i:Integer;
tmp:Real;
resultn:integer;
cursum:LongInt;
begin
try
Chart1.Series[1].Clear;

95
Chart1.Series[1].AddXY(-255,SpinEdit8.Value);
Chart1.Series[1].AddXy(255,SpinEdit8.Value);

needed:=0;
cursum:=0;
for i:=0 to 511 do begin
If differences[i]>=SpinEdit8.Value then begin
needed:=needed+1;
cursum:=cursum+differences[i];
end;
end;
tmp:=ln(needed)/ln(2);
If Trunc(tmp)<>tmp then resultn:=Trunc(tmp)+1
else resultn:=Trunc(tmp);
Label13.Caption:='Для кодирования изображения с заданным критерием значимости нужно представлять '+IntToStr(needed)+' различных значений '+#10+#13+'разностных отсчетов, для чего нужно
'+IntToStr(resultn)+' бит на каждый отсчет. Точно будут переданы '+IntToStr(Trunc(cursum/diffsum*100))+'% разностных отсчетов.';
except
end;
end;

//ДИКМ - адаптивный метод максимумов. Отключаем элементы других подменю


procedure TForm1.RadioButton19Click(Sender: TObject);
begin
If (RadioButton19.Checked) and (RadioButton18.Checked) then begin
SpinEdit7.Enabled:=True;
SpinEdit8.Enabled:=False;
SpinEdit12.Enabled:=False;
end;
end;

//ДИКМ - критерий значимости. Отключаем элементы других подменю


procedure TForm1.RadioButton20Click(Sender: TObject);
begin
If (RadioButton20.Checked) and (RadioButton18.Checked) then begin
SpinEdit7.Enabled:=False;
SpinEdit8.Enabled:=True;
SpinEdit12.Enabled:=False;
Label12.Enabled:=True;
SpinEdit8Change(Self);
end;
end;

//ДИКМ - адаптивный метод максимумов. Изменяем число бит на отсчет


procedure TForm1.SpinEdit7Change(Sender: TObject);
var
tmparr:array[0..511] of integer;
tmp,i:Integer;
cursum:LongInt;
begin
For tmp:=0 to 511 do tmparr[tmp]:=differences[tmp];

96
QuickSort(tmparr,Low(differences),High(differences));
tmp:=trunc(512-Power(2,SpinEdit7.Value));
threshold:=tmparr[tmp];
Label13.Caption:='Критерий значимости для заданной длины разностного отсчета:'+#10+#13+'Разностный отсчет должен встречаться не менее '+IntToStr(threshold)+' раз.';
Chart1.Series[1].Clear;
Chart1.Series[1].AddXY(-255,threshold+1);
Chart1.Series[1].AddXy(255,threshold+1);
cursum:=0;
For i:=tmp to 511 do cursum:=cursum+tmparr[i];
Label13.Caption:=Label13.Caption+' Будут точно переданы '+IntToStr(Trunc(cursum/diffsum*100))+'% разностных отсчетов.';
end;

// Реализация алгоритма ДИКМ


procedure TForm1.Button3Click(Sender: TObject);
var
i,j,k:Integer;
tmp:integer;
tmpr:Real;
currclr:TColor;
r,g,b: integer;//Byte;
pr,pg,pb:integer;//Byte;
diff:Integer;
Bitmap:TBitmap;
tmpstr:String;
begin
Bitmap:=Tbitmap.Create;
//difftable - массив, устанавливающий связь между номером уровня квантования (номером элемента в массиве) и размером кодируемого изменения
//При этом исходим из предположения, что используется линейный интерполятор нулевого порядка, то есть кодируется практически разность между текущим цветовым отсчетом и предыдущим
//для квантователя с отсечкой ничего сложного не нужно, поэтому прописываются просто фиксированные значения в том количестве, что задано доступным числом бит
//Для адаптивного квантователя по критерию значимости нужно needed элементов. Значения их узнаем из элементов differences, отвечающих требуемому критерию значимости
//Для адаптивного квантователя по критерию доступного числа бит на разностный отсчет количество элементов задается пользователем, а хранящиеся в них разности считываются аналитически.

//Чистим массивы
for i:=0 to 512 do difftable[i]:=4096;
For i:=0 to 1600 do
For j:=0 to 1600 do begin
Reds[i,j]:=0;
Greens[i,j]:=0;
Blues[i,j]:=0;
end;
//Линейный квантователь, равномерное заполнение
If (radiobutton30.Checked) and (radiobutton31.checked) then begin
tmp:=Trunc(Power(2,SpinEdit10.Value));
diff_used:=tmp;
j:=Round(255/(Power(2,SpinEdit10.Value)/2+1));
For i:=0 to Round(Power(2,SpinEdit10.Value)/2)-1 do begin
difftable[i]:=(i+1)*j;
difftable[tmp-1-i]:=-(i+1)*j;
end;
end;

97
//линейный квантователь, заполнение с заданным интервалом
If (radiobutton30.Checked) and (radiobutton32.checked) then begin
tmp:=Trunc(Power(2,SpinEdit10.Value));
diff_used:=tmp;
For i:=0 to Round(Power(2,SpinEdit10.Value)/2)-1 do begin
difftable[i]:=(i+1)*SpinEdit11.Value;
difftable[tmp-1-i]:=-(i+1)*SpinEdit11.Value;
end;

end;
//квантователь с отсечкой
If radiobutton17.Checked then begin
tmp:=Trunc(Power(2,SpinEdit6.Value));
diff_used:=tmp;
for i:=0 to diff_used-1 do difftable[i]:=i-trunc(tmp/2);
end;
//метод максимумов - ищем наиболее часто встречающиеся значения разностных отсчетов
If (radiobutton19.Checked) and (radiobutton18.checked) then begin
tmp:=Trunc(Power(2,SpinEdit7.Value));
diff_used:=tmp;
tmp:=0;
for i:=0 to 511 do if differences[i]>=threshold then begin
difftable[tmp]:=i-255;
tmp:=tmp+1;
end;
end;
//отбор по критерию значимости
If (radiobutton20.Checked) and (radiobutton18.checked) then begin
diff_used:=needed;
tmp:=0;
for i:=0 to 511 do if differences[i]>=SpinEdit8.Value then begin
difftable[tmp]:=i-255;
tmp:=tmp+1;
end;
end;
//равномерное заполнение околунулевого максимума
If (radiobutton18.Checked) and (radiobutton33.checked) then begin
//Ищем границы околонулевого максимума j=max k=min
i:=255;
Repeat
j:=i;
i:=i+1;
Until (differences[i]<100) or (i=511);
i:=254;
Repeat
k:=i;
i:=i-1;
Until (differences[i]<100) or (i=0);
//не слишком ли много у нас бит для кодирования всех значений разностей в нем? Если слишком много, нам столько не нужно
If (j-k)<=Power(2,SpinEdit12.Value) then begin

98
tmpr:=ln(j-k)/ln(2);
If Trunc(tmpr)<>tmpr then tmp:=Trunc(tmpr)+1
else tmp:=Trunc(tmpr);
diff_used:=Trunc(Power(2,tmp));
needed:=tmp;
For i:=k to j do begin
difftable[i-k]:=i-255;
end;
end
else begin
tmp:=Round((j-k)/(Power(2,SpinEdit12.Value)/2+1));
diff:=Round((j-255)-(j-k)/2);
diff_used:=Round(Power(2,SpinEdit12.Value));
needed:=SpinEdit12.Value;
For i:=0 to Round(Power(2,SpinEdit12.Value)/2)-1 do begin
difftable[i]:=diff+(i+1)*tmp;
difftable[diff_used-1-i]:=diff-(i+1)*tmp;
end;
end;
end;

//BP1. Здесь стоит посмотреть на содержимое difftable и diff_used.


//Копируем кодируемое изображение в чистое изображение на второй вкладке...
Image1.Picture.SaveToFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Image2.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Image2.AutoSize:=True;
//Собираем статистику потока данных
Label20.Caption:=IntToStr(Trunc((8*Image2.Width*Image2.Height)/2730.6666))+' кбайт';
Label21.Caption:=IntToStr(Trunc((8*Image2.Width*Image2.Height)/90.6666))+' кбайт';
//Размер потока данных для различных способов квантования зависит очевидным образом от количества выделяемых на кодирование одного отсчета бит
If RadioButton17.Checked then begin
Label22.Caption:=IntToStr(Trunc((SpinEdit6.Value*Image2.Width*Image2.Height)/2730.6666))+' кбайт';
Label23.Caption:=IntToStr(Trunc((SpinEdit6.Value*Image2.Width*Image2.Height)/90.6666))+' кбайт';
end;
If radiobutton30.Checked then begin
Label22.Caption:=IntToStr(Trunc((SpinEdit10.Value*Image2.Width*Image2.Height)/2730.6666))+' кбайт';
Label23.Caption:=IntToStr(Trunc((SpinEdit10.Value*Image2.Width*Image2.Height)/90.6666))+' кбайт';
end;

If (radiobutton19.Checked) and (radiobutton18.checked) then begin


Label22.Caption:=IntToStr(Trunc((SpinEdit7.Value*Image2.Width*Image2.Height)/2730.6666))+' кбайт';
Label23.Caption:=IntToStr(Trunc((SpinEdit7.Value*Image2.Width*Image2.Height)/90.6666))+' кбайт';
end;
If (radiobutton20.Checked) and (radiobutton18.checked) then begin
Label22.Caption:=IntToStr(Trunc((needed*Image2.Width*Image2.Height)/2730.6666))+' кбайт';
Label23.Caption:=IntToStr(Trunc((needed*Image2.Width*Image2.Height)/90.6666))+' кбайт';
end;
If (Radiobutton33.Checked) and (radiobutton18.Checked) then begin
Label22.Caption:=IntToStr(Trunc((needed*Image2.Width*Image2.Height)/2730.6666))+' кбайт';

99
Label23.Caption:=IntToStr(Trunc((needed*Image2.Width*Image2.Height)/90.6666))+' кбайт';
end;
//Кодируем
For i:=0 to Image2.Height-1 do begin
//опорный пиксель - для первого пикселя строки передаем значение, а не разностный отсчет
currclr:=Image2.Picture.Bitmap.Canvas.Pixels[0,i];
pr := currclr and $FF;
pg := (currclr shr 8) and $FF;
pb := (currclr shr 16) and $FF;
Reds[i,0]:=pr;
Greens[i,0]:=pg;
Blues[i,0]:=pb;
For j:=1 to Image2.Width-1 do begin
currclr:=Image2.Picture.Bitmap.Canvas.Pixels[j,i];
//раскладываем на цветовые компоненты. Цветовой отсчет - три слепленных байта, BGR. Берем соответствующие сдвиги.
r := currclr and $FF;
g := (currclr shr 8) and $FF;
b := (currclr shr 16) and $FF;
//BP2. Здесь стоит посмотреть на r, g и b, а также проследить ход преобразования в следующих строках.
//находим значения разностного отсчета и ближайший к ним уровень квантования для каждого из цветов
diff:=r-pr;
Reds[i,j]:=FindClosestDiff(diff);
pr:=pr+DiffTable[Reds[i,j]];
diff:=b-pb;
Blues[i,j]:=FindClosestDiff(diff);
pb:=pb+DiffTable[Blues[i,j]];
diff:=g-pg;
Greens[i,j]:=FindClosestDiff(diff);
pg:=pg+DiffTable[Greens[i,j]];
end;
end;
//вносим шумы
If RadioButton14.Checked=False then begin
For k:=1 to Trunc(width*height/SpinEdit3.Value) do begin
i:=random(Height);
j:=random(width);
tmp:=random(3);
//случайно определяем, матрицу кодовых отсчетов какого цвета зашумлять
//BP3. Здесь можно отследить процесс зашумления.
If tmp=0 then begin
//генерим шумовое искажение
If RadioButton15.Checked then tmp:=SpinEdit4.Value-Trunc(SpinEdit5.Value/2)+Random(SpinEdit5.Value)
else tmp:=Round(SpinEdit4.Value-SpinEdit5.Value/2)+Round((Random(SpinEdit5.Value)+Random(Spinedit5.Value)
+Random(Spinedit5.Value))/3);
Reds[i,j]:=Reds[i,j]+tmp;
If Reds[i,j]<0 then Reds[i,j]:=0;
If Reds[i,j]>diff_used-1 then Reds[i,j]:=diff_used-1;
end;
If tmp=1 then begin
//генерим шумовое искажение

100
If RadioButton15.Checked then tmp:=SpinEdit4.Value-Trunc(SpinEdit5.Value/2)+Random(SpinEdit5.Value)
else tmp:=Round(SpinEdit4.Value-SpinEdit5.Value/2)+Round((Random(SpinEdit5.Value)+Random(Spinedit5.Value)
+Random(Spinedit5.Value))/3);
Greens[i,j]:=Greens[i,j]+tmp;
If Greens[i,j]<0 then Greens[i,j]:=0;
If Greens[i,j]>diff_used-1 then Greens[i,j]:=diff_used-1;
end;
If tmp=2 then begin
//генерим шумовое искажение
If RadioButton15.Checked then tmp:=SpinEdit4.Value-Trunc(SpinEdit5.Value/2)+Random(SpinEdit5.Value)
else tmp:=Round(SpinEdit4.Value-SpinEdit5.Value/2)+Round((Random(SpinEdit5.Value)+Random(Spinedit5.Value)
+Random(Spinedit5.Value))/3);
Blues[i,j]:=Blues[i,j]+tmp;
If Blues[i,j]<0 then Blues[i,j]:=0;
If Blues[i,j]>diff_used-1 then Blues[i,j]:=diff_used-1;
end;
end;

end;
//декодируем
Bitmap.Width:=Image2.width;
Bitmap.Height:=Image2.Height;
For i:=0 to Bitmap.Height-1 do begin
//первый пиксель из значений
currclr:=Reds[i,0]+Greens[i,0]*256+Blues[i,0]*256*256;
{Image3.Picture.}Bitmap.Canvas.Pixels[0,i]:=currclr;
pr := Reds[i,0];
pg := Greens[i,0];
pb := Blues[i,0];
//преобразование, обратное кодированию (очевидно)
For j:=1 to Bitmap.Width-1 do begin
r:=pr+DiffTable[Reds[i,j]];
g:=pg+DiffTable[Greens[i,j]];
b:=pb+DiffTable[Blues[i,j]];
//BP4. Глядя на используемые в цикле переменные, можно отследить процесс декодирования.
//ограничения по уровню. В железе это работает так, а в имитации иначе перелив/недолив и выбитые пикселы
If r<0 then r:=0;
If r>255 then r:=255;
If g<0 then g:=0;
If g>255 then g:=255;
If b<0 then b:=0;
If b>255 then b:=255;
currclr:=r+256*g+256*256*b;
Bitmap.Canvas.Pixels[j,i]:=currclr;
pr:=r;
pb:=b;
pg:=g;
end;
end;
//выводим результат

101
tmpstr:=ExtractFileDir(Application.ExeName)+'\Pictures\Result_ДИКМ_';
If (radiobutton30.Checked) and (radiobutton31.checked) then begin
tmpstr:=tmpstr+'Лин_Кван-ль_Равномер_Заполн_Б'+IntToStr(SpinEdit10.Value);
end;
If (radiobutton30.Checked) and (radiobutton32.checked) then begin
tmpstr:=tmpstr+'Лин_Кван-ль_Зап_с_зад_интервалом_Б'+IntToStr(SpinEdit10.Value)+'_И'+IntToStr(SpinEdit11.Value);
end;
If radiobutton17.Checked then begin
tmpstr:=tmpstr+'Кван-ль_с_отсечкой_Б'+IntToStr(SpinEdit6.Value);
end;
If (radiobutton19.Checked) and (radiobutton18.checked) then begin
tmpstr:=tmpstr+'Адапт_Кван-ль_Максимумы_Б'+IntToStr(SpinEdit7.Value);
end;
If (radiobutton20.Checked) and (radiobutton18.checked) then begin
tmpstr:=tmpstr+'Адапт_Кван-ль_Значмость_П'+IntToStr(SpinEdit8.Value);
end;
If (radiobutton18.Checked) and (radiobutton33.checked) then begin
tmpstr:=tmpstr+'Адапт_Кван-ль_Околонул_Макс_Б'+IntToStr(SpinEdit12.Value);
end;
tmpstr:=tmpstr+'.bmp';

Bitmap.SaveToFile(tmpstr);
Image3.Picture.LoadFromFile(tmpstr);
Image2.AutoSize:=True;
Image3.AutoSize:=True;
RadioButton21.Checked:=True;
RadioButton21Click(Self);
//формируем разностное изображение
//BP9a. Здесь можно отследить формирование разностного изображения.
tmp:=0;
diff:=0;
For i:=0 to Image2.Height-1 do
For j:=0 to Image2.Width-1 do begin
Bitmap.Canvas.Pixels[j,i]:=Image2.Picture.Bitmap.Canvas.Pixels[j,i]-Image3.Picture.Bitmap.Canvas.Pixels[j,i]+16777215;
currclr:=Abs(Image2.Picture.Bitmap.Canvas.Pixels[j,i]-Image3.Picture.Bitmap.Canvas.Pixels[j,i]);
if (currclr<>0) and (((currclr and $FF)>5) or (((currclr shr 8) and $FF)>5) or (((currclr shr 16) and $FF)>5)) then begin
tmp:=tmp+1;
diff :=diff + (currclr and $FF) + ((currclr shr 8) and $FF) + ((currclr shr 16) and $FF);
end;
end;
//выводим его
Bitmap.SaveToFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Image4.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Label25.Caption:=IntToStr(Round(tmp/(Image2.Width*Image2.Height)*100))+'%';
Label27.Caption:=IntToStr((Round(diff/(Image2.Width*Image2.Height*765)*100)))+'%';
Bitmap.Destroy;
//задаем доступные виды статистики
Combobox2.Items.Clear;
Combobox2.Items.Add('Распределение значений цветовых отсчетов');
Combobox2.Items.Add('Распределение разностей цветовых отсчетов');

102
Combobox2.Items.Add('Отклонение от среднего значения');
Chart3.Series[0].Clear;
Application.MessageBox('Кодирование и декодирование завершено.','Сообщение',mb_ok);
PageSourceControl1.ActivePageIndex:=1;
end;

//Вкладка Изображения. Показываем исходное изображение


procedure TForm1.RadioButton21Click(Sender: TObject);
begin
If RadioButton21.Checked then begin
Image2.Visible:=True;
Image3.Visible:=False;
Image4.Visible:=False;
end;
end;

//Вкладка Изображения. Показываем изображение после передачи


procedure TForm1.RadioButton22Click(Sender: TObject);
begin
If RadioButton22.Checked then begin
Image2.Visible:=False;
Image3.Visible:=True;
Image4.Visible:=False;
end;
end;

//Вкладка Изображения. Показываем разностное изображение


procedure TForm1.RadioButton23Click(Sender: TObject);
begin
If RadioButton23.Checked then begin
Image2.Visible:=False;
Image3.Visible:=False;
Image4.Visible:=True;
end;
end;

//Статистика для исходного изображения. Функционал блоков очевиден из условных операторов.


procedure TForm1.RadioButton24Click(Sender: TObject);
var
i,j:Integer;
arr:array[-255..255] of Integer;
currclr,prevclr:Integer;
size,r,g,b,minr,ming,minb,maxr,maxg,maxb:Integer;
current_fragment_horizontal, current_fragment_vertical:Integer;
current_element_horizontal, current_element_vertical:Integer;
width_steps, height_steps:Integer;
tmp:Real;
begin
For i:=-255 to 255 do arr[i]:=0;
Chart3.Series[0].Clear;

103
If ComboBox2.Text='Распределение значений цветовых отсчетов' then begin
Chart3.Title.Text.Clear;
Chart3.Title.Text.Add('Распределение значений цветовых отсчетов в исходном изображении');
For i:=0 to Image2.Height-1 do
For j:=0 to Image2.Width-1 do begin
currclr:=Image2.Picture.Bitmap.Canvas.Pixels[j,i];
arr[(currclr and $FF)]:=arr[(currclr and $FF)]+1;
arr[((currclr shr 8) and $FF)]:=arr[((currclr shr 8) and $FF)]+1;
arr[((currclr shr 16) and $FF)]:=arr[((currclr shr 16) and $FF)]+1;
end;
For i:=-255 to 255 do Chart3.Series[0].AddXY(i,Round(arr[i]/3));
end;
If ComboBox2.Text='Распределение разностей цветовых отсчетов' then begin
Chart3.Title.Text.Clear;
Chart3.Title.Text.Add('Распределение разностей значений цветовых отсчетов в исходном изображении');
For i:=0 to Image2.Height-1 do
For j:=1 to Image2.Width-1 do begin
currclr:=Image2.Picture.Bitmap.Canvas.Pixels[j,i];
prevclr:=Image2.Picture.Bitmap.Canvas.Pixels[j-1,i];
arr[(currclr and $FF)-(prevclr and $FF)]:=arr[(currclr and $FF)-(prevclr and $FF)]+1;
arr[((currclr shr 8) and $FF)-((prevclr shr 8) and $FF)]:=arr[((currclr shr 8) and $FF)-((prevclr shr 8) and $FF)]+1;
arr[((currclr shr 16) and $FF)-((prevclr shr 16) and $FF)]:=arr[((currclr shr 16) and $FF)-((prevclr shr 16) and $FF)]+1;
end;
For i:=-255 to 255 do Chart3.Series[0].AddXY(i,Round(arr[i]/3));
end;
If ComboBox2.Text='Отклонение от среднего значения' then begin
Chart3.Title.Text.Clear;
Chart3.Title.Text.Add('Отклонение значений цветовых отсчетов от среднего значения в исходном изображении');
prevclr:=0;
For i:=0 to Image2.Height-1 do
For j:=0 to Image2.Width-1 do begin
currclr:=Image2.Picture.Bitmap.Canvas.Pixels[j,i];
prevclr:=prevclr+(currclr and $FF) + ((currclr shr 8) and $FF) + ((currclr shr 16) and $FF);
end;
prevclr:=Round(prevclr/Image2.Height/Image2.Width/3);
For i:=0 to Image2.Height-1 do
For j:=0 to Image2.Width-1 do begin
currclr:=Image2.Picture.Bitmap.Canvas.Pixels[j,i];
arr[(currclr and $FF)-prevclr]:=arr[(currclr and $FF)-prevclr]+1;
arr[((currclr shr 8) and $FF)-prevclr]:=arr[((currclr shr 8) and $FF)-prevclr]+1;
arr[((currclr shr 16) and $FF)-prevclr]:=arr[((currclr shr 16) and $FF)-prevclr]+1;
end;
For i:=-255 to 255 do Chart3.Series[0].AddXY(i,Round(arr[i]/3));
end;
If ComboBox2.Text='Динамический диапазон в фрагментах кодирования' then begin
If RadioButton26.Checked then size:=4
else size:=8;
tmp:=Image2.Height/size;
If trunc(tmp)=tmp then height_steps:=trunc(tmp)
else height_steps:=trunc(tmp)+1;

104
tmp:=Image2.Width/size;
If trunc(tmp)=tmp then width_steps:=trunc(tmp)
else width_steps:=trunc(tmp)+1;
for i:=-255 to 255 do arr[i]:=0;
For current_fragment_vertical:=0 to height_steps-1 do
For current_fragment_horizontal:=0 to width_steps-1 do begin
minr:=255;
maxr:=0;
ming:=255;
maxg:=0;
minb:=255;
maxb:=0;
For current_element_vertical:=0 to size-1 do
For current_element_horizontal:=0 to size-1 do begin

r:=(Image2.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_horizontal,current_fragment_vertical*size+current_element_vertical] and $FF);


if r<minr then minr:=r;
if r>maxr then maxr:=r;

g:=((Image2.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_horizontal,current_fragment_vertical*size+current_element_vertical] shr 8) and $FF);


if g<ming then ming:=g;
if g>maxg then maxg:=g;

b:=((Image2.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_horizontal,current_fragment_vertical*size+current_element_vertical] shr 16) and $FF);


if b<minb then minb:=b;
if r>maxb then maxb:=b;
end;
arr[maxr-minr]:=arr[maxr-minr]+1;
arr[maxg-ming]:=arr[maxg-ming]+1;
arr[maxb-minb]:=arr[maxb-minb]+1;
end;
For i:=-254 to 255 do Chart3.Series[0].AddXY(i,Round(arr[i]/3));
end;
end;

//Статистика для изображения после преобразования. Функционал блоков очевиден из условных операторов.
procedure TForm1.RadioButton25Click(Sender: TObject);
var
i,j:Integer;
arr:array[-255..255] of Integer;
currclr,prevclr:Integer;
size,r,g,b,minr,ming,minb,maxr,maxg,maxb:Integer;
current_fragment_horizontal, current_fragment_vertical:Integer;
current_element_horizontal, current_element_vertical:Integer;
width_steps, height_steps:Integer;
tmp:Real;
begin
For i:=-255 to 255 do arr[i]:=0;
Chart3.Series[0].Clear;
If ComboBox2.Text='Распределение значений цветовых отсчетов' then begin

105
Chart3.Title.Text.Clear;
Chart3.Title.Text.Add('Распределение значений цветовых отсчетов в изображении после преобразования');
For i:=0 to Image3.Height-1 do
For j:=0 to Image3.Width-1 do begin
currclr:=Image3.Picture.Bitmap.Canvas.Pixels[j,i];
arr[(currclr and $FF)]:=arr[(currclr and $FF)]+1;
arr[((currclr shr 8) and $FF)]:=arr[((currclr shr 8) and $FF)]+1;
arr[((currclr shr 16) and $FF)]:=arr[((currclr shr 16) and $FF)]+1;
end;
For i:=-255 to 255 do Chart3.Series[0].AddXY(i,Round(arr[i]/3));
end;
If ComboBox2.Text='Распределение разностей цветовых отсчетов' then begin
Chart3.Title.Text.Clear;
Chart3.Title.Text.Add('Распределение разностей значений цветовых отсчетов в изображении после преобразования');
For i:=0 to Image3.Height-1 do
For j:=1 to Image3.Width-1 do begin
currclr:=Image3.Picture.Bitmap.Canvas.Pixels[j,i];
prevclr:=Image3.Picture.Bitmap.Canvas.Pixels[j-1,i];
arr[(currclr and $FF)-(prevclr and $FF)]:=arr[(currclr and $FF)-(prevclr and $FF)]+1;
arr[((currclr shr 8) and $FF)-((prevclr shr 8) and $FF)]:=arr[((currclr shr 8) and $FF)-((prevclr shr 8) and $FF)]+1;
arr[((currclr shr 16) and $FF)-((prevclr shr 16) and $FF)]:=arr[((currclr shr 16) and $FF)-((prevclr shr 16) and $FF)]+1;
end;
For i:=-255 to 255 do Chart3.Series[0].AddXY(i,Round(arr[i]/3));
end;
If ComboBox2.Text='Отклонение от среднего значения' then begin
Chart3.Title.Text.Clear;
Chart3.Title.Text.Add('Отклонение значений цветовых отсчетов от среднего значения в изображении после преобразования');
prevclr:=0;
For i:=0 to Image3.Height-1 do
For j:=0 to Image3.Width-1 do begin
currclr:=Image3.Picture.Bitmap.Canvas.Pixels[j,i];
prevclr:=prevclr+(currclr and $FF) + ((currclr shr 8) and $FF) + ((currclr shr 16) and $FF);
end;
prevclr:=Round(prevclr/Image3.Height/Image3.Width/3);
For i:=0 to Image3.Height-1 do
For j:=0 to Image3.Width-1 do begin
currclr:=Image3.Picture.Bitmap.Canvas.Pixels[j,i];
arr[(currclr and $FF)-prevclr]:=arr[(currclr and $FF)-prevclr]+1;
arr[((currclr shr 8) and $FF)-prevclr]:=arr[((currclr shr 8) and $FF)-prevclr]+1;
arr[((currclr shr 16) and $FF)-prevclr]:=arr[((currclr shr 16) and $FF)-prevclr]+1;
end;
For i:=-255 to 255 do Chart3.Series[0].AddXY(i,Round(arr[i]/3));
end;
If ComboBox2.Text='Динамический диапазон в фрагментах кодирования' then begin
If RadioButton26.Checked then size:=4
else size:=8;
tmp:=Image3.Height/size;
If trunc(tmp)=tmp then height_steps:=trunc(tmp)
else height_steps:=trunc(tmp)+1;
tmp:=Image3.Width/size;

106
If trunc(tmp)=tmp then width_steps:=trunc(tmp)
else width_steps:=trunc(tmp)+1;
for i:=-255 to 255 do arr[i]:=0;
For current_fragment_vertical:=0 to height_steps-1 do
For current_fragment_horizontal:=0 to width_steps-1 do begin
minr:=255;
maxr:=0;
ming:=255;
maxg:=0;
minb:=255;
maxb:=0;
For current_element_vertical:=0 to size-1 do
For current_element_horizontal:=0 to size-1 do begin

r:=(Image3.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_horizontal,current_fragment_vertical*size+current_element_vertical] and $FF);


if r<minr then minr:=r;
if r>maxr then maxr:=r;

g:=((Image3.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_horizontal,current_fragment_vertical*size+current_element_vertical] shr 8) and $FF);


if g<ming then ming:=g;
if g>maxg then maxg:=g;

b:=((Image3.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_horizontal,current_fragment_vertical*size+current_element_vertical] shr 16) and $FF);


if b<minb then minb:=b;
if r>maxb then maxb:=b;
end;
arr[maxr-minr]:=arr[maxr-minr]+1;
arr[maxg-ming]:=arr[maxg-ming]+1;
arr[maxb-minb]:=arr[maxb-minb]+1;
end;
For i:=-254 to 255 do Chart3.Series[0].AddXY(i,Round(arr[i]/3));
end;
end;

//При выборе типа статистического анализа показываем его для выбранного изображения
procedure TForm1.ComboBox2Change(Sender: TObject);
begin
If Radiobutton24.Checked then RadioButton24Click(Self);
If Radiobutton25.Checked then RadioButton25Click(Self);
end;

//Преобразование Адамара. Метод порогового отбора. Выключаем табличку-элемент управления в правом блоке
procedure TForm1.RadioButton29Click(Sender: TObject);
begin
DefaultDropped(0,false);
StringGrid1.Enabled:=False;
SpinEdit9.Enabled:=True;
StringGrid1.FixedCols:=7;
StringGrid1.FixedRows:=7;
end;

107
//Преобразование Адамара. Метод зонального отбора. Включаем табличку-элемент управления в правом блоке
procedure TForm1.RadioButton28Click(Sender: TObject);
begin
SpinEdit9.Enabled:=False;
StringGrid1.Enabled:=True;
If RadioButton26.Checked then RadioButton26Click(Self);
If RadioButton27.Checked then RadioButton27Click(Self);
end;

//Преобразование Адамара. Размер кодируемого фрагмента 4х4. Задаем некоторое значение зон отбора по умолчанию
procedure TForm1.RadioButton26Click(Sender: TObject);
begin
If RadioButton28.Checked then begin
StringGrid1.FixedCols:=4;
StringGrid1.FixedRows:=4;
StringGrid1.Enabled:=True;
DefaultDropped(4,true);
end;
end;

//Преобразование Адамара. Размер кодируемого фрагмента 8х8. Задаем некоторое значение зон отбора по умолчанию
procedure TForm1.RadioButton27Click(Sender: TObject);
begin
If RadioButton28.Checked then begin
StringGrid1.FixedCols:=0;
StringGrid1.FixedRows:=0;
StringGrid1.Enabled:=True;
DefaultDropped(8,false);
end;
end;

//перерисовываем табличку-элемент управления для преобразования Адамара


procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
if dropped[ACol,ARow]=1 then StringGrid1.Canvas.Brush.color := clBlack
else StringGrid1.canvas.brush.Color := clWhite;
StringGrid1.canvas.fillRect(Rect);
end;

//отрабатываем нажатия на нее. Вносим изменения в таблицу dropped


procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean);
begin
if dropped[Acol,Arow]=1 then dropped[Acol,Arow]:=0
else dropped[Acol,Arow]:=1;
end;

//Увеличиваем исходное изображение на второй вкладке по щелчку

108
procedure TForm1.Image2Click(Sender: TObject);
begin
Image2.Picture.SaveToFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Form2.Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
If Image2.width/Image2.height<4/3 then begin
Form2.Image1.width:=Screen.Width;
Form2.Image1.height:=Round(Screen.Width/(Image2.width/Image2.height));
end
else begin
Form2.Image1.height:=Screen.Height;
Form2.Image1.width:=Round((Image2.width/Image2.height)*Screen.Height);
end;
Form2.AutoSize:=True;
Form2.Show;
end;

//Увеличиваем изображение после преобразования на второй вкладке по щелчку


procedure TForm1.Image3Click(Sender: TObject);
begin
Image3.Picture.SaveToFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Form2.Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
If Image3.width/Image3.height<4/3 then begin
Form2.Image1.width:=Screen.Width;
Form2.Image1.height:=Round(Screen.Width/(Image3.width/Image3.height));
end
else begin
Form2.Image1.height:=Screen.Height;
Form2.Image1.width:=Round((Image3.width/Image3.height)*Screen.Height);
end;
Form2.AutoSize:=True;
Form2.Show;
end;

//Увеличиваем разностное изображение на второй вкладке по щелчку


procedure TForm1.Image4Click(Sender: TObject);
begin
Image4.Picture.SaveToFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Form2.Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
If Image4.width/Image4.height<4/3 then begin
Form2.Image1.width:=Screen.Width;
Form2.Image1.height:=Round(Screen.Width/(Image4.width/Image4.height));
end
else begin
Form2.Image1.height:=Screen.Height;
Form2.Image1.width:=Round((Image4.width/Image4.height)*Screen.Height);
end;
Form2.AutoSize:=True;
Form2.Show;
end;

109
//Перерисовка графика шума сильно нагружает процессор
//Поэтому включаем или выключаем эту функцию по тычку на график
procedure TForm1.Chart2Click(Sender: TObject);
begin
if Chart2.AnimatedZoom then begin
Chart2.AnimatedZoom:=False;
Chart2.Title.Text.Clear;
Chart2.Series[0].Clear;
Chart2.Title.Text.Add('Распределение шума (пример). Щелкните, чтобы включить график.');
end
else begin
Chart2.AnimatedZoom:=True;
Chart2.Title.Text.Clear;
Chart2.Title.Text.Add('Распределение шума (пример).');
SpinEdit4Change(Self);
end;
end;

procedure TForm1.Chart2ClickAxis(Sender: TCustomChart; Axis: TChartAxis;


Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
Chart2Click(self);
end;

procedure TForm1.Chart2ClickBackground(Sender: TCustomChart;


Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
Chart2Click(self);
end;

procedure TForm1.Chart2ClickLegend(Sender: TCustomChart;


Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
Chart2Click(self);
end;

procedure TForm1.Chart2ClickSeries(Sender: TCustomChart;


Series: TChartSeries; ValueIndex: Integer; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Chart2Click(self);
end;

procedure TForm1.Chart2Enter(Sender: TObject);


begin
Chart2Click(self);
end;

procedure TForm1.Chart2MouseDown(Sender: TObject; Button: TMouseButton;


Shift: TShiftState; X, Y: Integer);

110
begin
Chart2Click(self);
end;

//ДИКМ. Линейный режим квантования. Выключаем и включаем соответствующие подменю


procedure TForm1.RadioButton30Click(Sender: TObject);
begin
If RadioButton30.Checked then begin
SpinEdit10.Enabled:=True;
RadioButton31.Enabled:=True;
RadioButton32.Enabled:=True;
SpinEdit11.Enabled:=True;
SpinEdit6.Enabled:=False;
RadioButton19.Enabled:=False;
RadioButton20.Enabled:=False;
label12.enabled:=False;
SpinEdit7.Enabled:=False;
SpinEdit8.Enabled:=False;
RadioButton33.Enabled:=False;
SpinEdit12.Enabled:=False;
If RadioButton31.Checked then RadioButton31click(Self)
else SpinEdit11Change(Self);
end;
end;

//ДИКМ. Линейное квантование. Меняем число доступных для одного отсчета бит (число уровней квантования)
procedure TForm1.SpinEdit10Change(Sender: TObject);
var
max:Integer;
i,j:Integer;
begin
try
If Radiobutton31.Checked then begin
Chart1.Series[1].Clear;
max:=0;
For i:=0 to 511 do If differences[i]>max then max:=differences[i];
j:=Round(255/(Power(2,SpinEdit10.Value)/2+1));
For i:=1 to Round(Power(2,SpinEdit10.Value)/2) do begin
Chart1.Series[1].AddXY(i*j,0);
Chart1.Series[1].AddXY(i*j,max);
Chart1.Series[1].AddXY(i*j+1,0);
Chart1.Series[1].AddXY(-i*j,0);
Chart1.Series[1].AddXY(-i*j,max);
Chart1.Series[1].AddXY(-i*j+1,0);
end;
Label13.Caption:='Пространство разностных отсчетов от -255 до +255 будет равномерно заполнено '+IntToStr(Trunc(Power(2,SpinEdit10.Value)))+' уровнями квантования.'
end
else SpinEdit11Change(Self);
except
end;

111
end;

//ДИКМ. Линейное квантование с заданным интервалом. Изменяем интервал.


procedure TForm1.SpinEdit11Change(Sender: TObject);
var
max:Integer;
i:Integer;
begin
try
Chart1.Series[1].Clear;
max:=0;
For i:=0 to 511 do If differences[i]>max then max:=differences[i];
For i:=1 to Round(Power(2,SpinEdit10.Value)/2) do begin
Chart1.Series[1].AddXY(i*SpinEdit11.Value,0);
Chart1.Series[1].AddXY(i*SpinEdit11.Value,max);
Chart1.Series[1].AddXY(i*SpinEdit11.Value+1,0);
Chart1.Series[1].AddXY(-i*SpinEdit11.Value,0);
Chart1.Series[1].AddXY(-i*SpinEdit11.Value,max);
Chart1.Series[1].AddXY(-i*SpinEdit11.Value+1,0);
end;
Label13.Caption:='Пространство разностных отсчетов от '+IntToStr(Round(-1*Power(2,SpinEdit10.Value)/2*SpinEdit11.Value))+' до '+IntToStr(Round(Power(2,SpinEdit10.Value)/2*SpinEdit11.Value))+' будет
заполнено '+IntToStr(Trunc(Power(2,SpinEdit10.Value)))+' уровнями квантования с шагом '+IntToStr(SpinEdit11.Value)+'.';
except
end;
end;

//ДИКМ. Равномерное заполнение.


procedure TForm1.RadioButton31Click(Sender: TObject);
begin
SpinEdit10Change(Self);
end;

//ДИКМ. Заданный интервал.


procedure TForm1.RadioButton32Click(Sender: TObject);
begin
SpinEdit11Change(Self);
end;

//ДИКМ. Равномерное заполнение околонулевого максимума


procedure TForm1.RadioButton33Click(Sender: TObject);
begin
If (RadioButton33.Checked) and (RadioButton18.Checked) then begin
SpinEdit7.Enabled:=False;
SpinEdit8.Enabled:=False;
SpinEdit12.Enabled:=True;
SpinEdit12Change(Self);
end;
end;

//ДИКМ. Адаптивное квантование. Равномерное заполнение околонулевого максимума.

112
//изменяем число доступных бит (доступное число уровней квантования)
procedure TForm1.SpinEdit12Change(Sender: TObject);
var
i,j:Integer;
min,max:Integer;
tmp:Real;
resultn:Integer;
begin
Chart1.Series[1].Clear;
//находим верхнюю и нижнюю границу околонулевого максимума
i:=255;
Repeat
max:=i;
i:=i+1;
Until (differences[i]<100) or (i=511);
i:=254;
Repeat
min:=i;
i:=i-1;
Until (differences[i]<100) or (i=0);
//распределяем по нему уровни квантования, убедившись, что отведенное число бит не позволяет нам заполнить его с избытком
If (max-min)<=Power(2,SpinEdit12.Value) then begin
Chart1.Series[1].AddXY(min-255,0);
Chart1.Series[1].AddXy(max-255,0);
For i:=min to max do Chart1.Series[1].AddXY(i-255,differences[i]);
tmp:=ln(max-min)/ln(2);
If Trunc(tmp)<>tmp then resultn:=Trunc(tmp)+1
else resultn:=Trunc(tmp);
Label13.Caption:='Центральный максимум от '+IntToStr(min-255)+' до '+IntToStr(max-255)+' будет заполнен '+IntToStr(max-min)+' уровнями квантования с шагом 1.'+#10+#13+'Для этого
потребуется '+IntToStr(resultn)+' бит на отсчет.';
end
else begin
Chart1.Series[1].AddXY(min,0);
Chart1.Series[1].AddXy(max,0);
j:=Round((max-min)/(Power(2,SpinEdit12.Value)/2+1));
resultn:=Round((max-255)-(max-min)/2);
For i:=1 to Round(Power(2,SpinEdit10.Value)/2) do begin
Chart1.Series[1].AddXY(resultn+i*j,0);
Chart1.Series[1].AddXY(resultn+i*j,differences[resultn+i*j+255]);
Chart1.Series[1].AddXY(resultn+i*j+1,0);
Chart1.Series[1].AddXY(resultn-i*j,0);
Chart1.Series[1].AddXY(resultn-i*j,differences[resultn-i*j+255]);
Chart1.Series[1].AddXY(resultn-i*j+1,0);
end;
resultn:=Round(Power(2,SpinEdit12.Value));
Label13.Caption:='Центральный максимум от '+IntToStr(min-255)+' до '+IntToStr(max-255)+' будет заполнен '+IntToStr(resultn)+' уровнями квантования с шагом '+IntToStr(j)+'.'
end;
end;

//Преобразование Адамара...

113
procedure TForm1.Button4Click(Sender: TObject);
var
width_steps, height_steps, size:Integer;
tmp:real;
i,j,k:Integer;
tmpi,diff:Integer;
current_fragment_horizontal, current_fragment_vertical:Integer;
current_element_horizontal, current_element_vertical:Integer;
H:array [0..7,0..7] of Integer;
r,g,b:integer;
currclr:TColor;
Bitmap:TBitmap;
transmitted:Integer;
tmpstr:String;
begin
//Загружаем обрабатываемое изображение в чистое изображение на второй вкладке
Image5.Picture.SaveToFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Image2.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Image2.AutoSize:=True;
Bitmap:=TBitmap.Create;
Bitmap.Height:=Image2.Height;
Bitmap.Width:=Image2.Width;
For i:=0 to Bitmap.Height-1 do
For j:=0 to Bitmap.Width-1 do Bitmap.Canvas.Pixels[j,i]:=0;
// Определяем количество фрагментов 4х4 или 8х8 в изображении
If RadioButton26.Checked then size:=4
else size:=8;
tmp:=Image2.Height/size;
If trunc(tmp)=tmp then height_steps:=trunc(tmp)
else height_steps:=trunc(tmp)+1;
tmp:=Image2.Width/size;
If trunc(tmp)=tmp then width_steps:=trunc(tmp)
else width_steps:=trunc(tmp)+1;
//Загружаем базисные изображения преобразования адамара.
//AdamarImages - массив этих изображений. По адресу [x,y] в нем хранится матрица отсчетов, соответствующая базисному изображению phiXY.
//В ней, аналогично, хранятся коэффициенты 1 и -1.
For i:=0 to size-1 do
For j:=0 to size-1 do LoadAdamarBasisImage(size,i,j);

//Обнуляем матрицу трансформант


For i:=0 to 7 do
For j:=0 to 7 do H[i,j]:=0;

transmitted:=0;//счетчик переданных трансформант


//Кодируем
//Проходим изображение, забирая фрагменты заданного размера...
For current_fragment_vertical:=0 to height_steps-1 do
For current_fragment_horizontal:=0 to width_steps-1 do begin
//Проходим все элементы фрагмента, умножая их на базисные изображения
For current_element_vertical:=0 to size-1 do

114
For current_element_horizontal:=0 to size-1 do begin
{Стандартным образом преобразуем цветовой отсчет, чтобы получить из него коды базовых цветов.
Цветовой отсчет составлен из трех байтов-кодов цветов, в порядке BGR. Сдвигаем его значение на нужное число бит, а затем делаем бинарное И.
r := color and $FF;
g := (color shr 8) and $FF;
b := (color shr 16) and $FF; }
//BP5. Правильно ли считались цветовые отсчеты?
//кодируем красный
H[current_element_horizontal,current_element_vertical]:=0;
For i:=0 to size-1 do
For j:=0 to size-1 do begin
r:=(Image2.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+i,current_fragment_vertical*size+j] and $FF);
H[current_element_horizontal,current_element_vertical]:=H[current_element_horizontal,current_element_vertical]
+r*AdamarImages[current_element_horizontal,current_element_vertical].Values[i,j];
end;
//Нормируем трансформант
H[current_element_horizontal,current_element_vertical]:=Round(H[current_element_horizontal,current_element_vertical]/size/size);
//BP6. Правильный ли получился нормированный трансформант?
transmitted:=transmitted+1;
//Метод порогового отбора
If (RadioButton29.Checked) and (Abs(H[current_element_horizontal,current_element_vertical])<SpinEdit9.Value) then begin
H[current_element_horizontal,current_element_vertical]:=0;
transmitted:=transmitted-1;
end;
//метод позиционного отбора. Вот здесь приходится учитывать смещение, внесенное, чтобы матрица позиционного отбора красиво смотрелась в
графическом элементе управления
If (radiobutton28.Checked) and (dropped[8-size+current_element_horizontal,8-size+current_element_vertical]=0) then begin
H[current_element_horizontal,current_element_vertical]:=0;
transmitted:=transmitted-1;
end;

Reds[current_fragment_vertical*size+current_element_vertical,current_fragment_horizontal*size+current_element_horizontal]:=H[current_element_horizontal,current_element_vertical];
//кодируем зеленый
H[current_element_horizontal,current_element_vertical]:=0;
For i:=0 to size-1 do
For j:=0 to size-1 do begin
g:=((Image2.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+i,current_fragment_vertical*size+j] shr 8) and $FF);
H[current_element_horizontal,current_element_vertical]:=H[current_element_horizontal,current_element_vertical]
+g*AdamarImages[current_element_horizontal,current_element_vertical].Values[i,j];
end;
//Нормируем трансформант
H[current_element_horizontal,current_element_vertical]:=Round(H[current_element_horizontal,current_element_vertical]/size/size);
//После этой строки можно ставить отладку, чтобы удостовериться, что трансформанта H получает верное значение. Преобразование Адамара для 4х4
легко реализуется альтернативными методами.
transmitted:=transmitted+1;
//Метод порогового отбора
If (RadioButton29.Checked) and (Abs(H[current_element_horizontal,current_element_vertical])<SpinEdit9.Value) then begin
H[current_element_horizontal,current_element_vertical]:=0;
transmitted:=transmitted-1;
end;

115
//метод позиционного отбора. Вот здесь приходится учитывать смещение, внесенное, чтобы матрица позиционного отбора красиво смотрелась в
графическом элементе управления
If (radiobutton28.Checked) and (dropped[8-size+current_element_horizontal,8-size+current_element_vertical]=0) then begin
H[current_element_horizontal,current_element_vertical]:=0;
transmitted:=transmitted-1;
end;

Greens[current_fragment_vertical*size+current_element_vertical,current_fragment_horizontal*size+current_element_horizontal]:=H[current_element_horizontal,current_element_vertical];
//Кодируем синий
H[current_element_horizontal,current_element_vertical]:=0;
For i:=0 to size-1 do
For j:=0 to size-1 do begin
b:=((Image2.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+i,current_fragment_vertical*size+j] shr 16) and $FF);
H[current_element_horizontal,current_element_vertical]:=H[current_element_horizontal,current_element_vertical]
+b*AdamarImages[current_element_horizontal,current_element_vertical].Values[i,j];
end;
//Нормируем трансформант
H[current_element_horizontal,current_element_vertical]:=Round(H[current_element_horizontal,current_element_vertical]/size/size);
//После этой строки можно ставить отладку, чтобы удостовериться, что трансформанта H получает верное значение. Преобразование Адамара для 4х4
легко реализуется альтернативными методами.
transmitted:=transmitted+1;
//Метод порогового отбора
If (RadioButton29.Checked) and (Abs(H[current_element_horizontal,current_element_vertical])<SpinEdit9.Value) then begin
H[current_element_horizontal,current_element_vertical]:=0;
transmitted:=transmitted-1;
end;
//метод позиционного отбора. Вот здесь приходится учитывать смещение, внесенное, чтобы матрица позиционного отбора красиво смотрелась в
графическом элементе управления
If (radiobutton28.Checked) and (dropped[8-size+current_element_horizontal,8-size+current_element_vertical]=0) then begin
H[current_element_horizontal,current_element_vertical]:=0;
transmitted:=transmitted-1;
end;

Blues[current_fragment_vertical*size+current_element_vertical,current_fragment_horizontal*size+current_element_horizontal]:=H[current_element_horizontal,current_element_vertical];
end;
end;
//вносим шумы
If RadioButton14.Checked=False then begin
For k:=1 to Trunc(Image2.width*Image2.height/SpinEdit3.Value) do begin
i:=random(Image2.Height);
j:=random(Image2.width);
tmpi:=random(3);
//BP7. Отсюда можно шаг за шагом проследить процесс зашумления.
//Случайно определяем, какую именно матрицу зашумлять
If tmpi=0 then begin
//генерим шумовое искажение
If RadioButton15.Checked then tmpi:=SpinEdit4.Value-Trunc(SpinEdit5.Value/2)+Random(SpinEdit5.Value)
else tmpi:=Round(SpinEdit4.Value-SpinEdit5.Value/2)+Round((Random(SpinEdit5.Value)+Random(Spinedit5.Value)
+Random(Spinedit5.Value))/3);
Reds[i,j]:=Reds[i,j]+tmpi;

116
//устанавливаем пороговые значения, чтобы имитационная модель была похожа на реальную жизнь, а не радовала переливами и недоливами
If Reds[i,j]<-255 then Reds[i,j]:=-255;
If Reds[i,j]>255 then Reds[i,j]:=255;
end;
If tmpi=1 then begin
//генерим шумовое искажение
If RadioButton15.Checked then tmpi:=SpinEdit4.Value-Trunc(SpinEdit5.Value/2)+Random(SpinEdit5.Value)
else tmpi:=Round(SpinEdit4.Value-SpinEdit5.Value/2)+Round((Random(SpinEdit5.Value)+Random(Spinedit5.Value)
+Random(Spinedit5.Value))/3);
Greens[i,j]:=Greens[i,j]+tmpi;
//устанавливаем пороговые значения, чтобы имитационная модель была похожа на реальную жизнь, а не радовала переливами и недоливами
If Greens[i,j]<-255 then Greens[i,j]:=-255;
If Greens[i,j]>255 then Greens[i,j]:=255;
end;
If tmpi=2 then begin
//генерим шумовое искажение
If RadioButton15.Checked then tmpi:=SpinEdit4.Value-Trunc(SpinEdit5.Value/2)+Random(SpinEdit5.Value)
else tmpi:=Round(SpinEdit4.Value-SpinEdit5.Value/2)+Round((Random(SpinEdit5.Value)+Random(Spinedit5.Value)
+Random(Spinedit5.Value))/3);
Blues[i,j]:=Blues[i,j]+tmpi;
//устанавливаем пороговые значения, чтобы имитационная модель была похожа на реальную жизнь, а не радовала переливами и недоливами
If Blues[i,j]<-255 then Blues[i,j]:=-255;
If Blues[i,j]>255 then Blues[i,j]:=255;
end;
end;

end;

//декодируем
For current_fragment_vertical:=0 to height_steps-1 do
For current_fragment_horizontal:=0 to width_steps-1 do begin
For i:=0 to size-1 do
For j:=0 to size-1 do H[i,j]:=0;
//декодирование красного
For current_element_vertical:=0 to size-1 do
For current_element_horizontal:=0 to size-1 do begin
For i:=0 to size-1 do
For j:=0 to size-1 do begin
H[current_element_horizontal,current_element_vertical]:=H[current_element_horizontal,current_element_vertical]
+Reds[current_fragment_vertical*size+i,current_fragment_horizontal*size+j]*AdamarImages[i,j].Values[current_element_horizontal,current_element_vertical];
end;
r:=Round(H[current_element_horizontal,current_element_vertical]);
//BP8. Момент истины - правильно ли декодируются цветовые отсчеты?
//устанавливаем пороговые значения, чтобы имитационная модель была похожа на реальную жизнь, а не радовала переливами и недоливами
If r<0 then r:=0;
If r>255 then r:=255;
//выводим декодированный цвет в текущий пиксель

Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_vertical,current_fragment_vertical*size+current_element_horizontal]:=Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_verti
cal,current_fragment_vertical*size+current_element_horizontal]+r;

117
end;
For i:=0 to size-1 do
For j:=0 to size-1 do H[i,j]:=0;
For current_element_vertical:=0 to size-1 do
For current_element_horizontal:=0 to size-1 do begin
For i:=0 to size-1 do
For j:=0 to size-1 do begin
H[current_element_horizontal,current_element_vertical]:=H[current_element_horizontal,current_element_vertical]
+Greens[current_fragment_vertical*size+i,current_fragment_horizontal*size+j]*AdamarImages[i,j].Values[current_element_horizontal,current_element_vertical];
end;
g:=Round(H[current_element_horizontal,current_element_vertical]);
//устанавливаем пороговые значения, чтобы имитационная модель была похожа на реальную жизнь, а не радовала переливами и недоливами
If g<0 then g:=0;
If g>255 then g:=255;
//выводим декодированный цвет в текущий пиксель

Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_vertical,current_fragment_vertical*size+current_element_horizontal]:=Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_verti
cal,current_fragment_vertical*size+current_element_horizontal]+Round(g*256);
end;
For i:=0 to size-1 do
For j:=0 to size-1 do H[i,j]:=0;
For current_element_vertical:=0 to size-1 do
For current_element_horizontal:=0 to size-1 do begin
For i:=0 to size-1 do
For j:=0 to size-1 do begin
H[current_element_horizontal,current_element_vertical]:=H[current_element_horizontal,current_element_vertical]
+Blues[current_fragment_vertical*size+i,current_fragment_horizontal*size+j]*AdamarImages[i,j].Values[current_element_horizontal,current_element_vertical];
end;
b:=Round(H[current_element_horizontal,current_element_vertical]);
//устанавливаем пороговые значения, чтобы имитационная модель была похожа на реальную жизнь, а не радовала переливами и недоливами
If b<0 then b:=0;
If b>255 then b:=255;
//выводим декодированный цвет в текущий пиксель

Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_vertical,current_fragment_vertical*size+current_element_horizontal]:=Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_verti
cal,current_fragment_vertical*size+current_element_horizontal]+Round(b*256*256);
end;

end;
//Полученное изображение выводим на вторую вкладку
tmpstr:=ExtractFileDir(Application.ExeName)+'\Pictures\Result_Адамар_';
If (RadioButton29.Checked) then tmpstr:=tmpstr+'Порог'+IntToStr(SpinEdit9.Value);
If (radiobutton28.Checked) then begin
tmpstr:=tmpstr+'Позиц_'+IntToStr(size)+'x'+IntToStr(size);
diff:=0;
For i:=0 to size-1 do
For j:=0 to size-1 do
If dropped[8-size+i,8-size+j]=1 then diff:=diff+1;
tmpstr:=tmpstr+'_Передано_'+IntToStr(diff);

118
end;
tmpstr:=tmpstr+'.bmp';
Bitmap.SaveToFile(tmpstr);
Image3.Picture.LoadFromFile(tmpstr);
Image3.AutoSize:=True;
//Показываем статистику потока данных, для одного кадра и для 30 в секунду.
Label20.Caption:=IntToStr(Trunc((8*Image2.Width*Image2.Height)/2730.6666))+' кбайт';
Label21.Caption:=IntToStr(Trunc((8*Image2.Width*Image2.Height)/90.6666))+' кбайт';
Label22.Caption:=IntToStr(Trunc(transmitted/910.2222))+' кбайт';
Label23.Caption:=IntToStr(Trunc(transmitted/30.34))+' кбайт';
RadioButton22.Checked:=True;

//Генерим разностное изображение


//BP9b. Отсюда можно проследить создание разностного изображения.
tmpi:=0;
diff:=0;
For i:=0 to Image2.Height-1 do
For j:=0 to Image2.Width-1 do begin
Bitmap.Canvas.Pixels[j,i]:=Image2.Picture.Bitmap.Canvas.Pixels[j,i]-Image3.Picture.Bitmap.Canvas.Pixels[j,i]+16777215;
currclr:=Abs(Image2.Picture.Bitmap.Canvas.Pixels[j,i]-Image3.Picture.Bitmap.Canvas.Pixels[j,i]);
if (currclr<>0) and (((currclr and $FF)>5) or (((currclr shr 8) and $FF)>5) or (((currclr shr 16) and $FF)>5)) then begin
tmpi:=tmpi+1;
diff :=diff + (currclr and $FF) + ((currclr shr 8) and $FF) + ((currclr shr 16) and $FF);
end;
end;
///...и выводим его
Bitmap.SaveToFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Image4.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Label25.Caption:=IntToStr(Round(tmpi/(Image2.Width*Image2.Height)*100))+'%';
Label27.Caption:=IntToStr((Round(diff/(Image2.Width*Image2.Height*765)*100)))+'%';
Bitmap.Destroy;
//инициализируем меню статистики
Combobox2.Items.Clear;
Combobox2.Items.Add('Распределение значений цветовых отсчетов');
Combobox2.Items.Add('Распределение разностей цветовых отсчетов');
Combobox2.Items.Add('Отклонение от среднего значения');
Combobox2.Items.Add('Динамический диапазон в фрагментах кодирования');
Chart3.Series[0].Clear;
Application.MessageBox('Кодирование и декодирование завершено.','Сообщение',mb_ok);
PageSourceControl1.ActivePageIndex:=1;
end;

//Выбор видео для кодирования в mpeg.


//Фильтр установлен в "только avi" по умолчанию, но в действительности ffmpeg перекодирует почти все, что угодно.
procedure TForm1.Button5Click(Sender: TObject);
begin
If OpenDialog2.Execute then begin
Button6.Enabled:=True;
Edit2.Text:=OpenDialog2.FileName;
Edit2.Enabled:=True;

119
FilterGraph.Stop;
FilterGraph.ClearGraph;
Button8.Enabled:=False;
end;
end;

//Загружаем выбранное видео для mpeg-кодирования.


procedure TForm1.Button6Click(Sender: TObject);
var
tmpstr:String;
i:Integer;
begin

GroupBox12.Visible:=True;
GroupBox5.Visible:=True;
GroupBox13.Visible:=True;

//Получаем информацию о доступных энкодерах


tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\ffprobe -encoders'+' 1>'+#34+ExtractFileDir(Application.ExeName)+'\ffmpeg\tmp.txt'+#34+' 2>&1';
//BP10. Правильно ли сформировалась команда на доступ к списку энкодеров?
GetDOSOutPut(tmpstr,ExtractFileDir(Application.ExeName));
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\tmp.txt';
Memo1.Lines.LoadFromFile(tmpstr);
DeleteFile(tmpstr);
//разблокируем соответствующие им элементы управления, и предупреждаем, если нашли не все
For i:=1 to Memo1.Lines.Count do begin
If Pos('mpeg2video',Memo1.Lines[i])>0 then RadioButton34.Enabled:=True;
If Pos('mpeg4',Memo1.Lines[i])>0 then RadioButton35.Enabled:=True;
If Pos('libx264',Memo1.Lines[i])>0 then RadioButton36.Enabled:=True;
end;
Memo1.Lines.Clear;
If RadioButton36.Enabled then RadioButton36.Checked:=True;
If RadioButton35.Enabled then RadioButton35.Checked:=True;
If RadioButton34.Enabled then RadioButton34.Checked:=True;
If (RadioButton34.Enabled=False) or (RadioButton35.Enabled=False) or (RadioButton36.Enabled=False) then Application.MessageBox('В системе доступны не все используемые программой кодеки. Пожалуйста,
поставьте свежий пакет (в папке программы есть дистрибутив K-Lite).','Ошибка',mb_ok or MB_ICONERROR);

//Получаем информацию о загруженном файле


Memo1.WordWrap:=False;
//Используем программу ffprobe (часть пакета ffmpeg), запускаем ее отдельным потоком
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\ffprobe -loglevel verbose -pretty -i '+#34+Edit2.Text+#34+' 1>'+#34+ExtractFileDir(Application.ExeName)+'\ffmpeg\tmp.txt'+#34+' 2>&1';
//BP11. Правильно ли сформировалась команда на доступ к свойствам выбранного файла?
GetDOSOutPut(tmpstr,ExtractFileDir(Application.ExeName));
//ее текстовый вывод показываем в правой части экрана
memo1.lines.add(tmpstr);
//если все отработало штатно, его копию забираем, минимально форматируем и показываем для информации пользователю
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\tmp.txt';
Memo1.Lines.LoadFromFile(tmpstr);
Memo1.Lines.Delete(0);
Repeat

120
Memo1.Lines.Delete(0);
Until (Memo1.Lines[0][1]<>' ') or (Memo1.Lines.Count=0);
Memo1.WordWrap:=True;

try
//пробуем проиграть выбранное видео в плеере
if not FilterGraph.Active then FilterGraph.Active := true;
FilterGraph.ClearGraph;
FilterGraph.RenderFile(Edit2.Text);
FilterGraph.Volume:=0;
FilterGraph.Play;
sleep(1000);
If (FilterGraph.State<>gsPlaying) or (FilterGraph.Duration<60) then ToolButton7Click(Self);
except
//если что-то не вышло, или если плеер вывалился из состояния "проигрывание", жмем на кнопку "открыть в стороннем проигрывателе"
ToolButton7Click(Self);
end;
Edit2.Enabled:=False;

end;

//процедуры управления проигрыванием превью ролика, который будем кодировать


//суть очевидна из используемых команд
procedure TForm1.ToolButton1Click(Sender: TObject);
begin
FilterGraph.Pause;
end;

procedure TForm1.ToolButton3Click(Sender: TObject);


begin
FilterGraph.Play;
end;

//процедура, отрабатывающая нажатие на кнопку стоп


//по умолчанию стоп не переводит проигрывание в начало, поэтому использовано предложенное
//разработчиком решение. omnissiah vult.
procedure TForm1.ToolButton5Click(Sender: TObject);
var
MediaSeeking: IMediaSeeking;
StopPosition, Position: int64;
begin
FilterGraph.Stop;
FilterGraph.QueryInterface(IMediaSeeking, MediaSeeking);
MediaSeeking.GetStopPosition(StopPosition);
Position := 0;
MediaSeeking.SetPositions(Position, AM_SEEKING_AbsolutePositioning, StopPosition, AM_SEEKING_NoPositioning);
end;

//если проигрыватель, встроенный в программу, не играет, проигрываем полученное видео сторонним


//особенности реализации проигрывателя (как, впрочем, и большинства проигрывателей Windows) таковы, что все,

121
//минимально отличное от наиболее распространенных настроек кодеков, он проиграть не в состоянии.
//как внешний проигрыватель используется ffplay, входящий в комплект ffmpeg, который поддерживает все кодеки комплекта
//в качестве альтернативы можно использовать VNC. он зарекомендовал себя хорошо.
procedure TForm1.ToolButton7Click(Sender: TObject);
var
tmpstr:String;
begin
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\ffplay';
ShellExecute(handle,'open',PChar(tmpstr), PChar('-an '+#34+Edit2.Text+#34),'',SW_SHOWNORMAL);
end;

//MPEG-кодирование.
procedure TForm1.Button7Click(Sender: TObject);
var
tmpstr,tmpstr2:String;
i,j,k,err1:Integer;
bitrate,framerate:Real;
MySystem: TSystemInfo;
begin
//получаем информацию о системе, чтобы эффективно разделить кодирование на число потоков,
//равное числу ядер
GetSystemInfo(MySystem);

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


//вызывающийся из командной строки, ffmpeg
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\ffmpeg.exe -i '+#34+Edit2.Text+#34+' -mbd rd ';
//пиксель-формат yuvXYZp - YUV X:Y:Z планарный
tmpstr:=tmpstr+'-pix_fmt yuv'+ComboBox3.Text[1]+ComboBox3.Text[3]+ComboBox3.Text[5]+'p ';
//треллис-квантование, если оно включено (убирает часть артефактов кодирования
If SpinEdit14.Value>0 then tmpstr:=tmpstr+'-trellis '+IntToStr(SpinEdit14.Value)+' ';
//рекомендуемые разработчиком параметры кодирования
//для mpeg-2: метод предсказания движения: EPZS
//для mpeg-4: use four motion vector by macroblock (mpeg4), h263 advanced intra coding / mpeg4 ac prediction
If radioButton34.checked then tmpstr:=tmpstr+'-me_method epzs '
else tmpstr:=tmpstr+'-flags +mv4+aic ';
//размер GOP
tmpstr:=tmpstr+'-g '+IntToStr(SpinEdit15.Value)+' ';
//частота B-кадров на P-кадр
if SpinEdit16.Value>0 then tmpstr:=tmpstr+'-bf '+IntToStr(SpinEdit16.Value)+' ';
//рекомендуемые разработчиком параметры кодирования
//full pel me compare function, sub pel me compare function
tmpstr:=tmpstr+'-cmp 2 -subcmp 2 -vcodec ';
//естественно, используемый видеокодек
If RadioButton34.Checked then tmpstr:=tmpstr+'mpeg2video ';
If RadioButton35.Checked then tmpstr:=tmpstr+'mpeg4 ';
If RadioButton36.Checked then tmpstr:=tmpstr+'libx264 ';
//без звука, перезаписываем все уже имеющиеся файлы, заданное время, в число потоков, равное числу процессоров
tmpstr:=tmpstr+'-an -y -t '+IntToStr(SpinEdit13.Value)+' -threads '+IntToStr(MySystem.dwNumberOfProcessors)+' ';
//если существует необходимость, добавляем шумовой фильтр, равномерный...
If RadioButton15.Checked then tmpstr:=tmpstr+'-vf mp=noise='+IntToStr(Round(1000/SpinEdit3.Value))+':'+IntToStr(Round(1000/SpinEdit3.Value))+'ut ';

122
//...или гауссовский
If RadioButton16.Checked then tmpstr:=tmpstr+'-vf mp=noise='+IntToStr(Round(1000/SpinEdit3.Value))+':'+IntToStr(Round(1000/SpinEdit3.Value))+'t ';
//указываем выходной файл
tmpstr:=tmpstr+#34+ExtractFileDir(Application.ExeName)+'\ffmpeg\result.avi'+#34;
//и, собственно, запускаем.
//BP12. Правильно ли сформировалась команда на кодирование?
tmpstr:=GetDOSOutPut(tmpstr,ExtractFileDir(Application.ExeName));
//если что-то не работает, брейкпойнт ставится на строчку ниже этого комментария. Во временной переменной - вывод кодера.
//Оцениваем результаты кодирования с помощью ffprobe.
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\ffprobe -loglevel verbose -pretty -i '+#34+ExtractFileDir(Application.ExeName)+'\ffmpeg\result.avi'+#34+' 1>'+#34+ExtractFileDir(Application.ExeName)
+'\ffmpeg\tmp.txt'+#34+' 2>&1';
GetDOSOutPut(tmpstr,ExtractFileDir(Application.ExeName));
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\tmp.txt';
memo2.lines.add(tmpstr);
Memo2.Lines.LoadFromFile(tmpstr);
framerate:=30;
bitrate:=300;
//в результатах ищем битрейт и фреймрейт, разделив одно на другое, получаем средний размер кадра.
For i:=1 to Memo2.Lines.Count do begin
j:=pos('bitrate',Memo2.Lines[i]);
If j>0 then begin
tmpstr:=Copy(Memo2.Lines[i],j+8,pos('kb/s',Memo2.Lines[i])-j-8);
Val(tmpstr,bitrate,err1);
end;
j:=pos('fps',Memo2.Lines[i]);
If j>0 then begin
k:=j-1;
Repeat
k:=k-1;
Until (Memo2.Lines[i][k]=',') or (k=0);
tmpstr:=Copy(Memo2.Lines[i],k+1,j-k-1);
tmpstr2:= StringReplace(tmpstr,'.',',', [rfReplaceAll]);
Val(tmpstr2,framerate,err1);
if tmpstr2<>tmpstr then framerate:=framerate+1;
end;
end;

tmpstr:='Кодирование завершено.'+#10+#13+'Размер одного кадра: '+IntToStr(Round(bitrate/framerate))+' кбит.'+#10+#13+'Поток при 30 кадрах в секунду: '+IntToStr(Round(bitrate/framerate*30))+' кбит/сек.';
Application.MessageBox(PChar(tmpstr),'Сообщение',mb_ok);

//запускаем оба ролика, исходный и кодированный, для сравнения


Button8.Enabled:=True;
Button8Click(Self);
end;

//по закрытию формы чистим проигрыватель. Разработчик компонента уверяет, что это важно.
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FilterGraph.ClearGraph;
end;

123
//для сравнения исходного и кодированного в mpeg роликов запускаем их бок о бок в универсальном проигрывателе ffplay
procedure TForm1.Button8Click(Sender: TObject);
var
tmpstr:String;
begin
ToolButton1Click(self);
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\ffplay';
ShellExecute(handle,'open',PChar(tmpstr), PChar('-an '+#34+Edit2.Text+#34),'',SW_SHOWNORMAL);
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\ffplay';
ShellExecute(handle,'open',PChar(tmpstr), PChar('-an '+#34+ExtractFileDir(Application.ExeName)+'\ffmpeg\result.avi'+#34),'',SW_SHOWNORMAL);

end;

//по щелчку на видеопроигрывателе запускаем его или ставим на паузу


procedure TForm1.VideoWindow1Click(Sender: TObject);
begin
If FilterGraph.State=gsPlaying then FilterGraph.Pause else FilterGraph.Play;
end;

//Преобразование Адамара. Для метода без устранения избыточности используем те же элементы управления, что для метода порогового отбора
procedure TForm1.RadioButton37Click(Sender: TObject);
begin
RadioButton29Click(self);
end;

end.

124
П3.3. Unit1.dfm
object Form1: TForm1
Left = 212
Top = 115
BorderStyle = bsDialog
Caption = #1048#1089#1089#1083#1077#1076#1086#1074#1072#1085#1080#1077' '#1084#1077#1090#1086#1076#1086#1074' '#1082#1086#1076#1080#1088#1086#1074#1072#1085#1080#1103'
'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1081
ClientHeight = 765
ClientWidth = 1309
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnClose = FormClose
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object PageSourceControl1: TPageControl
Left = 0
Top = 0
Width = 1305
Height = 761
ActivePage = ParametersTabSheet
TabOrder = 0
object ParametersTabSheet: TTabSheet
Caption = #1048#1089#1093#1086#1076#1085#1099#1077' '#1087#1072#1088#1072#1084#1077#1090#1088#1099
object GroupBox11: TGroupBox
Left = 0
Top = 56
Width = 641
Height = 49
Caption = #1042#1099#1073#1077#1088#1080#1090#1077' '#1080#1089#1093#1086#1076#1085#1086#1077' '#1074#1080#1076#1077#1086
TabOrder = 7
Visible = False
object Edit2: TEdit
Left = 8
Top = 16
Width = 457
Height = 21
TabOrder = 0
end
object Button5: TButton
Left = 472
Top = 13
Width = 75

125
Height = 25
Caption = #1042#1099#1073#1088#1072#1090#1100
TabOrder = 1
OnClick = Button5Click
end
object Button6: TButton
Left = 552
Top = 13
Width = 75
Height = 25
Caption = #1047#1072#1075#1088#1091#1079#1080#1090#1100
Enabled = False
TabOrder = 2
OnClick = Button6Click
end
end
object GroupBox12: TGroupBox
Left = 0
Top = 112
Width = 641
Height = 345
Caption = #1055#1072#1088#1072#1084#1077#1090#1088#1099' '#1074#1080#1076#1077#1086'-'#1082#1086#1076#1080#1088#1086#1074#1072#1085#1080#1103
TabOrder = 8
Visible = False
object Label32: TLabel
Left = 8
Top = 16
Width = 113
Height = 13
Caption = #1048#1089#1087#1086#1083#1100#1079#1091#1077#1084#1099#1081' '#1082#1086#1076#1077#1082':'
end
object Label33: TLabel
Left = 8
Top = 56
Width = 203
Height = 13
Caption = #1044#1083#1080#1090#1077#1083#1100#1085#1086#1089#1090#1100' '#1082#1086#1076#1080#1088#1091#1077#1084#1086#1075#1086' '#1086#1090#1088#1099#1074#1082#1072', '#1089':'
end
object Label34: TLabel
Left = 8
Top = 152
Width = 117
Height = 13
Caption = #1058#1088#1077#1083#1083#1080#1089'-'#1082#1074#1072#1085#1090#1086#1074#1072#1085#1080#1077': '
end
object Label35: TLabel
Left = 8
Top = 80
Width = 125
Height = 13

126
Caption = #1060#1086#1088#1084#1072#1090' '#1076#1080#1089#1082#1088#1077#1090#1080#1079#1072#1094#1080#1080':'
end
object Label36: TLabel
Left = 8
Top = 104
Width = 120
Height = 13
Caption = #1056#1072#1079#1084#1077#1088' '#1075#1088#1091#1087#1087#1099' '#1082#1072#1076#1088#1086#1074':'
end
object Label37: TLabel
Left = 8
Top = 128
Width = 142
Height = 13
Caption = 'B-'#1082#1072#1076#1088#1086#1074' '#1084#1077#1078#1076#1091' P-'#1082#1072#1076#1088#1072#1084#1080':'
end
object Panel6: TPanel
Left = 8
Top = 32
Width = 513
Height = 17
BevelOuter = bvNone
TabOrder = 0
object RadioButton34: TRadioButton
Left = 8
Top = 0
Width = 73
Height = 17
Caption = 'MPEG-2'
Enabled = False
TabOrder = 0
end
object RadioButton35: TRadioButton
Left = 80
Top = 0
Width = 97
Height = 17
Caption = 'MPEG-4 part 2'
Enabled = False
TabOrder = 1
end
object RadioButton36: TRadioButton
Left = 184
Top = 0
Width = 193
Height = 17
Caption = 'MPEG-4 part 10 (codec h264)'
Enabled = False
TabOrder = 2
end

127
end
object SpinEdit13: TSpinEdit
Left = 216
Top = 48
Width = 57
Height = 22
MaxValue = 600
MinValue = 1
TabOrder = 1
Value = 60
end
object SpinEdit14: TSpinEdit
Left = 216
Top = 144
Width = 57
Height = 22
MaxValue = 10
MinValue = 0
TabOrder = 2
Value = 2
end
object ComboBox3: TComboBox
Left = 216
Top = 72
Width = 57
Height = 21
ItemHeight = 13
TabOrder = 3
Text = '4:2:0'
Items.Strings = (
'4:1:0'
'4:1:1'
'4:2:0'
'4:2:2'
'4:4:0'
'4:4:4')
end
object SpinEdit15: TSpinEdit
Left = 216
Top = 96
Width = 57
Height = 22
MaxValue = 500
MinValue = 5
TabOrder = 4
Value = 100
end
object SpinEdit16: TSpinEdit
Left = 216
Top = 120

128
Width = 57
Height = 22
MaxValue = 10
MinValue = 0
TabOrder = 5
Value = 2
end
object Button7: TButton
Left = 456
Top = 48
Width = 75
Height = 113
Caption = #1050#1086#1076#1080#1088#1086#1074#1072#1090#1100
TabOrder = 6
OnClick = Button7Click
end
object Button8: TButton
Left = 552
Top = 48
Width = 75
Height = 113
Caption = #1057#1088#1072#1074#1085#1080#1090#1100
Enabled = False
TabOrder = 7
OnClick = Button8Click
end
end
object GroupBox4: TGroupBox
Left = 0
Top = 248
Width = 641
Height = 209
Caption = #1053#1072#1089#1090#1088#1086#1081#1082#1080' '#1082#1086#1076#1077#1088#1072
TabOrder = 3
Visible = False
object Label10: TLabel
Left = 8
Top = 16
Width = 71
Height = 13
Caption = #1050#1074#1072#1085#1090#1086#1074#1072#1090#1077#1083#1100
end
object Label13: TLabel
Left = 8
Top = 176
Width = 3
Height = 13
end
object RadioButton17: TRadioButton
Left = 16

129
Top = 80
Width = 225
Height = 17
Caption = #1057' '#1086#1090#1089#1077#1095#1082#1086#1081'. '#1041#1080#1090' '#1085#1072' '#1088#1072#1079#1085#1086#1089#1090#1085#1099#1081' '#1086#1090#1089#1095#1077#1090':'
TabOrder = 0
OnClick = RadioButton17Click
end
object RadioButton18: TRadioButton
Left = 16
Top = 104
Width = 113
Height = 17
Caption = #1040#1076#1072#1087#1090#1080#1074#1085#1099#1081
TabOrder = 1
OnClick = RadioButton18Click
end
object SpinEdit6: TSpinEdit
Left = 256
Top = 82
Width = 41
Height = 22
EditorEnabled = False
Enabled = False
MaxValue = 9
MinValue = 1
TabOrder = 2
Value = 9
OnChange = SpinEdit6Change
end
object Panel2: TPanel
Left = 32
Top = 120
Width = 513
Height = 51
BevelOuter = bvNone
TabOrder = 3
object Label12: TLabel
Left = 304
Top = 24
Width = 113
Height = 13
Caption = #1088#1072#1079#1085#1086#1089#1090#1085#1099#1093' '#1079#1085#1072#1095#1077#1085#1080#1081':'
Enabled = False
OnClick = Label12Click
end
object RadioButton19: TRadioButton
Left = 8
Top = 8
Width = 209
Height = 17

130
Caption = #1052#1077#1090#1086#1076' '#1084#1072#1082#1089#1080#1084#1091#1084#1086#1074'. '#1041#1080#1090' '#1085#1072' '#1086#1090#1089#1095#1077#1090':'
Checked = True
Enabled = False
TabOrder = 0
TabStop = True
OnClick = RadioButton19Click
end
object RadioButton20: TRadioButton
Left = 288
Top = 8
Width = 137
Height = 17
Caption = #1050#1088#1080#1090#1077#1088#1080#1081' '#1079#1085#1072#1095#1080#1084#1086#1089#1090#1080'.'
Enabled = False
TabOrder = 1
OnClick = RadioButton20Click
end
object SpinEdit7: TSpinEdit
Left = 224
Top = 8
Width = 41
Height = 22
EditorEnabled = False
Enabled = False
MaxValue = 9
MinValue = 1
TabOrder = 2
Value = 9
OnChange = SpinEdit7Change
end
object SpinEdit8: TSpinEdit
Left = 432
Top = 8
Width = 73
Height = 22
Enabled = False
MaxValue = 0
MinValue = 0
TabOrder = 3
Value = 10
OnChange = SpinEdit8Change
end
object RadioButton33: TRadioButton
Left = 8
Top = 36
Width = 417
Height = 17
Caption = #1056#1072#1074#1085#1086#1084#1077#1088#1085#1086#1077' '#1079#1072#1087#1086#1083#1085#1077#1085#1080#1077'
'#1086#1082#1086#1083#1086#1085#1091#1083#1077#1074#1086#1075#1086' '#1084#1072#1082#1089#1080#1084#1091#1084#1072'. '#1041#1080#1090' '#1085#1072' '#1086#1090#1089#1095#1077#1090':'
Enabled = False

131
TabOrder = 4
OnClick = RadioButton33Click
end
object SpinEdit12: TSpinEdit
Left = 432
Top = 32
Width = 73
Height = 22
Enabled = False
MaxValue = 9
MinValue = 1
TabOrder = 5
Value = 3
OnChange = SpinEdit12Change
end
end
object Button3: TButton
Left = 552
Top = 16
Width = 75
Height = 145
Caption = #1050#1086#1076#1080#1088#1086#1074#1072#1090#1100
TabOrder = 4
OnClick = Button3Click
end
object RadioButton30: TRadioButton
Left = 16
Top = 32
Width = 217
Height = 17
Caption = #1051#1080#1085#1077#1081#1085#1099#1081'. '#1041#1080#1090' '#1085#1072' '#1088#1072#1079#1085#1086#1089#1090#1085#1099#1081' '#1086#1090#1089#1095#1077#1090':'
Checked = True
TabOrder = 5
TabStop = True
OnClick = RadioButton30Click
end
object Panel5: TPanel
Left = 32
Top = 56
Width = 505
Height = 25
BevelOuter = bvNone
TabOrder = 6
object RadioButton31: TRadioButton
Left = 8
Top = 0
Width = 169
Height = 17
Caption = #1056#1072#1074#1085#1086#1084#1077#1088#1085#1086#1077' '#1079#1072#1087#1086#1083#1085#1077#1085#1080#1077
Checked = True

132
TabOrder = 0
TabStop = True
OnClick = RadioButton31Click
end
object RadioButton32: TRadioButton
Left = 288
Top = 0
Width = 113
Height = 17
Caption = #1048#1085#1090#1077#1088#1074#1072#1083':'
TabOrder = 1
OnClick = RadioButton32Click
end
object SpinEdit11: TSpinEdit
Left = 432
Top = 0
Width = 73
Height = 22
MaxValue = 255
MinValue = 1
TabOrder = 2
Value = 1
OnChange = SpinEdit11Change
end
end
object SpinEdit10: TSpinEdit
Left = 256
Top = 34
Width = 41
Height = 22
EditorEnabled = False
MaxValue = 9
MinValue = 1
TabOrder = 7
Value = 3
OnChange = SpinEdit10Change
end
end
object GroupBox9: TGroupBox
Left = 0
Top = 248
Width = 641
Height = 209
Caption = #1053#1072#1089#1090#1088#1086#1081#1082#1080' '#1082#1086#1076#1077#1088#1072
TabOrder = 5
Visible = False
object Label28: TLabel
Left = 8
Top = 16
Width = 170

133
Height = 13
Caption = #1056#1072#1079#1084#1077#1088' '#1082#1086#1076#1080#1088#1091#1077#1084#1086#1075#1086' '#1092#1088#1072#1075#1084#1077#1085#1090#1072':'
end
object Label29: TLabel
Left = 8
Top = 40
Width = 170
Height = 13
Caption = #1052#1077#1090#1086#1076' '#1091#1089#1090#1088#1072#1085#1077#1085#1080#1103' '#1080#1079#1073#1099#1090#1086#1095#1085#1086#1089#1090#1080':'
end
object Panel3: TPanel
Left = 208
Top = 8
Width = 353
Height = 33
BevelOuter = bvNone
TabOrder = 0
object RadioButton26: TRadioButton
Left = 8
Top = 8
Width = 113
Height = 17
Caption = '4x4'
Checked = True
TabOrder = 0
TabStop = True
OnClick = RadioButton26Click
end
object RadioButton27: TRadioButton
Left = 136
Top = 8
Width = 113
Height = 17
Caption = '8x8'
TabOrder = 1
OnClick = RadioButton27Click
end
end
object Panel4: TPanel
Left = 16
Top = 56
Width = 497
Height = 105
BevelOuter = bvNone
TabOrder = 1
object Label30: TLabel
Left = 24
Top = 80
Width = 267
Height = 13

134
Caption = #1050#1088#1080#1090#1077#1088#1080#1081' '#1079#1085#1072#1095#1080#1084#1086#1089#1090#1080' '#1086#1090#1089#1095#1077#1090#1072' -
'#1079#1085#1072#1095#1077#1085#1080#1077' '#1085#1077' '#1084#1077#1085#1100#1096#1077
end
object RadioButton28: TRadioButton
Left = 8
Top = 32
Width = 265
Height = 17
Caption = #1052#1077#1090#1086#1076' '#1079#1086#1085#1072#1083#1100#1085#1086#1075#1086' '#1086#1090#1073#1086#1088#1072
TabOrder = 0
OnClick = RadioButton28Click
end
object RadioButton29: TRadioButton
Left = 8
Top = 56
Width = 169
Height = 17
Caption = #1052#1077#1090#1086#1076' '#1087#1086#1088#1086#1075#1086#1074#1086#1075#1086' '#1086#1090#1073#1086#1088#1072
TabOrder = 1
OnClick = RadioButton29Click
end
object SpinEdit9: TSpinEdit
Left = 304
Top = 72
Width = 73
Height = 22
Enabled = False
MaxValue = 255
MinValue = 0
TabOrder = 2
Value = 10
end
object RadioButton37: TRadioButton
Left = 8
Top = 8
Width = 185
Height = 17
Caption = #1041#1077#1079' '#1091#1089#1090#1088#1072#1085#1077#1085#1080#1103' '#1080#1079#1073#1099#1090#1086#1095#1085#1086#1089#1090#1080
Checked = True
TabOrder = 3
TabStop = True
OnClick = RadioButton37Click
end
end
object Button4: TButton
Left = 552
Top = 16
Width = 75
Height = 145
Caption = #1050#1086#1076#1080#1088#1086#1074#1072#1090#1100

135
TabOrder = 2
OnClick = Button4Click
end
end
object GroupBox10: TGroupBox
Left = 648
Top = 0
Width = 649
Height = 729
Caption = #1048#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077' '#1080' '#1087#1088#1077#1076#1074#1072#1088#1080#1090#1077#1083#1100#1085#1099#1081'
'#1089#1090#1072#1090#1080#1089#1090#1080#1095#1077#1089#1082#1080#1081' '#1072#1085#1072#1083#1080#1079
TabOrder = 6
Visible = False
object Image5: TImage
Left = 16
Top = 16
Width = 364
Height = 273
Visible = False
end
object Label31: TLabel
Left = 16
Top = 296
Width = 413
Height = 13
Caption =
#1055#1077#1088#1077#1076#1072#1074#1072#1077#1084#1099#1077' '#1101#1083#1077#1084#1077#1085#1090#1099' '#1084#1072#1090#1088#1080#1094#1099' '#1087#1086#1089#1083#1077'
'#1087#1088#1077#1086#1073#1088#1072#1079#1086#1074#1072#1085#1080#1103' ('#1095#1077#1088#1085#1099#1077' '#1087#1077#1088#1077#1076 +
#1072#1102#1090#1089#1103'):'
end
object StringGrid1: TStringGrid
Left = 16
Top = 312
Width = 401
Height = 401
ColCount = 8
DefaultColWidth = 48
DefaultRowHeight = 48
FixedCols = 7
RowCount = 8
FixedRows = 7
TabOrder = 0
OnDrawCell = StringGrid1DrawCell
OnSelectCell = StringGrid1SelectCell
end
end
object GroupBox13: TGroupBox
Left = 648
Top = 0
Width = 649

136
Height = 729
Caption = #1055#1088#1077#1076#1074#1072#1088#1080#1090#1077#1083#1100#1085#1099#1081' '#1087#1088#1086#1089#1084#1086#1090#1088' '#1074#1080#1076#1077#1086' '#1080' '#1077#1075#1086'
'#1087#1072#1088#1072#1084#1077#1090#1088#1099
TabOrder = 9
Visible = False
object Label11: TLabel
Left = 8
Top = 496
Width = 95
Height = 13
Caption = #1055#1072#1088#1072#1084#1077#1090#1088#1099' '#1074#1080#1076#1077#1086':'
end
object Memo1: TMemo
Left = 8
Top = 512
Width = 633
Height = 209
TabOrder = 0
WordWrap = False
end
object VideoWindow1: TVideoWindow
Left = 2
Top = 79
Width = 645
Height = 418
Mode = vmVMR
FilterGraph = FilterGraph
VMROptions.Mode = vmrWindowed
Color = clBlack
OnClick = VideoWindow1Click
end
object ToolBar1: TToolBar
Left = 2
Top = 15
Width = 645
Height = 29
Caption = 'ToolBar1'
Images = ImageList1
TabOrder = 2
object ToolButton1: TToolButton
Left = 0
Top = 2
Hint = #1055#1072#1091#1079#1072
Caption = 'ToolButton1'
ImageIndex = 0
ParentShowHint = False
ShowHint = True
OnClick = ToolButton1Click
end
object ToolButton2: TToolButton

137
Left = 23
Top = 2
Width = 8
Caption = 'ToolButton2'
ImageIndex = 1
Style = tbsSeparator
end
object ToolButton3: TToolButton
Left = 31
Top = 2
Hint = #1042#1086#1089#1087#1088#1086#1080#1079#1074#1077#1076#1077#1085#1080#1077
Caption = 'ToolButton3'
ImageIndex = 1
ParentShowHint = False
ShowHint = True
OnClick = ToolButton3Click
end
object ToolButton4: TToolButton
Left = 54
Top = 2
Width = 8
Caption = 'ToolButton4'
ImageIndex = 2
Style = tbsSeparator
end
object ToolButton5: TToolButton
Left = 62
Top = 2
Hint = #1057#1090#1086#1087
Caption = 'ToolButton5'
ImageIndex = 2
ParentShowHint = False
ShowHint = True
OnClick = ToolButton5Click
end
object ToolButton6: TToolButton
Left = 85
Top = 2
Width = 8
Caption = 'ToolButton6'
ImageIndex = 3
Style = tbsSeparator
end
object ToolButton7: TToolButton
Left = 93
Top = 2
Hint = #1054#1090#1082#1088#1099#1090#1100' '#1074#1086' '#1074#1085#1077#1096#1085#1077#1084' '#1087#1088#1086#1080#1075#1088#1099#1074#1072#1090#1077#1083#1077
Caption = 'ToolButton7'
ImageIndex = 3
ParentShowHint = False

138
ShowHint = True
OnClick = ToolButton7Click
end
object Label38: TLabel
Left = 116
Top = 2
Width = 277
Height = 22
Caption = ' << '#1045#1089#1083#1080' '#1087#1088#1086#1080#1075#1088#1099#1074#1072#1090#1077#1083#1100' '#1085#1077' '#1088#1072#1073#1086#1090#1072#1077#1090',
'#1085#1072#1078#1084#1080#1090#1077' '#1089#1102#1076#1072
end
end
object DSTrackBar1: TDSTrackBar
Left = 0
Top = 48
Width = 641
Height = 25
TabOrder = 3
FilterGraph = FilterGraph
end
object Memo2: TMemo
Left = 464
Top = 632
Width = 185
Height = 89
TabOrder = 4
Visible = False
WordWrap = False
end
end
object GroupBox1: TGroupBox
Left = 0
Top = 0
Width = 641
Height = 49
Caption = #1042#1099#1073#1077#1088#1080#1090#1077' '#1084#1077#1090#1086#1076' '#1082#1086#1076#1080#1088#1086#1074#1072#1085#1080#1103
TabOrder = 0
object ComboBox1: TComboBox
Left = 8
Top = 16
Width = 617
Height = 21
ItemHeight = 13
TabOrder = 0
OnChange = ComboBox1Change
Items.Strings = (
#1044#1080#1092#1092#1077#1088#1077#1085#1094#1080#1072#1083#1100#1085#1072#1103' '#1080#1084#1087#1091#1083#1100#1089#1085#1086'-'#1082#1086#1076#1086#1074#1072#1103'
'#1084#1086#1076#1091#1083#1103#1094#1080#1103
#1050#1086#1076#1080#1088#1086#1074#1072#1085#1080#1077' '#1089' '#1080#1089#1087#1086#1083#1100#1079#1086#1074#1072#1085#1080#1077#1084'
'#1087#1088#1077#1086#1073#1088#1072#1079#1086#1074#1072#1085#1080#1103' '#1040#1076#1072#1084#1072#1088#1072

139
#1050#1086#1076#1080#1088#1086#1074#1072#1085#1080#1077' '#1089' '#1080#1089#1087#1086#1083#1100#1079#1086#1074#1072#1085#1080#1077#1084'
'#1087#1088#1086#1090#1086#1082#1086#1083#1072' MPEG')
end
end
object GroupBox2: TGroupBox
Left = 0
Top = 56
Width = 641
Height = 185
Caption = #1042#1099#1073#1077#1088#1080#1090#1077' '#1080#1089#1093#1086#1076#1085#1086#1077' '#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077
TabOrder = 1
Visible = False
object RadioButton1: TRadioButton
Left = 8
Top = 16
Width = 449
Height = 17
Caption = #1057#1090#1072#1085#1076#1072#1088#1090#1085#1086#1077
Checked = True
TabOrder = 0
TabStop = True
OnClick = RadioButton1Click
end
object RadioButton2: TRadioButton
Left = 8
Top = 120
Width = 457
Height = 17
Caption = #1053#1077#1089#1090#1072#1085#1076#1072#1088#1090#1085#1086#1077
TabOrder = 1
OnClick = RadioButton2Click
end
object Edit1: TEdit
Left = 8
Top = 144
Width = 457
Height = 21
Enabled = False
TabOrder = 2
end
object Button1: TButton
Left = 472
Top = 140
Width = 75
Height = 25
Caption = #1042#1099#1073#1088#1072#1090#1100
Enabled = False
TabOrder = 3
OnClick = Button1Click
end

140
object Button2: TButton
Left = 552
Top = 24
Width = 75
Height = 145
Caption = #1047#1072#1075#1088#1091#1079#1080#1090#1100
TabOrder = 4
OnClick = Button2Click
end
object Panel1: TPanel
Left = 24
Top = 32
Width = 521
Height = 81
BevelOuter = bvNone
TabOrder = 5
object RadioButton3: TRadioButton
Left = 8
Top = 8
Width = 217
Height = 17
Caption = #1055#1088#1077#1076#1089#1090#1072#1074#1080#1090#1077#1083#1100#1085#1086#1077
Checked = True
TabOrder = 0
TabStop = True
end
object RadioButton4: TRadioButton
Left = 8
Top = 24
Width = 217
Height = 17
Caption = #1063#1077#1088#1085#1086'-'#1073#1077#1083#1072#1103' '#1082#1072#1088#1090#1080#1085#1082#1072
TabOrder = 1
end
object RadioButton5: TRadioButton
Left = 8
Top = 40
Width = 217
Height = 17
Caption = #1062#1074#1077#1090#1085#1072#1103' '#1082#1072#1088#1090#1080#1085#1082#1072
TabOrder = 2
end
object RadioButton6: TRadioButton
Left = 256
Top = 8
Width = 257
Height = 17
Caption = #1064#1072#1093#1084#1072#1090#1085#1072#1103' '#1076#1086#1089#1082#1072
TabOrder = 3
end

141
object RadioButton7: TRadioButton
Left = 8
Top = 56
Width = 217
Height = 17
Caption = #1062#1074#1077#1090#1085#1099#1077' '#1087#1086#1083#1086#1089#1099
TabOrder = 4
end
object RadioButton8: TRadioButton
Left = 256
Top = 40
Width = 257
Height = 17
Caption = #1042#1099#1089#1086#1082#1086#1082#1086#1085#1090#1088#1072#1089#1090#1085#1099#1081' '#1090#1077#1082#1089#1090
TabOrder = 5
end
object RadioButton9: TRadioButton
Left = 256
Top = 56
Width = 257
Height = 17
Caption = #1053#1080#1079#1082#1086#1082#1086#1085#1090#1088#1072#1089#1090#1085#1099#1081' '#1090#1077#1082#1089#1090
TabOrder = 6
end
object RadioButton13: TRadioButton
Left = 256
Top = 24
Width = 257
Height = 17
Caption = #1064#1072#1093#1084#1072#1090#1085#1072#1103' '#1076#1086#1089#1082#1072' '#1074' '#1084#1077#1083#1082#1091#1102' '#1082#1083#1077#1090#1082#1091
TabOrder = 7
end
end
end
object GroupBox3: TGroupBox
Left = 648
Top = 0
Width = 649
Height = 729
Caption = #1048#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077' '#1080' '#1087#1088#1077#1076#1074#1072#1088#1080#1090#1077#1083#1100#1085#1099#1081'
'#1089#1090#1072#1090#1080#1089#1090#1080#1095#1077#1089#1082#1080#1081' '#1072#1085#1072#1083#1080#1079
TabOrder = 2
Visible = False
object Image1: TImage
Left = 8
Top = 16
Width = 300
Height = 200
AutoSize = True
Visible = False

142
end
object Label1: TLabel
Left = 456
Top = 64
Width = 84
Height = 13
Caption = #1053#1077' '#1084#1077#1085#1100#1096#1077', '#1088#1072#1079':'
end
object Label2: TLabel
Left = 336
Top = 48
Width = 102
Height = 13
Caption = #1079#1085#1072#1095#1080#1084#1086#1077' '#1095#1080#1089#1083#1086' '#1088#1072#1079
end
object Label3: TLabel
Left = 336
Top = 80
Width = 306
Height = 13
Caption = #1057#1077#1081#1095#1072#1089' '#1085#1072' '#1075#1088#1072#1092#1080#1082#1077' '#1086#1090#1086#1073#1088#1072#1078#1077#1085#1099' 100%
'#1088#1072#1079#1085#1086#1089#1090#1085#1099#1093' '#1086#1090#1089#1095#1077#1090#1086#1074'.'
end
object Label4: TLabel
Left = 328
Top = 128
Width = 216
Height = 13
Caption = #1041#1080#1090' '#1085#1072' '#1082#1086#1076#1080#1088#1086#1074#1072#1085#1080#1077' '#1088#1072#1079#1085#1086#1089#1090#1085#1099#1093'
'#1086#1090#1089#1095#1077#1090#1086#1074':'
end
object Label5: TLabel
Left = 336
Top = 144
Width = 266
Height = 13
Caption = #1042' '#1085#1077#1072#1076#1072#1087#1090#1080#1074#1085#1086#1084' '#1088#1077#1078#1080#1084#1077' '#1073#1091#1076#1091#1090' '#1074'
'#1090#1086#1095#1085#1086#1089#1090#1080' '#1087#1077#1088#1077#1076#1072#1085#1099
end
object Label6: TLabel
Left = 336
Top = 160
Width = 140
Height = 13
Caption = '100% '#1088#1072#1079#1085#1086#1089#1090#1085#1099#1093' '#1086#1090#1089#1095#1077#1090#1086#1074'.'
end
object Chart1: TChart
Left = 8
Top = 224
Width = 633

143
Height = 497
BackWall.Brush.Color = clWhite
BackWall.Brush.Style = bsClear
Title.Text.Strings = (
#1056#1072#1089#1087#1088#1077#1076#1077#1083#1077#1085#1080#1077' '#1088#1072#1079#1085#1086#1089#1090#1077#1081' '#1094#1074#1077#1090#1086#1074#1099#1093'
'#1086#1090#1089#1095#1077#1090#1086#1074)
BottomAxis.Title.Caption = #1056#1072#1079#1085#1086#1089#1090#1100
LeftAxis.Title.Caption = #1042#1089#1090#1088#1077#1095#1072#1077#1090#1089#1103' '#1085#1072' '#1082#1072#1088#1090#1080#1085#1082#1077' '#1088#1072#1079
Legend.Visible = False
TopAxis.Labels = False
TopAxis.Visible = False
View3D = False
TabOrder = 0
object Series1: TLineSeries
Marks.ArrowLength = 20
Marks.Style = smsValue
Marks.Visible = False
SeriesColor = clRed
ShowInLegend = False
Dark3D = False
Pointer.InflateMargins = True
Pointer.Style = psRectangle
Pointer.Visible = False
XValues.DateTime = False
XValues.Name = 'X'
XValues.Multiplier = 1.000000000000000000
XValues.Order = loAscending
YValues.DateTime = False
YValues.Name = 'Y'
YValues.Multiplier = 1.000000000000000000
YValues.Order = loNone
end
object Series2: TLineSeries
Marks.ArrowLength = 8
Marks.Visible = False
SeriesColor = clGreen
Pointer.InflateMargins = True
Pointer.Style = psRectangle
Pointer.Visible = False
XValues.DateTime = False
XValues.Name = 'X'
XValues.Multiplier = 1.000000000000000000
XValues.Order = loAscending
YValues.DateTime = False
YValues.Name = 'Y'
YValues.Multiplier = 1.000000000000000000
YValues.Order = loNone
end
end
object RadioButton10: TRadioButton

144
Left = 320
Top = 16
Width = 241
Height = 17
Caption = #1055#1086#1082#1072#1079#1099#1074#1072#1090#1100' '#1074#1089#1077' '#1087#1088#1086#1089#1090#1088#1072#1085#1089#1090#1074#1086'
'#1088#1072#1079#1085#1086#1089#1090#1077#1081
Checked = True
TabOrder = 1
TabStop = True
OnClick = RadioButton10Click
end
object RadioButton11: TRadioButton
Left = 320
Top = 32
Width = 257
Height = 17
Caption = #1055#1086#1082#1072#1079#1099#1074#1072#1090#1100' '#1090#1086#1083#1100#1082#1086' '#1088#1072#1079#1085#1086#1089#1090#1080',
'#1074#1089#1090#1088#1077#1095#1072#1102#1097#1080#1077#1089#1103
TabOrder = 2
OnClick = RadioButton11Click
end
object SpinEdit1: TSpinEdit
Left = 552
Top = 56
Width = 65
Height = 22
Enabled = False
MaxValue = 255
MinValue = 0
TabOrder = 3
Value = 10
OnChange = SpinEdit1Change
end
object SpinEdit2: TSpinEdit
Left = 552
Top = 120
Width = 65
Height = 22
EditorEnabled = False
MaxValue = 9
MinValue = 1
TabOrder = 4
Value = 9
OnChange = SpinEdit2Change
end
object RadioButton12: TRadioButton
Left = 320
Top = 104
Width = 313
Height = 17

145
Caption = #1054#1094#1077#1085#1080#1090#1100' '#1085#1077#1086#1073#1093#1086#1076#1080#1084#1086#1077' '#1082#1086#1083#1080#1095#1077#1089#1090#1074#1086'
'#1091#1088#1086#1074#1085#1077#1081' '#1082#1074#1072#1085#1090#1086#1074#1072#1085#1080#1103
TabOrder = 5
OnClick = RadioButton12Click
end
end
object GroupBox5: TGroupBox
Left = 0
Top = 464
Width = 641
Height = 265
Caption = #1053#1072#1089#1090#1088#1086#1081#1082#1080' '#1082#1072#1085#1072#1083#1072' '#1087#1077#1088#1077#1076#1072#1095#1080
TabOrder = 4
Visible = False
object Label7: TLabel
Left = 8
Top = 74
Width = 228
Height = 13
Caption = #1048#1085#1090#1077#1085#1089#1080#1074#1085#1086#1089#1090#1100' '#1096#1091#1084#1072': 1 '#1080#1089#1082#1072#1078#1077#1085#1085#1099#1081' '#1073#1072#1081#1090'
'#1080#1079
end
object Label8: TLabel
Left = 368
Top = 72
Width = 76
Height = 13
Caption = #1052#1072#1090#1086#1078#1080#1076#1072#1085#1080#1077': '
end
object Label9: TLabel
Left = 512
Top = 72
Width = 67
Height = 13
Caption = #1054#1090#1082#1083#1086#1085#1077#1085#1080#1077': '
end
object RadioButton14: TRadioButton
Left = 8
Top = 16
Width = 273
Height = 17
Caption = #1050#1072#1085#1072#1083' '#1087#1077#1088#1077#1076#1072#1095#1080' '#1073#1077#1079' '#1096#1091#1084#1072
Checked = True
TabOrder = 0
TabStop = True
OnClick = RadioButton14Click
end
object RadioButton15: TRadioButton
Left = 8
Top = 32

146
Width = 153
Height = 17
Caption = #1056#1072#1074#1085#1086#1084#1077#1088#1085#1099#1081' '#1096#1091#1084
TabOrder = 1
OnClick = RadioButton15Click
end
object RadioButton16: TRadioButton
Left = 8
Top = 48
Width = 193
Height = 17
Caption = #1043#1072#1091#1089#1089#1086#1074#1089#1082#1080#1081' '#1096#1091#1084
TabOrder = 2
OnClick = RadioButton16Click
end
object Chart2: TChart
Left = 8
Top = 104
Width = 625
Height = 153
BackWall.Brush.Color = clWhite
BackWall.Brush.Style = bsClear
Title.Text.Strings = (
#1056#1072#1089#1087#1088#1077#1076#1077#1083#1077#1085#1080#1077' '#1096#1091#1084#1072' ('#1087#1088#1080#1084#1077#1088'). '#1065#1077#1083#1082#1085#1080#1090#1077',
'#1095#1090#1086#1073#1099' '#1074#1082#1083#1102#1095#1080#1090#1100' '#1075#1088#1072#1092#1080#1082'.')
DepthAxis.Labels = False
LeftAxis.Labels = False
Legend.Visible = False
RightAxis.Visible = False
TopAxis.Visible = False
View3D = False
TabOrder = 3
OnClick = Chart2Click
object Series3: TLineSeries
Marks.ArrowLength = 8
Marks.Visible = False
SeriesColor = clRed
Pointer.InflateMargins = True
Pointer.Style = psRectangle
Pointer.Visible = False
XValues.DateTime = False
XValues.Name = 'X'
XValues.Multiplier = 1.000000000000000000
XValues.Order = loAscending
YValues.DateTime = False
YValues.Name = 'Y'
YValues.Multiplier = 1.000000000000000000
YValues.Order = loNone
end
end

147
object SpinEdit3: TSpinEdit
Left = 240
Top = 66
Width = 121
Height = 22
Enabled = False
MaxValue = 1000000
MinValue = 1
TabOrder = 4
Value = 1000
end
object SpinEdit4: TSpinEdit
Left = 448
Top = 64
Width = 57
Height = 22
Enabled = False
MaxValue = 254
MinValue = -254
TabOrder = 5
Value = 0
OnChange = SpinEdit4Change
end
object SpinEdit5: TSpinEdit
Left = 584
Top = 64
Width = 49
Height = 22
Enabled = False
MaxValue = 510
MinValue = 1
TabOrder = 6
Value = 510
OnChange = SpinEdit5Change
end
end
end
object ImageTabSheet: TTabSheet
Caption = #1048#1079#1086#1073#1088#1072#1078#1077#1085#1080#1103
ImageIndex = 1
object Image2: TImage
Left = 0
Top = 16
Width = 153
Height = 153
AutoSize = True
Visible = False
OnClick = Image2Click
end
object Image3: TImage

148
Left = 0
Top = 16
Width = 105
Height = 105
OnClick = Image3Click
end
object Image4: TImage
Left = 0
Top = 16
Width = 65
Height = 65
AutoSize = True
OnClick = Image4Click
end
object RadioButton21: TRadioButton
Left = 0
Top = 0
Width = 185
Height = 17
Caption = #1048#1089#1093#1086#1076#1085#1086#1077' '#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077
Checked = True
TabOrder = 0
TabStop = True
OnClick = RadioButton21Click
end
object RadioButton22: TRadioButton
Left = 176
Top = 0
Width = 233
Height = 17
Caption = #1048#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077' '#1087#1086#1089#1083#1077' '#1087#1088#1077#1086#1073#1088#1072#1079#1086#1074#1072#1085#1080#1103
TabOrder = 1
OnClick = RadioButton22Click
end
object RadioButton23: TRadioButton
Left = 408
Top = 0
Width = 241
Height = 17
Caption = #1062#1074#1077#1090#1086#1088#1072#1079#1085#1086#1089#1090#1085#1086#1077' '#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077
TabOrder = 2
OnClick = RadioButton23Click
end
end
object StatTabSheet: TTabSheet
Caption = #1057#1090#1072#1090#1080#1089#1090#1080#1082#1072
ImageIndex = 2
object GroupBox6: TGroupBox
Left = 0
Top = 0

149
Width = 569
Height = 89
Caption = #1042#1099#1073#1086#1088' '#1089#1090#1072#1090#1080#1089#1090#1080#1095#1077#1089#1082#1086#1075#1086' '#1075#1088#1072#1092#1080#1082#1072
TabOrder = 0
object RadioButton25: TRadioButton
Left = 192
Top = 48
Width = 217
Height = 17
Caption = #1048#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077' '#1087#1086#1089#1083#1077' '#1087#1088#1077#1086#1073#1088#1072#1079#1086#1074#1072#1085#1080#1103
TabOrder = 0
OnClick = RadioButton25Click
end
object RadioButton24: TRadioButton
Left = 8
Top = 48
Width = 185
Height = 17
Caption = #1048#1089#1093#1086#1076#1085#1086#1077' '#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077
TabOrder = 1
OnClick = RadioButton24Click
end
object ComboBox2: TComboBox
Left = 8
Top = 16
Width = 553
Height = 21
ItemHeight = 13
TabOrder = 2
OnChange = ComboBox2Change
end
end
object GroupBox7: TGroupBox
Left = 816
Top = 0
Width = 481
Height = 89
Caption = #1057#1090#1072#1090#1080#1089#1090#1080#1082#1072' '#1087#1086#1090#1086#1082#1072' '#1076#1072#1085#1085#1099#1093
TabOrder = 1
object Label14: TLabel
Left = 8
Top = 16
Width = 120
Height = 13
Caption = #1048#1089#1093#1086#1076#1085#1086#1077' '#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077
end
object Label15: TLabel
Left = 24
Top = 32
Width = 113

150
Height = 13
Caption = #1056#1072#1079#1084#1077#1088' '#1086#1076#1085#1086#1075#1086' '#1082#1072#1076#1088#1072':'
end
object Label16: TLabel
Left = 240
Top = 32
Width = 160
Height = 13
Caption = #1055#1086#1090#1086#1082' '#1087#1088#1080' 30 '#1082#1072#1076#1088#1072#1093' '#1074' '#1089#1077#1082#1091#1085#1076#1091':'
end
object Label17: TLabel
Left = 8
Top = 48
Width = 126
Height = 13
Caption = #1050#1086#1076#1086#1074#1086#1077' '#1087#1088#1077#1076#1089#1090#1072#1074#1083#1077#1085#1080#1077':'
end
object Label18: TLabel
Left = 24
Top = 64
Width = 113
Height = 13
Caption = #1056#1072#1079#1084#1077#1088' '#1086#1076#1085#1086#1075#1086' '#1082#1072#1076#1088#1072':'
end
object Label19: TLabel
Left = 240
Top = 64
Width = 160
Height = 13
Caption = #1055#1086#1090#1086#1082' '#1087#1088#1080' 30 '#1082#1072#1076#1088#1072#1093' '#1074' '#1089#1077#1082#1091#1085#1076#1091':'
end
object Label20: TLabel
Left = 144
Top = 32
Width = 3
Height = 13
end
object Label21: TLabel
Left = 408
Top = 32
Width = 3
Height = 13
end
object Label22: TLabel
Left = 144
Top = 64
Width = 3
Height = 13
end
object Label23: TLabel

151
Left = 408
Top = 64
Width = 3
Height = 13
end
end
object GroupBox8: TGroupBox
Left = 576
Top = 0
Width = 233
Height = 89
Caption = #1057#1090#1072#1090#1080#1089#1090#1080#1082#1072' '#1080#1089#1082#1072#1078#1077#1085#1080#1081
TabOrder = 2
object Label24: TLabel
Left = 8
Top = 16
Width = 179
Height = 13
Caption = #1055#1088#1086#1094#1077#1085#1090' '#1087#1080#1082#1089#1077#1083#1086#1074' '#1089' '#1080#1089#1082#1072#1078#1077#1085#1080#1103#1084#1080':'
end
object Label26: TLabel
Left = 8
Top = 48
Width = 156
Height = 13
Caption = #1055#1088#1086#1094#1077#1085#1090' '#1094#1074#1077#1090#1086#1074#1099#1093' '#1080#1089#1082#1072#1078#1077#1085#1080#1081':'
end
object Label25: TLabel
Left = 192
Top = 16
Width = 3
Height = 13
end
object Label27: TLabel
Left = 192
Top = 48
Width = 3
Height = 13
end
end
object Chart3: TChart
Left = 0
Top = 96
Width = 1297
Height = 633
BackWall.Brush.Color = clWhite
BackWall.Brush.Style = bsClear
Title.Text.Strings = (
#1057#1090#1072#1090#1080#1089#1090#1080#1082#1072)
Legend.Visible = False

152
View3D = False
TabOrder = 3
object Series4: TLineSeries
Marks.ArrowLength = 8
Marks.Visible = False
SeriesColor = clRed
Pointer.InflateMargins = True
Pointer.Style = psRectangle
Pointer.Visible = False
XValues.DateTime = False
XValues.Name = 'X'
XValues.Multiplier = 1.000000000000000000
XValues.Order = loAscending
YValues.DateTime = False
YValues.Name = 'Y'
YValues.Multiplier = 1.000000000000000000
YValues.Order = loNone
end
end
end
end
object OpenDialog1: TOpenDialog
Filter = 'bmp pictures|*.bmp'
Left = 604
Top = 72
end
object XPManifest1: TXPManifest
Left = 636
Top = 72
end
object OpenDialog2: TOpenDialog
Filter = 'AVI movies|*.avi|All Files|*.*'
Left = 564
Top = 72
end
object FilterGraph: TFilterGraph
GraphEdit = True
LinearVolume = True
Left = 532
Top = 72
end
object ImageList1: TImageList
Left = 636
Top = 104
Bitmap = {
494C010104000900040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
0000000000003600000028000000400000003000000001002000000000000030
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

153
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

154
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

155
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

156
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

157
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

158
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000080808000000000000000

159
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000080808000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

160
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000080808000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000080808000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000424D3E000000000000003E000000
2800000040000000300000000100010000000000800100000000000000000000
000000000000000000000000FFFFFF0000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF
FFFFFFFFFFFFF00FF1C7F3FFE003F81FF1C7F1FFE003FC3FF1C7F0FFE0038001
F1C7F07FE0038001F1C7F03FE0039FF9F1C7F01FE0039FF9F1C7F01FE0039FF9
F1C7F03FE0039FF9F1C7F07FE0039FF9F1C7F0FFE0039FF9F1C7F1FFE0038001
FFFFF3FFFFFF8001FFFFFFFFFFFFFFFF00000000000000000000000000000000
000000000000}
end
end

161
П3.4. Unit2.pas
unit Unit2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;

type
TForm2 = class(TForm)
Image1: TImage;
procedure Image1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Image1Click(Sender: TObject);


begin
Form2.Hide;
end;

end.

162
П3.5. Unit2.dfm
object Form2: TForm2
Left = 760
Top = 100
Align = alLeft
AutoSize = True
BorderStyle = bsNone
ClientHeight = 105
ClientWidth = 121
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Image1: TImage
Left = 0
Top = 0
Width = 121
Height = 105
Stretch = True
OnClick = Image1Click
end
end

163
Приложение 4. Результаты функционального
тестирования.
П4.1. ДИКМ.

Рис. П4.1а. Изображение шахматной доски до ДИКМ-кодирования.

Рис. П4.1б. Изображение шахматной доски после ДИКМ-кодирования с линейным


квантователем с равномерным распределением

164
Рис. П4.2. Изображение шахматной доски после ДИКМ-кодирования с адаптивным
квантователем, методом равномерного заполнения центрального максимума

Рис. П4.3. Изображение шахматной доски после ДИКМ-кодирования с адаптивным


квантователем, методом максимумов или значимости

165
Рис. П4.4. Изображение шахматной доски после ДИКМ-кодирования с линейным
квантователем, методом отсечки или с равными малыми интервалами.

166
Рис. П4.5а. Реальная цветная фотография после ДИКМ-кодирования с линейным
квантователем с равномерным распределением

Рис. П4.5б. Реальная цветная фотография после ДИКМ-кодирования с адаптивным


квантователем, методом равномерного заполнения центрального максимума

167
Рис. П4.6. Реальная цветная фотография после ДИКМ-кодирования с включенным
шумом.

168
П4.2. Преобразование Адамара

Рис. П4.7. Реальная фотография до кодирования методом преобразования Адамара

Рис. П4.8. Реальная фотография после кодирования методом преобразования Адамара

169
Рис. П4.8. Реальная фотография после кодирования методом преобразования Адамара с
зональным отбором

Рис. П4.8. Реальная фотография после кодирования методом преобразования Адамара с


пороговым отбором

170
Рис. П4.10а. Изображение с текстом до преобразования Адамара

Рис. П4.10а. Изображение с текстом после преобразования Адамара

171
Рис. П4.11. Реальная фотография после кодирования методом преобразования Адамара с
шумом и без устранения избыточности

172
П4.3. MPEG-кодирование

Рис. П4.12а. Фрагмент видеоизображения до сжатия при помощи MPEG.

Рис. П4.12б. Фрагмент видеоизображения после сжатия при помощи MPEG.

173
Приложение 5. Слайды

Разработка имитационной
модели для исследования
алгоритмов цифрового сжатия
изображений

174
Дискретизация изображения
Дискретизация:

Теорема Котельникова:

175
Дифференциальная импульсно-
кодовая модуляция
Линейный интерполятор 0го порядка

Специфические искажения ДИКМ

176
Преобразование Адамара
Преобразование: Базисные изображения: Сохраняемые зоны:
s(1,1), s (1,2), ..., s(1, n)
s(2,1) s (2,2) ..., s (2, n)
s 
... ... ... ...
s(n,1) s( n,2) ... s (n, n)

c(1,1), c(1,2), ..., c(1, n)


c(2,1) c(2,2) ..., c(2, n)
c 
... ... ... ...
c(n,1) c(n,2) ... c(n, n)

n n
c(k , l )   a klij s (i, j )
i 1 j 1

177
Стандарт цифрового сжатия
MPEG-2
Формирование транс-
портного потока:

Кодирование видео:

Группа изображений
при кодировании видео:

178
Программные модули
Структура имитационной модели:

Система
Источник данных Кодер Канал передачи Декодер
отображения
2 3 4 5 6

Данные изображения
Система
АРМ управления статистического
Команды управления анализа
1 7

179
Программные модули
АРМ управления: Источник данных: Канал передачи:
Начало
Начало
Начало

Начать работу
модели? Получить параметры загружаемого
изображения от АРМ управления
Получить закодированное сообщение от
Да кодера и параметры шума от АРМ
управления
Выбор исходного изображения и передача
параметров источнику данных
Загрузить изображение

Внести в данные изображения шум с


Выбор алгоритма кодирования и его заданными параметрами
параметров, передача параметров кодеру Вывести
Загрузка прошла
Нет сообщение
штатно?
об ошибке

Да
Выбор уровня искажений в канале, Конец
передача параметров каналу
Конец

Получение результатов от системы


отображения, вывод их на экран
Кодер: Декодер:
Нет

Отобразить Нет
статистическую
информацию?

Да

Выбор параметров отображения


статистических данных, передача
параметров системе статистического
анализа

Нет

Получение результатов от системы


статистического анализа, вывод их на Нет
экран

Завершить
работу со
статистикой?

Да

Выход?

Да

Выход

180
Программные модули
Система отображения: Система статистического анализа:

Начало

Получить декодированное сообщение от


декодера

Преобразовать его к виду,


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

Передать результаты преобразования на


АРМ управления

Конец

181
Работа с ДИКМ
Кодер: Декодер: Статистика:

182
Работа с преобразованием
Адамара
Кодер: Декодер: Статистика:

183
Модули статистики
Генератор шумовых искажений: Разностное изображение:

184
Работа с MPEG

185
Интерфейс программы

186
Дифференциальная импульсно-
кодовая модуляция

187
Дифференциальная импульсно-
кодовая модуляция

188
Дифференциальная импульсно-
кодовая модуляция

189
Разностное изображение

190
Преобразование Адамара

191
Преобразование Адамара

192
Преобразование Адамара

193
Стандарт цифрового сжатия
MPEG-2

194
Стандарт цифрового сжатия
MPEG-2

195
Результаты эксперимента: ДИКМ
Зависимость доли искажений от типа используемого квантователя:
Линейный квантователь Адаптивный квантователь

120

100
Пикселей с искажениями, %

80

60

40

20

0
2 4 6 8
Бит на разностный отсчет

196
Результаты эксперимента:
преобразование Адамара
Зависимость процента искажений от поро- Зависимость процента искажений от числа пере-
гового значения трансформанта при устра- данных трансформант при позиционном методе
нении избыточности пороговым методом: устранения избыточности для фрагментов 4х4:
4x4 8x8 25

70

60 20

пикселей с искажениями, %
пикселей с искажениями, %

50
15

40

30 10

20

5
10

0 0
0 5 10 20 30 40 50 3 4 6 8
пороговое значение число переданных трансформант

Зависимость процента искажений от числа пере- Зависимость доли пикселей с искажениями от


данных трансформант при позиционном методе размера кадра при различных методах устра-
устранения избыточности для фрагментов 8х8: нения избыточности
40 8х8 позиционный метод 4х4 позиционный метод 4х4 пороговый метод 8х8 пороговый метод

70
35

60
30
пикселей с искажениями, %

Пикселов с искажениями, %

50
25

40
20

30
15

20
10

10
5

0
0
18 20 22 27 43 70 74 75 80 82 95 129 148 192 222 271 296 346 395 469 593 791
3 6 9 11 14 16 19
число переданных трансформант Размер кадра, кБ

197
Результаты эксперимента: MPEG
Зависимость среднего размера кадра Зависимость среднего размера кадра видео-
видеоизображения от размера группы изображения от числа B-кадров между
изображений при MPEG-2 кодировании: P-кадрами при MPEG-2 кодировании:

100 120

100
95

Средний размер кадра


80
Средний размер кадра

90

60

85

40

80
20

75 0
15 25 50 75 100 150 300 0 1 2 3 4 5 6 7 8 9 10
Размер группы изображений Число B-кадров

198
Экономическое обоснование
НИР
Структура трудоемкости этапов работ: Директивный график работ:
№ этапа
7
6
5
4
3
2
1 Календарные
дни
5 10 15 20 25 30 35 40 45

Цена на НТПР: Ц НТПр


п
 421956,1 руб
Годовой экономический эффект: ЭНТПр  1206717,76 руб
Уровень эффективности затрат на создание новой системы: E  2,86

199
Охрана труда
• Расчет вентиляции помещения: AOЛ-
22-2
• Расчет кондиционирования: КТЦ2-200.
• Требования по шуму и вибрации.
• Противопожарные мероприятия.

200
Разработка имитационной
модели для исследования
алгоритмов цифрового сжатия
изображений

201