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

81



Федеральное агентство по образованию

Государственное образовательное учреждение

высшего профессионального образования

«ИЖЕВСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»

Факультет «Информатика и вычислительная техника»

Кафедра «Программное обеспечение»





ПОЯСНИТЕЛЬНАЯ ЗАПИСКА

к дипломной работе на тему:

«Система автоматизированного анализа пространственной структуры изображений. Подсистема линейной сегментации»









Дипломник

студент группы 10-19-2

Ю.Н. Данилов

Руководитель

ведущий инженер кафедры

«Программное обеспечение»



Л.Н. Левицкая

Консультант по экономической части

к.э.н., доцент

И.И. Радыгина

Консультант по безопасности и экологичности

к.б.н., доцент

Г.Ф. Якименко

Нормоконтроль

В.П. Соболева

Рецензент

ведущий инженер АО «Аксион»

В.Н. Захаров

	Заведующий кафедрой

	«Программное обеспечение» 

	д.т.н., профессор

А.И. Мурынов



Ижевск 2006


РЕФЕРАТ



Пояснительная записка к дипломной работе на тему «Система автоматизированного анализа пространственной структуры изображений. Подсистема линейной сегментации» оформлена на 119 листах, содержит 34 рисунка, 10 таблиц.

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

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

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

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

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

Система реализована для персональных электронно-вычислительных машин, работающих под управлением Microsoft Windows 98/Me/2000/XP/NT и выше, не требует установки дополнительных инструментов и не требовательна к системным ресурсам.


СОДЕРЖАНИЕ

ВВЕДЕНИЕ	7

1. РАЗРАБОТКА «ПОДСИСТЕМЫ ЛИНЕЙНОЙ СЕГМЕНТАЦИИ» В СОСТАВЕ «СИСТЕМЫ АВТОМАТИЗИРОВАННОГО АНАЛИЗА ПРОСТРАНСТВЕННОЙ СТРУКТУРЫ ИЗОБРАЖЕНИЙ»	9

1.1. Обоснование целесообразности разработки системы	9

1.1.1. Назначение системы	9

1.1.2. Обоснование цели создания системы	10

1.1.3. Назначение «Подсистемы линейной сегментации»	11

1.1.4. Характеристика организационной и функциональной структуры	11

1.1.5. Обоснование состава автоматизируемых задач	11

1.1.6. Обоснование применения типовых и оригинальных решений	12

1.1.7. Общая оценка экономической целесообразности создания подсистемы	13

1.2. Основные требования к «Подсистеме линейной сегментации»	13

1.2.1. Основные цели создания подсистемы	13

1.2.2. Функциональное назначение подсистемы	14

1.2.3. Требования к функциональной структуре подсистемы	14

1.2.4. Требования к техническому обеспечению	15

1.2.5. Требования к информационному обеспечению	15

1.2.6. Требования к программному обеспечению	16

1.3. Основные технические решения проекта подсистемы «Линейная сегментация»	16

1.3.1. Решения по комплексу технических средств	16

1.3.2. Описание организации информационной базы	17

2. РАЗРАБОТКА ЗАДАЧИ «ПОИСК УЗЛОВ»	19

2.1. Описание постановки задачи	19

2.1.1. Характеристика задачи	19

2.1.2. Входная информация	19

2.1.3. Выходная информация	19

2.1.4. Математическая постановка задачи	20

2.1.5. Специальные требования к техническому обеспечению	23

2.2. Описание алгоритма «Поиск узлов»	23

2.2.1. Назначение и характеристика	23

2.2.2. Используемая информация	24

2.2.3. Результаты решения	24

2.2.4. Алгоритм решения	24

2.2.6. Условные обозначения	25

2.3. Описание программы «Поиск узлов»	26

2.3.1. Вводная часть	26

2.3.2. Функциональное назначение	26

2.3.3. Описание информации	27

2.3.4. Используемые подпрограммы	27

2.3.5. Описание логики	27

2.3.6. Настройка программных средств	28

3. РАЗРАБОТКА ЗАДАЧИ «ПОИСК СЕГМЕНТОВ»	30

3.1. Описание постановки задачи	30

3.1.1. Характеристика задачи	30

3.1.2. Входная информация	31

3.1.3. Выходная информация	31

3.1.4. Математическая постановка задачи	31

3.1.5. Специальные требования к техническому обеспечению	34

3.2. Описание алгоритма «Поиск сегментов»	34

3.2.1. Назначение и характеристика	34

3.2.2. Используемая информация	35

3.2.3. Результаты решения	35

3.2.4. Алгоритм решения	35

3.2.5. Требования к контрольному примеру	36

3.2.6. Условные обозначения	36

3.3. Описание программы «Поиск сегментов»	37

3.3.1. Вводная часть	37

3.3.2. Функционально назначение	37

3.3.3. Описание информации	37

3.3.4. Используемые подпрограммы	38

3.3.5. Описание логики	38

3.3.6. Настройка программных средств	38

4. РАЗРАБОТКА ЗАДАЧИ «ОБРАБОТКА И КОДИРОВАНИЕ СЕГМЕНТОВ»	40

4.1. Описание постановки задачи	40

4.1.1. Характеристика задачи	40

4.1.2. Входная информация	40

4.1.3. Выходная информация	40

4.1.4. Математическая постановка задачи	41

4.1.5. Специальные требования к техническому обеспечению	42

4.2. Описание алгоритма «Обработка и кодирование сегментов»	42

4.2.1. Назначение и характеристика	42

4.2.2. Используемая информация	42

4.2.3. Результаты решения	43

4.2.4. Алгоритм решения	43

4.2.5. Требования к контрольному примеру	44

4.2.6. Список условных обозначений	44

4.3. Описание программы «Обработка и кодирование сегментов»	45

4.3.1. Вводная часть	45

4.3.2. Функциональное назначение	45

4.3.3. Описание информации	45

4.3.4. Используемые подпрограммы	46

4.3.5. Описание логики	47

4.3.6. Настройка программных средств	48

4.4. Описание контрольного примера	48

4.4.1. Назначение	48

4.4.2. Исходные данные	49

4.4.3. Результаты расчета	51

4.4.4. Результаты испытания программы	54

5. ОРГАНИЗАЦИОННО-ЭКОНОМИЧЕСКАЯ ЧАСТЬ	56

5.1. Расчет затрат на разработку «Подсистемы линейной сегментации»	56

6. ЭКОЛОГИЧНОСТЬ И БЕЗОПАСНОСТЬ ПРОЕКТА	61

6.1. Актуальность безопасности труда	61

6.2. Анализ опасных и вредных производственных факторов	62

6.3. Техника безопасности при работе с компьютером	64

6.4. Организация рабочего места оператора	68

6.5. Расчет защитного заземления	69

6.6. Требования к параметрам микроклимата	73

6.7. Пожаробезопасность	73

6.8. Выводы	74

ЗАКЛЮЧЕНИЕ	75

СПИСОК ЛИТЕРАТУРЫ	77

ПРИЛОЖЕНИЕ 1 РУКОВОДСТВО ПРОГРАММИСТА	79

ПРИЛОЖЕНИЕ 2 РУКОВОДСТВО ОПЕРАТОРА	85

ПРИЛОЖЕНИЕ 3 ТЕКСТ ПРОГРАММЫ	96

	
ВВЕДЕНИЕ



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

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

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


1. РАЗРАБОТКА «ПОДСИСТЕМЫ ЛИНЕЙНОЙ СЕГМЕНТАЦИИ» В СОСТАВЕ «СИСТЕМЫ АВТОМАТИЗИРОВАННОГО АНАЛИЗА ПРОСТРАНСТВЕННОЙ СТРУКТУРЫ ИЗОБРАЖЕНИЙ»



1.1. Обоснование целесообразности разработки системы



1.1.1. Назначение системы

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


Структурная схема системы автоматизированного анализа

пространственной структуры изображений





Рис. 1.1



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

- подсистема центроидной релаксации, которая осуществляет выделение кривых, углов, окружностей, определение их геометрических характеристик;

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

- подсистема цепного кодирования, позволяющая в дифференциальном кодированном виде представить линии;

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



1.1.2. Обоснование цели создания системы

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

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

- значительное уменьшение объемов хранимой информации;

- увеличение скорости и качества синтеза изображений;

- аккумуляция информации с целью последующего использования.



1.1.3. Назначение «Подсистемы линейной сегментации»

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



1.1.4. Характеристика организационной и функциональной структуры

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


1.1.5. Обоснование состава автоматизируемых задач



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



Структурная схема подсистемы линейной сегментации



Рис. 1.2

1.1.6. Обоснование применения типовых и оригинальных решений



В качестве технического обеспечения рабочей станции используется IBM-совместимый персональный компьютер, оснащенный русифицированной клавиатурой, манипулятором типа «мышь», монитором, накопителями на жестком диске. Данный состав технических средств был выбран исходя из их доступности и достаточно высокой надежности при оптимальных ценах. В качестве целевой операционной системы выбрана платформа Windows 2000/XP, являющаяся на данный момент наиболее широко распространенной платформой общего назначения. Средством разработки выбрана система C++ Builder 6 фирмы Borland. Выбор этого языка обусловлен наличием развитой среды программирования и отладки, его высокой эффективностью создания рабочих приложений, и легкостью создания пользовательского интерфейса приложения. 



1.1.7. Общая оценка экономической целесообразности создания подсистемы

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

	Создание системы позволит изменить такие показатели, как:

	- объем хранимой информации;

	- скорость передачи информации;

	- скорость синтеза изображений;

	- объем знаний о графических изображениях;

	- актуальность получения графической информации;

	- возможность использования больших объемов графических данных в системах реального времени.



1.2. Основные требования к «Подсистеме линейной сегментации»



1.2.1. Основные цели создания подсистемы

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



1.2.2. Функциональное назначение подсистемы

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

- получение изображения из различных источников;

- первичная обработка изображения при необходимости;

- поиск узловых элементов изображения;

- поиск линейных сегментов;

- поиск принадлежности точек изображения узлам и сегментам линий;

- вывод координат распознанных сегментов линий;

- определение направлений кодирования сегментов.



1.2.3. Требования к функциональной структуре подсистемы

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



1.2.4. Требования к техническому обеспечению

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

- персональный компьютер IBM PC с процессором не ниже Pentium I;

- клавиатура;

- монитор;

- жесткий диск с объемом свободного пространства не менее 50 МБ;

- оперативная память объемом не менее 128 МБ.

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

- сохранение работоспособности подсистемы при неправильной работе других подсистем;

- дублирование информации;

- проверка вводимых данных на корректность.



1.2.5. Требования к информационному обеспечению

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

			характеристики обрабатываемого изображения;

			взаимные связи всех характеристик в процессе решения;

			процедуры обработки описаний структурных элементов;

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

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

Следовательно, должны обеспечиваться:

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

			 формализация процедур для машинной обработки данных;

			 установка четкой последовательности обработки данных;

			 правильное использование накопленной информации.

1.2.6. Требования к программному обеспечению

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

- программы, реализующие задачи подсистемы, должны функционировать в среде операционной системы Microsoft Windows 98/Me/2000/XP/NT или выше;

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

- система должна быть способна функционировать с использованием только средств операционной системы.



1.3. Основные технические решения проекта подсистемы «Линейная сегментация»



1.3.1. Решения по комплексу технических средств

Комплекс технических средств подсистемы «Линейной сегментации» должен являться составной частью системы автоматизированного анализа пространственной структуры графических изображений и обеспечивать реализацию всех автоматизированных функций подсистемы (см. п. 1.2.2). Технические средства базируются на средствах обработки данных, на персональных ЭВМ и могут быть дополнены средствами ввода изображений (сканеры, планшеты рукописного ввода, цифровые фотокамеры) и вывода изображений (принтеры, плоттеры, графопостроители). 

Планируемый комплекс технических средств для функционирования задач реализующих подсистему «Линейная сегментация» включает следующие технические средства:

				 персональный компьютер IBM PC с процессором не ниже Pentium I;

				 клавиатура;

				 монитор; 

				 жесткий диск с объемом свободного пространства не менее 50 МБ;

				 оперативная память объемом не менее 128 МБ.



1.3.2. Описание организации информационной базы

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

Формат входного массива точек

<M >

<N>

a11,a12,…,a1m

a21,a22,…,a2m

an1,an2,…,anm

где <M > - строка, содержащая число точек изображения по горизонтали;

<N > - строка, содержащая число точек изображения по вертикали;

aij – элемент массива точек, соответствующий точке изображения с координатами (i,j), может принимать значения «1» и «0».

Пример входных данных:

8

8

00000000

01000000

00100000

00010000

11111111

00000100

00000010

00000000



Соответствующее данному массиву изображение показано на рис. 1.3.

Соответствующее изображение 8х8





Рис. 1.3



Формат описания сегментов линий:

n1:x11,y11 [,x12,y12 [,x13,y13]]

n2:x21,y21 [,x22,y22 [,x23,y23]]

nk:xk1,yk1 [,xk2,yk2 [,xk3,yk3]]

где ni – номер i-го сегмента линии (идентификатор);

xi1,yi1 – координаты первой точки i-го сегмента линии;

xi2,yi2 – координаты второй точки i-го сегмента линии, указываются в том случае, если точка (xi2,yi2) является узлом;

xi3,yi3 – координаты направления кодирования от точки (xi1,yi1), указываются в том случае, если точки (xi1,yi1) и (xi2,yi2) являются узлами.


2. РАЗРАБОТКА ЗАДАЧИ «ПОИСК УЗЛОВ»



2.1. Описание постановки задачи



2.1.1. Характеристика задачи

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

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



2.1.2. Входная информация

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



2.1.3. Выходная информация

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



2.1.4. Математическая постановка задачи

Изначально все изображение представлено в виде массива точек, каждый элемент которого может принимать значение 1 или 0, где 1 соответствует наличию точки, а 0 – ее отсутствию. Таким образом, структурные элементы изображения представлены в виде наборов точек, имеющих значение 1.

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

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

- если значение равно нулю, то это означает, что данному элементу не соответствует ни один из узлов и, следовательно, соответствующая точка в массиве точек не является узлом;

- если значение больше нуля, то оно представляет собой номер узла, которому соответствует данная точка.

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


Линия единичной толщины





Рис. 2.1



Линию еднинчной толщины можно представить следующим образом: 

	  (2.1)

где N – количество точек в линии;

xt, yt – координаты рассматриваемой точки at;

K(xt, yt) – количество точек, соседних с at.

Функцию вычисления количества соседних точек можно представить следующим образом:

	(2.2)

где A – двумерный массив точек, представляющих исходное изображение;

xt, yt – координаты рассматриваемой точки at;

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





Рис. 2.2



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

Это можно представить в виде формул:

	  (2.3)

где (x,y) – координаты рассматриваемой точки;

M и N – ширина и высота изображения;

B – массив узлов, размерность MxN;

n – номер обрабатываемого узла.

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

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

Пример пересечения линий





Рис. 2.3



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

Точки вокруг узла





Рис. 2.4



2.1.5. Специальные требования к техническому обеспечению

Требования к техническому обеспечению для решения задачи «Поиск узлов» полностью совпадают с требованиями к комплексу технических средств, предъявленными при разработке подсистемы «Линейная сегментация» (см. п. 1.3.1).

Реализация задачи возможна при наличии набора следующих технических средств:

				персональный компьютер IBM PC с процессором не ниже Pentium I;

				 клавиатура;

				 монитор; 

				 жесткий диск с объемом свободного пространства не менее 50 МБ;

				 оперативная память объемом не менее 128 МБ.

Работа программы возможна только на ЭВМ, которые поддерживают 32-разрядные операционные системы семейства Windows, такие как Windows 95,  Windows NT или выше. Как указано выше, работа может вестись на ЭВМ с процессором не ниже Intel Pentium. Но желательно использовать ЭВМ с процессором не ниже класса Intel Pentium II, который работает более эффективно.


2.2. Описание алгоритма «Поиск узлов»



2.2.1. Назначение и характеристика

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



2.2.2. Используемая информация

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



2.2.3. Результаты решения

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



2.2.4. Алгоритм решения

Алгоритм решения составлен с учетом математического описания, приведенного в пункте 2.1.4. Алгоритм представляется в текстовом виде следующим образом:

Начало;

Инициализация массива узлов;

i=0; j=0; z=0;

Если j>=N, то переход к п.11;

Если i>=M, то переход к п.10;

Если (apix[i][j]=1)и(apix2[i][j]<0)и(NeigCount(i,j)>2), то переход к п.7, иначе к п.9;

z=z+1;

NodeSelect(i,j,z);

i=i+1; переход к п.5;

i=0; j=j+1; переход к п.4;

Конец.

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



2.2.6. Условные обозначения

В таблице 2.1 представлены условные обозначения, введенные в тексте подраздела

	Таблица 2.1

Условные обозначения

Условные обозначения

Расшифровка

M

ширина входного изображения

N

высота входного изображения

apix[M][N]

исходный массив точек

apix2[M][N]

массив узлов

NeigCount

функция вычисления количества соседних точек

NodeSelect(x,y,n)

рекурсивная функция выделения узловых точек, x,y – координаты начала выделения, n – номер узла

Z

номер текущего узла




2.3. Описание программы «Поиск узлов»



2.3.1. Вводная часть

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



2.3.2. Функциональное назначение

Программа «Поиск узлов» предназначена выделения в составе обрабатываемого изображения элементов, представляющих собой области пересечения линий, называемые узлами. Программа работает с массивом точек, представляющих исходное изображение. В процессе ее выполнения происходит обход данного массива точек, с одновременным заполнением массива элементов узлов, расчетом координат узлов и подсчетом их количества. При этом в массиве узлов производится нумерация элементов, тем самым позволяя определять, какому из узлов принадлежит та или иная точка. Значения, полученные при поиске узлов, используются в дальнейшем при выполнении поиска сегментов линий, а также при кодировании линий и получении координат сегментов при генерации описания графического изображения. Программа рассчитана на работу в операционных системах семейства Windows, таких как Windows 9x, Windows NT или выше. Поэтому требования программы к памяти зависят от операционной системы. В этих операционных системах при выделении памяти используется файл подкачки Windows, в котором можно адресовать до 2 Гбайт виртуальной памяти. Но при обращении к диску скорость работы падает. Для Windows 95 оптимальный объем оперативной памяти 32 Мбайт, для Windows NT - 64 Мбайт. На винчестере программе достаточно иметь 100 Мбайт дискового пространства. 



2.3.3. Описание информации

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



2.3.4. Используемые подпрограммы

В процессе работы программа обращается к следующим подпрограммам:

- wlog – подпрограмма вывода сообщений в журнал вычислений;

- NeigCount – подпрограмма получения количества соседних точек;

- NeigNode – подпрограмма рекурсивной обработки узловых точек;

- NodeCentre – подпрограмма вычисления центра узла;

- DrawGrid – подпрограмма вывода сетки изображения.



2.3.5. Описание логики

Схема программы AnalyzeNode представлена на рис. 2.5. Здесь представлено текстовое описание схемы проргаммы:

Начало;

Инициализация массива узлов;

i=0; j=0; z=0;

Если j>=N, то переход к п.11;

Если i>=M, то переход к п.10;

Если (apix[i][j]=1)и(apix2[i][j]<0)и(NeigCount(i,j)>2), то переход к п.7, иначе к п.9;

z=z+1;

NodeSelect(i,j,z);

i=i+1; переход к п.5;

i=0; j=j+1; переход к п.4;

Конец.



2.3.6. Настройка программных средств

Для работы программы необходимо наличие операционной системы Windows 95/Windows NT или более поздней версии. Для работы программы с данными, размещенными в сети, необходима настройка сетевых подключений операционной системы к рабочей группе.

Схема программы AnalyzeNode Рис. 2.5


3. РАЗРАБОТКА ЗАДАЧИ «ПОИСК СЕГМЕНТОВ»



3.1. Описание постановки задачи



3.1.1. Характеристика задачи

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

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

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

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

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



	3.1.2. Входная информация

В качестве входной информации для данной задачи используются:

- массив точек исходного изображения;

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



3.1.3. Выходная информация

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



3.1.4. Математическая постановка задачи

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

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

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

- если значение равно нулю, то это означает, что данному элементу не соответствует ни одна из сегментов линий и, следовательно, соответствующая точка в массиве точек не является каким-либо сегментом линией;

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

Данные утверждения можно представить в виде формул:

	  (3.1)

где (x,y) – координаты рассматриваемой точки;

M и N – ширина и высота изображения;

C – массив сегментов, размерность MxN;

n – номер обрабатываемого сегмента.

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



Отдельные сегменты линий



Рис. 3.1



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

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

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

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

Сегмент линии, содержащий начальную и узловую точки





Рис. 3.2

Сегмент, определяемый двумя узловыми точками



Рис. 3.3



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



3.1.5. Специальные требования к техническому обеспечению

Требования к техническому обеспечению для решения задачи «Поиск узлов» полностью совпадают с требованиями к комплексу технических средств, предъявленными при разработке подсистемы «Линейная сегментация» (см. п. 1.3.1).

Реализация задачи возможна при наличии набора следующих технических средств:

				персональный компьютер IBM PC с процессором не ниже Pentium I;

				 клавиатура;

				 монитор; 

				 жесткий диск с объемом свободного пространства не менее 50 МБ;

				 оперативная память объемом не менее 128 МБ.

Работа программы возможна только на ЭВМ, которые поддерживают 32-разрядные операционные системы семейства Windows, такие как Windows 95,  Windows NT или выше. Как указано выше, работа может вестись на ЭВМ с процессором не ниже Intel Pentium. Но желательно использовать ЭВМ с процессором не ниже класса Intel Pentium II, который работает более эффективно.



3.2. Описание алгоритма «Поиск сегментов»



3.2.1. Назначение и характеристика

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



3.2.2. Используемая информация

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

- массив точек исходного изображения;

- массив узлов.



3.2.3. Результаты решения

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



3.2.4. Алгоритм решения

Алгоритм решения составлен с учетом математического описания, приведенного в пункте 3.1.4. Алгоритм представляется в текстовом виде следующим образом:

Начало;

Инициализация массива сегментов;

i=0; j=0; nsegs =0;

Если j>=N, то переход к п.11;

Если i>=M, то переход к п.10;

Если (apix[i][j]=1)и(apix1[i][j]<0)и((NeigCount(i,j)=1)или(NeigCount(i,j)=2)), то переход к п.7, иначе к п.9;

nsegs = nsegs +1;

NeigLine(i,j, nsegs);

i=i+1; переход к п.5;

i=0; j=j+1; переход к п.4;

Конец.



3.2.5. Требования к контрольному примеру

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

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

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

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



3.2.6. Условные обозначения

В таблице 3.1 представлены условные обозначения, введенные в тексте подраздела

	Таблица 3.1

Условные обозначения



Условные обозначения

Расшифровка

M

ширина входного изображения

N

высота входного изображения

apix[M][N]

исходный массив точек

apix1[M][N]

массив сегментов

NeigCount

функция вычисления количества соседних точек

NeigLine(x,y,n)

рекурсивная функция выделения узловых точек, x,y – координаты начала выделения, n – номер узла

nsegs

номер текущего сегмента




3.3. Описание программы «Поиск сегментов»



3.3.1. Вводная часть

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



3.3.2. Функционально назначение

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



3.3.3. Описание информации

Программа AnalyzeSeg на входе использует следующие данные:

- массив точек;

- массив узлов;

На выходе программа формирует следующие данные:

- массив сегментов;


3.3.4. Используемые подпрограммы

В процессе работы программа обращается к следующим подпрограммам:

- wlog – подпрограмма вывода сообщений в журнал вычислений;

- NeigCount – подпрограмма получения количества соседних точек;

- NeigLine – подпрограмма рекурсивной обработки точек одного сегмента линии;

- DrawGrid – подпрограмма вывода сетки изображения.



3.3.5. Описание логики

Схема программы AnalyzeSeg представлена на рис. 3.4. Здесь представлено текстовое описание схема программы:

Начало;

Инициализация массива сегментов;

i=0; j=0; nsegs =0;

Если j>=N, то переход к п.11;

Если i>=M, то переход к п.10;

Если (apix[i][j]=1)и(apix1[i][j]<0)и((NeigCount(i,j)=1)или(NeigCount(i,j)=2)), то переход к п.7, иначе к п.9;

nsegs = nsegs +1;

NeigLine(i,j, nsegs);

i=i+1; переход к п.5;

i=0; j=j+1; переход к п.4;

Конец.



3.3.6. Настройка программных средств

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

Схема программы AnalyzeSeg

Рис. 3.4

4. РАЗРАБОТКА ЗАДАЧИ «ОБРАБОТКА И КОДИРОВАНИЕ СЕГМЕНТОВ»



4.1. Описание постановки задачи



4.1.1. Характеристика задачи

Задача «Обработка и кодирование сегментов» предназначена для формирования кода трех типов сегментов линий на основании найденных сегментов линий и узлов. В задаче обрабатываются следующие типы сегментов линий:

- сегменты линий, не содержащие узлов;

- сегменты линий, одна из крайних точек которых является узлом;

- сегменты линий, обе крайних точки которой являются узлами.

Кодирование каждого типа сегментов связано с определенными особенностями. Формирование результатов обработки различается по способу передачи их в другие подсистемы (например, цепного кодирования).



4.1.2. Входная информация

В качестве входной информации для данной задачи используются:

- массив точек исходного изображения;

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

- массив сегментов, содержащий описания сегментов линий: точки, принадлежащие линии, координаты их пересечения и присвоенные номера для однозначной идентификации.



4.1.3. Выходная информация

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

Формат описания сегментов линий:

n1:x11,y11 [,x12,y12 [,x13,y13]]

n2:x21,y21 [,x22,y22 [,x23,y23]]

nk:xk1,yk1 [,xk2,yk2 [,xk3,yk3]]

где ni – номер i-го сегмента линии (идентификатор);

xi1,yi1 – координаты первой точки i-го сегмента линии;

xi2,yi2 – координаты второй точки i-го сегмента линии, указываются в том случае, если точка (xi2,yi2) является узлом;

xi3,yi3 – координаты направления кодирования от точки (xi1,yi1), указываются в том случае, если точки (xi1,yi1) и (xi2,yi2) являются узлами.



4.1.4. Математическая постановка задачи

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

Сравнение массивов сегментов и узлов происходит по следующему правилу: если точке соответствует положительное значение в массиве сегментов и нулевое значение в массиве узлов, то данная точка принадлежит сегменту и не образует узлов. Если точке соответствует положительное значение в массиве сегментов и положительное значение в массиве узлов, то данная точка образует узел и. следовательно, принадлежит более чем одному сегменту.

При кодировании сегментов линий определяется тип сегмента и в соответствие этим типом на выходе будет от двух до шести координат, представляющих точки. Типы сегментов линий и их характеристики описаны в пункте 3.1.4.



4.1.5. Специальные требования к техническому обеспечению

Требования к техническому обеспечению для решения задачи «Кодирование сегментов» полностью совпадают с требованиями к комплексу технических средств, предъявленными при разработке подсистемы «Линейная сегментация» (см. п. 1.3.1).

Реализация задачи возможна при наличии набора следующих технических средств:

				персональный компьютер IBM PC с процессором не ниже Pentium I;

				 клавиатура;

				 монитор; 

				 жесткий диск с объемом свободного пространства не менее 50 МБ;

				 оперативная память объемом не менее 128 МБ.

Работа программы возможна только на ЭВМ, которые поддерживают 32-разрядные операционные системы семейства Windows, такие как Windows 95, Windows NT или выше. Как указано выше, работа может вестись на ЭВМ с процессором не ниже Intel Pentium. Но желательно использовать ЭВМ с процессором не ниже класса Intel Pentium II, который работает более эффективно.

4.2. Описание алгоритма «Обработка и кодирование сегментов»



4.2.1. Назначение и характеристика

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



4.2.2. Используемая информация

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

- значения массива точек исходного графического изображения;

- значения массива сегментов, содержащего описания принадлежности точки тому или иному сегменту;

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



4.2.3. Результаты решения

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



4.2.4. Алгоритм решения



Алгоритм решения составлен с учетом математического описания, приведенного в пункте 4.1.4. Алгоритм представляется в текстовом виде следующим образом:

Начало;

Инициализация массивов и переменных;

Если поиск узлов выполнен, то переход к п.5, иначе к п.4;

AnalyzeNode, переход к п.3;

Если поиск сегментов выполнен, то переход к п.7, иначе к п.6;

AnalyzeSeg, переход к п.5;

i=0; j=0; lnum=0; lineno=0;

Если j>=N, то переход к п.15;

Если i>=M, то переход к п.14;

Если (apix[i][j]=1)и(apix1[i][j]<0)и((NeigCount(i,j)=1)или(NeigCount(i,j)=2)), то переход к п.11, иначе к п.13;

lnum=lnum+1; lineno=lineno+1;

GetLineVect(i,j,lineno);

i=i+1; переход к п.9;

i=0; j=j+1; переход к п.8;

Конец.



4.2.5. Требования к контрольному примеру

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

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

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

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

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



4.2.6. Список условных обозначений

В таблице 4.1 представлены условные обозначения, введенные в тексте подраздела

	Таблица 4.1

Условные обозначения



Условные обозначения

Расшифровка

lnum

порядковый номер обрабатываемого сегмента

lineno

идентификатор обрабатываемого сегмента в массиве сегментов

M

ширина изображения

N

высота изображения

AnalyzeNode

алгоритм поиска узлов, формирующий значения элементов массива узлов

AnalyzeSeg

алгоритм поиска сегментов линий, формирующий значения элементов массива сегментов

apix[M][N]

массив точек исходного изображения

apix1[M][N]

массив сегментов

NeigCount

функция вычисления количества соседних точек

GetLineVect(x,y,n)

рекурсивная функция обработки точек сегмента и кодирования его координат, x,y – координаты начала обработки сегмента, n – номер сегмента



4.3. Описание программы «Обработка и кодирование сегментов»



4.3.1. Вводная часть

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

4.3.2. Функциональное назначение

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



4.3.3. Описание информации

Программа SegCode в качестве входной информации использует следующие данные:

- массив точек исходного изображения;

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

- массив сегментов, содержащий описания сегментов линий: точки, принадлежащие линии, координаты их пересечения и присвоенные номера для однозначной идентификации.

На выходе программа формирует координаты сегментов с указанием типа сегмента.

Формат описания сегментов линий:

n1:x11,y11 [,x12,y12 [,x13,y13]]

n2:x21,y21 [,x22,y22 [,x23,y23]]

nk:xk1,yk1 [,xk2,yk2 [,xk3,yk3]]

где ni – номер i-го сегмента линии (идентификатор);

xi1,yi1 – координаты первой точки i-го сегмента линии;

xi2,yi2 – координаты второй точки i-го сегмента линии, указываются в том случае, если точка (xi2,yi2)является узлом;

xi3,yi3 – координаты направления кодирования от точки (xi1,yi1), указываются в том случае, если точки (xi1,yi1) и (xi2,yi2) являются узлами.



4.3.4. Используемые подпрограммы

В процессе обработки изображение программа использует следующие подпрограммы:

- actExitExecute – обработка запроса завершения работы программы;

- FormCreate – создание формы обработки изображения;

- actZoomInExecute – режим увеличения изображения;

- actZoomOutExecute - режим уменьшения изображения;

- actOpenFileExecute – открытие файла для обработки;

- actSaveFileExecute – сохранение файла;

- Image2MouseMove – обработка события движения указателя мыши при наведении на элементы изображения;

- Image2MouseDown – обработка события нажатия кнопки мыши при редаутировании изображения;

- actZoom1Execute - режим установки масштаба изображения 100%;

- actAnalyzeExecute – вызов основной функции обработки изображения;

- FormCanResize – изменение размера окна;

- actNewFileExecute – создание нового файла для обработки;

- actGridCheckExecute – изменение режима просмотра сетки;

- actLightCheckExecute - изменение режима подсветки структурных элементов изображения;

- actZoom10Execute – режим установки 10-кратного увеличения изображения;

- actSegLightCheckExecute - изменение режима подсветки сегментов линий;

- actLockViewExecute – изменение режима блокировки изображения;

- actAnalyzeNodeExecute – обработка узлов изображения ;

- actAnalyzeSegExecute – обработка сегментов изображения;

- FormCloseQuery – обработка запроса на закрытие окна;

- actOpenArrayExecute – открытие изображения из файла массива точек;

- actSaveArrayExecute – сохранение  изображения в файл массива точек;

- actOptionsExecute – вызов окна настройки;

- actSaveCodeExecute – запись результата обработки изображения в файл;

- actSegCodeOutExecute – выполнение алгоритма формирования координат сегментов;

- ZoomTo –установка заданного масштаба изображения;

- DrawGrid – рисование сетки изображения;

- ShowInfo – отображение информации о текущем состоянии;

- NeigCount – определение количества соседних точек;

- VectMove – осуществление движения координат обработки изобржаения в заданном направлении;

- wlog – вывод информации в журнал вычислений;

- VectToStr – преобразование кода вектора направления в строку;

- ValidateView – обработка свойств доступности элементов панели управления;

- plDistance(x, y, x1, y1, x2, y2) – вычисление расстояние (минимального) от точки (x,y) до прямой, заданной точками (x1,y1) и (x2,y2) 

StrToLen – выравнивание строки для образования формата определенной длины;

- NeigNode – рекурсивная обработка соседей точки на принадлежность узлу

- NeigLine – рекурсивная обраобтка соседей точки (x,y) на принадлежность сегменту

- GetLineVect – рекурсивная обработка кода сегмента линии;

- NodeCentre - вычисление значения центра узла;

- FillLine изменение принадлежности точек одного сегмента другому;

- CodeLine – формирование кода сегмента линии.

4.3.5. Описание логики

Схема программы SegCode представлена на рис. 4.1. Здесь представлено текстовое описание схемы программы:

Начало;

Инициализация массивов и переменных;

Если поиск узлов выполнен, то переход к п.5, иначе к п.4;

AnalyzeNode, переход к п.3;

Если поиск сегментов выполнен, то переход к п.7, иначе к п.6;

AnalyzeSeg, переход к п.5;

i=0; j=0; lnum=0; lineno=0;

Если j>=N, то переход к п.15;

Если i>=M, то переход к п.14;

Если (apix[i][j]=1)и(apix1[i][j]<0)и((NeigCount(i,j)=1)или(NeigCount(i,j)=2)), то переход к п.11, иначе к п.13;

lnum=lnum+1; lineno=lineno+1;

GetLineVect(i,j,lineno);

i=i+1; переход к п.9;

i=0; j=j+1; переход к п.8;

Конец.



4.3.6. Настройка программных средств

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


4.4. Описание контрольного примера



4.4.1. Назначение

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

Схема программы SegCode



50

Рис. 4.1

4.4.2. Исходные данные

В качестве исходных данных используется графическое изображение размером 32x32 точки, приведенное на рис. 4.2.

Данное изображение содержит рассмотренные типы сегментов линий и узлов, которые могут быть выделены для дальнейшей обработки. Координаты точек изображения находятся в интервале [0..31].



49

Рис. 4.1. Продолжение



Исходное изображение



Рис. 4.2



4.4.3. Результаты расчета

В результате анализа исходных данных определим точки, формирующие узлы. В данном случае изображение содержит 3 узла, отмеченных на рис. 4.3. 

Узлы изображения



Рис. 4.3



Выделенные узлы имеют координаты

1: (14,25)

2: (25,22)

3: (10,11)

Разобьем линии на изображении на сегменты. В результате разбиения можно выделить 11 сегментов линий.

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

На рис. 4.5 выделены 8 сегментов, одна из крайних точек которых является узлом. Для идентификации такого сегмента линии необходимо указать координаты начала сегмента и координаты узла, в котором завершается данных сегмент.

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



Сегмент, не имеющий пересечений



Рис. 4.4

Сегменты с одним узлом



Рис. 4.5



Сегменты, образованные двумя узлами



Рис. 4.6



Координаты точек сегментов представлены в таблице 4.2

		Таблица 4.2

	Координаты точек сегментов

	Номер сегмента

	Начальная точка

	Конечная точка

	Количество узлов в сегменте

	1

	30,11

	13,2

	0

	2

	14,30

	14,25

	1

	3

	25,30

	25,22

	1

	4

	7,27

	14,25

	1

	5

	28,22

	25,22

	1

	6

	5,16

	10,11

	1

	7

	1,7

	10,11

	1

	8

	14,7

	10,11

	1

	9

	25,9

	25,22

	1

	10

	14,25

	10,11

	2

	11

	14,25

	25,22

	2

	

Точки, определяющие направления для кодирования сегментов 10 и 11, образованных двумя узлами имеют координаты, представленные в таблице 4.3.

	Таблица 4.3

	Точки, определяющие направление

	

	Номер сегмента

	Координаты первой точки

	Координаты точки направления

	Координаты второй точки

	10

	14,25

	14,24

	10,11

	11

	14,25

	15,25

	25,22

	

4.4.4. Результаты испытания программы

Для проверки правильности работы программы использовались исходные данные, указанные в пункте 4.4.2, и на их основе согласно математическому описанию, (см. п. 2.1.4, 3.1.4, 4.1.4) были выведены результаты, указанные в п. 4.4.3. Ниже приведены результаты работы программы:

1: (14,30)-(14,25)

2: (25,30)-(25,22)

3: (7,27)-(14,25)

4: (14,25)-(25,22) [15,25]

5: (14,25)-(10,11) [14,24]

6: (28,22)-(25,22)

7: (25,9)-(25,22)

8: (5,16)-(10,11)

9: (30,11)

10: (1,7)-(10,11)

11: (14,7)-(10,11)

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


5. ОРГАНИЗАЦИОННО-ЭКОНОМИЧЕСКАЯ ЧАСТЬ



5.1. Расчет затрат на разработку «Подсистемы линейной сегментации»



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

Расчет сметы затрат осуществляется по следующим статьям:

		расходы на материалы;

		расходы на оплату труда разработчиков;

		единый социальный налог;

		расходы на содержание и амортизацию ВТ;

		накладные  расходы;

		прочие расходы.

К статье “Расходы на материалы” относятся покупные изделия, необходимые для выполнения работы, перечисленные в таблице 5.1.

	Таблица  5.1

Расходы на материалы



Наименование  материала

Количество

Стоимость, руб.

Картридж для 

HP DeskJet 3420C

1 шт.

983

Канцелярские товары

-

250

Итого:



1233



Для расчета расходов по оплате труда определим продолжительность разработки системы. Она составила 5 месяцев. График работ по этапам (и их длительность) отображен в таблице 5.2. 


Таблица 5.2

Продолжительность работ по этапам



Наименование этапа разработки

Длительность, месяцев

1. Исследование объекта автоматизации, изучение средств разработки и программирования, формулировка требований к подсистеме.



0.5

2. Анализ данных, разработка структур обмена данными, анализ быстродействия и ресурсоемкости структур обмена данными.



1



3. Проработка  интерфейсов, экранных форм, общая настройка  системы.



0.5

4. Разработка алгоритмов обработки

1

5. Реализация на ЯП и отладка 

1

6. Документирование 

1

Итого:

5



Оклад инженера-программиста, работающего над созданием системы, на период разработки  (Пм = 5 месяцев) составил Окл = 5000.00 рублей в месяц. Вычислим расходы на оплату труда разработчиков за весь период разработки (ОТобщ):

		Отр=Окл*Пм,	(5.1)

где Отр – расходы на оплату труда программиста за 5 месяцев.

	Отр = 5000 * 5 = 25000 руб.

Кроме того, необходимо учесть уральский коэффициент (15%).

	Кур = 25000 * 0.15= 3750 руб.

Следовательно, расходы на оплату труда с учетом уральского коэффициента (Отрук) составила:

		Отрук =Отр  + Кур 	(5.2)

	Отрук = 25000 + 3750 = 28750 руб.

Всего расходы на оплату труда:

		ОТобщ = 28750 руб.

Статья единый социальный налог (ЕСН) – 26% рассчитывается от расходов на оплату труда (ОТобщ), кроме того необходимо учитывать отчисления в фонд страхования от несчастных случаев (ФСС) – 0.2%:

Сумма отчислений  составляет:

		Сотч = ОТобщ * 0.262	(5.3)

	Сотч = 28750* 0.262 = 7532,50 руб.

Статья «Расходы на содержание и амортизацию ВТ» включает расходы, связанные с использованием ресурсов ЭВМ. 

Стоимость одного машинного часа рассчитывается по формуле:

		Ач = Сисп / (Чм * Кч),	(5.4)

где Ач – аренда за час использования;

Сисп - общая стоимость использования ЭВМ (рассчитывается по формуле);

Чм – число месяцев в году;

Кч – среднемесячная продолжительность рабочего времени.

		Сисп=Акомп+ЗПобсл+Сзч+Сэл+Апо,	(5.5)

где Акомп– амортизация компьютера и принтера за год эксплуатации;

ЗПобсл – расходы на оплату труда обслуживающего персонала за год эксплуатации; 

ЗПобсл = 1500 руб.

Сзч – стоимость запчастей для компьютера за год эксплуатации.

Сзч = 200 руб.

Сэл – стоимость израсходованной электроэнергии за год эксплуатации.

Сэл = 2000 руб.

Апо – годовая амортизация программного обеспечения.

		Акомп = Скомп / Спи,	(5.6)

где Скомп – стоимость компьютера и принтера;

Спи – срок полезного использования (в годах).

	Акомп = 20260 / 5 = 4052 руб.

		Апо = СТпо/Спипо,	(5.7)

где СТпо – стоимость программного обеспечения;

Спипо – срок полезного использования (в годах).

	Апо = 6200/5 = 1240 руб. 

	Сисп=4052+1500+200+2000+1240 = 8992 руб.

	Ач = 8992 / (12 * 165) = 4.54 руб.

ЭВМ использовалась на всех этапах разработки системы (5 мес.).

Итого продолжительность эксплуатации ЭВМ при 165 часах работы в месяц составила Эч = 825 часов. Следовательно, общая стоимость аренды ЭВМ составляет:

		Сар = Эч * Ач	(5.8)

	Сар = 825 * 4.54 = 3745.5 руб.

Статья «Накладные расходы» включает в себя затраты, связанные с содержанием управленческого персонала, оплаты электроэнергии на освещение и т.п. Накладные расходы составили 30 % от расходов на оплату труда.

	Нр = 28750*0.3=8625 руб.

Статья «Прочие расходы» содержит расходы, неучтенные в предыдущих статьях. (до 5 % от основной заработной платы). Прочие расходы составили 5% от расходов на оплату труда.

	Пр = 28750*0.05=1437.5 руб.

Сумма затрат (СЗ) на разработку подсистемы в целом составила 51325 руб. Таблица 5.3 отражает затраты по статьям и структуру этих затрат в общей сумме.

	Таблица  5.3

Смета затрат на разработку подсистемы



Статья затрат

Сумма затрат, руб.

Структура затрат, %

Расходы на материалы

Расходы на оплату труда

Налоги и отчисления

Расходы на содержание ВТ

Накладные расходы

Прочие расходы

1230

28750

7530

3750

8620

1440

2.4

56

14,6

7,3

16.8

2.8

Итого

51320

100



Структура затрат на разработку подсистемы представлена на рис. 5.1



Рис. 5.1


6. ЭКОЛОГИЧНОСТЬ И БЕЗОПАСНОСТЬ ПРОЕКТА



6.1. Актуальность безопасности труда



Охрана труда - система законодательных актов, социально-экономических, организационных, технических, гигиенических и лечебно-профилактических мероприятий и средств, обеспечивающих безопасность, сохранение здоровья и работоспособности человека в процессе труда. Научно-технический прогресс внес серьезные изменения в условия производственной деятельности работников умственного труда. Их труд стал более интенсивным, напряженным, требующим значительных затрат умственной, эмоциональной и физической энергии. Это потребовало комплексного решения проблем эргономики, гигиены и организации труда, регламентации режимов труда и отдыха /17/.

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

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

		особо вредные производственные факторы;

		электробезопасность;

		пожаробезопасность;

		расчет защитного заземления.



6.2. Анализ опасных и вредных производственных факторов



К особо вредным производственным факторам при работе с персональными электронно-вычислительными машинами в соответствии с СанПиН 2.2.4.548-96 «Гигиенические требования к микроклимату производственных помещений» /18/ относятся:

	Электромагнитное излучение

Любая электрическая техника при работе выделяет большое количество электромагнитного излучения. Электронно-лучевая трубка (ЭЛТ) - это электронная пушка. Это означает, что ЭЛТ заряжена отрицательно, а, следовательно, вне ЭЛТ происходит накопление  положительно  заряженных  частиц.  Человек чувствует себя  хорошо,  когда  в окружающей его среде соотношение положительных и отрицательных ионов почти одинаково.  Однако перед экраном  монитора  образуется  избыток  положительных  ионов. Всегда имеющиеся в воздухе офиса микрочастицы, разгоняются потоком положительно заряженных ионов и оседают на лице и глазах оператора, сидящего перед экраном. В результате такой "бомбардировки" у оператора могут возникать:

- головная боль, бессонница;

- раздражение кожи;

- усталость глаз.

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

Экран видеомонитора должен находиться от глаз пользователя на оптимальном расстоянии 600 - 700мм, но не ближе 500мм с учетом размеров алфавитно-цифровых знаков и символов.

	Шумы

Повышенный уровень шума вызывает трудности в распознавании цветовых сигналов, снижает быстроту восприятия цветовых сигналов, снижает быстроту восприятия цвета,  остроту зрения, зрительную адаптацию, нарушает восприятие визуальной информации, снижает способность быстро и четко выполнять координированные действия, уменьшает на 5-10% производительность труда. Длительное воздействие повышенного уровня шума с уровнем звукового давления 90 Дб снижает производительность труда на 30-60%. 

Медицинские обследования инженеров-программистов показали, что помимо снижения производительности труда высокие уровни шума при местном действии приводят к утомлению, ухудшению слуха и тугоухости. Кроме того, при общем действии повышенный уровень шума вызывает нарушение ритма сердечной деятельности, изменение кровяного давления, ухудшение органов дыхания. Источниками шума в помещении являются печатающие устройства. Производственные помещения, в которых для работы используются преимущественно ПЭВМ не должны граничить с помещениями, в которых уровни шума и вибрации превышают нормируемые значения (механические цеха, мастерские, гимнастические залы и т.п.). Звукоизоляция ограждающих конструкций помещений ПЭВМ должна отвечать гигиеническим требованиям и обеспечивать нормируемые параметры шума. Согласно ГОСТ 12.1.003-89 «Система стандартов безопасности труда. Шум. Общие требования безопасности» /19/ при выполнении основной работы на ПЭВМ уровень шума на рабочем месте не должен превышать 50 дБА. Шумящее оборудование (принтеры и т.п.), уровни шума которого превышают нормированные, должно находиться вне помещения с ПЭВМ. 

Снизить уровень шума в помещениях с ВДТ и ПЭВМ можно использованием звукопоглощающих материалов с максимальными коэффициентами звукопоглощения в области частот 63 - 8000 Гц для отделки помещений (разрешенных органами и учреждениями Госсанэпиднадзора России), подтвержденных специальными акустическими расчетами. Дополнительным звукопоглощением служат однотонные занавеси из плотной ткани, гармонирующие с окраской стен и подвешенные в складку на расстоянии 15 - 20см от ограждения. Ширина занавеси должна быть в 2 раза больше ширины окна.

	Выделение избытков теплоты

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

В производственных помещениях, в которых работа на ПЭВМ является основной (диспетчерские, операторские, расчетные, кабины и посты управления, залы вычислительной техники и др.), должны обеспечиваться оптимальные параметры микроклимата. При этом температура воздуха не должна превышать 23 – 25 градусов Цельсия, относительная влажность воздуха должна составлять 40-60%, скорость движения воздуха – 0,1 м/с.



6.3. Техника безопасности при работе с компьютером



Электробезопасность

Электрические установки, к которым относится практически все оборудование ЭВМ, представляют для человека большую потенциальную опасность, так как в процессе эксплуатации или проведении профилактических работ человек может коснуться частей, находящихся под напряжением. Специфическая опасность электроустановок: токоведущие проводники, корпуса стоек ЭВМ и прочего оборудования, оказавшегося под напряжением в результате повреждения (пробоя) изоляции, не подают каких-либо сигналов, которые предупреждают человека об опасности. Реакция человека на электрический ток возникает лишь при протекании последнего через тело человека. Исключительно важное значение для предотвращения электротравматизма имеет правильная организация обслуживания действующих электроустановок ИВЦ, проведения ремонтных, монтажных и профилактических работ. При этом под правильной организацией понимается строгое выполнение ряда организационных и технических мероприятий и средств, установленных действующими “Правилами технической эксплуатации электроустановок потребителей и правила техники безопасности при эксплуатации электроустановок потребителей” (ПТЭ и ПТБ потребителей) и “Правила установки электроустановок” (ПУЭ) В зависимости от категории помещения необходимо принять определенные меры, обеспечивающие достаточную электробезопасность при эксплуатации и ремонте электрооборудования. Так, согласно ГОСТ 12.1.009-76 «Система стандартов безопасности труда. Электробезопасность» /20/, в помещениях с повышенной опасностью электроинструменты, переносные светильники должны быть выполнены с двойной изоляцией или напряжение питания их не должно превышать 42 В. В ВЦ к таким помещениям могут быть отнесены помещения машинного зала, помещения для размещения сервисной и периферийной аппаратуры. В соответствии с ПТЭ и ПТВ потребителям и обслуживающему персоналу электроустановок предъявляются следующие требования: 

		лица, не достигшие 18-летнего возраста, не могут быть допущены к работам в электроустановках; 

		лица не должны иметь увечий и болезней, мешающих производственной работе; 

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

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

Защита расстоянием

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

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

При одновременном размещении в помещении нескольких компьютеров следует соблюдать минимальное расстояние между ними: оно должно быть не менее 1,5метров.

Защита временем

Продолжительная работа за компьютером приводит к накоплению усталости, в первую очередь, очень сильно утомляет глаза. При необходимости набора большого количества печатного текста также большую усталость испытывают пальцы рук и кистевые суставы. Для безопасной работы необходимо ограничивать продолжительность непрерывной работы за компьютером. Оптимальным считается следующий режим работы: каждый час работы должен сопровождаться 10-15 минутным перерывом, включающим в себя разминку глаз и пальцев рук. Ниже приведены способы разминки глаз:

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

Вариант упражнений для глаз 1

1. Закрыть глаза, сильно напрягая глазные мышцы, на счет 1-4, затем раскрыть глаза, расслабив мышцы глаз, посмотреть вдаль на счет 1-6. Повторить 4-5 раз.

2. Посмотреть на переносицу и задержать взор на счет 1-4. До усталости глаза не доводить. Затем открыть глаза, посмотреть вдаль на счет 1-6. Повторить 4-5 раз.

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

4. Перевести взгляд быстро по диагонали: направо вверх налево вниз, потом прямо вдаль на счет 1-6; затем налево вверх - направо вниз и посмотреть вдаль на счет 1-6. Повторить 4-5 раз.


Вариант упражнений для глаз 2

1. Закрыть глаза, не напрягая глазные мышцы, на счет 1-4, широко раскрыть глаза и посмотреть вдаль на счет 1-6. Повторить 4-5 раз.

2. Посмотреть на кончик носа на счет 1-4, а потом перевести взгляд вдаль на счет 1-6. Повторить 4-5 раз.

3. Не поворачивая головы (голова прямо), делать медленно круговые движения глазами вверх-вправо-вниз-влево и в обратную сторону: вверх-влево-вниз-вправо. Затем посмотреть вдаль на счет 1-6. Повторить 4-5 раз.

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

Вариант упражнений для глаз 3

1. Голову держать прямо. Поморгать, не напрягая глазные мышцы, на счет 10-15.

2. Не поворачивая головы (голова прямо), посмотреть направо на счет 1-4, затем налево на счет 1-4 и прямо на счет 1-6. Поднять глаза вверх на счет 1-4, опустить вниз на счет 1-4 и перевести взгляд прямо на счет 1-6. Повторить 4-5 раз.

3. Посмотреть на указательный палец, удаленный от глаз на расстояние 25-30см, на счет 1-4, потом перевести взор вдаль на счет 1-6. Повторить 4-5 раз.

4. В среднем темпе проделать 3-4 круговых движения в правую сторону, столько же в левую сторону и, расслабив глазные мышцы, посмотреть вдаль на счет 1-6. Повторить 1-2 раза.

6.4. Организация рабочего места оператора

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

Неправильно расположенная  клавиатура  стимулирует  развитие запястного синдрома - болезненного поражения срединного нерва запястья. 

Светло окрашенная мебель офиса и большие окна являются дополнительными источниками света. В очень светлом помещении плохо видны буквы и цифры на экране монитора. Это вызывает головную боль, ухудшение зрения, снижения концентрации, а также приводит к ошибкам в работе из-за некорректного восприятия информации. Клавиатура, корпус монитора и ПЭВМ, и другие блоки и устройства ПЭВМ должны иметь матовую поверхность одного цвета с коэффициентом отражения 0,4 - 0,6 и не иметь блестящих деталей, способных создавать блики. Освещенность на поверхности стола в зоне размещения рабочего документа должна быть 300 - 500 лк. Допускается установка светильников местного освещения для подсветки документов. Местное освещение не должно создавать бликов на поверхности экрана и увеличивать освещенность экрана более 300 лк. Следует ограничивать прямую блесткость от источников освещения. При этом яркость светящихся поверхностей (окна, светильники и др.), находящихся в поле зрения, должна быть не более 200 кд/кв. м. Следует ограничивать отраженную блесткость на рабочих поверхностях (экран, стол, клавиатура и др.) за счет правильного выбора типов светильников и расположения рабочих мест по отношению к источникам естественного и искусственного освещения, при этом яркость бликов на экране монитора и ПЭВМ не должна превышать 40 кд/кв. м и яркость потолка при применении системы отраженного освещения не должна превышать 200 кд/кв. м.

6.5. Расчет защитного заземления



Общая мощность оборудования - 50 Вт, напряжение питания 220В. Для контура заземления предполагается использовать трубы стальные диаметром 50мм, длиной 3м, заглубленные на 1м. Полоса связи заземлителей – стальная, ширина полосы 40мм. Почва – двухслойная (верхний слой – суглинок, нижний - песок). Высота верхнего слоя составляет 2м. Предполагается  оборудовать защитным заземлением рабочее место с характеристиками, описанными выше и располагающееся в здании, имеющим геометрические размеры представленные на рис. 6.1. 

План здания





а

b

c

где a=15м, b=10м, с=1м.

Рис. 6.1 



Минимальное расстояние установки заземлителей с=1м, обусловлено особенностями конструкции здания и фундамента, в частности. Ставится задача рассчитать количество труб, составляющих контур  заземления.

Согласно указаниям СНиП 24-05-95 «Правила устройства электроустановок» /22/, сопротивление защитного заземления в любое время года для электроустановок до 1000В не должна превышать 4 Ом. R н = 4 Ом.

Определяем расчетное значение удельного сопротивления грунта в месте установки устройств заземления. Удельное сопротивление грунта верхнего слоя (суглинка) составляет ρ1=1·102 Ом · м, а нижнего слоя (песка) ρ2=7·102 Ом · м.

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



Схема размещения заземлителей 



Рис. 6.2 



Число заземлителей n=16, расстояние между ними выбираем таким образом, чтобы выполнялось условие размещения заземлителей в установке, представленное в постановке задачи.



Используя рис.6.3 проведем ряд несложных вычислений:



Общий контур заземления



b

b1

c

a

a1

Рис. 6.3



Итак, a1= a +2c,  b1= b +2c.

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

L=2*(a+b+4c)=96м. 	(6.1)

Исходя из этого, делаем вывод о значении величины расстояния между одиночными заземлителями в контуре. Это значение aЇ должно быть равно или больше величины L/n=6м.

Находим коэффициент ηB использования вертикальных заземлителей. Отношение расстояния между трубами aЇ к длине труб составляет 4/3=1.3, число труб в контуре n=16. Тогда коэффициент ηB≈0.66.

Найдем коэффициент ηr использования горизонтальных заземлителей. Имеем, ηr=0.36.

Определяем расчетное сопротивление одиночного вертикального заземлителя RB выбранного профиля. Для этого используем формулу для случая типа заземлителя  –  трубчатый в двухслойном грунте.



, 	(6.2)



где ρ1 - удельное сопротивления грунта верхнего слоя (Ом · м);

ρ2 - удельное сопротивления грунта нижнего слоя (Ом · м);

l  - длина трубы (м);

h  - высота верхнего слоя почвы (м);

r0  - радиус сечения трубы (м).



(6.3)

Определяем сопротивление соединительных полос Rr без учета коэффициента использования. Тип заземлителя – горизонтальный, протяженный в однородном грунте (металлическая полоса). Полоса  связи находиться в верхнем слое грунта, поскольку  глубина заземления t=1м совместно с высотой полосы, которая в свою очередь < b, будет равна величине, меньшей высоты верхнего уровня грунта. Таким образом, в формуле расчета Rr в качестве ρ будем брать ρ1.

Итак, 

,  (6.4)

где ρ1 - удельное сопротивления грунта верхнего слоя (Ом · м);

l1  = aЇ*(n-1) (м);

h - высота верхнего слоя почвы (м);

b - ширина полосы связи (м);

t - глубина заложения заземлителя (м).

Данная формула применима для вычисления сопротивление соединительной полосы при выполнении следующих условий:

l1 >> d, l1 >> 4t, где d=0.5b.

Проверим истинность условий:

d=0.5*0.04=0.02,

l1 =6*15=90.

Очевидно, условия выполняются. Поэтому, мы вправе произвести вычисление величины Rr.

 (6.5)

Определяем сопротивление полученного контура

 (6.6)



Так как сопротивление расчитанного контура незначительно меньше установленной величины (< 4Ом), то условиям безопасности будет удовлетворять контур из 16 труб и соединительной полосы L=96м.


6.6. Требования к параметрам микроклимата



При организации помещения следует учитывать параметры микроклимата, необходимые для соблюдения. Выполнение требований к данным параметрам, а ими являются: относительная влажность воздуха в помещении, температура воздуха в помещении, скорость движения воздуха – позволяет уменьшить утомляемость людей, чьи рабочие места расположены в данном помещении и тем самым увеличить производительность труда. Для помещений, содержащих компьютерную технику, следует соблюдать следующие значения: относительная влажность воздуха должна быть 40-60%, температура воздуха в помещении 20-22 градуса Цельсия, скорость движения воздуха - 0,1 м/с.



6.7. Пожаробезопасность



В соответствии с ГОСТ 12.1.004-91 «Система стандартов безопасности труда. Пожарная безопасность. Общие требования» /21/, помещения, в которых установлены персональные ЭВМ, по пожарной опасности относятся к категории Д, и должны удовлетворять требованиям по предотвращению и тушению пожара. Обязательно наличие телефонной связи и пожарной сигнализации.

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

		в машинном зале должны быть размещены углекислотные огнетушители типов ОУ-2, ОУ-5, ОУ-8. Согласно типовым правилам пожарной безопасности на каждые 100 кв. метров площади помещения ИВЦ должен приходиться один огнетушитель;

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

		для непрерывного контроля машинного зала и зоны хранения носителей информации необходимо установить систему обнаружения пожаров, для этого можно использовать комбинированные извещатели типа КИ-1 из расчета один извещатель на 100м2 помещения. 

Пользователи допускаются к работе на персональных ЭВМ только после прохождения инструктажа по безопасности труда и пожарной безопасности в лаборатории в целом и на каждом рабочем месте.



6.8. Выводы



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


ЗАКЛЮЧЕНИЕ



В результате выполненной работы была спроектирована и программно реализована «Подсистема линейной сегментации». Данная подсистема была интегрирована в состав системы «Автоматизированного анализа пространственной структуры изображений» В рамках данной работы разрабатывались несколько задач: поиск узловых точек, поиск сегментов линий, обработка и кодирование сегментов линий. При поиске узловых точек был исследован ряд ситуаций, возникающих при различных взаимных расположениях линий, образующих графическое изображение. Были разработаны способы определения правильных координат узлов в условиях неполной определенности, тем самым позволяя подсистеме гибко обрабатывать различные типы изображений. При поиске сегментов линий учитывался характер точек, образующих изображение: такие точки могут принадлежать как одному, так и нескольким сегментам, в таком случае точка является узлом и определяет характер кодирования линии. Использование массивов узлов и сегментов позволило с минимальными затратами системных ресурсов выполнить реализацию представления всех узлов и сегментов изображения без необходимости выделения дополнительной памяти, а также предоставило возможность быстрого доступа ко всем описаниям любой точки изображения. Сравнение соответствующих элементов массивов узлов и точек позволяет получать характеристики пересечения сегментов, выделять дополнительные узлы и получать некоторые статистические данные.

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

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

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

Разработанная подсистема используется в составе системы «Автоматизированного анализа пространственной структуры изображений» и взаимодействует с другими ее подсистемами: подсистемой фильтрации и подсистемой цепного кодирования.


СПИСОК ЛИТЕРАТУРЫ



		Павлидис Т. Алгоритмы машинной графики и обработки изображений. - М.: Радио и связь, 1986. - 400с.

		Дуда Р., Харт П. Распознавание образов и анализ сцен. - М.: Мир, 1976. - 512с.

		Колмогоров А.Н., Фомин С.В. Элементы теории функций и функционального анализа. – М.: Наука, 1981. – 544с.

		Бакут П.А., Колмогоров П.С. Сегментация изображений: Методы выделения границ областей // Зарубежная радиоэлектроника, 1987, № 10. - С. 25-46.

		Бакут П.А., Колмогоров П.С., Варновицкий И.Э. Сегментация изображений: методы пороговой обработки // Зарубежная радиоэлектроника, 1988, № 4. - С. 6-24.

		Быстрые алгоритмы в цифровой обработке изображений. - М.: Радио и связь, 1984. - 224с.

		Вдовин А.М., Хаба Б.С., Мурынов А.И., Лялин В.Е. Исследование планарных элементов пространственной структуры изображений // Химическая физика и мезоскопия. Т.3, 2001, №2. - С.134-147.

		Журавлев Ю.И., Гуревич И.Б. Распознавание образов и анализ изображений // Искусственный интеллект. Кн. 2. Модели и методы. - М.: Радио и связь, 1990. - 304с.

		Прэтт У. Цифровая обработка изображений. - Кн. 1. - М.: Мир, 1982. - 312с. - Кн. 2. - М.: Мир, 1982. - 480с.

		Розенфельд А., Дейвис Л.С. Сегментация и модели изображения // ТИИЭР, т. 67, 1979, № 5. – С. 71-81.

		Толковый словарь по искусственному интеллекту / А. Н. Аверкин, М.Г. Гаазе-Рапопорт, Д.А. Поспелов. – М.: Радио и связь, 1992. – 256с.

		Эйнджел Э. Интерактивная компьютерная графика. – М.: Вильямс, 2001. – 592с.

		Murynov A.I., Levitskaya L.N., Shibaeva I.V. The model discretely - planimetry graphic structures of the image graphic // Тез. докл. - Нижний Новгород: Изд-во Нижегородского госуниверситета, 2004. – С. 258.

		Николаев Д.П. Алгоритмы цветовой сегментации, применимые в условиях сложного освещения сцены // Автореф. дисс. – М: Изд-во института по проблем передачи информации РАН, 2004

		Радыгина И. И. Методические пособия для выполнения раздела «Организационно экономическая часть».– Ижевск: ИжГТУ, 2002.

		Бычин В.Б., Малинин С.В. Нормирование труда: Учебник. – Москва: Издательство «Экзамен», 2002.

		ГОСТ 12.0.002-80 Система стандартов безопасности труда. Термины и определения - М.: Издательство стандартов, 1984.

		СанПиН 2.2.4.548-96 Гигиенические требования к микроклимату производственных помещений. -М.: Издательство стандартов, 1996.

		ГОСТ 12.1.003-89 Система стандартов безопасности труда. Шум. Общие требования безопасности. -М.: Издательство стандартов, 1989.

		ГОСТ 12.1.009-76 Система стандартов безопасности труда. Электробезопасность. -М.: Издательство стандартов, 1976.

		ГОСТ 12.1.004-91 Система стандартов безопасности труда. Пожарная безопасность. Общие требования. -М.: Издательство стандартов, 1992.

		СНиП 24-05-95 Правила устройства электроустановок. -М.: Издательство стандартов, 1995.

		Сенилов М.А., Почерняев С. В., Килин И. В. Методические указания по дипломному проектированию. -  Ижевск: ИжГТУ, 1998.

		ГОСТ 19.701-90 ЕСПД. Схемы  алгоритмов, программ, данных и систем.   – М.: Издательство стандартов, 1991.

		ГОСТ 19.504-79 ЕСПД. Руководство программиста. Требования к содержанию и оформлению. – М.: Издательство стандартов, 1979.

		ГОСТ 19.505-79 ЕСПД. Руководство оператора. Требования к содержанию и оформлению. – М.: Издательство стандартов, 1979.


ПРИЛОЖЕНИЕ 1

РУКОВОДСТВО ПРОГРАММИСТА



П.1.1. Назначение программы



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

Данная программа применяется в составе «Системы автоматизированного анализа пространственной структуры изображений».



П.1.2. Условия применения программы



При работе с программой необходимо обеспечить выполнение следующих требований к комплексу технических средств:

				персональный компьютер IBM PC с процессором не ниже Pentium I;

				 клавиатура;

				 монитор; 

				 жесткий диск с объемом свободного пространства не менее 50 МБ;

				 оперативная память объемом не менее 128 МБ.

Работа программы возможна только на ЭВМ, которые поддерживают 32-разрядные операционные системы семейства Windows, такие как Windows 95,  Windows NT или выше.

Программа реализована в среде программирования  Borland C++ Builder 6.

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

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

Модуль lineseg.cpp:

- actExitExecute – обработка запроса завершения работы программы;

- FormCreate – создание формы обработки изображения;

- actZoomInExecute – режим увеличения изображения;

- actZoomOutExecute - режим уменьшения изображения;

- actOpenFileExecute – открытие файла для обработки;

- actSaveFileExecute – сохранение файла;

- Image2MouseMove – обработка события движения указателя мыши при наведении на элементы изображения;

- Image2MouseDown – обработка события нажатия кнопки мыши при редаутировании изображения;

- actZoom1Execute - режим установки масштаба изображения 100%;

- actAnalyzeExecute – вызов основной функции обработки изображения;

- FormCanResize – изменение размера окна;

- actNewFileExecute – создание нового файла для обработки;

- actGridCheckExecute – изменение режима просмотра сетки;

- actLightCheckExecute - изменение режима подсветки структурных элементов изображения;

- actZoom10Execute – режим установки 10-кратного увеличения изображения;

- actSegLightCheckExecute - изменение режима подсветки сегментов линий;

- actLockViewExecute – изменение режима блокировки изображения;

- actAnalyzeNodeExecute – обработка узлов изображения ;

- actAnalyzeSegExecute – обработка сегментов изображения;

- FormCloseQuery – обработка запроса на закрытие окна;

- actOpenArrayExecute – открытие изображения из файла массива точек;

- actSaveArrayExecute – сохранение  изображения в файл массива точек;

- actOptionsExecute – вызов окна настройки;

- actSaveCodeExecute – запись результата обработки изображения в файл;

- actSegCodeOutExecute – выполнение алгоритма формирования координат сегментов;

- ZoomTo –установка заданного масштаба изображения;

- DrawGrid – рисование сетки изображения;

- ShowInfo – отображение информации о текущем состоянии;

- NeigCount – определение количества соседних точек;

- VectMove – осуществление движения координат обработки изобржаения в заданном направлении;

- wlog – вывод информации в журнал вычислений;

- VectToStr – преобразование кода вектора направления в строку;

- ValidateView – обработка свойств доступности элементов панели управления;

- plDistance(x, y, x1, y1, x2, y2) – вычисление расстояние (минимального) от точки (x,y) до прямой, заданной точками (x1,y1) и (x2,y2) 

StrToLen – выравнивание строки для образования формата определенной длины;

- NeigNode – рекурсивная обработка соседей точки на принадлежность узлу

- NeigLine – рекурсивная обраобтка соседей точки (x,y) на принадлежность сегменту

- GetLineVect – рекурсивная обработка кода сегмента линии;

- NodeCentre  - вычисление значения центра узла;

- FillLine изменение принадлежности точек одного сегмента другому;

- CodeLine – формирование кода сегмента линии.

Модуль lsImgSize:

- btnCancelClick – обработка события отмены создания нового файла;

TfrmImgSize – конструктор диалога создания нового файла;

Модуль lsOptions:

- btnCancelClick – обработка события отмены изменения настроек программы;

- Label1MouseDown – обработка события изменения цвета сетки изображения;

- Label2MouseDown – обработка события изменения цвета подсветки линий изображения;

- Label3MouseDown – обработка события изменения цвета подсветки узлов изображения;

- Label4MouseDown – обработка события изменения шрифта окна журнала;

- Label5MouseDown – обработка события изменения шрифта окна результатов;

- TfrmOptions – конструктор диалога настройки программы;



П.1.3. Характеристики программы



Программа имеет следующие режимы работы:

- импорт/экспорт файлов изображений;

- просмотр и редактирование изображений;

- поиск узлов;

- поиск сегментов;

- кодирование сегментов;

- автоматическая обработка изображения.

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

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

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

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

Любой из режимов работы может быть выбран пользователем с выбором соответствующего пункта меню.



П.1.4. Обращение к программе



Для вызова программы необходимо запустить на выполнения исполняемый файл lineseg.exe.

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



П.1.5. Входные и выходные данные



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

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

П.1.6. Сообщения



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

	Таблица П.1.1

Сообщения, выдаваемые при работе программы  и необходимые действия при их получении



Сообщение

Описание

Действия

1

2

3

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

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

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

Неверно указано число

Введенное число не соответствует заданному формату

Ввести корректное число

Выход ?

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

Подтвердить или опровергнуть запрос на выход

Невозможно открыть файл

Произошла ошибка при попытке открыть указанный файл 

Проверить наличие файла и доступа к нему

Невозможно сохранить файл

Произошла ошибка при попытке сохранить указанный файл 

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

Файл уже  существует. Перезаписать ?

Файл с именем, указанным для сохранения, уже существует

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

Настройка

Вызван диалог настройки программы

Выполнить необходимые действия по настройке, затем нажать кнопку «ОК» для сохранения изменений или кнопку «Отмена» для их отмены

Не выполнен поиск узлов

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

Сначала необходимо выполнить поиск узлов, а затем выполнять поиск сегментов

Не выполнен поиск сегментов

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

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




П.1.7. Настройка программы



Для работы программы не требуется настройки дополнительных программных средств.


ПРИЛОЖЕНИЕ 2

РУКОВОДСТВО ОПЕРАТОРА



П.2.1. Назначение программы



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

Данная программа применяется в составе «Системы автоматизированного анализа пространственной структуры изображений».



П.2.2. Условия применения программы



При работе с программой необходимо обеспечить выполнение следующих требований к комплексу технических средств:

				персональный компьютер IBM PC с процессором не ниже Pentium I;

				 клавиатура;

				 монитор; 

				 жесткий диск с объемом свободного пространства не менее 50 МБ;

				 оперативная память объемом не менее 128 МБ.

Работа программы возможна только на ЭВМ, которые поддерживают 32-разрядные операционные системы семейства Windows, такие как Windows 95,  Windows NT или выше.



П.2.3. Пуск программы



Для вызова программы необходимо запустить на выполнения исполняемый файл lineseg.exe.

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



П.2.4. Команды оператора



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

Ниже приведено описание пиктограмм с указанием в скобках «горячих клавиш»:

 - Создать новый файл (F2);

 - Открыть BMP-файл (F3);

 - Открыть массив точек из файла (Ctrl+F3);

 - Сохранить BMP-файл (F4);

 - Сохранить массив точек в файл (Ctrl+F4);

 - Сохранить код линий в файл (Shift+F4);

 - Выполнить полную обработку изображения (F9);

 - Выполнить поиск узлов (F5);

 - Выполнить поиск сегментов линий (F6);

- Выполнить кодирование сегментов линий(F7);

 - Уменьшить масштаб изображения (Ctrl+=);

- Увеличить масштаб изображения (Ctrl+-);

 - Установить масштаб изображения 100% (Ctrl+1);

 - Установить 10-кратное увеличение изображения (Ctrl+0);

 - Установить масштаб изображения по размерам окна (Ctrl+\);

 - Вкл/Выкл сетку (Ctrl+G);

 - Вкл/Выкл подсветку сегментов (Ctrl+J);

 - Вкл/Выкл подсветку узлов пересечений (Ctrl+K);

 - Вкл/Выкл блокировку изображения (Ctrl+L);

 - Показать окно настройки программы (F10);



Окно программы представлено на рис. П.2.1.



Окно программы



Рис. П.2.1



Для открытия файла, содержащего входное изображение следует выбрать в меню «Файл» пункт «Открыть файл» или «Загрузить массив» для получения изображения из файла формата BMP или файла массива точек соответственно (рис. П.2.2). Далее в диалоге выбора файла следует выбрать необходимый файл или ввести его имя и нажать кнопку «Открыть». После этого файл будет загружен и из него будет сформирован массив точек исходного изображения. 



Меню «Файл»



Рис. П.2.2



При просмотре изображения для изменения масштаба следует воспользоваться элементами подменю «Масштаб» меню «Вид» (рис. П.2.3).

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

Подменю «Масштаб» меню «Вид»



Рис. П.2.3



Режим редактирования изображения



Рис. П.2.4



Для создания нового изображения следует использовать в меню «Файл» пункт «Новый». При этом будет вызван диалог, позволяющий задать необходимые размеры нового изображения (рис. П.2.5).

Выбор размера нового изображения



Рис. П.2.5



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

- в режиме пошаговой обработки;

- в режиме полной обработки.

Доступ к режимам обработки изображения осуществляется с помощью пунктов меню «Обработка» (рис. П.2.6).

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

Режим полной обработки позволяет последовательно автоматически выполнить поиск узлов, поиск сегментов и кодирование сегментов, получая на выходе результат, готовый для передачи в подсистему цепного кодирования. Для вызова обработки в данном режиме следует воспользоваться соответствующим пунктом меню «Обработка» (рис. П.2.6).

Меню «Обработка»



Рис. П.2.6



После выполнения обработки изображения ее результаты могут быть просмотрены на самом исходном изображении. Для этого следует воспользоваться пунктами-переключателями меню «Вид» (рис. П.2.7).

Пункт «Сетка» позволяет включить или выключить отображение сетки изображения при его увеличении.

Пункт «Подсветка линий» позволяет включить или выключить подсветку сегментов линий при наведении указателя мыши на различные области изображения (для данного режима требуется предварительное выполнение процедуры «Поиск сегментов»). 

Пункт «Подсветка узлов» позволяет включить или выключить подсветку узлов при наведении указателя мыши на различные области изображения (для данного режима требуется предварительное выполнение процедуры «Поиск узлов»).

Пункт «Заблокировать вид» позволяет зафиксировать выделенные элементы изображения, не изменяя подсветку при перемещении курсора мыши в области изображения.

Меню «Вид»



Рис. П.2.7



Пример подсветки узла приведен на рис. П.2.8



Подсветка узла



Рис. П.2.8

Пример подсветки сегмента приведен на рис. П.2.9



Подсветка сегмента



Рис. П.2.9



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



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



Рис. П.2.10

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

После работы с программой для корректного ее завершения следует использовать пункт «Выход» в меню «Файл» (рис. П.2.11) или использовать стандартную пиктограмму закрытия окна. При этом будет выдан запрос на подтверждение выхода из программы (рис. П.2.12). Во избежание потери данных при выходе из программы следует убедиться, что все необходимые данные сохранены.



Выход из программы



Рис. П.2.11



Запрос на подтверждение выхода



Рис. П.2.12


П.2.5. Сообщения оператору



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

	Таблица П.2.1

Сообщения, выдаваемые при работе программы  и необходимые действия при их получении



Сообщение

Описание

Действия

1

2

3

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

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

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

Неверно указано число

Введенное число не соответствует заданному формату

Ввести корректное число

Выход ?

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

Подтвердить или опровергнуть запрос на выход

Невозможно открыть файл

Произошла ошибка при попытке открыть указанный файл 

Проверить наличие файла и доступа к нему

Невозможно сохранить файл

Произошла ошибка при попытке сохранить указанный файл 

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

Файл уже  существует. Перезаписать ?

Файл с именем, указанным для сохранения, уже существует

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

Настройка

Вызван диалог настройки программы

Выполнить необходимые действия по настройке, затем нажать кнопку «ОК» для сохранения изменений или кнопку «Отмена» для их отмены

Не выполнен поиск узлов

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

Сначала необходимо выполнить поиск узлов, а затем выполнять поиск сегментов

Не выполнен поиск сегментов

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

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




ПРИЛОЖЕНИЕ 3

ТЕКСТ ПРОГРАММЫ



П.3.1. Текст модуля lineseg.h



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



#ifndef LineSegH

#define LineSegH

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

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <ActnList.hpp>

#include <Menus.hpp>

#include <Dialogs.hpp>

#include <Graphics.hpp>

#include <ExtCtrls.hpp>

#include <ComCtrls.hpp>

#include <ToolWin.hpp>

#include <ImgList.hpp>

#include <CustomizeDlg.hpp>

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

class TfrmLineSeg : public TForm

{

__published:	// IDE-managed Components

TStatusBar *sb1;

TPanel *Panel1;

TScrollBox *scb1;

TImage *Image1;

TImage *Image2;

TMainMenu *MainMenu1;

TMenuItem *N1;

TMenuItem *N3;

TMenuItem *N5;

TMenuItem *N4;

TMenuItem *N2;

TMenuItem *N6;

TMenuItem *N10;

TMenuItem *N11;

TMenuItem *N12;

TMenuItem *N1001;

TMenuItem *N10x1;

TMenuItem *N9;

TActionList *ActionList1;

TAction *actExit;

TAction *actOpenFile;

TAction *actSaveFile;

TAction *actNewFile;

TAction *actZoomIn;

TAction *actZoomOut;

TAction *actZoom1;

TAction *actZoom10;

TAction *actAnalyze;

TAction *actGridCheck;

TAction *actLightCheck;

TOpenDialog *OpenDialog1;

TSaveDialog *SaveDialog1;

TImageList *ImageList1;

TCoolBar *CoolBar1;

TToolBar *ToolBar1;

TToolBar *ToolBar2;

TToolBar *ToolBar3;

TToolButton *ToolButton1;

TToolButton *ToolButton2;

TToolButton *ToolButton3;

TToolButton *ToolButton4;

TToolButton *ToolButton5;

TToolButton *ToolButton6;

TToolButton *ToolButton7;

TToolButton *ToolButton8;

TToolButton *ToolButton13;

TToolButton *ToolButton14;

TAction *actLineLightCheck;

TToolButton *ToolButton11;

TToolButton *ToolButton10;

TAction *actSegLightCheck;

TSplitter *Splitter1;

TPanel *Panel2;

TMemo *MemoLog;

TMemo *MemoOut;

TSplitter *Splitter2;

TToolButton *ToolButton12;

TAction *actLockView;

TToolButton *ToolButton16;

TMenuItem *N8;

TMenuItem *N16;

TMenuItem *N17;

TMenuItem *N18;

TToolButton *ToolButton17;

TAction *actAnalyzeNode;

TAction *actAnalyzeSeg;

TToolButton *ToolButton9;

TAction *actMatchLines;

TToolButton *ToolButton18;

TToolButton *ToolButton20;

TAction *actZoomWnd;

TMenuItem *N19;

TToolButton *ToolButton21;

TAction *actMatchOut;

TMenuItem *N7;

TMenuItem *N22;

TAction *actOpenArray;

TAction *actSaveArray;

TMenuItem *N23;

TMenuItem *N24;

TToolButton *ToolButton22;

TToolButton *ToolButton23;

TMemo *mArray;

TAction *actOptions;

TMenuItem *N13;

TToolButton *ToolButton15;

TToolButton *ToolButton19;

TLabel *Label1;

TLabel *Label2;

TToolButton *ToolButton24;

TMenuItem *N14;

TAction *actSaveCode;

TMenuItem *N20;

TToolButton *ToolButton25;

TToolButton *ToolButton26;

TToolButton *ToolButton27;

TAction *actSegCodeOut;

TMenuItem *N15;

void __fastcall actExitExecute(TObject *Sender);

void __fastcall FormCreate(TObject *Sender);

void __fastcall actZoomInExecute(TObject *Sender);

void __fastcall actZoomOutExecute(TObject *Sender);

void __fastcall actOpenFileExecute(TObject *Sender);

void __fastcall actSaveFileExecute(TObject *Sender);

void __fastcall Image2MouseMove(TObject *Sender, TShiftState Shift,

int X, int Y);

void __fastcall Image2MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y);

void __fastcall actZoom1Execute(TObject *Sender);

void __fastcall actAnalyzeExecute(TObject *Sender);

void __fastcall FormCanResize(TObject *Sender, int &NewWidth,

int &NewHeight, bool &Resize);

void __fastcall actNewFileExecute(TObject *Sender);

void __fastcall actGridCheckExecute(TObject *Sender);

void __fastcall actLightCheckExecute(TObject *Sender);

void __fastcall actZoom10Execute(TObject *Sender);

void __fastcall actLineLightCheckExecute(TObject *Sender);

void __fastcall actSegLightCheckExecute(TObject *Sender);

void __fastcall actLockViewExecute(TObject *Sender);

void __fastcall actAnalyzeNodeExecute(TObject *Sender);

void __fastcall actAnalyzeSegExecute(TObject *Sender);

void __fastcall actMatchLinesExecute(TObject *Sender);

void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose);

void __fastcall actZoomWndExecute(TObject *Sender);

void __fastcall actMatchOutExecute(TObject *Sender);

void __fastcall actOpenArrayExecute(TObject *Sender);

void __fastcall actSaveArrayExecute(TObject *Sender);

void __fastcall actOptionsExecute(TObject *Sender);

void __fastcall actSaveCodeExecute(TObject *Sender);

void __fastcall actSegCodeOutExecute(TObject *Sender);

private:	// User declarations

void ZoomTo(double z);

void DrawGrid();

void ShowInfo(int X, int Y);

int __fastcall NeigCount(int x, int y);

int VectMove(int &x, int &y, int vect);

void wlog(AnsiString s);

AnsiString VectToStr(int v);

void ValidateView();

double plDistance(double x,double y,double x1,double y1,double x2,double y2);

// plDistance вычисляет расстояние (минимальное) от точки (x,y)

// до прямой, заданной точками (x1,y1) и (x2,y2)

AnsiString StrToLen(AnsiString str, int len);

// StrToLen возвражает строку длины len

// заполняя пробелями недостающие символы в начале строки str 

void __fastcall NeigNode(int x, int y, int n);

// NeigSeg обрабатывает соседей точки (x,y)

// на принадлежность узлу n

// является рекурсивной

void __fastcall NeigLine(int x,int y, int n);

// NeigLine обрабатывает соседей точки (x,y)

// на продолжение линии n

// является рекурсивной

void __fastcall GetLineVect(int x,int y, int n);

// GetLineVect обрабатывает линию в код

// рекурсивная 

TPoint NodeCentre(int n);

// NodeCentre возвращает центр узла n (координаты узловой точки)

void __fastcall FillLine(int n1, int n2);

// FillLine присваивает линии n2 пикселы линии n1 (объединение двух линий)

TPoint __fastcall FindMatch(int x, int y);

// FindMatch возвращает точку, соответствующую точке x,y

void __fastcall CodeLine(int x1,int y1,int x2,int y2);

// CodeLine добавляет в глобальную переменную linecode код для отрезка (x1,y1)-(x2,y2)

void __fastcall GetLineVect2(int x,int y, int n);

// GetLineVect2 обрабатывает линию в код

// рекурсивная

public:// User declarations

__fastcall TfrmLineSeg(TComponent* Owner);

};

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

extern PACKAGE TfrmLineSeg *frmLineSeg;

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

#endif

П.3.2. Текст модуля lineseg.cpp

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

#include <vcl.h>

#pragma hdrstop

#include "LineSeg.h"

#include "lsImgSize.h"

#include "lsOptions.h"

#include <math.h>

#include <values.h>

#include <io.h>

#include <fcntl.h>

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

#pragma package(smart_init)

#pragma link "PERFGRAP"

#pragma resource "*.dfm"

#define min(a, b)  (((a) < (b)) ? (a) : (b))

#define max(a, b)  (((a) > (b)) ? (a) : (b))

TfrmLineSeg *frmLineSeg;

double zoom,dzoom,maxzoom;

int w,h,def,defh,selline,selnode,oldselline,oldselnode,isnode;

const int maxw=1024,maxh=1024;

TColor c0,c1,c2,c3,c4,c21,c5;

bool logs; // вести журнал вычислений

int nodescnt,xs1,ys1,xs2,ys2,xs3,ys3;

AnsiString linecode; // содержит код текущей линии

// apix[i][j][0] - массив точек

// apix[i][j][1] - массив линий, номер линии

// apix[i][j][2] - массив узлов, номер узла

// -1 - пиксел не обработан, 0 - нет точки, >0 - номер линии, кот. принадлежит точка

// apix[i][j][3] - массив врЕменных атрибутов

int apix[maxw][maxh][4];

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

__fastcall TfrmLineSeg::TfrmLineSeg(TComponent* Owner)

: TForm(Owner)

{

}

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

void __fastcall TfrmLineSeg::actExitExecute(TObject *Sender)

{

frmLineSeg->Close();

}

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

void __fastcall TfrmLineSeg::FormCreate(TObject *Sender)

{

scb1->Enabled=false;

logs=true;

zoom=1.0f; dzoom=1.0f;

maxzoom=100.0f;

selline=-1;

Image1->Left=0; Image1->Top=0;

Image2->Left=0; Image2->Top=0;

w=0; h=0;

c0=TColor(RGB(0,0,0)); c1=TColor(RGB(255,255,255));

c2=TColor(RGB(0,255,0)); c3=TColor(RGB(0,0,255));

c4=TColor(RGB(255,0,0)); c21=TColor(RGB(255,255,0));

c5=TColor(RGB(200,200,200));

for(int i=0;i<=maxw-1;i++)

for(int j=0;j<=maxh-1;j++)

{

apix[i][j][0]=0;

apix[i][j][1]=apix[i][j][2]=apix[i][j][3]=-1;

}

}

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

void __fastcall TfrmLineSeg::FormCloseQuery(TObject *Sender, bool &CanClose)

{

CanClose=MessageBox(Handle,"Выход ?", "ЛС", MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2)==ID_YES;

}

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

void __fastcall TfrmLineSeg::actZoomInExecute(TObject *Sender)

{

zoom+=dzoom;

ZoomTo(zoom);

DrawGrid();

}

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

void __fastcall TfrmLineSeg::actZoomOutExecute(TObject *Sender)

{

if(zoom>dzoom) zoom-=dzoom;

ZoomTo(zoom);

DrawGrid();

}

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

void TfrmLineSeg::DrawGrid()

{

if(Image2->Visible)

{

Image2->Picture->Bitmap->Width=Image1->Width;

Image2->Picture->Bitmap->Height=Image1->Height;

Image2->Width=Image1->Width;

Image2->Height=Image1->Height;

Image2->Canvas->Pen->Color=c5;

Image2->Canvas->FillRect(Image2->ClientRect);

if(actGridCheck->Checked)

{

for(int i=1;i<=Image2->Height;i++)

{

Image2->Canvas->MoveTo(int(zoom*i),0);

Image2->Canvas->LineTo(int(zoom*i),Image2->Height);

}

for(int i=1;i<=Image2->Width;i++)

{

Image2->Canvas->MoveTo(0,int(zoom*i));

Image2->Canvas->LineTo(Image2->Width,int(zoom*i));

}

}

} // Image2->Visible

}

void __fastcall TfrmLineSeg::actOpenFileExecute(TObject *Sender)

{

OpenDialog1->Title="Открыть изображение";

OpenDialog1->Filter="Файлы изображений (*.bmp)|*.bmp|Все файлы (*.*)|*.*";

if(OpenDialog1->Execute())

{

sb1->SimplePanel=true; sb1->SimpleText="Открытие файла ...";

Image1->Picture->LoadFromFile(OpenDialog1->FileName);

Image1->Width=Image1->Picture->Bitmap->Width;

Image1->Height=Image1->Picture->Bitmap->Height;

w=Image1->Picture->Width;

h=Image1->Picture->Height;

scb1->Enabled=true;

ZoomTo(zoom);

for(int i=0;i<=w-1;i++)    // maxw-1

for(int j=0;j<=h-1;j++)  // maxh-1

{

apix[i][j][0]=Image1->Canvas->Pixels[i][j]==c0?1:0;

apix[i][j][1]=apix[i][j][2]=apix[i][j][3]=-1;

}

sb1->SimpleText=""; sb1->SimplePanel=false;

}

}

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

void __fastcall TfrmLineSeg::actSaveFileExecute(TObject *Sender)

{

SaveDialog1->Filter="Файлы изображений (*.bmp)|*.bmp|Все файлы (*.*)|*.*";

SaveDialog1->DefaultExt="*.bmp";

SaveDialog1->Title="Сохранить изображение";

if(SaveDialog1->Execute())

{

Image1->Picture->SaveToFile(SaveDialog1->FileName);

}

}

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

void __fastcall TfrmLineSeg::Image2MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y)

{

if (actLockView->Checked) return;

int ix=int(X/zoom),iy=int(Y/zoom);

if(Button==mbLeft)

{

if(Image1->Canvas->Pixels[ix][iy]!=c0)

{

Image1->Canvas->MoveTo(ix,iy);

Image1->Canvas->Pixels[ix][iy]=c0;

apix[ix][iy][0]=1;

}

}

else if(Button==mbRight)

{

if(Image1->Canvas->Pixels[ix][iy]!=c1)

{

Image1->Canvas->MoveTo(ix,iy);

Image1->Canvas->Pixels[ix][iy]=c1;

apix[ix][iy][0]=0;

}

}

}

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

void __fastcall TfrmLineSeg::Image2MouseMove(TObject *Sender,

TShiftState Shift, int X, int Y)

{

ShowInfo(X,Y);

if (actLockView->Checked) return;

int ix=int(X/zoom),iy=int(Y/zoom);

oldselline=selline;

oldselnode=selnode;

selline=apix[ix][iy][1];

selnode=apix[ix][iy][2];

TPoint p=NodeCentre(selnode);

if(Shift.Contains(ssLeft))

{

if(apix[ix][iy][0]!=1)

{

apix[ix][iy][0]=1;

Image1->Canvas->Pen->Color=c0;

Image1->Canvas->Pixels[ix][iy]=c0;

}

else

Image1->Canvas->MoveTo(ix,iy);

}

else if(Shift.Contains(ssRight))

{

if(apix[ix][iy][0]!=0)

{

apix[ix][iy][0]=0;

Image1->Canvas->Pen->Color=c1;

Image1->Canvas->Pixels[ix][iy]=c1;

}

else

Image1->Canvas->MoveTo(ix,iy);

}

if(actLineLightCheck->Checked && selline!=oldselline)

{

if(apix[ix][iy][1]>0) // есть линия

{

DrawGrid();

Image2->Canvas->Pen->Color=c2;

for(int i=0;i<w;i++) // выделяем линию

{

for(int j=0;j<h;j++)

{

if(apix[i][j][1]==selline) // линия

{

Image2->Canvas->MoveTo(int(zoom*i),int(zoom*j));

Image2->Canvas->LineTo(int(zoom*(i+1)),int(zoom*j));

Image2->Canvas->LineTo(int(zoom*(i+1)),int(zoom*(j+1)));

Image2->Canvas->LineTo(int(zoom*i),int(zoom*(j+1)));

Image2->Canvas->LineTo(int(zoom*i),int(zoom*j));

if(NeigCount(i,j)==1) // начало линии

{

Image2->Canvas->MoveTo(int(zoom*i),int(zoom*j));

Image2->Canvas->LineTo(int(zoom*(i+1)),int(zoom*(j+1)));

Image2->Canvas->MoveTo(int(zoom*(i+1)),int(zoom*j));

Image2->Canvas->LineTo(int(zoom*i),int(zoom*(j+1)));

}

if(apix[i][j][2]>0) // пересечение линии с узлом

{

Image2->Canvas->MoveTo(int(zoom*i),int(zoom*j));

Image2->Canvas->LineTo(int(zoom*(i+1)),int(zoom*(j+1)));

p=NodeCentre(apix[i][j][2]);

Image2->Canvas->Pen->Color=c4;

Image2->Canvas->MoveTo(int(zoom*p.x),int(zoom*p.y));

Image2->Canvas->LineTo(int(zoom*(p.x+1)),int(zoom*p.y));

Image2->Canvas->LineTo(int(zoom*(p.x+1)),int(zoom*(p.y+1)));

Image2->Canvas->LineTo(int(zoom*p.x),int(zoom*(p.y+1)));

Image2->Canvas->LineTo(int(zoom*p.x),int(zoom*p.y));

Image2->Canvas->Pen->Color=c2;

}

}

} // for j

} // for i

}

} // actLineLightCheck->Checked

if(actSegLightCheck->Checked  && selnode!=oldselnode)

{

if(apix[ix][iy][2]>0)  // есть узел

{

DrawGrid();

Image2->Canvas->Pen->Color=c3;

for(int i=0;i<w;i++)  // выделяем узел

{

for(int j=0;j<h;j++)

{

if(apix[i][j][2]==selnode) // узел

{

Image2->Canvas->MoveTo(int(zoom*i),int(zoom*j));

Image2->Canvas->LineTo(int(zoom*(i+1)),int(zoom*j));

Image2->Canvas->LineTo(int(zoom*(i+1)),int(zoom*(j+1)));

Image2->Canvas->LineTo(int(zoom*i),int(zoom*(j+1)));

Image2->Canvas->LineTo(int(zoom*i),int(zoom*j));

if(apix[i][j][1]>0) // пересечение узла с линией

{

Image2->Canvas->MoveTo(int(zoom*i),int(zoom*j));

Image2->Canvas->LineTo(int(zoom*(i+1)),int(zoom*(j+1)));

}

}

} // for j

} // for i

//

Image2->Canvas->Pen->Color=c4;

Image2->Canvas->MoveTo(int(zoom*p.x),int(zoom*p.y));

Image2->Canvas->LineTo(int(zoom*(p.x+1)),int(zoom*p.y));

Image2->Canvas->LineTo(int(zoom*(p.x+1)),int(zoom*(p.y+1)));

Image2->Canvas->LineTo(int(zoom*p.x),int(zoom*(p.y+1)));

Image2->Canvas->LineTo(int(zoom*p.x),int(zoom*p.y));

}

} // actSegLightCheck->Checked

}

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

void TfrmLineSeg::ShowInfo(int X,int Y)

{

unsigned char r,g,b;

int ix=int(X/zoom),iy=int(Y/zoom);

if (X>=0 && Y>=0)

{

sb1->Panels->Items[1]->Text=IntToStr(ix);

sb1->Panels->Items[3]->Text=IntToStr(h-1-iy);

r=Image1->Canvas->Pixels[ix][iy];

g=Image1->Canvas->Pixels[ix][iy] >>8;

b=Image1->Canvas->Pixels[ix][iy] >>16;

sb1->Panels->Items[5]->Text=IntToStr(r);

sb1->Panels->Items[7]->Text=IntToStr(g);

sb1->Panels->Items[9]->Text=IntToStr(b);

}

sb1->Panels->Items[11]->Text=IntToStr(int(zoom));

//  if(apix[ix][iy][0]!=-1)

{

sb1->Panels->Items[13]->Text=IntToStr(apix[ix][iy][0]);

sb1->Panels->Items[15]->Text=IntToStr(apix[ix][iy][1]);

}

  sb1->Panels->Items[17]->Text=IntToStr(apix[ix][iy][2]);

  sb1->Panels->Items[19]->Text=IntToStr(apix[ix][iy][3]);

}

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

void __fastcall TfrmLineSeg::actZoom1Execute(TObject *Sender)

{

zoom=1.0f;

Image1->Width=Image1->Picture->Width;

Image1->Height=Image1->Picture->Height;

DrawGrid();

}

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

void __fastcall TfrmLineSeg::actAnalyzeExecute(TObject *Sender)

{

MemoLog->Clear();

actAnalyzeNodeExecute(Sender);

actAnalyzeSegExecute(Sender);

}

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

int __fastcall TfrmLineSeg::NeigCount(int x, int y)

{

int n=0;

if(Image1->Canvas->Pixels[x-1][y-1]==c0 && x>0 && y>0) n+=1; // lu=1

if(Image1->Canvas->Pixels[x  ][y-1]==c0        && y>0) n+=1; // u=2

if(Image1->Canvas->Pixels[x+1][y-1]==c0 && x<w && y>0) n+=1; // ru=3

if(Image1->Canvas->Pixels[x-1][y  ]==c0 && x>0       ) n+=1; // l=4

if(Image1->Canvas->Pixels[x+1][y  ]==c0 && x<w       ) n+=1; // r=5

if(Image1->Canvas->Pixels[x-1][y+1]==c0 && x>0 && y<h) n+=1; // ld=6

if(Image1->Canvas->Pixels[x  ][y+1]==c0        && y<h) n+=1; // d=7

if(Image1->Canvas->Pixels[x+1][y+1]==c0 && x<w && y<h) n+=1; // rd=8

return (n);

}

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

int TfrmLineSeg::VectMove(int &x, int &y, int vect)

{

int res=0;

if(vect>0) wlog("VectMove: new point");

else if(vect<0 && vect>-10) wlog("VectMove: new node");

else if(vect<-10 && vect>-20) wlog("VectMove: existing node");

else wlog("VectMove: ERROR POINT");

int amvect=abs(vect) % 10;

switch(amvect)

{

// точка принадлежит линии

case 1: x-=1; y-=1; res=1; break;

case 2: y-=1;       res=1; break;

case 3: x+=1; y-=1; res=1; break;

case 4: x-=1;       res=1; break;

case 5: x+=1;       res=1; break;

case 6: x-=1; y+=1; res=1; break;

case 7: y+=1;       res=1; break;

case 8: x+=1; y+=1; res=1; break;

}

return res;

}

void __fastcall TfrmLineSeg::FormCanResize(TObject *Sender, int &NewWidth,

int &NewHeight, bool &Resize)

{

if(NewHeight<300) Resize=false;

}

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

void TfrmLineSeg::ZoomTo(double z)

{

if(z<0.1) zoom=0.1f;

else if(z>maxzoom) zoom=maxzoom;

else zoom=z;

Image1->Width=int(Image1->Picture->Width*zoom);

Image1->Height=int(Image1->Picture->Height*zoom);

DrawGrid();

ShowInfo(-1,-1);

}

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

AnsiString TfrmLineSeg::VectToStr(int v)

{

switch(v)

{

case 1:return ("LU");

case 2:return ("U");

case 3:return ("RU");

case 4:return ("L");

case 5:return ("R");

case 6:return ("LD");

case 7:return ("D");

case 8:return ("RD");

case -1:return ("LUn");

case -2:return ("Un");

case -3:return ("RUn");

case -4:return ("Ln");

case -5:return ("Rn");

case -6:return ("LDn");

case -7:return ("Dn");

case -8:return ("RDn");

default:return("");

}

}

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

void __fastcall TfrmLineSeg::actNewFileExecute(TObject *Sender)

{

if(frmImgSize->ShowModal()==mrOk)

{

try

{

w=StrToInt(frmImgSize->edtWidth->Text);

h=StrToInt(frmImgSize->edtHeight->Text);

Image1->Picture->Bitmap->Width=w;

Image1->Picture->Bitmap->Height=h;

Image1->Width=w;

Image1->Height=h;

Image1->Canvas->FillRect(Image1->ClientRect);

zoom=1.0f;

scb1->Enabled=true;

for(int i=0;i<=w-1;i++)    // maxw-1

for(int j=0;j<=h-1;j++)  // maxh-1

{

apix[i][j][0]=Image1->Canvas->Pixels[i][j]==c0?1:0;

apix[i][j][1]=apix[i][j][2]=-1;

}

}

catch (...)

{

MessageBox(Handle,"Неверно указано число", "Ошибка", MB_OK);

}

DrawGrid();

ShowInfo(-1,-1);

}

}

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

void __fastcall TfrmLineSeg::actGridCheckExecute(TObject *Sender)

{

ValidateView();

  DrawGrid();

}

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

void __fastcall TfrmLineSeg::actLightCheckExecute(TObject *Sender)

{

ValidateView();

DrawGrid();

}

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

void __fastcall TfrmLineSeg::actZoom10Execute(TObject *Sender)

{

ZoomTo(10.0f);

}

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

void __fastcall TfrmLineSeg::actLineLightCheckExecute(TObject *Sender)

{

ValidateView();

DrawGrid();

}

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

void TfrmLineSeg::wlog(AnsiString s)

{

if(logs)

if(s!="")

MemoLog->Lines->Add(s);

}

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

void __fastcall TfrmLineSeg::actSegLightCheckExecute(TObject *Sender)

{

ValidateView();

DrawGrid();

}

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

void TfrmLineSeg::ValidateView()

{

Image2->Visible=actGridCheck->Checked

|| actLightCheck->Checked

|| actLineLightCheck->Checked

|| actSegLightCheck->Checked;

}

double TfrmLineSeg::plDistance(double x,double y,double x1,double y1,double x2,double y2)

{

double R=0.0f;

try

{

R=((y1-y2)*x+(x2-x1)*y+(x1*y2-x2*y1))/sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));

}

catch(...)

{  }

 return fabs(R);

}

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

void __fastcall TfrmLineSeg::actLockViewExecute(TObject *Sender)

{

ValidateView();

}

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

AnsiString TfrmLineSeg::StrToLen(AnsiString str, int len)

{

AnsiString s=str;

while(s.Length()<len) s=" "+s;

return s;

}

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

void __fastcall TfrmLineSeg::NeigNode(int x, int y, int n)

{

int i,j;

AnsiString s;

if(x<0 || y<0 || x>=w || y>=h) return; //если не принадлежит области изображения

if(apix[x][y][0]!=1) return; // если не является точкой

if(apix[x][y][2]!=-1) return; // если уже обработана на принадлежность узлу

if(NeigCount(x,y)<=2) return;// если мало соседей для сегментации

if(apix[x][y][2]==-1) // если точка не обработана

apix[x][y][2]=n; // точка будет принадлежать узлу n

// wlog(IntToStr(x)+","+IntToStr(y));

// обрабатываем ее соседей

NeigNode(x-1,y-1,n); NeigNode(x,y-1,n); NeigNode(x+1,y-1,n);

NeigNode(x-1,y  ,n);                   NeigNode(x+1,y  ,n);

NeigNode(x-1,y+1,n); NeigNode(x,y+1,n); NeigNode(x+1,y+1,n);

}

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

void __fastcall TfrmLineSeg::actAnalyzeNodeExecute(TObject *Sender)

{

sb1->SimplePanel=true; sb1->SimpleText="Поиск узлов ...";

AnsiString s;

TPoint p;

int i,j,x,y,x1,y1,x2,y2,ssize,nsegs, v,oldv;

for(i=0;i<=w-1;i++)    // maxw-1

for(j=0;j<=h-1;j++)  // maxh-1

apix[i][j][2]=-1;

i=0; j=0;

nsegs=0;

wlog("Поиск узлов ...");

while(j<h)

{

while(i<w)

{

if( apix[i][j][0]==1      // есть точка

&& apix[i][j][2]==-1  // не обработана на принадлежность узлу

&& NeigCount(i,j)>2 ) // является частью узла

{// начинаем выделение узла

nsegs+=1;

wlog("Найден узел №"+IntToStr(nsegs));

//  wlog("Точки в области узла:");

NeigNode(i,j,nsegs); // обрабатываем точки вокруг узла

p=NodeCentre(nsegs);

wlog("Координаты узла: "+IntToStr(p.x)+","+IntToStr(h-1-p.y));

}

i+=1;

} // while i

i=0; j+=1;

} // while j

DrawGrid();

wlog("Поиск узлов завершен");

wlog("ВСЕГО УЗЛОВ: "+IntToStr(nsegs));

sb1->SimpleText=""; sb1->SimplePanel=false;

}

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

void __fastcall TfrmLineSeg::NeigLine(int x,int y, int n)

{

int nc=NeigCount(x,y);

if(nc==1 || nc==2) // если начало или продолжение линии

{

apix[x][y][1]=n;

wlog(IntToStr(x)+","+IntToStr(h-1-y));

// если ( есть точка И не обработана на принадлежность линии )

if(apix[x-1][y-1][0]==1 && apix[x-1][y-1][1]==-1) NeigLine(x-1,y-1,n);

if(apix[x  ][y-1][0]==1 && apix[x  ][y-1][1]==-1) NeigLine(x  ,y-1,n);

if(apix[x+1][y-1][0]==1 && apix[x+1][y-1][1]==-1) NeigLine(x+1,y-1,n);

if(apix[x-1][y  ][0]==1 && apix[x-1][y  ][1]==-1) NeigLine(x-1,y  ,n);

if(apix[x+1][y  ][0]==1 && apix[x+1][y  ][1]==-1) NeigLine(x+1,y  ,n);

if(apix[x-1][y+1][0]==1 && apix[x-1][y+1][1]==-1) NeigLine(x-1,y+1,n);

if(apix[x  ][y+1][0]==1 && apix[x  ][y+1][1]==-1) NeigLine(x  ,y+1,n);

if(apix[x+1][y+1][0]==1 && apix[x+1][y+1][1]==-1) NeigLine(x+1,y+1,n);

}

else if(nc>2) // соединение с узлом

{

apix[x][y][1]=n;

}

}

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

void __fastcall TfrmLineSeg::actAnalyzeSegExecute(TObject *Sender)

{

sb1->SimplePanel=true; sb1->SimpleText="Поиск сегментов линий ...";

AnsiString s;

int i,j,x,y,x1,y1,x2,y2,llen,nlines, v,oldv;

for(i=0;i<=w-1;i++)    // maxw-1

for(j=0;j<=h-1;j++)  // maxh-1

apix[i][j][1]=-1;

i=0; j=0;

nlines=0;

wlog("Поиск сегментов ...");

while(j<h)

{

while(i<w)

{

if( apix[i][j][0]==1 // есть точка

&& apix[i][j][1]==-1 // и она не обработана на принадлежность сегменту линии

&& (NeigCount(i,j)==1    // и является началом (1 сосед)

||  NeigCount(i,j)==2 )) // или продолжением линии (2 соседа)

{// начинаем выделение сегмента

nlines+=1;

wlog("Найден сегмент №"+IntToStr(nlines)+": ["+IntToStr(i)+","+IntToStr(h-1-j)+"]");

wlog("Точки сегмента:");

NeigLine(i,j,nlines); // обрабатываем сегмент линии

}

i+=1;

} // while i

i=0; j+=1;

} // while j

DrawGrid();

wlog("Поиск сегментов завершен");

wlog("ВСЕГО СЕГМЕНТОВ: "+IntToStr(nlines));

sb1->SimpleText=""; sb1->SimplePanel=false;

}

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

void __fastcall TfrmLineSeg::actMatchLinesExecute(TObject *Sender)

{

sb1->SimplePanel=true; sb1->SimpleText="Поиск линий ...";

int i,j,cline,cseg,x,y;

double dist,mindist;

TPoint p;

wlog("Поиск линий ...");

for(i=0;i<=w-1;i++)    // maxw-1

for(j=0;j<=h-1;j++)  // maxh-1

apix[i][j][3]=-1;

i=0; j=0;

while(j<h)

{

while(i<w)

{

if(apix[i][j][1]>0 && apix[i][j][2]>0 // есть соединение с сегментом

&& apix[i][j][3]==-1 // точка не обработана

)

{ // обрабатываем точку и выполняем поиск ей соответствующей

apix[i][j][3]=1;

cline=apix[i][j][1]; // текущая линия

cseg=apix[i][j][2];  // текущий сегмент

p=NodeCentre(cseg);

mindist=MAXDOUBLE;

x=y=-1;

wlog("Поиск соответствия фрагменту "+IntToStr(apix[i][j][1])+" ["+IntToStr(i)+","+IntToStr(j)+"]");

wlog("Центр сегмента "+IntToStr(cseg)+" ["+IntToStr(p.x)+","+IntToStr(p.y)+"]");

for(int j1=0;j1<h;j1++) // поиск точки соответствия

for(int i1=0;i1<w;i1++)

{

if(apix[i1][j1][0]==1     // есть точка

&& apix[i1][j1][3]==-1 // не обработана на соответствие линий

&& apix[i1][j1][1]>0 && apix[i1][j1][2]==cseg  // является пересечением этого сегмента с одной из линий 

)

{

if((dist=plDistance(p.x,p.y,i,j,i1,j1))<=mindist)  // если образует наименьшее отклонение от центра сегмента

{ // запоминаем точку как самую подходящую

x=i1; y=j1;

mindist=dist;

wlog("["+IntToStr(i1)+","+IntToStr(j1)+"] - соотв.:"+FloatToStr(dist));

}

else

{

wlog("["+IntToStr(i1)+","+IntToStr(j1)+"] - не соотв:"+FloatToStr(dist));

}

}

}

if(x>0 && y>0)

{

wlog("Найдено соответствие фрагментов: "+IntToStr(cline)+" и "+IntToStr(apix[x][y][1]));

apix[x][y][3]=1; // точка обработана

FillLine(apix[x][y][1],cline); // заполняем линию

}

}

i+=1;

} // while i

i=0; j+=1;

} // while j

DrawGrid();

wlog("Line matching end");

sb1->SimpleText=""; sb1->SimplePanel=false;

}

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

void __fastcall TfrmLineSeg::FillLine(int n1, int n2)

{

for(int i=0;i<=w-1;i++)    // maxw-1

for(int j=0;j<=h-1;j++)  // maxh-1

if(apix[i][j][1]==n1) apix[i][j][1]=n2;

}

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

TPoint TfrmLineSeg::NodeCentre(int n)

{

int i=0, j=0, cnt=0, xsum=0, ysum=0,x=0,y=0;

while(j<h)

{

while(i<w)

{

if( apix[i][j][2]==n  // точка принадлежит этому узлу

// && apix[i][j][1]>0   // есть пересечение с линией

)

{

xsum+=i;

ysum+=j;

cnt+=1;

}

i+=1;

} // while i

i=0; j+=1;

} // while j

if(cnt>0)

{

x=xsum/cnt;

y=ysum/cnt;

}

return Point(x,y);

}

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

void __fastcall TfrmLineSeg::actZoomWndExecute(TObject *Sender)

{

if(w>0 || h>0)

{

zoom=min(scb1->Width,scb1->Height)/max(w,h);

ZoomTo(zoom);

}

}

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

void __fastcall TfrmLineSeg::GetLineVect(int x,int y,int n)

{

TPoint p;

if(apix[x][y][1]==n && apix[x][y][3]==-1) // принадлежит этой линии и не обработана в код

{

// обработка текущей точки

apix[x][y][3]=1;

if(linecode=="")

linecode+=IntToStr(x)+","+IntToStr(y);

else

linecode+=","+IntToStr(x)+","+IntToStr(h-1-y);

// обрабтка продолжения линии

if(apix[x][y][2]>0) // если пересечение с сегментом

{// обработка линии внутри сегмента

p=FindMatch(x,y);

CodeLine(x,y,p.x,p.y); // вывод кода линии внутри сегмента

x=p.x;

y=p.y;

apix[x][y][3]=1;

if(linecode=="")

linecode+=IntToStr(x)+","+IntToStr(y);

else

linecode+=","+IntToStr(x)+","+IntToStr(h-1-y);

}

GetLineVect(x-1,y-1,n); GetLineVect(x,y-1,n); GetLineVect(x+1,y-1,n);

GetLineVect(x-1,y  ,n);  GetLineVect(x+1,y  ,n);

GetLineVect(x-1,y+1,n); GetLineVect(x,y+1,n); GetLineVect(x+1,y+1,n);

}

}

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

void __fastcall TfrmLineSeg::CodeLine(int x1,int y1,int x2,int y2)

{

wlog("Кодирование линии ["+IntToStr(x1)+","+IntToStr(h-1-y1)+"]-["+IntToStr(x2)+","+IntToStr(h-1-y2)+"]:");

if(abs(x1-x2)>abs(y1-y2)) // точек по x больше

{

wlog("Цикл по оси x. Точки линии:");

int x, y, xa=min(x1,x2), xb=max(x1,x2);

double k=double(y2-y1)/(x2-x1), b=y1-x1*k;

x=xa+1;

while(x<xb)

{

y=k*x+b;

if(linecode=="")

linecode+=IntToStr(x)+","+IntToStr(h-1-y);

else

linecode+=","+IntToStr(x)+","+IntToStr(h-1-y);

wlog(IntToStr(x)+","+IntToStr(h-1-y));

x+=1;

}

}

else // точек по y больше

{

wlog("Цикл по оси y. Точки линии:");

int x, y, ya=min(y1,y2), yb=max(y1,y2);

double k=double(x2-x1)/(y2-y1), b=x1-y1*k;

y=ya+1;

while(y<yb)

{

x=k*y+b;

if(linecode=="")

linecode+=IntToStr(x)+","+IntToStr(h-1-y);

else

linecode+=","+IntToStr(x)+","+IntToStr(h-1-y);

wlog(IntToStr(x)+","+IntToStr(h-1-y));

y+=1;

}

}

}

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

TPoint __fastcall TfrmLineSeg::FindMatch(int x, int y)

{

int i,j;

TPoint p;

p.x=x;

p.y=y;

i=0; j=0;

while(j<h)

{

while(i<w)

{

if(apix[i][j][1]==apix[x][y][1]     // если принадлежит той же линии

&& apix[i][j][2]==apix[x][y][2]  // и принадлежит тому же сегменту

&& (i!=x || j!=y) // и это другая точка

)

{ // это искомая точка

p.x=i;

p.y=j;

}

i+=1;

} // while i

i=0; j+=1;

} // while j

  return p;

}

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

void __fastcall TfrmLineSeg::actMatchOutExecute(TObject *Sender)

{

int i,j,lineno,lnum;

sb1->SimplePanel=true; sb1->SimpleText="Вывод кода линий ...";

for(j=0;j<h;j++)  // инициализация массива временных атрибутов

for(i=0;i<w;i++)

apix[i][j][3]=-1;

MemoOut->Clear();

lnum=0;

for(j=0;j<h;j++)

for(i=0;i<w;i++)

{

if( apix[i][j][1]>0// есть линия

&& apix[i][j][3]==-1 // и она не обработана

&& (NeigCount(i,j)==1 // точка является началом линии

|| apix[i][j][2]>0)      // или узлом

)

{ // формируем код для этой линии

lineno=apix[i][j][1];

lnum+=1;

linecode="";

GetLineVect(i,j,lineno);

MemoOut->Lines->Add(IntToStr(lnum)+":"+linecode);

wlog(IntToStr(lnum)+"(line #"+IntToStr(lineno)+"):"+linecode);

}

}

sb1->SimpleText=""; sb1->SimplePanel=false;

}

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

void __fastcall TfrmLineSeg::actOpenArrayExecute(TObject *Sender)

{

int i,j;

AnsiString s;

OpenDialog1->Title="Открыть массив точек";

OpenDialog1->Filter="Файлы массивов точек (*.dat)|*.dat|Все файлы (*.*)|*.*";

if(OpenDialog1->Execute())

{

sb1->SimplePanel=true; sb1->SimpleText="Открытие массива точек ...";

mArray->Lines->LoadFromFile(OpenDialog1->FileName);

try

{

w=StrToInt(mArray->Lines->Strings[0]);

h=StrToInt(mArray->Lines->Strings[1]);

if(w>0 & h>0)

{

Image1->Picture->Bitmap->Width=w;

Image1->Picture->Bitmap->Height=h;

Image1->Width=w;

Image1->Height=h;

Image1->Canvas->FillRect(Image1->ClientRect);

scb1->Enabled=true;

ZoomTo(zoom);

for(j=0;j<h;j++)

{

s=mArray->Lines->Strings[j+2];

for(i=0;i<w;i++)

{

apix[i][j][1]=apix[i][j][2]=apix[i][j][3]=-1;

if(s[i+1]=='1') // есть точка

{

apix[i][j][0]=1;

Image1->Canvas->Pixels[i][j]=c0;

}

else // нет точки

{

apix[i][j][0]=0;

Image1->Canvas->Pixels[i][j]=c1;

}

}

}

}

else

throw Exception("");

}

catch (...)

{

MessageBox(Handle,"Ошибка открытия массива", "ОШИБКА", MB_OK);

}

sb1->SimpleText=""; sb1->SimplePanel=false;

}

}

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

void __fastcall TfrmLineSeg::actSaveArrayExecute(TObject *Sender)

{

int i,j;

AnsiString s;

SaveDialog1->Filter="Файлы массивов точек (*.dat)|*.dat|Все файлы (*.*)|*.*";

SaveDialog1->DefaultExt="*.dat";

SaveDialog1->Title="Сохранить массив точек";

if(SaveDialog1->Execute())

{

sb1->SimplePanel=true; sb1->SimpleText="Запись массива точек ...";

mArray->Clear();

mArray->Lines->Add(IntToStr(w));

mArray->Lines->Add(IntToStr(h));

for(j=0;j<h;j++)

{

s="";

for(i=0;i<w;i++)

{

s+=apix[i][j][0]==1 ? '1' : '0';

}

mArray->Lines->Add(s);

}

mArray->Lines->SaveToFile(SaveDialog1->FileName);

sb1->SimpleText=""; sb1->SimplePanel=false;

}

}

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

void __fastcall TfrmLineSeg::actOptionsExecute(TObject *Sender)

{

frmOptions->Label1->Font->Color=c5;

frmOptions->Label2->Font->Color=c2;

frmOptions->Label3->Font->Color=c3;

frmOptions->Label4->Font=MemoLog->Font;

frmOptions->Label5->Font=MemoOut->Font;

frmOptions->cbLogs->Checked=logs;

if(frmOptions->ShowModal()==mrOk)

{

try

{

c5=frmOptions->Label1->Font->Color;

c2=frmOptions->Label2->Font->Color;

c3=frmOptions->Label3->Font->Color;

MemoLog->Font=frmOptions->Label4->Font;

MemoOut->Font=frmOptions->Label5->Font;

logs=frmOptions->cbLogs->Checked;

}

catch (...)

{

MessageBox(Handle,"Неверно указано число", "Ошибка", MB_OK);

}

DrawGrid();

ShowInfo(-1,-1);

}

}

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

void __fastcall TfrmLineSeg::actSaveCodeExecute(TObject *Sender)

{

SaveDialog1->Filter="Файлы кодов линий (*.lsc)|*.lsc|Все файлы (*.*)|*.*";

SaveDialog1->DefaultExt="*.lsc";

SaveDialog1->Title="Сохранить коды линий";

if(SaveDialog1->Execute())

{

MemoOut->Lines->SaveToFile(SaveDialog1->FileName);

}

}

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

void __fastcall TfrmLineSeg::GetLineVect2(int x,int y,int n)

{

TPoint p;

if(apix[x][y][1]==n && apix[x][y][3]==-1) // принадлежит этой линии и не обработана в код

{

// обработка текущей точки

if (NeigCount(x,y)==1) // если конец линии

{ // обработка конца линии

if(nodescnt==0) // если не было найдено конечных точек

{

nodescnt+=1;

xs1=x; ys1=1; // первая координата

}

else if(nodescnt==1) // если уже имеется одна конечная точка

{

}

apix[x][y][3]=1;

xs1=x;

ys1=y;

nodescnt+=1;

}

else if(apix[x][y][2]>0) // если начинается узел

{

}

else // продолжение линии, продолжаем обработку

{

GetLineVect(x-1,y-1,n); GetLineVect(x,y-1,n); GetLineVect(x+1,y-1,n);

GetLineVect(x-1,y  ,n); GetLineVect(x+1,y  ,n);

GetLineVect(x-1,y+1,n); GetLineVect(x,y+1,n); GetLineVect(x+1,y+1,n);

}

}

}

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

void __fastcall TfrmLineSeg::actSegCodeOutExecute(TObject *Sender)

{

int i,j,lineno,lnum;

sb1->SimplePanel=true; sb1->SimpleText="Вывод кода сегментов ...";

for(j=0;j<h;j++)  // инициализация массива временных атрибутов

for(i=0;i<w;i++)

apix[i][j][3]=-1;

MemoOut->Clear();

lnum=0;

for(j=0;j<h;j++)

for(i=0;i<w;i++)

{

if( apix[i][j][1]>0 // есть сегмент

&& apix[i][j][3]==-1 // и он не обработан

&& (NeigCount(i,j)==1 // точка является началом сегмента

|| NeigCount(i,j)==2)   // или продолжением сегмента

)

{ // формируем код для этой линии

xs1=ys1=xs2=ys2=xs3=ys3=-1;

nodescnt=0;

lineno=apix[i][j][1];

lnum+=1;

linecode="";

GetLineVect2(i,j,lineno);

MemoOut->Lines->Add(IntToStr(lnum)+":"+linecode);

wlog(IntToStr(lnum)+"(line #"+IntToStr(lineno)+"):"+linecode);

}

}

sb1->SimpleText=""; sb1->SimplePanel=false;

}

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



П.3.3. Текст модуля lsimgsize.h



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

#ifndef lsImgSizeH

#define lsImgSizeH

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

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

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

class TfrmImgSize : public TForm

{

__published:	// IDE-managed Components

TButton *btnOK;

TButton *btnCancel;

TEdit *edtWidth;

TEdit *edtHeight;

TLabel *Label1;

TLabel *Label2;

void __fastcall btnCancelClick(TObject *Sender);

private:// User declarations

public:// User declarations

__fastcall TfrmImgSize(TComponent* Owner);

};

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

extern PACKAGE TfrmImgSize *frmImgSize;

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

#endif



П.3.4. Текст модуля lsimgsize.cpp



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

#include <vcl.h>

#pragma hdrstop

#include "LineSeg.h"

#include "lsImgSize.h"

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

#pragma package(smart_init)

#pragma resource "*.dfm"

TfrmImgSize *frmImgSize;

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

__fastcall TfrmImgSize::TfrmImgSize(TComponent* Owner)

: TForm(Owner)

{

}

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

void __fastcall TfrmImgSize::btnCancelClick(TObject *Sender)

{

Close();

}

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



П.3.5. Текст модуля lsoptions.h



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

#ifndef lsOptionsH

#define lsOptionsH

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

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <Dialogs.hpp>

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

class TfrmOptions : public TForm

{

__published:// IDE-managed Components

TButton *btnOk;

TButton *btnCancel;

TColorDialog *ColorDialog1;

TFontDialog *FontDialog1;

TCheckBox *cbLogs;

TGroupBox *gbColors;

TLabel *Label1;

TLabel *Label2;

TLabel *Label3;

TGroupBox *gbFonts;

TLabel *Label4;

TLabel *Label5;

void __fastcall btnCancelClick(TObject *Sender);

void __fastcall Label1MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y);

void __fastcall Label2MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y);

void __fastcall Label3MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y);

void __fastcall Label4MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y);

void __fastcall Label5MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y);

private:// User declarations

public:// User declarations

__fastcall TfrmOptions(TComponent* Owner);

};

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

extern PACKAGE TfrmOptions *frmOptions;

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

#endif



П.3.6. Текст модуля lsoptions.cpp



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

#include <vcl.h>

#pragma hdrstop

#include "lsOptions.h"

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

#pragma package(smart_init)

#pragma resource "*.dfm"

TfrmOptions *frmOptions;

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

__fastcall TfrmOptions::TfrmOptions(TComponent* Owner)

: TForm(Owner)

{

}

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

void __fastcall TfrmOptions::btnCancelClick(TObject *Sender)

{

Close();

}

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

void __fastcall TfrmOptions::Label1MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y)

{

ColorDialog1->Color=Label1->Font->Color;

if(ColorDialog1->Execute())

Label1->Font->Color=ColorDialog1->Color;

}

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

void __fastcall TfrmOptions::Label2MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y)

{

ColorDialog1->Color=Label2->Font->Color;

if(ColorDialog1->Execute())

Label2->Font->Color=ColorDialog1->Color;

}

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

void __fastcall TfrmOptions::Label3MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y)

{

ColorDialog1->Color=Label3->Font->Color;

if(ColorDialog1->Execute())

Label3->Font->Color=ColorDialog1->Color;

}

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

void __fastcall TfrmOptions::Label4MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y)

{

FontDialog1->Font=Label4->Font;

if(FontDialog1->Execute())

Label4->Font=FontDialog1->Font;

}

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

void __fastcall TfrmOptions::Label5MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y)

{

FontDialog1->Font=Label5->Font;

if(FontDialog1->Execute())

Label5->Font=FontDialog1->Font;

}

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



П.3.7. Текст модуля prjlineseg.cpp



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

#include <vcl.h>

#pragma hdrstop

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

USEFORM("LineSeg.cpp", frmLineSeg);

USEFORM("lsImgSize.cpp", frmImgSize);

USEFORM("lsOptions.cpp", frmOptions);

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

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

{

try

{

Application->Initialize();

Application->Title = "Линейная сегментация";

Application->CreateForm(__classid(TfrmLineSeg), &frmLineSeg);

Application->CreateForm(__classid(TfrmImgSize), &frmImgSize);

Application->CreateForm(__classid(TfrmOptions), &frmOptions);

Application->Run();

}

catch (Exception &exception)

{

Application->ShowException(&exception);

}

catch (...)

{

try

{

throw Exception("");

}

catch (Exception &exception)

{

Application->ShowException(&exception);

}

}

return 0;

}

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