Статья затрат
|
Сумма затрат, руб.
|
Структура затрат, %
|
Расходы на материалы
Расходы на оплату труда
Налоги и отчисления
Расходы на содержание ВТ
Накладные расходы
Прочие расходы
|
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.
План здания
где 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 проведем
ряд несложных вычислений:
Общий контур
заземления
Рис. 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.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.
Подсистема
также имеет возможность редактирования исходного изображения прямо в процессе
его обработки, а также выбора необходимого режима просмотра (выбор масштаба, выделение
узлов и сегментов линий), что позволяет наглядно изучить влияние характеристик
входного изображения на работу алгоритмов его распознавания. Встроенная панель состояния
позволяет интерактивно получать информацию о текущем состоянии подсистемы.
Разработанная
подсистема используется в составе системы «Автоматизированного анализа пространственной
структуры изображений» и взаимодействует с другими ее подсистемами: подсистемой
фильтрации и подсистемой цепного кодирования.
СПИСОК ЛИТЕРАТУРЫ
1.
Павлидис Т. Алгоритмы машинной графики и обработки
изображений. - М.: Радио и связь, 1986. - 400с.
2.
Дуда Р., Харт П. Распознавание образов и анализ
сцен. - М.: Мир, 1976. - 512с.
3.
Колмогоров А.Н., Фомин С.В. Элементы теории функций
и функционального анализа. – М.: Наука, 1981. – 544с.
4.
Бакут П.А., Колмогоров П.С. Сегментация
изображений: Методы выделения границ областей // Зарубежная радиоэлектроника,
1987, № 10. - С. 25-46.
5.
Бакут П.А., Колмогоров П.С., Варновицкий И.Э.
Сегментация изображений: методы пороговой обработки // Зарубежная
радиоэлектроника, 1988, № 4. - С. 6-24.
6.
Быстрые алгоритмы в цифровой обработке изображений.
- М.: Радио и связь, 1984. - 224с.
7.
Вдовин А.М., Хаба Б.С., Мурынов А.И., Лялин В.Е.
Исследование планарных элементов пространственной структуры изображений //
Химическая физика и мезоскопия. Т.3, 2001, №2. - С.134-147.
8.
Журавлев Ю.И., Гуревич И.Б. Распознавание образов и
анализ изображений // Искусственный интеллект. Кн. 2. Модели и методы. - М.:
Радио и связь, 1990. - 304с.
9.
Прэтт У. Цифровая обработка изображений. - Кн. 1. -
М.: Мир, 1982. - 312с. - Кн. 2. - М.: Мир, 1982. - 480с.
10. Розенфельд А., Дейвис Л.С. Сегментация и модели изображения // ТИИЭР,
т. 67, 1979, № 5. – С. 71-81.
11. Толковый словарь по искусственному интеллекту / А. Н. Аверкин, М.Г.
Гаазе-Рапопорт, Д.А. Поспелов. – М.: Радио и связь, 1992. – 256с.
12. Эйнджел Э. Интерактивная компьютерная графика. – М.: Вильямс, 2001. –
592с.
13. Murynov A.I., Levitskaya L.N., Shibaeva I.V. The model
discretely - planimetry graphic structures of the image graphic // Тез. докл. - Нижний Новгород: Изд-во
Нижегородского госуниверситета, 2004. – С. 258.
14. Николаев Д.П. Алгоритмы цветовой сегментации, применимые в условиях
сложного освещения сцены // Автореф. дисс. – М: Изд-во института по проблем
передачи информации РАН, 2004
15. Радыгина И. И. Методические пособия для
выполнения раздела «Организационно экономическая часть».– Ижевск: ИжГТУ, 2002.
16. Бычин В.Б., Малинин С.В. Нормирование труда: Учебник. – Москва:
Издательство «Экзамен», 2002.
17. ГОСТ 12.0.002-80 Система стандартов безопасности труда. Термины и
определения - М.: Издательство стандартов, 1984.
18. СанПиН 2.2.4.548-96 Гигиенические требования к микроклимату
производственных помещений. -М.: Издательство стандартов, 1996.
19. ГОСТ 12.1.003-89 Система стандартов безопасности труда. Шум. Общие
требования безопасности. -М.: Издательство стандартов, 1989.
20. ГОСТ 12.1.009-76 Система стандартов безопасности труда.
Электробезопасность. -М.: Издательство стандартов, 1976.
21. ГОСТ 12.1.004-91 Система стандартов безопасности труда. Пожарная
безопасность. Общие требования. -М.: Издательство стандартов, 1992.
22. СНиП 24-05-95 Правила устройства электроустановок. -М.: Издательство
стандартов, 1995.
23. Сенилов М.А., Почерняев С. В., Килин И. В. Методические указания по
дипломному проектированию. - Ижевск: ИжГТУ, 1998.
24. ГОСТ 19.701-90 ЕСПД. Схемы алгоритмов, программ, данных и систем. –
М.: Издательство стандартов, 1991.
25. ГОСТ 19.504-79 ЕСПД. Руководство программиста. Требования к содержанию
и оформлению. – М.: Издательство стандартов, 1979.
26. ГОСТ 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 *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("Поиск
узлов завершен");
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";
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;
}
//---------------------------------------------------------------------------