Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
PAGE 2
Федеральное агентство по образованию
Государственное образовательное учреждение
высшего профессионального образования
«ИЖЕВСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»
Факультет «Информатика и вычислительная техника»
Кафедра «Программное обеспечение»
ПОЯСНИТЕЛЬНАЯ ЗАПИСКА
к дипломной работе на тему:
«Система идентификации личности по отпечаткам пальцев. Подсистема распознавания»
Дипломник студент группы 10-19-1 Вотинцев А.С.
Руководитель д.т.н., профессор Мурынов А.И.
Консультант по экономической части к.э.н., доцент Радыгина И.И.
Консультант по безопасности и экологичности проекта Якименко Г.Ф.
Нормоконтроль Соболева В.П.
Рецензент вед. Инженер Кропачева Л.Н.
Заведующий кафедрой «Программное обеспечение» д. т. н., профессор
Мурынов А.И.
РЕФЕРАТ
Пояснительная записка к дипломной работе на тему «Система идентификации личности по отпечаткам пальцев. Подсистема распознавания» оформлена на 128 листах, содержит 27 рисунков, 18 таблиц.
Целью данной работы является разработка подсистемы распознавания отпечатка пальца в составе системы идентификации личности по отпечаткам пальцев на основе структурного представления отпечатка.
Работа включает в себя разработку и реализацию алгоритма формирования относительных параметров для минюций. Подбор параметров системы допусков и критериев схожести при сравнении двух отпечатков. Разработку и реализацию алгоритма поиска схожих отпечатков на основе относительных параметров минюций и разработанных критериев схожести.
Для написания соответствующего программного обеспечения были изучены материалы и публикации в области цифровой обработки изображений, векторизации, биологического строения человека и его биометрических параметров.
В результате проделанной работы было разработано программное обеспечение, предназначенное для автоматизации процесса идентификации личности по отпечаткам пальцев на основе характерных особенносетей любого папиллярного узора. В работе подсистемы используются характеристики локальных особенностей, получаемые в результате работы другой подсистемы в составе системы.
На сегодняшний день существуют готовые системы для идентификации личности, обладающие высокой степенью защиты, быстродействием, а также удобством в применении. Однако ни одна из существующих разработок не дает объектного описания и метода сравнения отпечатков. Все разработки являются уникальными, обладают собственными нововведениями, «ноу-хау» и составляют коммерческую тайну.
Данная разработка обладает открытым кодом и позволяет проводить структурное описание папиллярного узора. Поэтому данная разработка является уникальной и не имеет аналогов в современной индустрии компьютерной обработки изображений.
Необходимо отметить, что используемый метод, пригоден не только для распознавания изображения отпечатков пальцев, но и для распознавания других битовых изображений, таких как символьная информация, щрифты и подписи.
Разработанное программное обеспечение является исследовательским, оно направлено на изучение и анализ методов обработки изображений и его описания. С его помощью уже были получены важные экспериментальные данные, использованные в данной работе. Конечным программным продуктом может являться оболочка, представляющая в значительной мере автоматизированный интерфейс для идентификации личности.
СОДЕРЖАНИЕ
[1]
[2] [2.1] Обоснование целесообразности разработки системы идентификации личности по отпечаткам пальцев [2.1.1] Назначение системы [2.1.2] Характеристика функциональной структуры системы [2.1.3] Обоснование цели создания системы [2.1.4] Обоснование состава автоматизируемых задач
[2.2] [2.2.1] BioLink [2.2.1.1] BioLink BioTime 2006 [2.2.1.2] BioLink Authenteon Software Appliance (ASA) [2.2.2] Microsoft IntelliMouse Explorer with Fingerprint Reader [2.2.3] Сотовый телефон GI100 [2.2.4] Adobe Photoshop [2.2.5] FineReader [2.2.6] Вывод по аналитическому обзору [2.3] Основные требования к системе [2.3.1] Основные цели создания системы и критерии эффективности ее функционирования [2.3.2] Функциональное назначение системы [2.3.3] Особенности и условия эксплуатации системы [2.3.4] Требования к функциональной структуре [2.3.5] Требования к техническому обеспечению [2.3.6] Требования к информационному обеспечению [2.3.7] Требования к программному обеспечению [2.4] Основные технические решения проекта системы [2.4.1] Решение по комплексу технических средств [2.4.2] Описание системы программного обеспечения
[3] [3.1] Описание постановки задачи распознавания [3.1.1] Характеристика задачи [3.1.2] Входная информация [3.1.3] 2.1.3. Выходная информация [3.1.4] Математическая постановка задачи [3.2] Описание алгоритма преобразования абсолютных параметров минюций к относительным параметрам [3.2.1] Назначение и характеристика алгоритма преобразования абсолютных параметров минюций к относительным [3.2.2] Используемая информация [3.2.3] Результаты решения [3.2.4] Математическое описание алгоритма преобразования абсолютных параметров минюций к относительным [3.2.4.1] Алгоритм нахождения габаритных размеров и количества точек в непрерывной области [3.2.5] Требования к контрольному примеру [3.2.6] Список условных обозначений [3.3] Описание алгоритма сравнения структурных представлений отпечатков пальцев [3.3.1] Назначение и характеристика алгоритма сравнения структурных представлений отпечатков пальцев [3.3.2] Используемая информация [3.3.3] Результаты решения [3.3.4] Математическое описание алгоритма нахождения статистических характеристик цветового кластера [3.3.5] Алгоритм нахождения статистических характеристик цветового кластера [3.3.6] Требования к контрольному примеру [3.3.7] Список условных обозначений [3.4] Описание подпрограммы «OnBnClickedCompare» [3.4.1] Вводная часть [3.4.2] Функциональное назначение [3.4.3] Описание информации [3.4.4] Используемые подпрограммы [3.4.5] Схема подпрограммы «OnBnClickedCompare» [3.5] Описание подпрограммы «Convert» [3.5.1] Вводная часть [3.5.2] Функциональное назначение [3.5.3] Описание информации [3.5.4] Используемые подпрограммы [3.5.5] Схема подпрограммы «Convert» [3.6] Описание подпрограммы «CompareWithBase» [3.6.1] Вводная часть [3.6.2] Функциональное назначение [3.6.3] Описание информации [3.6.4] Используемые подпрограммы [3.6.5] Схема подпрограммы « CompareWithBase » [3.7] Описание подпрограммы «Compare» [3.7.1] Вводная часть [3.7.2] Функциональное назначение [3.7.3] Описание информации [3.7.4] Используемые подпрограммы [3.7.5] Схема подпрограммы «Compare» [3.8] Описание контрольного примера [3.8.1] Назначение [3.8.2] Исходные данные [3.8.3] Контрольный пример [3.8.4] Тестирование программного обеспечения системы распознавания личности по отпечаткам пальцев
[4] [4.1] Обоснование необходимости разработки подсистемы распознавания в системе идентификации личности по отпечаткам пальцев. [4.2] Расчет затрат на разработку подсистемы распознавания в системе идентификации личности по отпечаткам пальцев
[5] [5.1] Анализ опасных и вредных факторов, возникающих при работе на компьютере [5.2] Техника безопасности при эксплуотации компьютера [5.3] Организация рабочего места оператора [5.4] Требования к освещению и расчет искусственного освещения [5.5] Пожарная безопасность
[6]
[7]
[8]
[9]
[10] |
ПЕРЕЧЕНЬ УСЛОВНЫХ ОБОЗНАЧЕНИЙ
СТ специфическая точка миньюция
БД база данных с отпечатками
PIN персональный идентификационный номер
ПЗС память с зарядовой связью
КМОП технология изготовления микросхем кремний метал оксид полупроводник
ОП отпечаток пальца
dpi количество точек на дюйм (dot per inch)
ПО программное обеспечение
ОС операционная система
ЭВМ электронно-вычислительная машина
ПК персональный компьютер
LIFO - Last In First Out, метод обработки информации в структурах данных
MFC Microsoft Foundation Class
В наше время пароли, персональные идентификационные номера и специальные идентификационные карточки стали жизненной необходимостью. Например, чтобы получить наличные из банкомата, Вам потребуется код PIN, чтобы получить доступ к почтовой программе или к определенной категории компьютерных данных, необходим пароль. В свете последних событий, происходящих в мире, особенно в связи с ростом активности международного терроризма, вопросам безопасности уделяется все более пристальное внимание.
Таким образом, человек должен хранить в своей памяти огромное количество различных комбинаций цифр и букв. Чтобы облегчить участь современного человека, компании, специализирующиеся на производстве компьютеров, начали заниматься разработкой биометрических технологий. Биометрия эта наука, изучающая возможности использования различных характеристик человеческого тела (будь то отпечатки пальцев или уникальные свойства человеческого зрачка или голоса) для идентификации каждого конкретного человека. Пользуясь биометрическими технологиями, человек никогда не сможет забыть необходимый ему пароль или код, поскольку его большой палец, голос или зрачок глаза всегда находятся с ним /1/.
Отпечаток пальца образует так называемые папиллярные линии на гребешковых выступах кожи, разделенных бороздками. Из этих линий складываются сложные узоры (дуговые, петлевые и завитковые), которые обладают свойствами индивидуальности и неповторимости, что позволяет абсолютно надежно идентифицировать личность. Хотя процент отказа в доступе уполномоченных пользователей составляет около 3, процент ошибочного доступа меньше одного к миллиону. Преимущества доступа по отпечатку пальца простота использования, удобство и надежность. Весь процесс идентификации занимает мало времени и не требует усилий от тех, кто использует данную систему доступа. Исследования также показали, что использование отпечатка пальца для идентификации личности является наиболее удобным из всех биометрических методов. Вероятность ошибки при идентификации пользователя намного меньше в сравнении с другими биометрическими методами /2/. Кроме того, устройство идентификации по отпечатку пальца не требует много места на клавиатуре или в механизме.
Образ отпечатка пальца, как правило, сохраняется в двоичном коде, где каждый пиксель рисунка описывается 8 битами, то есть 256 оттенками серого цвета. В передовых системах сканирования цифровой образ отпечатка обрабатывается с помощью специального алгоритма улучшения изображения. Этот алгоритм обеспечивает обратную связь с датчиком для регулирования параметров сканирования. Когда датчик фиксирует окончательный образ, алгоритм настраивает контрастность и четкость изображения отпечатка для получения наилучшего качества.
Методы опознания отпечатка пальца основаны на сравнении с образцами или на использовании характерных деталей.
При опознании по деталям из образа извлекаются только специфические места, где найдена особенность (деталь). Обычно это либо окончание гребня, либо его раздвоение (рис. 1). Содержание шаблона в этом случае составляют относительные координаты и сведения об ориентации детали. Распознающий алгоритм отыскивает и сравнивает между собой соответствующие детали. Ни поворот отпечатка пальца, ни его параллельный перенос (сдвиг) не влияют на функционирование системы, поскольку алгоритм работает с относительными величинами.
Типы минюций
Рис. 1
Для сравнения на битовом образе находятся локальные особенности папиллярного узора минюции.
Для поиска минюций алгоритм производит обход по контуру гребней.
Система идентификации личности по отпечаткам пальцев реализует определение личности на основе биометрических параметров, а именно отпечатков пальцев. Система предназначена для обработки графических изображений отпечатков. Система позволяет сравнить несколько отпечатков друг с другом по выделенным локальным особенностям минюциям и их относительным параметрам (расположению одних минюций относительно всех остальных), что гарантирует независимость сравнения от параллельного переноса и вращения.
Программный продукт найдет применение в различных прикладных системах, включая:
Системы гражданской идентификации включают в себя:
Криминалистические системы идентификации включают в себя:
Крупномасштабные коммерческие приложения включают в себя:
Функциональная схема системы приведена на рис. 1.1.
Обработка изображений состоит из следующих этапов:
Функциональная схема системы идентификации личности по отпечаткам пальцев
- подсистема анализа - подсистема распознавания
Рис. 1.1
На данный момент надежная информационная защита является одним из основных критериев, по которым должны отбираться системы, предназначенные для хранения и обработки важной информации. Это обусловлено существующей вероятностью несанкционированного доступа в такие системы, поскольку они имеют широкое информационное взаимодействие со смежными системами управления через сеть INTRANET. Поэтому обеспечение информационной безопасности должно являться важнейшим этапом при их разработке.
Защита на основе биометрических параметров человеческого тела, в частности по отпечатку пальца, обладает рядом неоспоримых полюсов: простота использования, удобство и надежность. Весь процесс идентификации занимает мало времени и не требует усилий от тех, кто использует данную систему доступа. Исследования также показали, что использование отпечатка пальца для идентификации личности является наиболее удобным из всех биометрических методов. Вероятность ошибки при идентификации пользователя таким способом намного меньше в сравнении с другими биометрическими методами. Кроме того, устройство идентификации по отпечатку пальца не требует много места на клавиатуре или в механизме.
В большинстве случаев работа с важной информацией подразумевает также своевременное принятие решений и непрерывное управление ходом выполнения. В связи с этим существует необходимость непрерывного подтверждения личности (в случае если человек по какой-то причине покинет свое рабочее место, то любой в это время сможет задавать команды телеуправления или ответственные команды). Такое подтверждение личности метод «единого входа в сеть» предоставить не может, а вводить пароль после каждой команды обременительно.
Хотя на рынке существуют готовые системы, но на ряду со своими преимуществами они обладают рядом недостатков, таких как закрытость исходного кода и алгоритма, а также высокая цена. Вследствие чего есть смысл в разработке системы, которая бы предоставляла возможность всем разработчикам иметь готовую базу для разработки собственных проектов на основе биометрических технологий
Целью данной работы является разработка и реализация такого преобразования изображения, при котором данные о расположение уникальных особенностей сохраняются наиболее полно и с наименьшим содержанием ложной информации.
Создаваемая система носит поисково-исследовательский характер и направлена на облегчение разработки алгоритмов обработки изображений, упрощение анализа экспериментальных данных и выявление общих закономерностей.
Реализация системы идентификации личности по отпечаткам позволит интегрировать в едином интерфейсе все этапы обработки изображения отпечатка пальца и сравнения его с другими отпечатками:
Как уже было указано во введении, метод опознавания личности по отпечаткм пальцев известен достаточно давно и с появлением электронно-вычислительной техники начали появлятся программные продукты для анализа и сравнения изображений.
BioLink, ведущий поставщик технологий обеспечения безопасности, проектирует, производит и продает передовые биометрические продукты, основанные на принципе дактилоскопии. Предлагаемые решения составляют основу для систем аутентификации пользователей в компьютерных сетях, платформах электронной коммерции и системах обеспечения безопасности физического доступа.
BioLink предлагает гамму продуктов, основанных на фирменных технологиях сканирования отпечатков пальцев и обработки изображений, а также на алгоритме идентификации «один ко многим», решающих многие из существующих сегодня проблем безопасности.
BioTime 2006 это система управления рабочим временем, являющаяся новейшей разработкой компании BioLink. Система BioTime 2006 упрощает обычные задачи учета и управления рабочим временем и обеспечивает простоту, легкость и удобство регистрации прихода и ухода сотрудников компании. Кроме того, система BioTime 2006 предоставляет различные виды отчетов по опозданиям, недоработкам и переработкам сотрудников, времени их прихода и ухода, а также автоматизирует создание табеля учета рабочего времени.
Программный сервер BioLink Authenteon Software Appliance (ASA) - это программное обеспечение для сравнения шаблонов отпечатков пальцев BioLink. ASA объединяет в себе парольную защиту и клиент-серверную аутентификацию при входе в Windows, Novell и NFS при решении одной из самых актуальный на сегодняшний день проблем защиты - положительной идентификации пользователей корпоративной сети. Сервер поддерживает до 300 пользователей.
Анонсированная Microsoft осенью 2004г. новая линейка продуктов с использованием биометрических технологий - сканер отпечатков пальцев, клавиатура со встроенным сканером и беспроводная оптическая мышь со сканером обладает возможностями:
Продукт подходит для применения за личным ПК. Программное обеспечение имеет очень ограниченную функциональность. Нет возможности получить параметры отсканированного отпечатка пальца, установить дополнительные действия от того какой палец был приложен.
GI100 - первый телефон с функцией распознавания отпечатков пальцев. Отпечатки пальцев используются как для набора номера, так и для игр. Каждый из пальцев владельца телефона используются для быстрого набора одного из десяти введенных в память телефона номеров. Таким же образом и во время игр можно использовать вместо нажатия кнопок отпечатки пальцев;
Ограничение доступа при включении телефона происходит сканирование отпечатка пальца включившего /3/.
Большим недостатком продукта является то, что в случае трехкратной неудачи при распознавании отпечатка пальца предлагается ввести пароль. Таким образом, доступ к телефону может получить не владелец, а просто знающий пароль человек /4/.
Профессиональный редактор растровых изображений. Основные возможности:
Профессиональная программа распознавания печатного текста. Основные возможности:
Продукт предназначен для распознавания печатного текста различной сложности после сканирования, имеет мощный набор инструментов для улучшения качества распознавания, а также исправления неточно распознанных символов. Не имеет возможности дополнять набор распознаваемых символов, вследствие чего применение ограничивается только распознаванием печатного текста. /6/
Список программных продуктов, безусловно, может быть расширен, но все же самые характерные и популярные разработки в него включены.
Среди программных продуктов, посвященных идентификации по папиллярному узору, можно выделить основные возможности:
В связи с указанными особенностями существующих программных средств актуальной является разработка системы, обладающая открытым кодом и позволяющая проводить структурное описание папиллярного узора. Возможность получать его обектное описание и сравнение. Применение алгоритма не только для описания изображения отпечатков пальцев, но и для объектного описания других битовых изображений, таких как символьная информация, щрифты и подписи.
Эту задачу решает система распознавания личности по отпечаткам пальцев.
Создание системы распознавания личности позволит получить новую возможность по подготовке изображений к структурному анализу, разработать инструмент, улучшающий качество графической информации за счет снижения искажений и шумов.
Для оценки эффективности работы системы можно использовать качество получаемых на выходе изображений, и их структурное описание. А также уровень правильного распознавания отпечатков, который можно судить по количеству отказов для правильного отпечатка, и количеству входов для неверного отпечатка.
Разработанная система обладает открытым кодом, позволяет получать структурное описание папиллярного узора и его сравнение с другими. Алгоритм подходит для работы не только с изображениями отпечатков пальцев, но и для других битовых изображений, таких как символьная информация, щрифты и подписи.
Реализация системы идентификации личности по отпечаткам позволит интегрировать в едином интерфейсе все этапы обработки изображения отпечатка пальца и сравнения его с другими отпечатками:
Система идентификации личности по отпечаткам пальцев предназначена для работы с цифровыми изображениями, полученными посредством сканирования.
Получение электронного представления отпечатков пальцев с хорошо различимым папиллярным узором достаточно сложная задача. Поскольку отпечаток пальца слишком мал, для получения его качественного изображения приходится использовать достаточно изощренные методы.
На сегодняшний момент можно выделить следующие сканеры отпечатков пальцев по используемым ими физическим принципам:
Старейшей технологией сканирования отпечатка является оптическая. Сканирование отпечатка пальца мини-камерами на ПЗС или КМОП-чипе позволило существенно уменьшить стоимость систем идентификации. Но этот способ снятия отпечатка сталкивается с некоторыми трудноразрешимыми проблемами: получаемый образ зависит от окружающего освещения, на границах образа возможны искажения, датчик может быть относительно легко "обманут" (некоторые дешевые датчики можно "дурачить" печатной копией, сделанной на обычном копире). Остаются проблемы и с размерами сканера. Датчик не может быть меньше, чем фокусное расстояние камеры. Среди главных преимуществ оптических систем можно еще раз упомянуть относительно низкую цену и практическую неуязвимость к воздействию электростатического разряда.
Абсолютно новой является технология использования электромагнитного поля. Датчик излучает слабый электромагнитный сигнал, который следует по гребням и впадинам отпечатка пальца и учитывает изменения этого сигнала для составления образа отпечатка. Такой принцип сканирования позволяет просматривать рисунок кожи под слоем омертвевших клеток, что приводит к хорошим результатам при распознавании бледных или стершихся отпечатков. Остается проблема отсутствия приемлемого соотношения между размером датчика и его разрешающей способностью.
Еще одна перспективная технология, которую следует упомянуть - ультразвуковая. Трехмерный ультразвуковой сканер измеряет пересеченную поверхность пальца своего рода радаром. Этот метод сканирования может быть особенно удобен, например, в здравоохранении. Он не требует касания каких-либо считывающих устройств датчика стерильными руками, а отпечаток легко считывается даже через резиновые или пластиковые перчатки хирурга. Главное неудобство ультразвуковой технологии - ее высокая стоимость и длительное время сканирования.
Существуют и другие методы, либо использовавшиеся в прошлом, либо только разрабатываемые.
Полученные таким образом изображения имеют размер порядка нескольких мегапикселей и должны сохраняться в формате без сжатия, чтобы избежать искажений. Таким образом, объем графической информации, обрабатываемый системой, достаточно велик и составляет мегабайты. Эти особенности накладывают ограничения на использование непроизводительных и медленных алгоритмов.
Построение системы идентификации личности по отпечаткам пальцев предполагает модульную структуру. Общий интерфейс и возможность доступа ко всем модулям в составе системы должна обеспечивать оболочка. Из оболочки вызываются следующие модули: подсистема анализа изображения, подсистема сравнения одного отпечатка с множеством других. Обмен данными между подсистемами происходит через проект в рамках общей оболочки.
Подсистема анализа изображения должна обеспечивать возможность получения основных статистических характеристик папиллярного узора по ключевым участкам. Подсистема предполагает наличие средств для получения качественного образа отпечатка пальца.
Подсистема сравнения изображений отпечатков служит для автоматизированного выявления схожести различных изображений папиллярного узора.
Задача обработки изображений в системе связана с автоматическим анализом больших массивов графической информации. Преобразования, проводимые в системе, должны проводиться в процессе интерактивного взаимодействия с пользователем, поэтому паузы на обработку не должны превышать нескольких секунд. Исходя из этого, сформулированы требования к техническим характеристикам персонального компьютера, на котором будет функционировать система. Требования сведены в табл.1.1.
Таблица 1.1
Технические характеристики персонального компьютера
Наименование |
Значение |
Частота процессора, МГц |
от 900 |
Объем оперативной памяти, Мб |
от 64 |
Разрешение экрана монитора |
не менее 1024x768 |
Система предназначена для обработки битовых изображений. Вследствие неточностей, шумов и аппроксимаций, вносимых оборудованием (сканер или любое иное дискретизирующее графику устройство) в изображении появляются шумы различной природы. Система позволяет частично избавиться от этих искажений. Поэтому качество входных образов должно быть на приемлимом уровне.
Основным видом информации, обрабатываемым в системе идентификации личности, является графическая информация в растровом представлении. Такой вид данных воспринимается человеком непосредственно и целостно, поэтому необходимо обеспечить средства наглядной визуализации изображений на различных этапах обработки.
Систему целесообразно разрабатывать для функционирования под операционной системой семейства Windows, так как ОС данного класса наиболее широко распространены в современном мире. Платформой для разработки выбрана среда для разработки приложений Microsoft Visual Studio C++ 2003. Эта среда поддерживает алгоритмический язык C++ и обладает при этом возможностями быстрой разработки и проектирования визуальных интерфейсов, что особенно важно при работе с графической информацией.
Как уже отмечалось в п. 1.3.5, для достижения удобного пользователю режима функционирования системы необходимо следующая минимальная конфигурация персонального компьютера: частота процессора 900 МГц, объем оперативной памяти 64 Мб, монитор, поддерживающий разрешение 1024x768 точек. Также желательно наличие следующих периферийных технических средств: сканер отпечатков пальцев, цветной струйный принтер для вывода на печать результатов.
Для реализации и функционирования проекта необходимо общесистемное программное обеспечение ОС Windows XP, в основе которой лежит ядро, характеризуемое 32-разрядной вычислительной архитектурой и полностью защищенной моделью памяти, что обеспечивает надежную вычислительную среду.
Разработка системы распознавания личности и ее подсистем будет вестись с использованием среды для разработки приложений Microsoft Visual Studio C++ 2003. Среда разработки включает в себя высокопроизводительный 32-битный компилятор, что позволяет оптимизировать создаваемый код. Microsoft Visual Studio C++ включает обширный набор средств, который повышает производительность труда программистов и сокращают продолжительность цикла разработки. Многофункциональная интегрированная среда разработки Microsoft Visual Studio C++ 2003 включает компилятор, удовлетворяющий стандарта ANSI/ISO, встроенный дизайнер форм, богатый набор средств для работы с компонентами, инструмент Solution Explorer, менеджер проектов и отладчик. Удобство разработки и эффективность созданных в данной среде разработки программа делают Microsoft Visual Studio C++ 2003 оптимальным выбором для построения исследовательской системы, какой является система распознавания личности.
При приложении пальца к сканирующему устройству возможно смещение или поворот изображения отпечатка пальца по сравнению с тем, что уже хранится в базе. Данные погрешности не должны оказывать влияние на результат распознавания получаемого отпечатка пальца. Для этого был разработан алгоритм преобразования абсолютных параметров минюций к относительным. Посредствам такого преобразования удается предоствратить негативное влияние поворота и смещения, и распознать отпечаток, даже если он повернут на 180°.
Представим структурное представление отпечатка пальцев в виде списка M, содержащего параметры специальных точек:
Каждый из наборов параметров представляет собой одну точку. Для приведения параметров к относительным параметрам необходимо провести обзор и преобразование всех точек.
Вследствие эластичности кожи и роста человека расстояние между точками может измениться, также точки, находящиеся ближе к краю отпечатка могут сместиться относительно других точек, что не должно влиять на результат распознавания, однако разные точки так же не должны быть приняты за одну. Для этого в подсистеме распознавания была разработана система допусков при сравнении двух отпечатков. Значения допусков были получены опытным путем, так же как и условия совпадения отпечатков.
Таким образом, задача распознавания отпечатка пальцев по абсолютным параметрам минюций на изображении может быть разбита на несколько подзадач:
Входной информацией являются список минюций в абсолютных параметрах, расположенный в памяти, содержащий все необходимые параметры. Каждый элемент массива содержит все необходимые параметры минюций: координаты целого типа 2х4 байта, угол направления 8 байт, тип точки 1 байт, поэтому общий размер массива должен быть кратен 2*4+8+1 = 17 байт.
,
где Xi, Yi координаты минюций на растровом представлении изображения отпечатка пальцев, целые числа, величина которых ограничена размером изображения отпечатка в пикселах;
αi направление предполагаемого продолжения гребня на отпечатке пальцев в точки типа окончание и направление слипания для точки типа раздвоение, дробное число, величина которого изменяется (pi, +pi);
Тi тип обнаруженной точки, битовое поле, принимает 2 значения «раздвоение» = 0 (false) и «окончание» = 1 (true);
k количество минюций на исследуемом отпечатке.
Так же в качестве входной информации для данной задачи являются матрицы, содержащие список минюций в абсолютных параметрах, хранящиеся в базе данных отпечатков, содержащие все, необходимые для распознавания, параметры найденные при предыдущих расчетах параметров отпечатков пальцев. В каждой строке массива содержится описание расположения одной точки на изображении отпечатка, а так же ее направление, тип и видимость. В табл. 2.1 приведен формат элемента матрицы.
Таблица 2.1
Формат элемента матрицы
Поле |
Формат |
Описание |
x |
Целое |
Абцисса минюции на растре |
y |
Целое |
Ордината минюции на растре |
alpha |
Целое |
Ориентация минюции на растре |
type |
Байт |
Тип минюции. Раздвоение или окончание |
show |
Байт |
Видимость точки |
Выходной информацией для данной подсистемы является список, содержащий отпечатки из базы данных, в которых были обнаружены сходства с обрабатываемым отпечатком. Значение, говорящее о том, что отпечатки совпали, так же получено опытным путем.
В каждой строке массива списка содержится описание отпечатка, его имя, количество совпавших точек при распознавании и степень сходства. В табл. 2.2 приведен формат строки.
Таблица 2.2
Формат строки
Поле |
Формат |
Описание |
Name |
Строковое |
Имя отпечатка (наименование файла, из которого были взяты параметры) |
Count |
Целое |
Количество минюций совпавших при сравнении отпечатков. |
Pct |
Дробное |
Степень сходства отпечатков в процентах, принимает значения (0, 100]. |
Преобразование относительных параметров к абсолютным параметрам компенсирует влияние параллельного переноса и поворота отпечатков пальцев при сканировании.
Преобразование происходит для каждой обнаруженной минюции относительно всех остальных минюций на изображении
На рис. 2.1 представлено изображение отпечатка пальца, с обнаруженными на нем минюциями. Линиями представлено относительное расположение точек относительно центральной.
На рис. 2.2 представлено изображение отпечатка того же пальца, но повернутого относительного первого на 45 градусов. Линиями представлено относительное расположение точек относительно центральной.
Прямой отпечаток
Рис. 2.1
Повернутый отпечаток
Рис 2.2
Для определения степени сходства обрабатываемого отпечатка с отпечатком, хранящимся в базе, была разработана сисьема допусков и критериев схожести отпечатков. Вследствие эластичности кожи и неплотного прижатия пальца при снятии отпечатка некоторые минюции на новом отпечатке могут сместиться, относительно минюций, хранящихся в базе.
Таким образом, точка считается совпавшей, если ее местоположение относительно другой точек входит в определенную область вокруг первоначального положения. На рис. 2.3 представлена область, в которой положение точки относительно другой считается совпавшим.
Область допуска
Рис. 2.3
Для вычисления степени сходства двух отпечатков происходит сравнение каждой минюции на обоих отпечатках. Cписок совпавших минюций получается при помощи отсеивания из первоначального списка тех минюций, которые не были обнаружены во втором списке, тоесть вокруг данной точки небыло обнаружено ниодной другой точки в попавшей в область допуска.
Отпечатки считаются схожими, если количество совпавших точек превышает определенный порог сходства.
Работа подсистемы реализуется следующими этапами:
Функциональная схема подсистемы представлена на рис.2.4
Функциональная схема подсистемы распознавания
Рис. 2.4
При приложении пальца к сканирующему устройству возможно смещение или поворот изображения отпечатка пальца по сравнению с тем, что уже хранится в базе. Данные погрешности не должны оказывать влияние на результат распознавания получаемого отпечатка пальца. Для этого был разработан алгоритм преобразования абсолютных параметров минюций к относительным. Посредствам такого преобразования удается предоствратить негативное влияние поворота и смещения, и распознать отпечаток, даже если он повернут на 180°.
Представим структурное представление отпечатка пальцев в виде списка M, содержащего параметры специальных точек:
Каждый из наборов параметров представляет собой одну точку. Для приведения параметров к относительным параметрам необходимо провести обзор и преобразование всех точек.
Так как необходимо оценить расстояние между каждой из пар минюций, сложность этих алгоритмов превышает o(N2), где N - количество обнаруженных минюций на изображении отпечатка пальца. В среднем количество точек на отпечатке не превышает 50, таким образом, потребуется 502 = 2500 операций, что является небольшим объемом вычислений. Тесты показывают, что современные пользовательские ЭВМ способны выполнять около операций вычисления расстояния в секунду.
Таким образом, на анализ одного изображения будет уходить в среднем секунд. Такие темпы обработки информации вполне отвечают понятию интерактивности, что является приемлемым условием.
При реализации данного алгоритма используется массив информации, сформированный на предыдущем этапе обработки изображения отпечатка пальца в подсистеме анализа изображения. Каждый элемент массива представляет из себя структуру, содержащую все необходимые для обработки параметры минюций: координаты целого типа 2х4 байта, угол направления 8 байт, тип точки 1 байт, поэтому общий размер массива должен быть кратен 2*4+8+1 = 17 байт.
,
где Xi, Yi координаты минюций на растровом представлении изображения отпечатка пальцев, целые числа, величина которых ограничена размером изображения отпечатка в пикселах;
αi направление предполагаемого продолжения гребня на отпечатке пальцев в точки типа окончание и направление слипания для точки типа раздвоение, дробное число, величина которого изменяется (pi, +pi);
Тi тип обнаруженной точки, битовое поле, принимает 2 значения «раздвоение» = 0 (false) и «окончание» = 1 (true);
k количество минюций на исследуемом отпечатке.
Для обработки массивов используется двунаправленный список. Список представляет собой вектор:
В данную информационную структуру можно заносить и извлекать элементы с любой стороны.
Выходной информацией для данной задачи является массив размерностью (k x k) с пустыми диагональными элементами, содержащий списки минюций и их взаимное расположение друг с другом.
Каждый элемент массива содержит описание точки, расстояние до второй точки, угол между собственным направлением точки и направлением во вторую точку, Угол между собственными направлениями двух точек. В табл. 2.3 приведен формат элемента массива.
Таблица 2.3
Структура элемента массивазаписи
Поле |
Формат |
Описание |
lij |
Целое |
Расстояние между i и j точками |
A1ij |
Дробное |
Угол между собственным направлением точки i и направлением из точки i в точку j. A1ij[0, 2*M_PI) |
A2i |
Дробное |
Угол между собственными направлениями точек i и j. A2ij[0, 2*M_PI) |
Обобщенное математическое описание преобразования приведено в п.2.1.4.
Преобразование происходит для каждой обнаруженной минюции относительно всех остальных точек по следующим формулам:
,
где i, j минюции
dLengthij расстояние между точками i и j
dAlpha1ij угол между направлением точки i и направлением на точку j
dAlpha2ij угол между направлением точки i и точки j
Alphai угол вектора самой точки
Alphaij угол вектора направления от точки i к точке j
На рис. 2.5 представлено расположение точки i относительно точки j со всеми полученными параметрами.
относительные параметры
Рис. 2.5
Контрольный пример должен содержать отпечатки более чем с одной обнаруженной минюцией.
RelFing - список минюций в относительных параметрах
AbsFing - список минюций в абсолютных параметрах
listDots относительные параметры точки
iterA1 исследуемая точка в абсолютных параметрах
iterA2 точка в абсолютных параметрах, относительно которой вычисляется точка iterA1
l расстояние между точками iterA1 и iterA2
GetS функция вычисления расстояния
|| - округление до ближайшего целого
vecAB вектор между направлениями точки iterA1 и iterA2
GetAlpha функция вычисления угла между векторами
tmpa
a1 = угол между направлением самой точки и направлением на другую точку
a2 = угол между направлениями точек.
Вследствие эластичности кожи и роста человека расстояние между точками может измениться, что не должно влиять на результат распознавания, однако разные точки так же не должны быть приняты за одну. Для этого в подсистеме распознавания была разработана система допусков при сравнении двух отпечатков.
Данный алгоритм предназначен для сравнения двух отпечатков, один из которых получается на предыдущем этапе, а второе считывается из файла базы данных. Оба отпечатка представлены в виде относительных параметров
При реализации алгоритма используются относительные параметры минюций, полученные в результате преобразования, проводимого алгоритмом преобразования абсолютных параметров минюций к относительным, описанного в п. 2.2. Информация о необходимых параметрах минюций содержится в списке fng, каждая запись которого имеет структуру, приведенную в табл. 2.3.
Результатами решения является список отпечатков из базы данных, структурное представление которых совпадает с исследуемым отпечатком или схоже с ним на несколько процентов. Структура элемента списка приведена в табл. 2.4.
Таблица 2.4
Структура записи об обнаруженных отпечатках
Поле |
Формат |
Описание |
Name |
Строковое |
Имя отпечатка (наименование файла, из которого были взяты параметры) |
Count |
Целое |
Количество минюций совпавших при сравнении отпечатков. |
Pct |
Дробное |
Степень сходства отпечатков в процентах, принимает значения (0, 100]. |
Таким образом, точка считается совпавшей, если ее местоположение относительно другой точек входит в определенную область вокруг первоначального положения. На рис. 2.6 представлена область, в которой положение точки относительно другой считается совпавшим.
Область допуска
Рис. 2.6
Для вычисления степени сходства двух отпечатков происходит сравнение каждой минюции на обоих отпечатках:
M список минюций на обрабатываемом образе
k количество минюций на обрабатываемом образе
M = {m1, m2, …, mk}
N список минюций одного отпечатка из базы отпечатков
l количество минюций на отпечатке из базы отпечатков
N = {n1, n2, …, nl}
Cписок совпавших минюций получается при помощи отсеивания из первоначального списка тех минюций, которые небыли обнаружены во втором списке:
S = {mi, где i=(1..k), P(mi, N)}
r = | S | количество совпавших точек.
P(mi , N) Точка считается совпавшей, если относительно нее найдено необходимое количество удовлетворяющих условию точек.
Отпечатки считаются схожими, если количество совпавших точек превышает порог сходства (p):
r ≥ p условия совпадения
r < p условие не совпадения
Контрольный пример должен содержать не менее одного отпечатка пальца, похожего на обрабатываемый, одного отпечатка, не похожего на обрабатываемый, и одного отпечатка, являющегося похожим на обрабатываемый, но смещенный и повернутый на некоторый угол.
confirmVal - количество совпавших сопряженных СТ с текущей СТ
confirmDot - количество совпавших СТ (спец точек)
min функция с 2 входными параметрами, результатом которой является минимальное из входных значений.
CONFIRM_VAL = 9
DELTA_L = 10.0
DELTA_A = 10.0
|| - округление до ближайшего целого
tekFing список точек в относительных параметрах на входном отпечатке.
baseFing список точек в относительных параметрах на отпечатке из базы
tekIter список точек относительно исследуемой (ее относительные параметры) для точки на входном отпечатке
baseIter список точек относительно исследуемой (ее относительные параметры) для точки отпечатке из базы
Подпрограмма OnBnClickedCompare предназначена для обработки события на диалоговом окне нажатие кнопки «Сравнить». Подпрограмма производит проверку, был ли проведен анализ отпечатка пальца. Результат поиска сохраняется в файл.
Текст подпрограммы приведен в приложении 1.3
Подпрограмма OnBnClickedCompare предназначена для
Структура TCompareFing предназначена для хранения информации о сравниваемых отпечатках пальцев. Структура TCompareFing объявлена следующим образом:
struct TCompareFing
{
double val;
short cDot;
short nfng;
CString name;
list<TPairAbsDot> dots;
list<TPairSur> surdots;
};
val - уровень схожести отпечатков
cDot - количество совпавших точек
nfng - номер отпечатка
name - файл отпечатка
dots; - совпавшие точки на отпечатках
surdots - окружения на одинаковых отпечатках
Структура TAbsFing список точек в абсолютных параметрах, полученый в разультате работы подсистемы анализа. Структура TAbsFing объявлена следующим образом:
class TAbsDot
{
public:
CPoint coord;
double alpha;
bool type;
bool show;
};
coord - координаты
alpha - направление в точке
type - тип точки (1- окончание, 0- раздвоение)
show - видимость точки (1- видима, 0- скрыта)
Входные данные для данной подпрограммы представлены:
TAbsFing fing список точек в абсолютных параметрах, полученый в разультате работы подсистемы анализа. Каждый элемент списка содержит все наобходимые параметры для обработки и преобразования в подсистеме распознавания:
Выходные данные для данной подпрограммы представлены:
Результат работы подпрограммы сохраняется в файл отчет
В подпрограмме используются следующие подпрограммы:
Схема подпрограммы «OnBnClickedCompare» приведена на рис. 2.7.
Схема подпрограммы OnBnClickedCompare
Рис. 2.7
Подпрограмма Convert предназначена для реализации алгоритма преобразования отпечатка из абсолютных параметров к относительным. Подпрограмма сравнивает каждую точку на входном отпечатке со всеми остальными точками на отпечатке. Результат преобразования возвращается как выходной параметр функции.
Текст подпрограммы приведен в разделе П.1.2
Подпрограмма Convert предназначена для
Структура TRelFing предназначена для хранения информации о отпечатках пальцев в относительных параметрах. Структура TRelFing объявлена следующим образом:
class TRelFing: public list<listTRelDot>
typedef list<TRelDot> listTRelDot;
class TRelDot
{
public:
short l,a1,a2;
TAbsDot absDot;
}
l - растояние между точками
a1 - угол между направлением точки А и направлением A->B
a2 - угол между направлением точки В и направлением A
absDot - абсолютные параметры (необходимо для отображения на экране совпавших точек)
TAbsFing fing список точек в абсолютных параметрах, полученый в разультате работы подсистемы анализа. Каждый элемент списка содержит все наобходимые параметры для обработки и преобразования в подсистеме распознавания:
class TAbsFing: public list<TAbsDot>
class TAbsDot
{
public:
CPoint coord;
double alpha;
bool type;
bool show;
};
coord - координаты
alpha - направление в точке
type - тип точки (1- окончание, 0- раздвоение)
show - видимость точки (1- видима, 0- скрыта)
Входные данные для данной подпрограммы представлены
TAbsFing &fng ссылка на список точек отпечатка пальца в абсолютных параметрах.
Выходные данные для данной подпрограммы представлены:
TRelFing *указатель на список точек отпечатка пальца в относительных параметрах.
В подпрограмме используются следующие подпрограммы:
Схема подпрограммы «Convert» приведена на рис. 2.8.
Подпрограмма CompareWithBase предназначена для загрузки данных из файла базы данных, преобразования их к относительным параметрам. Подпрограмма сравнивает каждый отпечаток из базы данных с отпечатком, открытым для исследования. Результат возвращается как выходной параметр функции.
Текст подпрограммы приведен в разделе П.1.3
Подпрограмма CompareWithBase предназначена для:
Схема подпрограммы Convert
Рис. 2.8
Структура TCompareFing предназначена для хранения информации о сравниваемых отпечатках пальцев. Структура TCompareFing объявлена следующим образом:
struct TCompareFing
{
double val;
short cDot;
short nfng;
CString name;
list<TPairAbsDot> dots;
list<TPairSur> surdots;
};
val - уровень схожести отпечатков
cDot - количество совпавших точек
nfng - номер отпечатка
name - файл отпечатка
dots; - совпавшие точки на отпечатках
surdots - окружения на одинаковых отпечатках
Структура TRelFing предназначена для хранения информации о отпечатках пальцев в относительных параметрах. Структура TRelFing объявлена следующим образом:
class TRelFing: public list<listTRelDot>
typedef list<TRelDot> listTRelDot;
class TRelDot
{
public:
short l,a1,a2;
TAbsDot absDot;
}
l - растояние между точками
a1 - угол между направлением точки А и направлением A->B
a2 - угол между направлением точки В и направлением A
absDot - абсолютные параметры (необходимо для отображения на экране совпавших точек)
TAbsFing fing список точек в абсолютных параметрах, полученый в разультате работы подсистемы анализа. Каждый элемент списка содержит все наобходимые параметры для обработки и преобразования в подсистеме распознавания:
class TAbsFing: public list<TAbsDot>
class TAbsDot
{
public:
CPoint coord;
double alpha;
bool type;
bool show;
};
coord - координаты
alpha - направление в точке
type - тип точки (1- окончание, 0- раздвоение)
show - видимость точки (1- видима, 0- скрыта)
Входные данные для данной подпрограммы представлены
TRelFing fingR исследуемый отпечаток в относительных параметрах;
Bse содержимое базы данных с отпечатками.
Выходные данные для данной подпрограммы представлены:
list<TCompareFing> список, содержащий результаты сравнения отпечатков для каждого отпечатка из базы данных с исследуемым отпечатком.
В подпрограмме используются следующие подпрограммы:
Схема подпрограммы «CompareWithBase» приведена на рис. 2.9.
Подпрограмма Compare предназначена для сравнения двух поданных на вход отпечатков. Подпрограмма реализует задачу поиска совпадающих отпечатков по базе данных. Сравнивает каждую точку на входном отпечатке с каждой точке на втором отпечатке. Результат возвращается как выходной параметр функции.
Текст подпрограммы приведен в разделе П.1.2
Подпрограмма Compare предназначена для
Схема подпрограммы CompareWithBase
Рис. 2.9
Структура TCompareFing предназначена для хранения информации о сравниваемых отпечатках пальцев. Структура TCompareFing объявлена следующим образом:
struct TCompareFing
{
double val;
short cDot;
short nfng;
CString name;
list<TPairAbsDot> dots;
list<TPairSur> surdots;
};
val - уровень схожести отпечатков
cDot - количество совпавших точек
nfng - номер отпечатка
name - файл отпечатка
dots; - совпавшие точки на отпечатках
surdots - окружения на одинаковых отпечатках
Структура TRelFing предназначена для хранения информации о отпечатках пальцев в относительных параметрах. Структура TRelFing объявлена следующим образом:
class TRelFing: public list<listTRelDot>
typedef list<TRelDot> listTRelDot;
class TRelDot
{
public:
short l,a1,a2;
TAbsDot absDot;
}
l - растояние между точками
a1 - угол между направлением точки А и направлением A->B
a2 - угол между направлением точки В и направлением A
absDot - абсолютные параметры (необходимо для отображения на экране совпавших точек)
Входные данные для данной подпрограммы представлены
TRelFing &fng ссылка на список точек отпечатка пальца в относительных параметрах.
This указатель на список точек второго отпечатка пальца в относительных параметрах
Выходные данные для данной подпрограммы представлены:
TCompareFing результат сравнения двух отпечатков.
В подпрограмме используются следующие подпрограммы: нет
Схема подпрограммы «Compare» приведена на рис. 2.10.
Основной целью работы программы является опознавание личности по отпечаткам пальцев на основе сравнения структурного представления папиллярных узоров. Контрольный пример должен содержать большое количество тестовых отпечатков пальцев, при этом отпечаток одного и того же пальца должен быть представлен как минимум в двух экземплярах для сравнения их между собой.
Схема подпрограммы Compare
Рис. 2.10
Для теста использовалось около 50 отпечатков разных людей и разного возраста. На рис. 2.11, 2.12, 2.13 приведены несколько изображений папиллярного узора, которые предполагается сравненить между собой и другими отпечаткаи в базе данных отпечатков. Данные изображения получены посредством зачернения пальца и приложения его к листу белой бумаги, после чего отпечатоки были отсканированы и сохранены в виде bmp файлов на компьютере. Полученные таким образом отпечатки имеют не высокое качество, поэтому можно полностью проверить все этапы работы программы.
На рис. 2.11, 2.12 представлены отпечатки одного и тогоже пальца, а значит, в результате работы программы они должны совпасть. Рис. 2.13 это отпечаток другого пальца, нежели предыдущие три отпечатка.
Подсистема распознавания в качестве входных параметров принимает результат работы подсистемы анализа изображения. На рис. 2.14 изображен обработанный отпечаток А1, на рис. 2.15 А2, на рис. 2.16 В
Исходный образ A1
Рис. 2.11
Исходный образ A2
Рис. 2.12
Исходный образ B
Рис. 2.13
Обработанный образ A1
Рис. 2.14
Обработанный образ A2
Рис. 2.15
Обработанный образ В
Рис. 2.16
При снятии отпечатков для проверки корректности работы программы их изображениям давались имена, однозначно идентифицирующие палец, чтобы при сравнении по имени файла можно было определить правильно ли прошло распознавание.
Имя файла имеет формат:
Имя или номер человек, с которого снимали отпечаток
L или R правая или левая рука
1,2,3,4 или 5 палец на руке от большого к мизинцу
символ «_»
номер с каждого пальца снималось несколько отпечатков.
Пример: отпечаток с именем файла 2r1_0.bmp должен совпасть с отпечатками 2r1_1.bmp и 2r1_2.bmp, но должен отличаться от отпечатка 2r2_0.bmp или 3r1_0.bmp.
Для испытания программного обеспечения системы на вход были поданы тестовые образы, описанные в п.2.8.2. Испытания проводились согласно руководству программиста, приведенному в приложении 2, и руководству оператора, приведенному в приложении 3. В результате были получены структурные описания представленные на рис. 2.14, 2.15, 2.16.
Полученные структурные представления точно описывают входные образы, что не трудно проверить визуальным сравнением с входными образами. Статистически было выявлено, что на отпечатках имеется около 40-50 минюций, эта величина может изменяться в зависимости от размеров пальца. На тестовых образах найдено 19, 40, 37 соответственно.
В приложении 4 можно увидеть что отпечатки A1 (1.bmp), A2 (1R1_3rotate2.bmp) схожи между собой и отпечатком 1R1_1.bmp, что является верным, так как все они являются образами большого пальца правой руки одного и того же человека. Отпечаток B (3l2_2.bmp) не совпадает ни с одним из A1 и A2, но совпадает с 3l2_1.bmp, что является также верным результатом, это отпечатки указательного пальца правой руки другого человека.
Тестирование показало, что разработанное программное обеспечение способно сравнивать и отыскивать схожие отпечатки, а значит и есть возможность определить человека, которому принадлежит, обрабатываемы отпечаток. Полученные результаты совпадают с ожидаемыми и совпадают с ручным сравнением.
Помимо объектного описания папиллярного узора отпечатков и последующего распознавания личности по отпечаткам пальцев реализованный в программе алгоритм пригоден для описания и распознавания символьной информации и подписей. Для распознавания других, в отличие от отпечатков, образов в программе достаточно изменить параметры выделения локальных особенностей и убрать несколько этапов. Этап восстановление растра для символов не годится, так как он специально разработан для папиллярного узора.
Программа, после небольшой корректировки параметров анализа и сравнения, была настроена для распознавания символов алфавита. Результаты работы приведены в приложении 5.
Для проверки был введен в базу данных набор символов изображенных на рис. 2.17, который в последующем сравнивался с алфавитом на рис. 2.18.
Алфавит для базы данных
Рис. 2.17
Алфавит для сравнения
Рис. 2.18
Подсистема распознавания отпечатка пальца является неотъемлимой частью системы идентификации личности по отпечаткам пальцев, предназначенной для сравнения исследуемого отпечатка с отпечатками, хранящимися в базе данных посредством сравнения минюций на двух отпечатках. Разрабатываемая система носит исследовательский характер и предназначена для поиска и отладки наиболее эффективных алгоритмов обработки изображений отпечатков пальцев. Реализация подсистемы позволит в значительной степени облегчить труд программиста-исследователя посредством автоматизации процесса поиска интересующего отпечатка, вычисления статистических параметров найденых отпечатков.
Распознавание помимо непосредственного поиска интересующего отпечатка дает несколько других преимуществ:
Рапределение доступа к секретной информации, имеет большое значение. Самый простой способ однозначной идентификации личности является идентификация по отпечатку пальца. Таким образом, разработка системы позволит, помимо выполнения основной задачи распознавания личности, уменьшить вероятность несанкционированного доступа к конфеденциальной информации и снять нагрузку на системы шифрования и с систем, отвечающих за сохранность информации.
Для определения величины расходов на создание подсистемы, используем прямой метод калькуляции.
Расчет сметы затрат осуществляется по следующим статьям
К статье «Расходы на материалы» относятся покупные изделия, необходимые для выполнения работы, перечисленные в табл. 3.1.
Таблица 3.1
Расходы на материалы
Наименование материала |
Количество |
Стоимость, р. |
Матрица CD-R |
1 шт. |
20 |
Матрица CD-RW |
3 шт. |
75 |
Бумага писчая 80 г. |
250 листов |
80 |
Тонер для принтера |
1 шт. |
100 |
Прочие канцелярские товары |
25 |
|
Итого |
300 |
Оклад инженера-программиста в период разработки составлял 5000 р. в месяц. Продолжительность разработки 3 месяца.
ЗП = ЗПМ*ПМ (3.1)
ЗП = 5000 * 3 = 15000 руб.
К окладу начисляется премия. Процент премиальных составил 15% в месяц.
ЗП,% = ЗП*1.15 (3.2)
ЗП,% = 15000 * 1.15 = 17250 руб.
Плановые накопления в фонд резерва отпусков (ЗД) рассчитывается в размере 10% от тарифной платы:
ЗПД = ЗП * 0.10 (3.3)
ЗПД = 15000 * 0.10 = 1500 руб.
В расходы на оплату труда необходимо включить уральский коэффициент (15%). Районный коэффициент рассчитывается от оклада вместе с премиальными и дополнительной заработной платой.
КУР = (15000 + 1500) * 0.15 = 2475 руб.
Следовательно, расходы на оплату труда с учетом зонального коэффициента составят:
ЗПОСН = ЗП,% + ЗПД + КУР (3.4)
ЗПОСН = 17250 + 1500 + 2475 = 21225 руб.
Сумма налоговой базы не превышает 280000 руб., поэтому статья «Расходы на социальные налоги» включает в себя отчисления в пенсионный фонд (20%), на медицинское (3.1%) и социальное страхование (2.9%), отчисления в фонд страхования от несчастных случаев (0.2%), что составляет 26.2% /7/. Отчисления производятся c общих расходов на оплату труда. Сумма отчислений составляет:
СОТЧ = ЗПОСН * 0.262 (3.5)
СОТЧ = 21225 * 0.262 = 5560,95 руб.
Статья «Расходы на амортизацию и содержание ВТ» включает расходы, связанные с эксплуатацией вычислительной техники. Стоимость одного машинного часа рассчитывается по формуле:
АЧ = СИСП / (ЧМ * КЧ), (3.6)
где АЧ аренда за час использования;
СИСП - общая стоимость использования ЭВМ (рассчитывается по формуле (3.7));
ЧМ число месяцев в году;
КЧ - количество рабочих часов в месяце.
СИСП = АКОМП + ЗПОБСЛ + СЗЧ + СЭЛ + АПО, (3.7)
где АКОМП амортизация компьютера за год эксплуатации;
ЗПОБСЛ расходы на оплату труда обслуживающего персонала за год эксплуатации;
ЗПОБСЛ = 2000 руб/мес.
СЗЧ стоимость комплектующих для компьютера за год эксплуатации.
СЗЧ = 800 руб/год.
СЭЛ стоимость израсходованной электроэнергии за год эксплуатации.
СЭЛ = 1000 руб/год.
АПО годовая амортизация программного обеспечения.
АКОМП = СКОМП / СПИ, (3.8)
где СКОМП стоимость компьютера;
СПИ срок полезного использования (в годах).
АКОМП = 19000 / 5 = 3800 руб. (3.9)
АПО = СТПО / СПИ,
где СТПО стоимость программного обеспечения;
СПИ срок полезного использования (в годах).
АПО = 4000 / 5 = 800 руб.
СИСП = 3800 + 2000*12 + 800 + 1000 + 800 = 30400 руб.
АЧ = 30400 / (12 * 176) = 14.394 руб
ЭВМ использовалась на этапах проектирования (40 час), программирования (80 часов), отладки (320 часов) и документирования (160 часов), таким образом, всего 600 часов. Следовательно, сумма амортизационных отчислений составит:
САР = Эч * Ач (3.10)
САР = 600 * 14.394 = 8636,4 руб.
Статья «Прочие расходы» содержит расходы, неучтенные в предыдущих статьях (до 50 % от расходов на оплату труда) :
ПР = ЗПОСН * 0.5 (3.11)
ПР = 21225 * 0.5 = 10612,5 руб.
Статья «Накладные расходы» включает в себя расходы по управлению (заработная плата управления, расходы на все виды командировок управленческого аппарата), содержание пожарной и сторожевой охраны, содержание и текущий ремонт зданий, сооружений, инвентаря; содержание персонала, не относящегося к аппарату управления; расходы по изобретательству и рационализации; по подготовке кадров; расходы на содержание ВЦ; канцелярские, почтово-телеграфные расходы и др. общехозяйственные расходы; непроизводственные расходы. Накладные расходы составляют 130% от расходов на оплату труда, таким образом, получаем:
НР = ЗПОСН * 1.3 (3.12)
НР = 21225 * 1.3 = 27592,5 руб.
Сумма затрат на разработку подсистемы в целом составила 73930 руб. Табл.3.2 отражает затраты по статьям и структуру этих затрат в общей сумме.
Таблица 3.2
Смета затрат на разработку подсистемы
Статья затрат |
Сумма затрат, руб. |
Структура затрат, % |
Расходы на материалы |
300 |
0,4 |
Расходы на оплату труда |
21230 |
28,7 |
Расходы на социальные налоги |
5560 |
7,5 |
Расходы на содержание и амортизацию ВТ |
8640 |
11,7 |
Накладные расходы |
27590 |
37,3 |
Прочие расходы |
10610 |
14,4 |
Итого |
73930 |
100 |
Округлим полученную сумму до тысяч для учета непредвиденных затрат. Получим, что сумма затрат на разработку системы составит 74000.0 руб.
Структура затрат на разработку ПО приведена на рис. 3.1.
Структура затрат на разработку ПО
Рис. 3.1
Исследовательская работа в рамках данного проекта заключается в выполнении многих этапов, практически все из которых проходят в тесном контакте с ЭВМ. Длительная работа инженера-программиста с компьютером сопряжена с целым рядом вредных и опасных факторов. Рассмотрим некоторые из них.
Постоянное напряжение глаз
Работа с компьютером характеризуется высокой напряженностью зрительной работы. В выполняемом исследовании значительный объем информации на разных стадиях обработки представлен в графической форме с большим количеством мелких деталей, что дает серьезную нагрузку на зрение. Постоянное напряжение глаз может привести к снижению остроты зрения. Экран видеомонитора должен находиться от глаз пользователя на оптимальном расстоянии 600…700 мм, но не ближе 500 мм с учетом размеров алфавитно-цифровых знаков и символов. Также для снижения утомляемости рекомендуется делать 15-минутные перерывы в работе за компьютером в течение каждого часа.
Влияние электростатических и электромагнитных полей
Большинство ученых считают, что как кратковременное, так и длительное воздействие всех видов излучения от экрана монитора не опасно для здоровья персонала, обслуживающего компьютеры. Однако исчерпывающих данных относительно опасности воздействия излучения от мониторов на работающих с компьютерами не существует и исследования в этом направлении продолжаются.
Допустимые значения параметров неионизирующих электромагнитных излучений от монитора компьютера представлены в табл. 4.1 /8/.
Максимальный уровень рентгеновского излучения на рабочем месте оператора компьютера обычно не превышает 10 мкбэр/ч, а интенсивность ультрафиолетового и инфракрасного излучений от экрана монитора лежит в пределах 10…100 мВт/м2 /9/.
Таблица 4.1
Допустимые значения параметров неионизирующих электромагнитных излучений (в соответствии с СанПиН 2.2.2.542-96)
Наименование параметра |
Допустимые значения |
Напряженность электрической составляющей электромагнитного поля на расстоянии 50см от поверхности видеомонитора |
10В/м |
Напряженность магнитной составляющей электромагнитного поля на расстоянии 50см от поверхности видеомонитора |
0,3А/м |
Напряженность электростатического поля не должна превышать: для взрослых пользователей для детей дошкольных учреждений и учащихся средних специальных и высших учебных заведений |
20кВ/м 15кВ/м |
Для снижения воздействия этих видов излучения рекомендуется применять мониторы с пониженным уровнем излучения (MPR-II, TCO-92, TCO-99), устанавливать защитные экраны, а также соблюдать регламентированные режимы труда и отдыха.
Длительное неизменное положение тела
Работа с компьютером характеризуется значительным умственным напряжением и нервно-эмоциональной нагрузкой операторов, высокой напряженностью зрительной работы и достаточно большой нагрузкой на мышцы рук при работе с клавиатурой ЭВМ. Большое значение имеет рациональная конструкция и расположение элементов рабочего места, что важно для поддержания оптимальной рабочей позы человека-оператора.
Шум
Шум ухудшает условия труда, оказывая вредное действие на организм человека. Работающие в условиях длительного шумового воздействия испытывают раздражительность, головные боли, головокружение, снижение памяти, повышенную утомляемость, понижение аппетита, боли в ушах и так далее. В табл. 4.2 указаны предельные уровни звука в зависимости от категории тяжести и напряженности труда, являющиеся безопасными в отношении сохранения здоровья и работоспособности.
Таблица 4.2
Предельные уровни звука, дБ, на рабочих местах
Категория напряженности труда |
Категория тяжести труда |
|||
I. Легкая |
II. Средняя |
III. Тяжелая |
IV. Очень тяжелая |
|
I. Мало напряженный |
80 |
80 |
75 |
75 |
II. Умеренно напряженный |
70 |
70 |
65 |
65 |
III. Напряженный |
60 |
60 |
- |
- |
IV. Очень напряженный |
50 |
50 |
- |
- |
Уровень шума на рабочем месте инженеров-программистов и операторов видеоматериалов не должен превышать 50дБА, а в залах обработки информации на вычислительных машинах - 65дБА. Для снижения уровня шума стены и потолок помещений, где установлены компьютеры, могут быть облицованы звукопоглощающими материалами. Уровень вибрации в помещениях вычислительных центров может быть снижен путем установки оборудования на специальные виброизоляторы.
Техника безопасности на ПК тесно связана с электробезопасностью. Большинство компьютеров имеют трехштырьковый разъем кабеля питания (в отличие от двухштырьковой вилки большинства бытовых приборов). Третий разъем - это так называемая «земля». В грамотно оборудованных компьютеризированных помещениях существует настоящая земля ≈ заземляющий контур, который через металлическую ленту выводится на заземляющий штырь. Все это довольно громоздкое и дорогостоящее оборудование и часто разъем заземления не используется или используется «земляная» фаза обычной электросети. Результатом неправильного заземления могут быть удары статического напряжения от корпуса ПК. Часто из-за этого сгорает сетевое оборудование компьютеров. Следует соблюдать не только правила электробезопасности, но и следить за состоянием здоровья обслуживающего персонала и пользователей ПК, защищая их от вредного воздействия электромагнитных излучений, заботясь о зрении, так как именно оно испытывает основные нагрузки при работе с вычислительной техникой.
Важно также следить за состоянием техники и соблюдать основные правила бережного обращения с ней, так как техника эта дорогостоящая.
Системный блок следует включать как можно реже (обычно включается в начале рабочего дня и выключается в конце дня). Для того чтобы не выгорал экран и не расходовалась лишняя энергия, в компьютере предусмотрен специальный режим гашения экрана - через определенное время, если никто не работает на нем (нет обращения к клавиатуре или мыши) он выключается. Если монитор получает питание от системного блока, включая системный блок, включается и монитор (не надо щелкать выключателем на мониторе). Если соединение монитора и системного блока параллельно, то сначала необходимо включить монитор, потом системный блок. Выключать в обратной последовательности.
Экран монитора стеклянный, а потому и хрупкий, и поэтому надо обращаться с ним осторожно. Недопустимо попадание жидкости за заднюю часть экрана может замкнуть проводка, что выведет из строя монитор и может привести к возникновению пожара. В случае попадания жидкости следует отключить электропитание.
Защита от излучения расположена только на экране, поэтому, находясь прямо перед экраном, пользователь наиболее защищен от вредного воздействия излучения. На заднюю и боковые части монитора в целях экономии защиту не устанавливают. Следовательно, находясь сбоку или сзади монитора, можно получить максимально вредное воздействие.
При работе с клавиатурой стоит придерживаться следующих правил:
Разработка данного дипломного проекта проводится одним автором на персональном компьютере. Проведем расчет параметров рабочего места инженера-программиста с точки зрения эргономических требований.
В табл. 4.3 приведены параметры стола для занятий с ПЭВМ. Рост автора данного дипломного проекта в обуви составляет 184 см, что входит в категорию «выше 175 см». Это означает, что согласно эргономическим правилам и нормам высота поверхности стола над полом должна составлять 760 мм, при этом размер пространства для ног в столе должен быть не менее 700 мм.
Таблица 4.3
Высота одноместного стола для занятий с ПЭВМ
Высота над полом, мм |
||
Рост учащихся или студентов в обуви, см |
поверхность стола |
пространство для ног, не менее |
116 - 130 |
520 |
400 |
131 - 145 |
580 |
520 |
146 - 160 |
640 |
580 |
161 - 175 |
700 |
640 |
Выше 175 |
760 |
700 |
Примечание. Ширина и глубина пространства для ног определяются конструкцией стола.
Реальная высота стола на рабочем месте автора данного проекта составляет 760 мм. Размер пространства для ног составляет 800 мм. Эти показатели соответствуют допустимым.
В табл. 4.4 приведены параметры стула, которым должно быть оснащено рабочее место инженера-программиста. Рост автора данного дипломного проекта в обуви составляет 184 см, что входит в категорию «выше 175 см». Это означает, что согласно эргономическим правилам и нормам высота сиденья над полом должна составлять 460 мм, ширина сиденья не менее 360 мм, глубина сиденья 400 мм, высота нижнего края спинки над сиденьем 190 мм, высота верхнего края спинки над сиденьем 400 мм, высота линии прогиба спинки не менее 220 мм, радиус изгиба переднего края сиденья от 20 до 50 мм, угол наклона сиденья от 0 до 4 градусов, угол наклона спинки от 95 до 108 градусов, радиус спинки в плане не менее 300 мм. Стул, которым оборудовано рабочее место автора данного проекта, является подъемно-поворотным и обладает возможностью регулирования по высоте и углам наклона сиденья и спинки, а также расстоянию спинки от переднего края сиденья. Стул имеет стационарные подлокотники длиной 250 мм и шириной 50 мм. Параметры, которые могли быть настроены в зависимости от роста инженера-программиста, были настроены. Остальные параметры стула (ширина и глубина сиденья и т.д.) удовлетворяют допустимым нормам.
Таблица 4.4
Основные размеры стула для учащихся и студентов
Рост учащихся и студентов в обуви, см |
|||||
Параметры стула |
116-130 |
131-145 |
146-160 |
161-175 |
> 175 |
Высота сиденья над полом, мм |
300 |
340 |
380 |
420 |
460 |
Ширина сиденья не менее, мм |
270 |
290 |
320 |
340 |
360 |
Глубина сиденья, мм |
290 |
330 |
360 |
380 |
400 |
Высота нижнего края спинки над сиденьем, мм |
130 |
150 |
160 |
170 |
190 |
Высота верхнего края спинки над сиденьем, мм |
280 |
310 |
330 |
360 |
400 |
Высота линии прогиба спинки не менее, мм |
170 |
190 |
200 |
210 |
220 |
Радиус изгиба переднего края сиденья, мм |
20 - 50 |
||||
Угол наклона сиденья, град. |
0 - 4 |
||||
Угол наклона спинки, град. |
95-108 |
||||
Радиус спинки в плане не менее, мм |
300 |
Рабочее место должно быть оборудовано подставкой для ног, имеющей ширину не менее 300 мм, глубину не менее 400 мм, регулировку по высоте в пределах до 150 мм и по углу наклона опорной поверхности подставки до 20 градусов. Поверхность подставки должна быть рифленой и иметь по переднему краю бортик высотой 10 мм. На рабочем месте подставка для ног отсутствует.
Исходя из эргономических требований, пространство рабочего места можно разделить на несколько частей:
Зоны досягаемости рук в горизонтальной плоскости
а - зона максимальной досягаемости;
б - зона досягаемости пальцев при вытянутой руке;
в - зона легкой досягаемости ладони;
г - оптимальное пространство для грубой ручной работы;
д - оптимальное пространство для тонкой ручной работы.
Рис. 4.1
Оптимальное размещение предметов труда и документации в зонах досягаемости:
ДИСПЛЕЙ размещается в зоне а (в центре);
СИСТЕМНЫЙ БЛОК размещается в предусмотренной нише стола;
КЛАВИАТУРА - в зоне г/д;
«МЫШЬ» - в зоне в справа;
СКАНЕР в зоне а/б (слева);
ПРИНТЕР находится в зоне а (справа);
ДОКУМЕНТАЦИЯ: необходимая при работе - в зоне легкой досягаемости ладони в, а в выдвижных ящиках стола - литература, неиспользуемая постоянно.
На рис. 4.2 показан образец размещения основных и периферийных составляющих ПК на рабочем столе инженера-программиста.
Размещение основных и периферийных составляющих ПК
1 сканер, 2 монитор, 3 принтер, 4 поверхность рабочего стола,
5 клавиатура, 6 манипулятор типа «мышь».
Рис. 4.2
На рис. 4.3 показана схема реального размещения основных и периферийных составляющих ПК на рабочем столе инженера-программиста.
Реальное размещение основных и периферийных составляющих ПК.
1 принтер, 2 монитор, 3 поверхность рабочего стола,
4 клавиатура, 5 манипулятор типа «мышь».
Рис. 4.3
Положение экрана определяется расстоянием считывания (0,6…0,7м), углом считывания, направлением взгляда на 20 ниже горизонтали к центру экрана, причем экран перпендикулярен этому направлению. Должна также предусматриваться возможность регулирования экрана по высоте +3 см, по наклону от -10 до +20 относительно вертикали, в левом и правом направлениях.
Большое значение также придается правильной рабочей позе пользователя. При неудобной рабочей позе могут появиться боли в мышцах, суставах и сухожилиях. Требования к рабочей позе пользователя видеотерминала следующие:
Причина неправильной позы пользователей обусловлена следующими факторами: нет хорошей подставки для документов, клавиатура находится слишком высоко, а документы - низко, некуда положить руки и кисти, недостаточно пространство для ног.
В целях преодоления указанных недостатков даются общие рекомендации: лучше передвижная клавиатура; должны быть предусмотрены специальные приспособления для регулирования высоты стола, клавиатуры и экрана, а также подставка для рук.
Существенное значение для производительной и качественной работы на компьютере имеют размеры знаков, плотность их размещения, контраст и соотношение яркостей символов и фона экрана. Если расстояние от глаз оператора до экрана дисплея составляет 60…80 см, то высота знака должна быть не менее 3мм, оптимальное соотношение ширины и высоты знака составляет 3:4, а расстояние между знаками 15…20% их высоты. Соотношение яркости фона экрана и символов - от 1:2 до 1:15.
Во время пользования компьютером медики советуют устанавливать монитор на расстоянии 50-60 см от глаз. Специалисты также считают, что верхняя часть видеодисплея должна быть на уровне глаз или чуть ниже. Когда человек смотрит прямо перед собой, его глаза открываются шире, чем когда он смотрит вниз. За счет этого площадь обзора значительно увеличивается, вызывая обезвоживание глаз. К тому же если экран установлен высоко, а глаза широко открыты, нарушается функция моргания. Это значит, что глаза не закрываются полностью, не омываются слезной жидкостью, не получают достаточного увлажнения, что приводит к их быстрой утомляемости.
Рабочее место инженера-программиста в составе данного проекта в целом соответствует предъявляемым к нему эргономическим требованиям, связанным с параметрами мебели и размещением предметов труда в рабочих зонах. При этом можно сформулировать следующие рекомендации: установить на рабочее место подставку для ног.
4.4. Требования к параметрам микроклимата помещения
Под метеорологическими условиями (ГОСТ 12.1.005-88) понимают сочетание температуры, относительной влажности, скорости движения и запыленности воздуха. Перечисленные параметры оказывают огромное влияние на функциональную деятельность человека, его самочувствие и здоровье и на надежность средств вычислительной техники. Эти микроклиматические параметры влияют как каждый в отдельности, так и в различных сочетаниях.
Температура воздуха является одним из основных параметров, характеризующих тепловое состояние микроклимата. Суммарное тепловыделение в помещении поступает от:
Наибольшее количество теплоты выделяют ЭВМ и вспомогательное оборудование. Средняя величина тепловыделения от компьютеров колеблется до 100 Вт/м2. Тепловыделения от приборов освещения также велики. Удельная величина их составляет 35 Вт/м2. При этом, чем больше уровень освещенности, тем выше удельные величины тепловыделений. Количество теплоты от обслуживающего персонала незначительно. Оно зависит от числа работающих в помещении, интенсивности работы, выполняемой человеком.
К внешним источникам поступления теплоты относят теплоту, поступающую через окна от солнечной радиации, приток теплоты через непрозрачные ограждения конструкций. Интенсивность этих источников зависит от расположения здания, ориентации по частям света, цветовой гаммы и прочее.
С целью создания нормальных условий труда программиста, ГОСТом 12.1.005-88 установлены оптимальные и допустимые значения всех параметров микроклимата. Оптимальные параметры при длительном и систематическом воздействии на организм человека обеспечивают сохранение нормального функционирования и теплового состояния организма, создают ощущение теплового комфорта и являются предпосылкой высокого уровня работоспособности. Допустимые параметры микроклимата могут вызвать приходящие и быстро нормализующиеся изменения организма, не выходящие за пределы физиологически приспособительных возможностей, не создающие нарушений состояния здоровья, но вызывающие дискомфортные теплоощущения, ухудшение самочувствия и понижение работоспособности. Оптимальные и допустимые значения основных микроклиматических параметров представлены в табл. 4.5.
Таблица 4.5
Параметры микроклимата производственных помещений
Параметры |
Значения параметров |
|
оптимальные |
допустимые |
|
Температура |
20-22 °С |
17-22 °С |
Относительная влажность |
40-60 % |
до 75% |
Скорость движения воздуха |
0,1 м/с |
не более 0,3 м/с |
Для обеспечения нормальных условий труда необходимо придерживаться вышеуказанных данных. В целях поддержания температуры и влажности воздуха в помещении можно использовать системы отопления, вентиляции и кондиционирования воздуха.
На исследуемом предприятии температура воздуха, влажность и скорость движения воздуха держится в рамках оптимальных параметров. Вредные вещества в воздухе рабочей зоны не превышают предельной допустимой концентрации.
Организация рационального освещения рабочих мест является одним из основных вопросов охраны труда. Основные параметры освещения приведены в СНиП 23-05-95 "Естественное и искусственное освещение". Правильно спроектированное и выполненное производственное освещение сохраняет зрение рабочего, снижает утомляемость, способствует повышению производительности труда, качеству выпускаемой продукции, безопасности труда и снижению травматизма. Неправильно выбранные при проектировании осветительные приборы и аппаратура, а также нарушение правил их технической эксплуатации могут быть причиной пожара, взрыва, аварии на предприятии.
К современному освещению помещений, где работают с вычислительной техникой, предъявляют высокие требования как гигиенического, так и технического характера. Правильно спроектированное и выполненное освещение обеспечивает высокий уровень работоспособности, оказывает положительное психологическое воздействие, способствует повышению производительности труда. Условия деятельности пользователя в системе «человек-машина» связаны с явным преобладанием зрительной информации - до 90% общего объема.
В помещениях с компьютерной техникой применяется совмещенная система освещения. К таким системам предъявляют следующие требования:
Искусственное освещение в помещениях эксплуатации ЭВМ должно осуществляться системой общего равномерного освещения. В производственных и административно-общественных помещениях, в случаях преимущественной работы с документами, допускается применение системы комбинированного освещения (к общему освещению дополнительно устанавливаются светильники местного освещения, предназначенные для освещения зоны расположения документов).
Согласно СНиП /10/ освещенность при системе общего освещения составляет 200 лк, а при системе комбинированного освещения 400 лк, в том числе от общего освещения 200 лк.
Для искусственного освещения помещений с вычислительной техникой следует использовать люминесцентные лампы, у которых высокая световая отдача (до 75 лм/Вт и более), продолжительный срок службы (до 10000 ч), малая яркость светящейся поверхности, близкий к естественному спектр излучения, что обеспечивает хорошую цветопередачу. Наиболее приемлемыми являются люминесцентные лампы белого света и тепло-белого света мощностью 40, 80 Вт.
Для исключения засветки экранов дисплеев прямым световым потоком, светильники общего освещения располагают сбоку от рабочего места, параллельно линии зрения пользователя и стене с окнами. Такое расположение светильников позволяет производить их последовательное включение по мере необходимости и исключает раздражение глаз чередующимися полосами света и тени, возникающее при поперечном расположении светильников.
При периметральном расположении компьютеров линии светильников должны располагаться локализовано над рабочим столом ближе к его переднему краю, обращенному к оператору.
Для обеспечения оптимальных условий зрительных работ для пользователей дисплейных устройств необходима определенная световая отделка помещения.
Следует ограничивать неравномерность распределения яркости в поле зрения пользователя ЭВМ, при этом соотношение яркости между рабочими поверхностями не должно превышать 3:1 - 5:1, а между рабочими поверхностями и поверхностями стен и оборудования 10:1.
Освещенность рабочего места пользователя на исследуемом предприятии является совмещенной (искусственное + естественное), расположение рабочих мест исключает попадание прямых солнечных лучей на экран дисплея и в глаза. В качестве источника искусственного освещения используют люминесцентные лампы белого света мощностью 40 Вт. Точность зрительной работы характеризуется размером объекта различения. Объект различения это элемент рассматриваемого объекта минимального размера, который нужно узнавать и различать (элемент буквы или толщина ее начертания, размер отдельных деталей или расстояние между ними и т.п.). По степени точности все зрительные работы делятся на восемь разрядов.
Для естественного освещения нормируется коэффициент естественного освещения (КЕО), который определяется с помощью освещенности в данной точке внутри помещения и освещенности снаружи помещения. Причем нужно отметить, что КЕО при IV разряде зрительных работ должно быть не менее 1,2.
Для искусственного освещения нормируемым параметром является освещенность. В зависимости от контраста объекта с фоном и яркости фона каждый из восьми разрядов зрительных работ подразделяется на четыре подраздела, для каждого из которого нормируется освещенность. Например, при IV разряде зрительных работ нормированное значение освещенности принимает 400 лк.
Необходимый уровень освещенности тем выше, чем темнее фон, меньше объект различения и контраст объекта с фоном.
Наиболее часто для расчета искусственного освещения используется метод коэффициента использования осветительной установки, который сводится к определению светового потока:
,
где FЛ световой поток источника света, лм;
ЕН нормированное значение освещенности - ЕН=400 лк (разряд зрительной работы IV(в), комбинированное освещение);
кз коэффициент запаса, кз=1.3;
Sn площадь рабочей поверхности помещения, Sn=45=20 (м2);
Z поправочный коэффициент, численно равный отношению средней освещенности к минимальной, Еср/Emin Z=1,1;
n количество источников света - n=12;
И коэффициент использования осветительной установки, значение которого зависит от типа светильника, коэффициента отражения стен с, потолка п, рабочей поверхности р, размеров освещаемого помещения (индекса помещения).
Для определения индекса помещения следует применять уравнение:
,
где b, ln соответственно ширина и длина освещаемого помещения;
Нр высота подвеса светильников над рабочей поверхностью.
Коэффициент использования светового потока светильников с лампами накаливания И определяем по таблице, приведенной в СНиП 23-05-95, с помощью следующих значений:
; р=0,1; с=0,2; п=0,7.
В итоге И = 0,73.
Соответственно:
Для полученного значения светового потока источника света FЛ=3130 лм наиболее подходят два типа ламп накаливания: ЛБ40-М и ЛД65-7.
Все необходимые данные определены в СНиП 23-05-95.
Помещение, в котором установлено рабочее место инженера-программиста, относится к категории “Д” по взрывопожароопасности, так как не содержит горючих веществ, но лишь негорючие вещества и материалы в холодном состоянии.
Пожары в помещении, в котором находится ЭВМ, представляют особую опасность, так как сопряжены с большими материальными потерями. Площадь помещения, в котором ведется проектирование, невелика и составляет 8 м2. Как известно пожар может возникнуть при взаимодействии горючих веществ, окисления и источников зажигания. В помещении присутствуют все три основные фактора, необходимые для возникновения пожара. Горючими компонентами являются: строительные материалы для акустической и эстетической отделки помещений, двери, полы, бумага, изоляция кабелей и др.
Противопожарная защита - это комплекс организационных и технических мероприятий, направленных на обеспечение безопасности людей, на предотвращение пожара, ограничение его распространения, а также на создание условий для успешного тушения пожара.
Источниками зажигания в помещении, содержащем ЭВМ, могут быть электронные схемы от ЭВМ, приборы, применяемые для технического обслуживания, устройства электропитания, где в результате различных нарушений образуются перегретые элементы, электрические искры и дуги, способные вызвать загорания горючих материалов.
В современных ЭВМ очень высока плотность размещения элементов электронных схем. В непосредственной близости друг от друга располагаются соединительные провода, кабели. При протекании по ним электрического тока выделяется значительное количество теплоты. При этом возможно оплавление изоляции. Для отвода избыточной теплоты от ЭВМ служат системы вентиляции и кондиционирования воздуха. При постоянном действии эти системы представляют собой дополнительную пожарную опасность.
Одной из наиболее важных задач пожарной защиты является защита строительных помещений от разрушений и обеспечение их достаточной прочности в условиях воздействия высоких температур при пожаре. Учитывая высокую стоимость электронного оборудования, а также категорию его пожарной опасности, здания, в которых предусмотрено размещение ЭВМ должны быть 1 и 2 степени огнестойкости.
К средствам тушения пожара, предназначенных для локализации небольших возгорании, относятся пожарные стволы, внутренние пожарные водопроводы, огнетушители, сухой песок, асбестовые одеяла и т. п.
В соответствии с “Типовыми правилами пожарной безопасности для промышленных предприятий” залы ЭВМ, помещения для внешних запоминающих устройств, подготовки данных, сервисной аппаратуры, архивов, копировально-множительного оборудования и т.п. необходимо оборудовать дымовыми пожарными извещателями. В этих помещениях в начале пожара при горении различных пластмассовых, изоляционных материалов и бумажных изделий выделяется значительное количество дыма и мало теплоты.
Помещение, в котором производится разработка данного проекта, необходимо оборудовать средствами оповещения о пожаре, а также средствами для тушения пожара.
В данном разделе дипломной работы был проведен анализ вредных и опасных производственных факторов, действующих на рабочем месте инженера-программиста. Среди них были выделены: постоянное напряжение глаз, влияние электростатических и электромагнитных полей, длительное неизменное положение тела, шум. Был проведен анализ и указан комплекс мер по пожаробезопасности и электробезопасности. Проведен расчет эргономических требований к рабочему месту инженера-программиста. Созданные условия должны обеспечивать комфортную работу. На основании изученной литературы по данной проблеме, были указаны оптимальные размеры рабочего стола и кресла, параметры рабочей поверхности, а также сформулированы предложения по улучшению параметров рабочего места. Соблюдение условий, определяющих оптимальную организацию рабочего места инженера - программиста, позволит сохранить хорошую работоспособность в течение всего рабочего дня, повысит как в количественном, так и в качественном отношениях производительность труда программиста, что в свою очередь будет способствовать быстрейшей разработке и отладке программного продукта.
В результате проделанной работы был разработан метод автоматизации поиска схожих отпечатков и реализована программа, для реализации данного метода. Программа позволяет за приемлемое время автоматически определять личность по отпечатку пальца посредством выделения локальных особенностей. По сравнению с ручным определением «на глаз» по ключевым участкам исходного изображения получен значительный выигрыш в скорости и удобстве использования. Получаемые статистические характеристики достаточно полно описывают изображение и позволяют провести распознавание с высокой степенью точности.
Разработанная подсистема является неотъемлемой частью системы идентификации личности по отпечаткам пальцев, предназначенной для обнаружения сходства между двумя изображениемя отпечатка пальца. В результате распознавания можно установить личность человека, приложившего палец, что может использоваться при входе в систему. Посредством подсистемы распознавания удается значительно понизить уровень влияния смещения и переноса отпечатка пальцев, а также шумов и искажений в изображении.
Созданную систему следует рассматривать как исследовательскую систему, предназначенную для выявления эмпирических закономерностей в предметной области и дальнейшую разработку в направлении большей автоматизации процесса идентификации личности.
Разработанная система реализует новый вид функциональности подготовку изображений к автоматизированному структурному анализу.
П.1.1. ТЕКСТ МОДУЛЯ FING.H
#pragma once
#include "stdafx.h"
using namespace std;
//Элемент "карты точек"
//"Карта точек" - список точек для обработки
class TMapElDot{
public:
CPoint coord; //координаты точки
bool pr1, pr2; //признаки точки
public:
TMapElDot(CPoint dot){pr1 = true; pr2 = true; coord = dot;};
TMapElDot(){pr1 = true; pr2 = true;};
~TMapElDot(){};
};
//"Карта точек" - список точек для обработки
class TMapDot{
public:
list<TMapElDot> map; //карта точек на изображении
TMapDot(){};
~TMapDot(){map.clear();};
};
//сопроводительна информация
class TInfo{
public:
short kol; //количество точек
short dpi; //качество исходного отпечатка (dot per inch)
CString src; //путь к образу из которого была получена информация
CTime date; //дата отпечатка
CString description; //описание
bool operator==(const TInfo &inf){return src == inf.src;}; //сравнение расположения изображений на диске
TInfo(){kol = -1; dpi = -1; /*src = ""; description = "";*/};
void Printf(FILE *fout) //запись данных в файл
{
fwrite((void *)(&kol), sizeof(kol), 1, fout);
fwrite((void *)(&dpi), sizeof(dpi), 1, fout);
int strlen = src.GetLength();
fwrite((void *)(&strlen), sizeof(int), 1, fout);
fwrite((void *)(src.GetBuffer()), strlen, 1, fout);
};
void Scanf(FILE *fin) //чтение данных из файла
{
fread((void *)(&kol), sizeof(kol), 1, fin);
fread((void *)(&dpi), sizeof(dpi), 1, fin);
int strlen;
fread((void *)(&strlen), sizeof(int), 1, fin);
char * text = new char[strlen+1];
fread((void *)(text), strlen, 1, fin);
text[strlen] = '\0';
src = text;
delete(text);
};
};
//абсолютные параметры точки
class TAbsDot{
public:
CPoint coord; //координаты
double alpha; //направление в точке
bool type; //тип точки (1- окончание, 0- раздвоение)
bool show; //видимость точки (1- видима, 0- скрыта)
public:
TAbsDot(){coord.x = -1; coord.y = -1; alpha = 0; type = false; show = false;};
~TAbsDot(){};
bool operator==(const TAbsDot &f){return (coord.x == f.coord.x && coord.y == f.coord.y && alpha == f.alpha);};
bool operator <(const TAbsDot &f){return (alpha < f.alpha);};
bool operator >(const TAbsDot &f){return (alpha > f.alpha);};
bool operator!=(const TAbsDot &f){return false;};
bool operator<=(const TAbsDot &f){return false;};
bool operator>=(const TAbsDot &f){return false;};
CString toStr()
{
CString str;
str.Format("%d %d %f %d %d\n", coord.x, coord.y, alpha, type, show);
return str;
};
};
//класс для хранения точек в _абсолютных_ параметрах
//Описание отпечатка в абсолютных параметрах
class TAbsFing: public list<TAbsDot>
{
public:
TAbsFing(){this->clear();};
~TAbsFing(){this->clear();};
bool LoadFing(CString src); //Загрузка отпечатка из файла *.sav
bool SaveFing(CString fsav); //Сохранение отпечатка в файл *.sav
};
//относительные параметры точки
class TRelDot{
public:
short l,a1,a2; //координаты точки
//l - растояние между точками
//a1 - угол между собственным направлением точки А и направлением A -> B [0, 2*M_PI)
//a2 - угол между собственным направлением точки В и направлением A -> B [0, 2*M_PI)
TAbsDot absDot; //ее абсолютные параметры (необходимо для отображения на экране совпавших точек)
public:
bool operator<(const TRelDot &f){return this->l < f.l;}
bool sortByA1(TRelDot &f){return a1 < f.a1;} //эта функция нужна для сортировки, но сортировка так и не реализованна
bool operator==(const TRelDot &f){return (this->l == f.l && this->a1 == f.a1 && this->a2 == f.a2);}
CString toStr(){CString s; s.Format("%d %d %d\n", l, a1, a2); return s;}
};
//класс для хранения _относительных_ параметров точки
typedef list<TRelDot> listTRelDot;
//Шаблон для хранения пары значений {first, second}
template <class data_t1, class data_t2> struct TPair{
data_t1 first;
data_t2 second;
TPair(data_t1 _f, data_t2 _s){first = _f; second = _s;};
};
typedef TPair<TAbsDot, TAbsDot> TPairAbsDot;
typedef TPair<listTRelDot*, listTRelDot*> TPairSur;
//результат сравнения отпечатков
struct TCompareFing{
double val; //уровень схожести отпечатков
short cDot; //количество совпавших точек
short nfng; //номер отпечатка
CString name; //файл отпечатка
list<TPairAbsDot> dots; //first - совпавшие точки на отпечатке в базе
//second - совпавшие точки на открытом отпечатке
list<TPairSur> surdots;
//окружения на одинаковых отпечатках должны быть одинаковыми,
//на этом основано сравнение "роз"
};
//Описание отпечатка в _относительных_ параметрах
class TRelFing: public list<listTRelDot>{
private:
inline double GetS(const CPoint A, const CPoint B); //растояние между точками
double GetAlpha(const CPoint A, const CPoint B); //Направлени из точки А в В [-pi,pi)
public:
TRelFing(){};
~TRelFing(){};
TRelFing *Convert(TAbsFing &fng); //конвертировать абсолютные параметры к относительным
TCompareFing Compare(TRelFing &fng); //сравнить отпечатки
};
П.1.2. ТЕКСТ МОДУЛЯ FING.CPP
#include "stdafx.h"
#include "fing.h"
bool TAbsFing::SaveFing(CString fsav)
//Сохранение отпечатка в файл *.sav
{
if(!this->size()) return false;
TAbsFing::iterator iter;
FILE *fingfile = fopen(fsav, "wb");
if(fingfile == NULL)
{
MessageBox(NULL,"Невозможно создать файл: '"+fsav+"'", "Ошибка работы с файлом", MB_OK);
return false;
}
for(iter = this->begin(); iter != this->end(); iter++)
{
TAbsDot dot = *iter;
if(iter->show) fwrite((void *)&dot, 1, sizeof(dot), fingfile);
}
fclose(fingfile);
return true;
}
bool TAbsFing::LoadFing(CString src)
//Загрузка отпечатка из файла *.sav
{
TAbsDot dot;
FILE *fingfile = fopen(src, "rb");
if(fingfile == NULL)
{
MessageBox(NULL,"Невозможно открыть файл: '"+src+"'", "Ошибка работы с файлом", MB_OK);
return false;
}
this->clear();
while(!feof(fingfile))
{
fread((void *)&dot, 1, sizeof(dot), fingfile);
this->push_back(dot);
}
this->pop_back();
fclose(fingfile);
return true;
}
///////////////////////////////////////////////////////////////////////////////////////
///TRelFing//TRelFing/TRelFing/TRelFing/TRelFing/TRelFing/TRelFing/TRelFing/TRelFing///
///////////////////////////////////////////////////////////////////////////////////////
TRelFing *TRelFing::Convert(TAbsFing &fng)
//конвертировать абсолютные параметры к относительным
{
if(fng.empty()) return this;
this->clear();
TAbsFing::iterator iterA1, iterA2;
TRelDot tmpR;
listTRelDot listDots;
double tmpa, vecAB;
for(iterA1 = fng.begin(); iterA1 != fng.end(); iterA1++)
{
for(iterA2 = fng.begin(); iterA2 != fng.end(); iterA2++)
{
if(iterA2 == iterA1) continue;
tmpR.l = (short)(GetS(iterA1->coord, iterA2->coord)+0.5); //l - растояние между точками
vecAB = GetAlpha(iterA2->coord, iterA1->coord);
tmpa = iterA1->alpha - vecAB;
if(tmpa < 0) tmpa = 2*M_PI + tmpa;
tmpR.a1 = (short)(tmpa * 180.0/M_PI +0.5); //a1 - угол между собственным направлением точки А и направлением A -> B
tmpa = iterA2->alpha - vecAB;
if(tmpa < 0) tmpa = 2*M_PI + tmpa;
tmpR.a2 = (short)(tmpa * 180.0/M_PI +0.5); //a2 - угол между собственным направлением точки В и направлением A -> B
tmpR.absDot = *iterA1; //Во всех точках хранятся одни и те же данные!(необходимо для отображения совпавших точек)
listDots.push_back(tmpR);
}
listDots.sort();
this->push_back(listDots);
listDots.clear();
}
return this;
}
inline double TRelFing::GetS(const CPoint A, const CPoint B)
//растояние между точками
{
return sqrt( (double)((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)) );
}
double TRelFing::GetAlpha(const CPoint A, const CPoint B)
//Направлени из точки А в В [-pi,pi)
{
if(A == B) return 0.0;
double alpha;
if (A.x - B.x == 0)
{
if (A.y > B.y) alpha = M_PI_2;
else alpha = -M_PI_2;
}else
{
double a = ((double)A.y-B.y)/((double)B.x-A.x);
alpha = atan(a);
if (A.x > B.x)
{
if (alpha < 0) alpha += M_PI;
else alpha -= M_PI;
if (A.y == B.y) alpha = -M_PI;
}
}
return alpha;
}
TCompareFing TRelFing::Compare(TRelFing &fng)
//сравнить отпечаток с отпечатком из файла
{
TCompareFing ret;
ret.nfng = (short)fng.size();
const short CONFIRM_VAL = 9;
const double DELTA_L = 10.0; //ограничитель
const double DELTA_A = 10.0; //ограничитель
short confirmDot = 0; //количество совпавших СТ (спец точек)
short confirmVal = 0; //количество совпавших сопряженных СТ с текущей СТ
short needVal = (short)(min(this->size(),fng.size())/3.0 +0.5);
if(needVal > CONFIRM_VAL) needVal = CONFIRM_VAL;
listTRelDot *surroundDots1, *surroundDots2;
listTRelDot::iterator baseIter;
for(TRelFing::iterator tekFing = this->begin();
tekFing != this->end();
tekFing++)
{
for(TRelFing::iterator baseFing = fng.begin();
baseFing != fng.end();
baseFing++)
{
confirmVal = 0;
surroundDots1 = new(listTRelDot);
surroundDots2 = new(listTRelDot);
for(listTRelDot::iterator tekIter = (*tekFing).begin();
tekIter != (*tekFing).end();
tekIter++)
{
baseIter = (*baseFing).begin();
short prev, next;
prev = next = abs(baseIter->l - tekIter->l);
while(
prev >= next &&
next >= DELTA_L &&
baseIter != (*baseFing).end())
{
prev = next;
baseIter++;
next = abs(baseIter->l - tekIter->l);
}
if(prev >= DELTA_L && prev < next) continue; //нет смысла сравнивать дальше т.к. всегда будет next >= DELTA_L
for(;
baseIter != (*baseFing).end();
baseIter++)
{
int len = abs(tekIter->l - baseIter->l);
if(len >= DELTA_L) break; //нет смысла сравнивать дальше т.к. всегда будет next >= DELTA_L
int delta_a = DELTA_A;
if(
((abs(tekIter->a1 - baseIter->a1)<delta_a)||(abs(tekIter->a1 - baseIter->a1) > 360-delta_a))&&
((abs(tekIter->a2 - baseIter->a2)<delta_a)||(abs(tekIter->a2 - baseIter->a2) > 360-delta_a)))
{
confirmVal++;
surroundDots1->push_back(*baseIter);
surroundDots2->push_back(*tekIter);
break;
}
}
if(confirmVal > needVal)
{
///////////////////////////
//удалим эту точку из последующего перебора, т.к. она уже совпала
ret.dots.push_back(TPairAbsDot(baseFing->back().absDot, tekFing->back().absDot));
ret.surdots.push_back(TPairSur(surroundDots1,surroundDots2));
baseFing->clear();
fng.erase(baseFing);
confirmDot++;
break;
}
}
if(confirmVal > needVal){break;}
else{
ret.dots.push_back(TPairAbsDot(baseFing->back().absDot, tekFing->back().absDot));
ret.surdots.push_back(TPairSur(surroundDots1,surroundDots2));
surroundDots1->clear();
surroundDots2->clear();
}
}
}
ret.cDot = confirmDot;
ret.val = 0;
return ret;
}
П.1.3. ТЕКСТ МОДУЛЯ FINGERANALYSERDLG.CPP
// FingerAnalyserDlg.cpp : implementation file
//
#include "stdafx.h"
#include "FingerAnalyser.h"
#include "FingerAnalyserDlg.h"
#include "TAnalysePicture.h"
#include ".\fingeranalyserdlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CString sav_path, db_file;
TAnalysePicture *picture;
TAbsFing fingA;
TRelFing fingR;
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CFingerAnalyserDlg dialog
CFingerAnalyserDlg::CFingerAnalyserDlg(CWnd* pParent /*=NULL*/)
: CDialog(CFingerAnalyserDlg::IDD, pParent)
, m_kolDots(0)
, m_workFile(_T(""))
, m_scantime(0)
, m_show_base(FALSE)
, m_mouse_x(0)
, m_mouse_y(0)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
CFingerAnalyserDlg::~CFingerAnalyserDlg()
{
delete(fp);
delete(picture);
if(compareResult)
{
for(list<TCompareFing>::iterator i = compareResult->begin();
i != compareResult->end();
i++)
{
list<TPairSur>::iterator j;
for(j=i->surdots.begin(); j!=i->surdots.end(); j++)
{
j->first->clear(); delete(j->first);
j->second->clear(); delete(j->second);
}
}
compareResult->clear();
delete(compareResult);
compareResult = NULL;
}
}
void CFingerAnalyserDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_SPEC_DOT, m_kolDots);
DDX_Control(pDX, IDC_LOAD_PROGRESS, loadProgress);
DDX_Text(pDX, IDC_WORK_FILE, m_workFile);
DDX_Control(pDX, IDC_LOAD_COMPARE_PROGRESS, compare_progress);
DDX_Text(pDX, IDC_TEMESCAN, m_scantime);
DDX_Check(pDX, IDC_SHOW_BASE, m_show_base);
}
BEGIN_MESSAGE_MAP(CFingerAnalyserDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_OPEN_FILE, OnBnClickedOpenFile)
ON_BN_CLICKED(IDC_EXIT, OnBnClickedExit)
ON_WM_CLOSE()
ON_WM_ACTIVATE()
ON_BN_CLICKED(IDC_ANALYSE, OnBnClickedAnalyse)
ON_BN_CLICKED(IDC_COMPARE, OnBnClickedCompare)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_SAVE_TO_DB, OnBnClickedSaveToDb)
ON_BN_CLICKED(IDC_BUTTON_PREV, OnBnClickedButtonPrev)
ON_BN_CLICKED(IDC_BUTTON_NEXT, OnBnClickedButtonNext)
ON_BN_CLICKED(IDC_SHOW_BASE, OnBnClickedShowBase)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
// CFingerAnalyserDlg message handlers
BOOL CFingerAnalyserDlg::OnInitDialog()
{
CDialog::OnInitDialog();
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
fp = new TFingPicture(this->GetDC());
char fullpath[200];
_fullpath(fullpath, NULL, 200);
sav_path = fullpath;
sav_path += "\\sav\\";
db_file = sav_path + "fingbase.bse";
compareResult = NULL;
return TRUE; // return TRUE unless you set the focus to a control
}
void CFingerAnalyserDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CFingerAnalyserDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
if(m_show_base)
{//режим просмотра базы
ShowBase(true, false);
}
else
{//режим просмотра открытого образа
if (picture != NULL)
{
picture->GetPic1()->Show(110, 45);
picture->GetPic2()->Show(545, 45);
}
m_kolDots = (int)fingA.size();
UpdateData(false);
}
CDialog::OnPaint();
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CFingerAnalyserDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CFingerAnalyserDlg::OnBnClickedOpenFile()
{
char szFilters[]= "Образы (*.bmp)|*.bmp|All Files (*.*)|*.*||";
CFileDialog dlg(TRUE, "bmp", "*.bmp", OFN_FILEMUSTEXIST| OFN_HIDEREADONLY, szFilters, this);
if(dlg.DoModal() != IDOK)
return; //никаких файлов не открыли
if(dlg.GetFileExt().CompareNoCase("bmp"))
return; //открытый файл не имеет расширеня .bmp
CString fileName = dlg.GetFileName();
delete(picture);
picture = new TAnalysePicture(fileName, this->GetDC());
m_workFile = fileName;
if(compareResult)
{
for(list<TCompareFing>::iterator i = compareResult->begin();
i != compareResult->end();
i++)
{
list<TPairSur>::iterator j;
for(j=i->surdots.begin(); j!=i->surdots.end(); j++)
{
j->first->clear();
delete(j->first);
j->second->clear();
delete(j->second);
}
}
compareResult->clear();
}
m_show_base = false;
Invalidate();
}
void CFingerAnalyserDlg::OnBnClickedExit()
{
CDialog::SendMessage(WM_CLOSE);
}
void CFingerAnalyserDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
CDialog::OnActivate(nState, pWndOther, bMinimized);
// pWndOther->SetProperty(
}
void CFingerAnalyserDlg::OnBnClickedAnalyse()
{
if(picture == NULL) return;
LPSYSTEMTIME mTime;
mTime = new SYSTEMTIME;
GetSystemTime(mTime);
long int workTime;
workTime = mTime->wSecond*1000+mTime->wMilliseconds;
fingA = picture->AnalysePicture();
fingA.SaveFing(GetSAV(picture->getPathSrc()));
GetSystemTime(mTime);
workTime = mTime->wSecond*1000+mTime->wMilliseconds - workTime;
workTime = (workTime<0)?60000+workTime:workTime;
delete(mTime);
m_scantime = workTime;
Invalidate();
}
void CFingerAnalyserDlg::OnBnClickedCompare()
{
if(fingA.size() == 0)
{
MessageBox("Отпечаток не обработан", "Ошибка");
return;
}
fingR.Convert(fingA);
if(compareResult)
{
for(list<TCompareFing>::iterator i = compareResult->begin();
i != compareResult->end();
i++)
{
list<TPairSur>::iterator j;
for(j=i->surdots.begin(); j!=i->surdots.end(); j++)
{
j->first->clear(); delete(j->first);
j->second->clear(); delete(j->second);
}
}
compareResult->clear();
delete(compareResult);
compareResult = NULL;
showIter = NULL;
}
compareResult = CompareWithBase();
if(compareResult->size() == 0) return;
CString sOut="";
for(list<TCompareFing>::iterator i = compareResult->begin();
i != compareResult->end();
i++)
{
CString s="";
int mlevel = min(i->nfng,m_kolDots);
int percent;
if(mlevel > 10) mlevel = 10;
if(i->cDot > mlevel) percent = 100;
else percent = (int)(100.0*i->cDot/(double)mlevel + 0.5);
if(percent == 0) continue;
s.Format("%d %d %% %s\n", i->cDot, percent, i->name);
sOut += s;
}
if(sOut.GetLength()==0) sOut = "Ни одного отпечатка не найдено!\n";
CString kol; kol.Format("\n Всего в базе: %d", compareResult->size());
sOut += kol;
PrintReport(picture->getPathSrc(), sOut);
MessageBox(sOut, picture->getPathSrc());
}
void CFingerAnalyserDlg::OnTimer(UINT nIDEvent)
{
Invalidate();
CDialog::OnTimer(nIDEvent);
}
void CFingerAnalyserDlg::OnBnClickedSaveToDb()
{
char szFilters[] = "Образы (*.bmp)|*.bmp|All Files (*.*)|*.*||";
CFileDialog dlg( TRUE, "bmp", "*.bmp",
OFN_FILEMUSTEXIST| OFN_HIDEREADONLY| OFN_ALLOWMULTISELECT,
szFilters, this);
if(dlg.DoModal() == IDOK)
{
listTInfo *fingDB = LoadDB(db_file);
FILE *fbse = fopen(db_file, "wb");
if(fbse == NULL)
{
MessageBox("Невозможно создать базу данных с отпечатками", "Ошибка создания БД", MB_OK);
return;
}
POSITION pos, posStart;
TInfo newFingInDB;
pos = posStart = dlg.GetStartPosition();
int kolFile = 0;
while(pos)
{
dlg.GetNextPathName(pos);
kolFile++;
}
pos = posStart;
loadProgress.SetRange(0, kolFile);
int progressPos = 1;
while(pos)
{
CString fileName = dlg.GetNextPathName(pos).MakeLower();
if(fileName.Find(".bmp") == -1) continue;
TAnalysePicture *loadingPic;
loadingPic = new TAnalysePicture(fileName, this->GetDC());
m_workFile = fileName;
fingA = loadingPic->AnalysePicture();
if(fingA.size() < MIN_SIZE)
{
MessageBox("Отпечаток не пригоден для сохраниения в базу!", fileName);
continue;
}
if(fingA.size() > MAX_SIZE)
{
MessageBox("Отпечаток не пригоден для сохраниения в базу!", fileName);
continue;
}
fingA.SaveFing(GetSAV(fileName));
newFingInDB.src = fileName;
fingDB->remove(newFingInDB);
fingDB->push_back(newFingInDB);
loadProgress.SetPos(progressPos);
progressPos++;
Invalidate();
delete(loadingPic);
}
loadProgress.SetPos(0);
int count = 0;
fwrite((void*)&count, sizeof(count), 1, fbse);
for(list<TInfo>::iterator iter = fingDB->begin(); iter != fingDB->end(); iter++)
{
iter->Printf(fbse);
count++;
}
fseek(fbse, 0, SEEK_SET);
fwrite((void*)&count, sizeof(count), 1, fbse);
fingDB->clear();
delete(fingDB);
fclose(fbse);
}
}
listTInfo *CFingerAnalyserDlg::LoadDB(CString dbFile)
//загрузить точки из БД
{
listTInfo *bse = new listTInfo();
TInfo finf; //данные по отпечатку
FILE *fbse = fopen(dbFile, "rb");
if(fbse == NULL)
{
// MessageBox("Невозможно загрузить базу данных с отпечатками", "Ошибка загрузки БД", MB_OK);
return bse;
}
int count = 0;
fread((void*)&count, sizeof(count), 1, fbse);
for(;count > 0; count--)
{
finf.Scanf(fbse);
bse->push_back(finf);
}
fclose(fbse);
return bse;
}
list<TCompareFing> *CFingerAnalyserDlg::CompareWithBase()
//сравнить точку с точками в БД
{
listTInfo *bse;
list<TCompareFing> *cFng;
cFng = new list<TCompareFing>;
bse = LoadDB(db_file);
if(bse->empty())
{
MessageBox("База данных отпечатков пуста", "Сообщение", MB_OK);
return cFng;
}
TAbsFing aFng;
TRelFing baseFng;
compare_progress.SetRange(0, (short)bse->size());
for(list<TInfo>::iterator ibse = bse->begin();
ibse != bse->end(); ibse++)
{
if(!aFng.LoadFing(GetSAV(ibse->src))) continue;
baseFng.Convert(aFng);
TCompareFing compareRes = fingR.Compare(baseFng);
compareRes.name = ibse->src;
cFng->push_back(compareRes);
compare_progress.SetPos((int)cFng->size());
}
bse->clear();
compare_progress.SetPos(0);
delete(bse);
return cFng;
}
void CFingerAnalyserDlg::OnBnClickedButtonPrev(){ ShowBase(false);}
void CFingerAnalyserDlg::OnBnClickedButtonNext(){ ShowBase(true);}
void CFingerAnalyserDlg::ShowBase(bool key, bool next)
//key - направление перемотки по базе (влево, вправо)
//next - нужно ли переходить к следующему отпечатку
{
if(!compareResult) return;
if(compareResult->size() == 0)
{
MessageBox("База данных отпечатков пуста", "Сообщение", MB_OK);
return;
}
if(showIter == NULL) showIter = compareResult->begin();
else
{
if(next)
if(key)
{
showIter++;
if(showIter == compareResult->end())
showIter = compareResult->begin();
}
else
{
if(showIter == compareResult->begin())
showIter = compareResult->end();
showIter--;
}
}
TFingPicture *pic;
pic = new TFingPicture(this->GetDC());
if(!pic->Load(BLANK)) return;
CPaintDC dc(this); // device context for painting
list<TPairSur>::iterator is = showIter->surdots.begin();
list<TPairAbsDot>::iterator id = showIter->dots.begin();
for(; id != showIter->dots.end(); id++, is++)
{
COLORREF col;
if(is->first->empty()) col = 0xBBBBBB;
else col = (id->first.type)?0xff0000:0x000000;
pic->Line(id->first.coord, id->first.coord, 5, col);
pic->Line(id->first.coord,
CPoint(id->first.coord.x+(int)(10.0*cos(id->first.alpha)),id->first.coord.y-(int)(10.0*sin(id->first.alpha))),
2, col);
if(is->first->empty()) continue; //окружения для этой точки нет
//проверка, что "мышь" находится над точкой
if( abs(mouse_pos.x-id->first.coord.x)<6 && abs(mouse_pos.y-id->first.coord.y)<6 )
{
TFingPicture pic2(this->GetDC());
if(!pic2.Load(BLANK)) return;
pic2.Copy(*picture->GetPic2());
for(listTRelDot::iterator ii = is->first->begin(); ii != is->first->end(); ii++)
{
COLORREF cl = 0x554444;
CPoint cd;
cd.x = (long)(id->first.coord.x - ii->l * cos(ii->a1*M_PI/180.0 - id->first.alpha));
cd.y = (long)(id->first.coord.y - ii->l * sin(ii->a1*M_PI/180.0 - id->first.alpha));
pic->Line(id->first.coord, cd, 1, cl);
}
for(listTRelDot::iterator ii = is->second->begin(); ii != is->second->end(); ii++)
{
COLORREF cl = 0x554444;
CPoint cd;
cd.x = (long)(id->second.coord.x - ii->l * cos(ii->a1*M_PI/180.0 - id->second.alpha));
cd.y = (long)(id->second.coord.y - ii->l * sin(ii->a1*M_PI/180.0 - id->second.alpha));
pic2.Line(id->second.coord, cd, 1, cl);
}
pic2.Show(545, 45);
}
}
if (pic != NULL)
{
pic->Show(110, 45);
m_workFile = showIter->name;
}
UpdateData(false);
delete(pic);
}
void CFingerAnalyserDlg::PrintReport(CString file, CString report)
{
FILE *outf = fopen("report.txt", "a");
CString msg = "\n------ "+file+" ------\n"+report;
fprintf(outf, msg);
fclose(outf);
}
CString CFingerAnalyserDlg::GetSAV(CString srcName)
{
CString fsav = srcName.Left(srcName.GetLength() - 3) + "sav";
while(fsav.Find("\\") != -1){ fsav = fsav.Right(fsav.GetLength() - fsav.Find("\\")-1); }
return sav_path + fsav;
}
void CFingerAnalyserDlg::OnBnClickedShowBase()
{
m_show_base =! m_show_base;
UpdateData(false);
if(m_show_base)
{
ShowBase(true, false);
}
else
{
OnPaint();
}
}
void CFingerAnalyserDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
if(!m_show_base) return;
mouse_pos = point;
mouse_pos.x -= 110;
mouse_pos.y -= 45;
ShowBase(true, false);
CDialog::OnLButtonDown(nFlags, point);
}
П.1.4. ТЕКСТ МОДУЛЯ FINGERANALYSERDLG.H
// FingerAnalyserDlg.h : header file
//
#pragma once
#include "TFingPicture.h"
#include "afxcmn.h"
typedef list<TInfo> listTInfo;
// CFingerAnalyserDlg dialog
class CFingerAnalyserDlg : public CDialog
{
// Construction
public:
CFingerAnalyserDlg(CWnd* pParent = NULL); // standard constructor
~CFingerAnalyserDlg(); // деструктор
// Dialog Data
enum { IDD = IDD_FINGERANALYSER_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
HICON m_hIcon;
CDC memDC;
CBitmap bm;
BITMAP bmp;
UINT timer;
TFingPicture *fp;
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedOpenFile();
afx_msg void OnBnClickedExit();
afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
afx_msg void OnBnClickedAnalyse();
afx_msg void OnBnClickedCompare();
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnEnChangeSpecDot();
int m_kolDots;
afx_msg void OnBnClickedSaveToDb();
CProgressCtrl loadProgress;
public:
listTInfo *LoadDB(CString dbFile);
list<TCompareFing> *CompareWithBase();
CString m_workFile;
CProgressCtrl compare_progress;
long m_scantime;
afx_msg void OnBnClickedButtonPrev();
list<TCompareFing> *compareResult;
list<TCompareFing>::iterator showIter;
afx_msg void OnBnClickedButtonNext();
void ShowBase(bool key, bool next = true);
void PrintReport(CString file, CString report);
CString GetSAV(CString srcName); //получение пути к sav файлу
BOOL m_show_base;
afx_msg void OnBnClickedShowBase();
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
CPoint mouse_pos;
int m_mouse_x;
int m_mouse_y;
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
};
П.1.5. ТЕКСТ МОДУЛЯ Resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by FingerAnalyser.rc
//
#define IDM_ABOUTBOX 0x0010
#define IDD_ABOUTBOX 100
#define IDS_ABOUTBOX 101
#define IDD_FINGERANALYSER_DIALOG 102
#define IDR_MAINFRAME 128
#define IDR_TOOLBAR 130
#define IDI_FING_ICON 135
#define IDR_MENU1 138
#define IDC_OPEN_FILE 1000
#define IDC_ANALYSE 1001
#define IDC_COMPARE 1002
#define IDC_EXIT 1003
#define IDC_SAVE_TO_DB 1004
#define IDC_SPEC_DOT 1005
#define IDC_LOAD_PROGRESS 1006
#define IDC_WORK_FILE 1007
#define IDC_LOAD_COMPARE_PROGRESS 1008
#define IDC_TEMESCAN 1009
#define IDC_BUTTON_PREV 1012
#define IDC_BUTTON_NEXT 1013
#define IDC_SHOW_BASE 1014
#define IDC_EDIT1 1015
#define ID_BASE 32771
#define ID_PROPERTY 32772
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 139
#define _APS_NEXT_COMMAND_VALUE 32774
#define _APS_NEXT_CONTROL_VALUE 1016
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
П.1.6. ТЕКСТ МОДУЛЯ FingAnalyser.h
// FingerAnalyser.h : main header file for the PROJECT_NAME application
//
#pragma once
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
// CFingerAnalyserApp:
// See FingerAnalyser.cpp for the implementation of this class
//
class CFingerAnalyserApp : public CWinApp
{
public:
CFingerAnalyserApp();
// Overrides
public:
virtual BOOL InitInstance();
// Implementation
DECLARE_MESSAGE_MAP()
};
extern CFingerAnalyserApp theApp;
П.1.7. ТЕКСТ МОДУЛЯ FingAnalyser.cpp
// FingerAnalyser.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "FingerAnalyser.h"
#include "FingerAnalyserDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CFingerAnalyserApp
BEGIN_MESSAGE_MAP(CFingerAnalyserApp, CWinApp)
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
// CFingerAnalyserApp construction
CFingerAnalyserApp::CFingerAnalyserApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
// The one and only CFingerAnalyserApp object
CFingerAnalyserApp theApp;
// CFingerAnalyserApp initialization
BOOL CFingerAnalyserApp::InitInstance()
{
CWinApp::InitInstance();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
// Change the registry key under which our settings are stored
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
CFingerAnalyserDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
П.1.8 ТЕКСТ МОДУЛЯ TAnalysePicture.h
#pragma once
#include "TFingPicture.h"
//MESSAGEOUT отображать отладочную информацию с помощью popup окон
//#define MESSAGEOUT true
#define MESSAGEOUT false
#define OUT_FILE "fingAnalyserOut.txt" //файл отчет
#define BLANK "blank.bmp" //пустое изображение
///////////////////////////////////////////////////////////////////////////////////
//важные параметры для обхода изображения
#define LEN_S 3 //длина малого вектора (LEN_S точек)
#define LEN_L 4 //длина большого вектора (LEN_L малых векторов)
#define KOL_L 2 //необходимое количество больших векторов
#define KOL_S LEN_L*KOL_L //необходимое количество точек
#define TEST_ALPHA 130.0 //тест на разворот вектора. Указывается угол в градусах
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
// Класс АНАЛИЗА ИЗОБРАЖЕНИЯ
///////////////////////////////////////////////////////////////////////////////////
class TAnalysePicture
{
private:
TFingPicture *pic; //Собственно сама картинка
TFingPicture *tmpPic; //копия картинки
TFingPicture *pic2; //изображение для отображения в окне
int height, width; //высота и ширина изображения
CString srcImg; //путь к изображению
int err; //Код состояния картинки
TInfo info; //сопроводительная информация
private:
int ChangeLine(list<TMapElDot>::iterator _dot, list<TMapElDot> &_map);//Обработка картинки, ее изменение
TAbsFing ReadPic(list<TMapElDot>::iterator _dot); //Нахождение на изображении спец точек
list<TMapElDot> LookPic(); //Сканирование картинки и нахождение линий на ней
inline double GetAlpha(const CPoint A, const CPoint B); //Направлени из точки А в В [-pi,pi)
inline double GetS(CPoint A, CPoint B); //растояние между точками
CPoint FindAcceptDot(CPoint dot, double alpha, bool type); //Поиск продолжения из окончания/раздвоения
bool TestFindDot(int _x, int _y);//тест точки: Разность направлений вперед и назад должно быть меньше 110 градусов
double ChangeAlphaInterval(double _alpha); //Приведение итрервала к [-pi,pi)
int DotsFilter(TAbsFing &_dots);
/*Фильтрование полученных точек отсеиваются близкостоящие направленные в противоположные строки
а так же точки слева и справа от которых нет линий*/
bool LeftDot(TAbsFing::iterator &iter);
/*Если точка является окончанием, то слева и справа от нее должны быть линии если это не так, то точку нужно исключить из дальнейшего анализа*/
public:
TAnalysePicture(const CString src, CDC *screen);
~TAnalysePicture(void);
int getErr();
CString getErrMsg();
CString getPathSrc(){return srcImg;};
TAbsFing AnalysePicture(); //Обработка загруженного изображения и получение образа
bool Show(int x, int y, int xt=-1, int yt=-1);
TFingPicture *GetPic1();
TFingPicture *GetPic2();
};
П.1.9 ТЕКСТ МОДУЛЯ TAnalysePicture.cpp
#include "StdAfx.h"
#include "TAnalysePicture.h"
TAnalysePicture::TAnalysePicture(const CString src, CDC *screen)
{
pic = new TFingPicture(screen);
err = -1;
if(!pic->Load(src)) err = 0;
pic->Rectangle(CPoint(0, 0), pic->GetSize(), 10);
srcImg = src;
tmpPic = new TFingPicture(screen);
tmpPic->Load(src);
pic2 = new TFingPicture(screen);
pic2->Load(BLANK);
}
TAnalysePicture::~TAnalysePicture(void)
{
delete(tmpPic);
delete(pic2);
delete(pic);
}
//Код ошибки
int TAnalysePicture::getErr()
{
return err;
}
//Сообщение ошибки
CString TAnalysePicture::getErrMsg()
{
CString msg = "";
switch (err)
{
case -1: {msg = "Ошибок при загрузке изображения нет"; break;}
case 0: {msg = "Изображение не загружено"; break;}
case 1: {msg = "Возникла ошибка при загрузке изображения"; break;}
default: {msg = "Нераспознанная ошибка";}
}
return msg;
}
// Обработка загруженного изображения и получение образа
TAbsFing TAnalysePicture::AnalysePicture()
{
TAbsFing ret, ret2;
if(err != -1)
{
if(MESSAGEOUT) MessageBox(NULL, getErrMsg(), "Ошибка", MB_OK);
return ret;
}
int prevCol;
int changeN = 0; //Счетчик произведенных изменений на изображении
list<TMapElDot> map; //Карта точек принадлежащих линиям
list<TMapElDot>::iterator imap; //Итератор для map
map = LookPic(); //сканирование картинки и нахождение линий на ней
do{
changeN = 0;
prevCol = (int)map.size();
imap = map.begin();
do{ //Изображение можно модифицировать
if(imap->pr1) //Линия нуждается в обработке
changeN += ChangeLine(imap, map); //Обработка (преобразование) изображения
imap++; //Переход для обработки следующей линии
}while(imap != map.end()); //Изображение можно модифицировать
}while(prevCol<0.1*map.size()); //Изображение можно модифицировать
map = LookPic(); //сканирование картинки и нахождение линий на ней
imap = map.begin();
do{ //Изображение можно модифицировать
ret.merge(ReadPic(imap));
imap++; //Переход для обработки следующей линии
}while(imap != map.end()); //Изображение можно модифицировать
////////////////////////////////////////////////////////////////////
/////////////////////Фильтрование полученных точек//////////////////
///отсеиваются близкостоящие направленные в противоположные строки//
//////////а так же точки слева и справа от которых нет линий////////
int leftDots = 0; //число отсеянных точек
leftDots = DotsFilter(ret); //Фильтрование полученных точек
////////////////////////////////////////////////////////////////////
ret2.clear();
for(TAbsFing::iterator iter = ret.begin(); iter != ret.end(); iter++)
{
if(!iter->show) continue;
//рисование найденных точек (цвет окончания и раздвоения различный)
COLORREF col = (iter->type)?0xFF0000:0x000000;
pic2->Line(iter->coord, iter->coord, 5, col);
pic2->Line(iter->coord,
CPoint(iter->coord.x+(int)(10.0*cos(iter->alpha)),iter->coord.y-(int)(10.0*sin(iter->alpha))),
2, col);
ret2.push_back(*iter);
}
ret.clear();
return ret2;
}
TAbsFing TAnalysePicture::ReadPic(list<TMapElDot>::iterator _dot)
//Нахождение на изображении спец точек
{
TAbsFing retFing; //Образ отпечатка в абсолютных координатах
int kol = 0; //количество пройденных точек
int vec = 0; //направление поиска очередной точки
int tekS = 0; //Текущее количество коротких векторов
CPoint A, //Начало вектора
B; //Конец вектора
TAbsFing vecDotS; //массив точек для коротких векторов
TAbsFing vecDotL; //массив точек для длинных векторов
TAbsFing historyDotL; //история точек для длинных векторов
TAbsDot _tmpDotFing, bestDot;
TAbsFing::iterator iter;
double alpha; //направление вектора (в радианах)
int stopKol = 2000; //предел шагов
int ret = 0; //счетчик шагов после прохождения начальной точки
bool homeOver = false; //признак окончания обработки
A = _dot->coord; B = _dot->coord;
CPoint olddot, dot = _dot->coord; //Текущая точка на линии
do{
//основной цикл обработки,
//варианты завершения цикла
//продолжается до тех пор, пока вся линия не будет пройдена (нормальный вариант)
//зацикливание (не нормальный вариант, их несколько)
//
olddot = dot;
dot = pic->NextDotCW(dot, vec); //Поиск следующей точки _по часовой_ стрелке
if(dot.x == olddot.x && dot.y == olddot.y)
{//положение точки не изменилось => выход//
CString s;
s.Format("x = %d, y = %d, kol= %d", dot.x, dot.y, kol);
if(MESSAGEOUT)MessageBox(0, "положение точки не изменилось => выход\n" + s, "", MB_OK);
return retFing;
}
kol++; //подсчет пройденных точек
if(kol % LEN_S == 0)
{//появился новый короткий вектор
tekS++;
A = B;
B = dot;
pic2->Line(A,B, 1, 0x999999);
_tmpDotFing.coord = A;
alpha = GetAlpha(A, B); //расчет локального направления между KOL_S пикселями (направление короткого вектора)//
double dAlpha = 0.0; //Разница углов
if(vecDotS.size() > 0) //в списке можно взять предыдущее значение
dAlpha = alpha - vecDotS.begin()->alpha;
/**/ if (abs(dAlpha) >= M_PI) //разница между новым углом и предыдущим не нормальная!
{//необходимо скорректировать текущую alpha
/**/ if (dAlpha < 0.0)
{
while (abs(dAlpha) > M_PI)
{
alpha += 2.0 * M_PI;
dAlpha += 2.0 * M_PI;
}
}else
{
while (dAlpha >= M_PI)
{
alpha -= 2.0 * M_PI;
dAlpha -= 2.0 * M_PI;
}
}
}
_tmpDotFing.alpha = alpha; //запоминание направления из точки А//
vecDotS.push_front(_tmpDotFing);
///////////////////////////////////////////////////////////////////////
///////проверяем два соседних длинных вектора при условии что//////////
///////пройдено достаточно точек, чтоб сравнивать длнинные вектора/////
if(vecDotS.size() < KOL_S) continue;
//Вычисление среднего направления LEN_L коротких векторов//
//запись данных по длинному вектору////////////////////////
double sumAlpha = 0.0;
iter = vecDotS.begin();
vecDotL.clear(); //пересчитаем длинные вектора
for(int i = 0; i < KOL_S; i++)
{
sumAlpha += iter->alpha;
if ((i+1) % LEN_L == 0)
{
_tmpDotFing = *iter;
_tmpDotFing.alpha = sumAlpha / LEN_L;
vecDotL.push_back(_tmpDotFing);
sumAlpha = 0.0;
}
iter++;
}
if (abs(vecDotL.begin()->alpha) > 3*2*M_PI)
{//слишком много оборотов//
CString s;
s.Format("alpha = %.2f", vecDotL.begin()->alpha*180);
if(MESSAGEOUT)MessageBox(0, "слишком много оборотов\n"+s, "", MB_OK);
return retFing;
}
//проверяем два соседних длинных вектора//
dAlpha = vecDotL.begin()->alpha - (++vecDotL.begin())->alpha;
if (abs(dAlpha) > (TEST_ALPHA / 180.0 * M_PI)) //сильный изгиб//
{
if (historyDotL.empty())
{ //сохранение состояния//
bestDot.alpha = 0.0;
}
if (dAlpha > 0) //раздвоение
alpha = (vecDotL.begin()->alpha - M_PI + (++vecDotL.begin())->alpha) / 2.0;
else //окончание
alpha = (vecDotL.begin()->alpha + M_PI + (++vecDotL.begin())->alpha) / 2.0;
_tmpDotFing = vecDotL.front();
_tmpDotFing.alpha = alpha; //направление в СТ (специфичная точка)//
_tmpDotFing.type = dAlpha<0; //тип СТ//
historyDotL.push_front(_tmpDotFing);
if(bestDot.alpha <= abs(dAlpha))
{
bestDot.coord = _tmpDotFing.coord;
bestDot.alpha = abs(dAlpha);
}
}
else //сильный изгиб//
{
if (!historyDotL.empty()) //был _пройден_ сильный изгиб
{
alpha = 0;
for(iter = historyDotL.begin(); iter != historyDotL.end(); iter++)
alpha += iter->alpha;
alpha /= historyDotL.size(); //среднее значение в пройденной СТ
iter = historyDotL.begin();
for(unsigned int i = 0; i<(historyDotL.size()/2); i++) iter++;
//CPoint wdot = iter->coord; //наиболее вероятная точка для СТ
CPoint wdot = bestDot.coord; //наиболее вероятная точка для СТ
//Если раскомментировать эти строки, то исключатся точки имеющие продолжение
//CPoint dotForAccept = FindAcceptDot(wdot, alpha, iter->type);
//if (dotForAccept.x == -1)
{ //точка не имеет продолжения, запомним ее//
_tmpDotFing.alpha = ChangeAlphaInterval(alpha);
_tmpDotFing.coord = wdot;
_tmpDotFing.show = true;
_tmpDotFing.type = historyDotL.begin()->type;
retFing.push_back(_tmpDotFing);
}
historyDotL.clear();
stopKol += (kol*1.5 > stopKol)?1000:0;
}
}
}
if (dot.x == _dot->coord.x && dot.y == _dot->coord.y)
{//вероятно обход линии завершен
if (kol <= 2)
{//Линия подозрительно короткая
CString s;
s.Format("%d", kol);
if(MESSAGEOUT)MessageBox(0, "kol<=2 kol = " + s, "", MB_OK);
return retFing;
}else
{
homeOver = true; //пройти необходимо дальше начала
stopKol = kol + KOL_L*LEN_L*LEN_S;
}
}
if (homeOver) ret++;
}while(ret < (LEN_L*LEN_S*KOL_L) && ret < stopKol && kol <= stopKol);
_dot->pr1 = false;
_dot->pr2 = false;
return retFing;
}
list<TMapElDot> TAnalysePicture::LookPic()
//Попиксельное "пробегание" по картинке и
//запоминание черных точек, после нахождения черной точки
//заливка всей линии в цвет фона (удаление линии с картинки)
{
list<TMapElDot> map;
TMapElDot dot;
tmpPic->Copy(*pic);
for(int j = 0; j < pic->GetSize().y; j++)
for(int i = 0; i < pic->GetSize().x; i++)
{
if(!tmpPic->GetPixel(i,j)) //найден черный пиксель
{
dot.coord.x = i; dot.coord.y = j;
dot.pr1 = dot.pr2 = true;
map.push_back(dot);
tmpPic->FloodFill(i, j, 0xffffff); //удаление линии
}
}
tmpPic->Copy(*pic);
return map;
}
int TAnalysePicture::ChangeLine(list<TMapElDot>::iterator _dot, list<TMapElDot> &_map)
//Обработка картинки, ее изменение
//Обработка линии на которую указывает imap
//Исправление псевдо-раздвоений и псевдо-окончаний на указанной линии
{
int changeN = 0; //количество модификаций на линии
int kol = 0; //количество пройденных точек
int vec = 0; //направление поиска очередной точки
int tekS = 0; //Текущее количество коротких векторов
CPoint A, //Начало вектора
B; //Конец вектора
TAbsFing vecDotS; //массив точек для коротких векторов
TAbsFing vecDotL; //массив точек для длинных векторов
TAbsFing historyDotL; //история точек для длинных векторов
TAbsDot _tmpDotFing;
TAbsFing::iterator iter;
TAbsDot resetDot, bestDot;
double alpha; //направление вектора (в радианах)
int stopKol = 1500; //предел шагов
int ret = 0; //счетчик шагов после прохождения начальной точки
bool homeOver = false; //признак окончания обработки
_dot->pr1 = false;
A = _dot->coord; B = _dot->coord;
CPoint olddot, dot = _dot->coord; //Текущая точка на линии
do{
//основной цикл обработки,
//варианты завершения цикла
//продолжается до тех пор пока вся линия не будет пройдена (нормальный вариант)
//зацикливание (не нормальный вариант, их несколько)
//
olddot = dot;
dot = pic->NextDotCW(dot, vec); //Поиск следующей точки _по часовой_ стрелке
if(dot.x == olddot.x && dot.y == olddot.y)
{//положение точки не изменилось => выход//
CString s;
s.Format("x = %d, y = %d, kol= %d", dot.x, dot.y, kol);
if(MESSAGEOUT)MessageBox(0, "положение точки не изменилось => выход\n" + s, "", MB_OK);
return changeN;
}
kol++; //подсчет пройденных точек
if(kol % LEN_S == 0)
{//появился новый короткий вектор
tekS++;
A = B;
B = dot;
//pic2->Line(A,B, 1, 0x999999);
_tmpDotFing.coord = A;
alpha = GetAlpha(A, B); //расчет локального направления между KOL_S пикселями (направление короткого вектора)//
double dAlpha = 0.0; //Разница углов
if(vecDotS.size() > 0) //в списке можно взять предыдущее значение
dAlpha = alpha - vecDotS.begin()->alpha;
/**/ if (abs(dAlpha) >= M_PI) //разница между новым углом и предыдущим не нормальная!
{//необходимо скорректировать текущую alpha
/**/ if (dAlpha < 0.0)
{
while (abs(dAlpha) > M_PI)
{
alpha += 2.0 * M_PI;
dAlpha += 2.0 * M_PI;
}
}else
{
while (dAlpha >= M_PI)
{
alpha -= 2.0 * M_PI;
dAlpha -= 2.0 * M_PI;
}
}
}
_tmpDotFing.alpha = alpha; //запоминание направления из точки А//
vecDotS.push_front(_tmpDotFing);
///////////////////////////////////////////////////////////////////////
///////проверяем два соседних длинных вектора при условии что//////////
///////пройдено достаточно точек, чтоб сравнивать длнинные вектора/////
if(vecDotS.size() < KOL_S) continue;
//Вычисление среднего направления LEN_L коротких векторов//
//запись данных по длинному вектору////////////////////////
double sumAlpha = 0.0;
iter = vecDotS.begin();
vecDotL.clear(); //пересчитаем длинные вектора
for(int i = 0; i < KOL_S; i++)
{
sumAlpha += iter->alpha;
if ((i+1) % LEN_L == 0)
{
_tmpDotFing = *iter;
_tmpDotFing.alpha = sumAlpha / LEN_L;
vecDotL.push_back(_tmpDotFing);
sumAlpha = 0.0;
}
iter++;
}
if (abs(vecDotL.begin()->alpha) > 3*2*M_PI)
{//слишком много оборотов//
CString s;
s.Format("alpha = %.2f", vecDotL.begin()->alpha*180);
if(MESSAGEOUT)MessageBox(0, "слишком много оборотов\n"+s, "", MB_OK);
return changeN;
}
//проверяем два соседних длинных вектора//
dAlpha = vecDotL.begin()->alpha - (++vecDotL.begin())->alpha;
if (abs(dAlpha) > (TEST_ALPHA / 180.0 * M_PI)) //сильный изгиб//
{
if (historyDotL.empty())
{ //сохранение состояния//
resetDot = vecDotL.back();
bestDot.alpha = 0.0;
}
if (dAlpha > 0) //раздвоение
alpha = (vecDotL.front().alpha - M_PI + (vecDotL.back().alpha)) / 2.0;
else //окончание
alpha = (vecDotL.front().alpha + M_PI + (vecDotL.back().alpha)) / 2.0;
_tmpDotFing = vecDotL.front();
_tmpDotFing.alpha = alpha; //направление в СТ (специфичная точка)//
_tmpDotFing.type = dAlpha<0; //тип СТ//
historyDotL.push_front(_tmpDotFing);
if(bestDot.alpha <= abs(dAlpha))
{
bestDot.coord = _tmpDotFing.coord;
bestDot.alpha = abs(dAlpha);
}
}
else //сильный изгиб//
{
if (!historyDotL.empty()) //был _пройден_ сильный изгиб
{
alpha = 0.0;
for(iter = historyDotL.begin(); iter != historyDotL.end(); iter++)
alpha += iter->alpha;
alpha /= historyDotL.size(); //среднее значение в пройденной СТ
iter = historyDotL.begin();
for(unsigned int i = 0; i<(historyDotL.size()/2); i++) iter++;
CPoint wdot = bestDot.coord; //наиболее вероятная точка для СТ
CPoint dotForAccept = FindAcceptDot(wdot, alpha, iter->type);
if (dotForAccept.x != -1)
{ //точка имеет продолжение//
COLORREF cl;
cl = (historyDotL.begin()->type)?0x000000:0xffffff;
//здесь можно поиграть с разной толщиной линии//
pic->Line(wdot, dotForAccept, 4, cl);
_dot->pr1 = true; //эту линию необходио еще раз проанализировать
changeN++;
stopKol += (stopKol-kol < 200)?200:0;
//stopKol += (kol*1.5 > stopKol)?500:0;
//загрузить начальное состояние
if(!historyDotL.begin()->type)
{ //если ликвидировано слипание то необходимо добавить новую точку на карту
_map.push_back(TMapElDot(dot));
}
//пройдена начальная точка, продлим анализ
//очень возможно, что начальную точку мы больше не попадем
if(ret-KOL_S*LEN_S < 0)
{
ret = 0;
homeOver = false;
stopKol = 500;
}
A = B = dot = resetDot.coord;
vecDotS.clear();
vecDotL.clear();
//------------------------------
}
historyDotL.clear();
}
}
}
if (dot.x == _dot->coord.x && dot.y == _dot->coord.y)
{//вероятно обход линии завершен
if (kol <= 2)
{//Линия подозрительно короткая
CString s;
s.Format("%d", kol);
if(MESSAGEOUT)MessageBox(0, "kol<=2 kol = " + s, "", MB_OK);
return changeN;
}else
{
homeOver = true; //пройти необходимо дальше начала
stopKol = kol + KOL_L*LEN_L*LEN_S;
}
}
if (homeOver) ret++;
}while(ret < (LEN_L*LEN_S*KOL_L) && ret < stopKol && kol <= stopKol);
_dot->pr2 = false;
return changeN;
}
inline double TAnalysePicture::GetAlpha(const CPoint A, const CPoint B)
//Направлени из точки А в В [-pi,pi)
{
if(A == B) return 0.0;
double alpha;
if (A.x - B.x == 0)
{
if (A.y > B.y) alpha = M_PI_2;
else alpha = -M_PI_2;
}else
{
double a = ((double)A.y-B.y)/((double)B.x-A.x);
alpha = atan(a);
if (A.x > B.x)
{
if (alpha < 0) alpha += M_PI;
else alpha -= M_PI;
if (A.y == B.y) alpha = -M_PI;
}
}
return alpha;
}
bool TAnalysePicture::TestFindDot(int _x, int _y)
//тест точки: Разность направлений вперед и назад должно быть меньше 110 градусов
{
const int len = 7;
CPoint A(_x, _y), B, C;
//первый вектор
B = A;
int vec = 0;
for(int i = 1; i<=len; i++)
B = tmpPic->NextDotCW(B, vec);
//------расчет угла-------//
double alpha1 = GetAlpha(A, B);
//второй вектор
C = B;
B = A;
vec = 0;
for(int i = 1; i<=len; i++)
{
B = tmpPic->NextDotCCW(B, vec);
if(abs(B.x-C.x) < 3 && abs(B.y-C.y) < 3) return true;
}
//------расчет угла-------//
double alpha2 = GetAlpha(A, B);
//-----alpha1, alpha2------//
alpha1 = abs(alpha2 - alpha1);
if (alpha1 > M_PI) alpha1 = 2.0*M_PI - alpha1;
return alpha1 < (110.0/180.0 * M_PI);
}
CPoint TAnalysePicture::FindAcceptDot(CPoint dot, double alpha, bool type)
//Поиск продолжения из окончания/раздвоения
{
const int maxL = 11;
const int minL = 3;
COLORREF color;
color = (type)?0x000000:0xffffff;
//окончание - ищем черную точку
//раздвоение - ищем белую точку
int i = 0;
while (i<=6) //разброс поиска в указанном направлении alpha
{
int l = minL;
int k = (i+1) / 2;
if (i % 2 == 1) k = -k;
while (l<=maxL)
{
double arg = alpha + k * M_PI * 5.0/180.0;
int x = dot.x + (int)(l*cos(arg)+0.5);
int y = dot.y - (int)(l*sin(arg)+0.5);
if (tmpPic->GetPixel(x, y) == color) //важное условие цвета точки!!!
{
if(TestFindDot(x,y)) //проверка найденной точки (на "вшивость" :) )
return CPoint(x, y); //найденная точка
else
break;
}
l++; //увеличение дальности поиска
}
i++;
}
return CPoint(-1, -1); //точка не найдена
}
bool TAnalysePicture::Show(int x, int y, int xt, int yt)
{
if(xt!=-1) pic2->Show(xt, yt);
return pic->Show(x, y);
}
TFingPicture *TAnalysePicture::GetPic1()
{
return pic;
}
TFingPicture *TAnalysePicture::GetPic2()
{
return pic2;
}
double TAnalysePicture::ChangeAlphaInterval(double _alpha)
//Приведение итрервала к [-pi,pi)
{
double ret = abs(_alpha);
while(ret >= 2.0*M_PI) ret -= 2.0*M_PI;
if(ret > M_PI) ret = 2.0*M_PI - ret;
else ret = -ret;
if(_alpha > 0) ret = -ret;
return ret;
}
/*Фильтрование полученных точек
отсеиваются близкостоящие направленные в противоположные строки
а так же точки слева и справа от которых нет линий*/
int TAnalysePicture::DotsFilter(TAbsFing &_dots)
{
int leftDots = 0;
TAbsFing::iterator iter1;
TAbsFing::iterator iter2;
for(iter1 = _dots.begin(); iter1 != _dots.end(); iter1++)
{
if(!iter1->show) continue;
//отсев точек сложным условием (условие окружения)
iter1->show = LeftDot(iter1);
}
for(iter1 = _dots.begin(); iter1 != _dots.end(); iter1++)
{
if(!iter1->show) continue;
//отсев близкостоящих точек
for(iter2 = iter1, ++iter2; iter2 != _dots.end(); iter2++)
{
if(!iter2->show) continue;
double difL = GetS(iter1->coord,iter2->coord);
if( //условия отсева
(
//на близком растоянии (15) находятся два окончания/раздвоения направленных друг на друга
(difL < 15)&&
((abs(iter2->alpha - iter1->alpha) > (165.0/180.0*M_PI))&&(abs(iter2->alpha - iter1->alpha)<(195.0/180.0*M_PI)))
)
||
(
//или просто очень близкие точки (<5..10)
(difL < 10)&&(iter1->type == iter2->type)
)
)
{
iter1->show = false;
iter2->show = false;
}
}
}
return leftDots;
}
inline double TAnalysePicture::GetS(CPoint A, CPoint B)
//растояние между точками
{
return sqrt( (double)((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)) );
}
/*Если точка является окончанием, то слева и справа от нее должны быть линии если это не так, то точку нужно исключить из дальнейшего анализа*/
bool TAnalysePicture::LeftDot(TAbsFing::iterator &iter)
{
COLORREF color = 0x000000; //ищем черную точку для окончаний
if(!iter->type) color = 0xffffff;; //ищем белую точку для раздвоений
int l, k = 35;
const int minL = 4, maxL = 12;
bool find = false;
while(k <= 55)
{
l = minL;
while(l <= maxL)
{
int x = iter->coord.x + (int)(l*cos(iter->alpha + k/180.0*M_PI)+0.5);
int y = iter->coord.y - (int)(l*sin(iter->alpha + k/180.0*M_PI)+0.5);
if(pic->GetPixel(x,y) == color) // важное условие!!!
{ find = true; break;} //нашли точку слева
l++;
}
if(find) break;
k += 10; //Поиск с шагом 10гр
}
if(!find) return false;
k = 35;
while(k <= 55)
{
l= minL;
while(l <= maxL)
{
int x = iter->coord.x + (int)(l*cos(iter->alpha - k/180.0*M_PI)+0.5);
int y = iter->coord.y - (int)(l*sin(iter->alpha - k/180.0*M_PI)+0.5);
if(pic->GetPixel(x,y) == color) // важное условие!!!
return true; //нашли точку справа
l++;
}
k += 10;
}
return false;
}
П.1.10. ТЕКСТ МОДУЛЯ TFingPicture.h
#pragma once
#include "Fing.h"
///////////////////////////////////////////////////////////////////////////////
//Класс изображения.
//Хранение изображения, выполнение простейших операции над ним
///////////////////////////////////////////////////////////////////////////////
class TFingPicture
{
private:
CDC pic; //указатель на изображение
BITMAP bmp; //изображение
bool IsLoad; //изображение загружено
CDC *Screen; //указатель на окно программы
public:
TFingPicture(CDC *_Screen); //_Screen - указатель на окно
~TFingPicture(void);
bool Load(const CString src); //загрузить изображение из файла src
bool Show(int X, int Y); //отобразить изображение на окне в координатах (X,Y)
bool SetPixel(CPoint dot, COLORREF color); //установка цвета пикселя dot
bool SetPixel(int x, int y, COLORREF color); //установка цвета пикселя (x,y)
COLORREF GetPixel(CPoint dot); //взятие цвета пикселя dot
COLORREF GetPixel(int x, int y); //взятие цвета пикселя (x,y)
bool FloodFill(CPoint dot, COLORREF color=0xffffff); //заливка области (по умолчанию черным цветом)
bool FloodFill(int x, int y, COLORREF color=0xffffff); //заливка области (по умолчанию черным цветом)
bool Line(CPoint from, CPoint to, int width, COLORREF color);//рисование линии
bool Rectangle(CPoint from, CPoint to, int width=2, COLORREF color=0xffffff); //рисование прямоугольника
bool Copy(TFingPicture &from); //копирование изображения
CPoint NextDotCW(const CPoint dot, int &vec); //Поиск следующей точки "_по часовой_ стрелке"
CPoint NextDotCCW(const CPoint dot, int &vec); //Поиск следующей точки "_против часовой_ стрелке"
CPoint GetSize(); //получение размера изображения
};
П.1.11. ТЕКСТ МОДУЛЯ TFingPicture.cpp
#include "StdAfx.h"
#include "TFingPicture.h"
///////////////////////////////////////////////////////////////////////////////
//Класс изображения.
//Хранение изображения, выполнение простейших операции над ним
///////////////////////////////////////////////////////////////////////////////
//координаты окружающих точек
const CPoint incXY[8]=
{
CPoint(-1, -1),
CPoint(0, -1),
CPoint(1, -1),
CPoint(1, 0),
CPoint(1, 1),
CPoint(0, 1),
CPoint(-1, 1),
CPoint(-1, 0)};
TFingPicture::TFingPicture(CDC *_Screen)
{
Screen = _Screen;
pic.CreateCompatibleDC(Screen);
IsLoad = false;
}
TFingPicture::~TFingPicture(void){}
//отобразить изображение на окне в координатах (X,Y)
bool TFingPicture::Show(int X, int Y)
{
if (!IsLoad) return false;
int kx = bmp.bmWidth;
int ky = bmp.bmHeight;
return Screen->StretchBlt(X, Y, bmp.bmWidth, bmp.bmHeight, &pic, 0, 0, kx, ky, SRCCOPY)>0;
}
//загрузить изображение из файла src
bool TFingPicture::Load(const CString src)
{
IsLoad = false;
CBitmap bm;
bm.Detach();
IsLoad = bm.Attach(LoadImage(0, src, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE))>0;
bm.GetObject(sizeof(BITMAP), &bmp);
pic.SelectObject(&bm);
return IsLoad;
}
// color = BGR;
bool TFingPicture::SetPixel(CPoint dot, COLORREF color)
{
if (!IsLoad) return false;
pic.SetPixel(dot.x, dot.y, color);
return true;
}
bool TFingPicture::SetPixel(int x, int y, COLORREF color)
{
if (!IsLoad) return false;
pic.SetPixel(x, y, color);
return true;
}
// color = BGR;
COLORREF TFingPicture::GetPixel(CPoint dot)
{
if (!IsLoad) return false;
return pic.GetPixel(dot.x, dot.y);
}
COLORREF TFingPicture::GetPixel(int x, int y)
{
if (!IsLoad) return false;
return pic.GetPixel(x, y);
}
bool TFingPicture::FloodFill(CPoint dot, COLORREF color)
{
if(!IsLoad) return false;
COLORREF col = GetPixel(dot);
CBrush br(color);
pic.SelectObject(&br);
pic.ExtFloodFill(dot.x, dot.y, col, FLOODFILLSURFACE);
return true;
}
bool TFingPicture::FloodFill(int x, int y, COLORREF color)
{
if(!IsLoad) return false;
COLORREF col = GetPixel(x, y);
CBrush br(color);
pic.SelectObject(&br);
pic.ExtFloodFill(x, y, col, FLOODFILLSURFACE);
return true;
}
bool TFingPicture::Line(CPoint from, CPoint to, int width, COLORREF color)
{
if(!IsLoad) return false;
CPen pen(PS_SOLID, width, color);
pic.SelectObject(&pen);
pic.MoveTo(from.x, from.y);
pic.LineTo(to.x, to.y);
return true;
}
bool TFingPicture::Rectangle(CPoint from, CPoint to, int width, COLORREF color)
{
if(!IsLoad) return false;
Line(from, CPoint(from.x, to.y), width, color);
Line(CPoint(from.x, to.y), to, width, color);
Line(to, CPoint(to.x, from.y), width, color);
Line(CPoint(to.x, from.y), from, width, color);
return true;
}
bool TFingPicture::Copy(TFingPicture &from)
{
bmp = from.bmp;
IsLoad = from.IsLoad;
Screen = from.Screen;
return pic.BitBlt(0, 0, bmp.bmWidth, bmp.bmHeight, &from.pic, 0, 0, SRCCOPY)>0;
}
CPoint TFingPicture::NextDotCW(const CPoint dot, int &vec)
//Поиск следующей точки "_по часовой_ стрелке"
//vec вероятное направление поиска
{
int i = vec,
step = 0;
CPoint newdot = dot;
COLORREF clMas[9];
clMas[8] = clMas[0] = GetPixel(dot.x-1, dot.y-1);
clMas[1] = GetPixel(dot.x, dot.y-1);
clMas[2] = GetPixel(dot.x+1, dot.y-1);
clMas[3] = GetPixel(dot.x+1, dot.y);
clMas[4] = GetPixel(dot.x+1, dot.y+1);
clMas[5] = GetPixel(dot.x, dot.y+1);
clMas[6] = GetPixel(dot.x-1, dot.y+1);
clMas[7] = GetPixel(dot.x-1, dot.y);
do{
if(clMas[i+1] < clMas[i])
{
vec = (i + 1) % 8;
newdot.x = dot.x + incXY[vec].x;
newdot.y = dot.y + incXY[vec].y;
if(vec % 2 == 0) SetPixel(dot.x + incXY[vec+1].x, dot.y + incXY[vec+1].y, 0x000000);
vec = (vec + 5) % 8;
return newdot; //найдена новая точка
}
i = (i + 1) % 8;
step++;
}while(step <= 8);
return dot; //поиск ни к чему не привел
}
CPoint TFingPicture::NextDotCCW(const CPoint dot, int &vec)
//Поиск следующей точки "_против часовой_ стрелке"
//vec вероятное направление поиска
{
int i = vec,
step = 0;
CPoint newdot = dot;
COLORREF clMas[9];
clMas[8] = clMas[0] = GetPixel(dot.x-1, dot.y-1);
clMas[1] = GetPixel(dot.x-1, dot.y);
clMas[2] = GetPixel(dot.x-1, dot.y+1);
clMas[3] = GetPixel(dot.x, dot.y+1);
clMas[4] = GetPixel(dot.x+1, dot.y+1);
clMas[5] = GetPixel(dot.x+1, dot.y);
clMas[6] = GetPixel(dot.x+1, dot.y-1);
clMas[7] = GetPixel(dot.x, dot.y-1);
do{
if(clMas[i+1] < clMas[i])
{
vec = (i + 1) % 8;
newdot.x = dot.x + incXY[(8-vec)%8].x;
newdot.y = dot.y + incXY[(8-vec)%8].y;
if(vec % 2 == 0) SetPixel(dot.x + incXY[8-vec-1].x, dot.y + incXY[8-vec-1].y, 0x000000);
vec = (vec + 5) % 8;
return newdot; //найдена новая точка
}
i = (i + 1) % 8;
step++;
}while(step <= 8);
return dot; //поиск ни к чему не привел
}
CPoint TFingPicture::GetSize()
//получение размера изображения
{ if(!IsLoad) return false;
return CPoint(bmp.bmWidth, bmp.bmHeight);}
ПРИЛОЖЕНИЕ 2 РУКОВОДСТВО ПРОГРАММИСТА
П.2.1. НАЗНАЧЕНИЕ ПРОГРАММЫ
Программа распознавания личности по отпечаткам пальцев имеет идентификатор FingerAnalyser и предназначена для автоматической идентификации личности по папиллярному узору. Программа FingerAnalyser выполняет следующие функции:
Данная работа реализует такое преобразование изображения, при котором данные о расположение уникальных особенностей сохраняются наиболее полно и с наименьшим содержанием ложной информации.
Создаваемая система облегчит разработку алгоритмов обработки изображений, упростит анализ экспериментальных данных и выявление общих закономерностей.
П.2.2. УСЛОВИЯ ПРИМЕНЕНИЯ ПРОГРАММЫ
Программа FingerAnalyser предъявляет следующие требования к техническим средствам:
Программа FingerAnalyser предъявляет следующие требования к программным средствам:
Интерфейс программы представлен на рис. П.2.1.
Интерфейс программы FingerAnalyser
Рис. П.2.1
На форме программы в визуальном виде представляется, после открытия через пункт «Открыть», исходное изображение, после нажатия на кнопку «Анализ», скорректированное изображение и визуальное представление структурного вида отпечатка. После чего можно нажатием на кнопку «Сравнить» отыскать в базе схожие отпечатки.
При каждом анализе отпечатка создается файл с его структурным описанием. Для того чтобы поместить отпечаток в базу данных отпечатков, для последующего стравнения с ним, необходимо нажать на кнопку «Запомнить в базу». Для запоминания в базу можно выбирать группу файлов для применения операции записи в базу данных для всех выбранных файлов.
П.2.3. ХАРАКТЕРИСТИКА ПРОГРАММЫ
Программа FingerAnalyser требует для своего функционирования наличия в проекте файлов, содержащих растровые представления папиллярного узора.
В состав программы входят следующие файлы, необходимые для ее функционирования:
Программа является интерактивной, требующей взаимодействия с пользователем, поэтому время выполнения отдельных этапов обработки не превышает 0.5 с. при использовании требуемых технических средств.
П.2.4. ОБРАЩЕНИЕ К ПРОГРАММЕ
Для запуска программы необходимо убедиться в том, что необходимые библиотеки MFC находятся в том же каталоге, что и исполняемый файл или в каталоге Windows/System32.
Для корректной работы программы она должна находиться в каталоге, к которому есть права на чтение и запись.
Для запуска подсистемы необходимо в оболочке системы на главном окне нажать на кнопку «Анализ» - для сравнения нужного отпечатка с набором имеющимся в базе данных, или «Запомнить в базу» - для внесения указанных отпечатков в базу данных.
П.2.5. ВХОДНЫЕ И ВЫХОДНЫЕ ДАННЫЕ
Входными и выходными данными для программы является файл базы данных отпечатков sav/fingbase.bse. Структура файла:
src [kol] [dpi] [date] [description]
src [kol] [dpi] [date] [description]
src [kol] [dpi] [date] [description]
В каждой строке файла базы данных отпечатков содержится описание одного отпечатка. В табл. П.2.1 приведен формат записи в файле базы данных.
Таблица П.2.1
Формат записи файла базы данных
Поле |
Формат |
Описание |
src |
Строка |
путь к образу из которого была получена информация |
kol |
Целое |
количество точек |
dpi |
Целое |
качество исходного отпечатка (dot per inch) |
date |
Дата |
дата отпечатка |
description |
строка |
описание |
Выходными данными для программы является файл sav/*.sav со структурным представлением, содержащий статистические характеристики минюций на отпечатке. Этот файл имеет следующий формат:
x y alpha type [show]
x y alpha type [show]
x y alpha type [show]
В каждой строке файла структурного представления содержится описание одной минюции. В табл. П.2.2 приведен формат строки со структурным описанием минюции в абсолютных параметрах.
Таблица П.2.2
Формат строки файла со структурным описанием
Поле |
Формат |
Описание |
x |
Целое |
Абцисса минюции на растре |
y |
Целое |
Ордината минюции на растре |
alpha |
Целое |
Ориентация минюции на растре |
type |
Байт |
Тип минюции. Раздвоение или окончание |
Кроме того, выходной информацией для данной подсистемы является файл отчет report.txt, содержащий отпечатки из базы данных, в которых были обнаружены сходства с обрабатываемым отпечатком.
В каждой строке отчета содержится описание отпечатка, его имя, количество совпавших точек при распознавании и степень сходства.
В табл. П.2.3 приведен формат данных. На рис. П.2.2 приведен пример файла отчета.
report.txt имеет следующий формат:
------ Namei ------
Counti1 Pcti1 Sourcei1
Counti2 Pcti2 Sourcei2
Countik Pctik Sourceik
Всего в базе: NN
Таблица П.2.3
Формат данных файла-отчета
Поле |
Формат |
Описание |
Name |
Строка |
Имя отпечатка |
Count |
Целое |
Абсцисса минюции на растре |
Pct |
Целое |
Степень сходства отпечатков в процентах, принимает значения (0, 100] |
Source |
Строка |
Путь к файлу, из которого были взяты параметры |
NN |
Целое |
Количество отпечатков имеющихся в базе данных |
Файл-отчет
------ hedgeR1_2.bmp ------ 7 70 с:\мои документы\fing\fingc\fingeranalyser\pic\base\hedger1_1.bmp Всего в базе: 58 ------ starkyR2_2.bmp ------ 5 50 с:\мои документы\fing\fingc\fingeranalyser\pic\base\starkyr2_1.bmp Всего в базе: 58 ------ karR2_2.bmp ------ 3 30 с:\мои документы\fing\fingc\fingeranalyser\pic\base\karr2_1.bmp Всего в базе: 58 ------ vasL1_2.bmp ------ 21 100 с:\мои документы\fing\fingc\fingeranalyser\pic\vasl1_1.bmp 56 100 с:\мои документы\fing\fingc\fingeranalyser\pic\vasl1_2.bmp 12 100 с:\мои документы\fing\fingc\fingeranalyser\pic\vasl1_3.bmp Всего в базе: 58 ------ tatL1_2.bmp ------ Ни одного отпечатка не найдено! |
Рис. П.2.2
П.2.6. СООБЩЕНИЯ
Сообщения, выдаваемые программисту, приведены в табл. П.2.4.
Таблица П.2.4
Сообщения программисту
Сообщение |
Действие программиста |
Отпечаток не обработан |
Прежде чем запускать сравнение необьходимо провести анализ |
База данных пуста |
В базе данных нет информации ни об одном отпечатке. Необходимо заполнить базу данных отпечатков |
Отпечаток не пригоден для сохранения в базу |
На отпечатке либо слишком мало обнаружено минюций, менее 10, либо слишком много, более 80 |
Ни одного отпечатка не найдено |
В результате поиска не совпало ни одного отпечтака |
Невозможно создать базу данных с отпечатками |
Возможно нет прав на запись или нет свободного места на носителе |
Невозможно создать файл |
Возможно нет прав на запись или нет свободного места на носителе |
Невозможно открыть файл |
Возможно нет прав на чтение или не сеществует запрашиваемого файла на носителе |
Обнаружены сходства |
В базе данных были обнаружены отпечатки, имеющие схожее представление. |
Визуализация результатов проведения анализа приведена на рис. П.2.2.
ПРИЛОЖЕНИЕ 3 РУКОВОДСТВО ОПЕРАТОРА
П.3.1. НАЗНАЧЕНИЕ ПРОГРАММЫ
Программа распознавания личности по отпечаткам пальцев имеет идентификатор FingerAnalyser и предназначена для автоматической идентификации личности по папиллярному узору. Программа FingerAnalyser выполняет следующие функции:
Данная работа реализует такое преобразование изображения, при котором данные о расположение уникальных особенностей сохраняются наиболее полно и с наименьшим содержанием ложной информации.
Создаваемая система облегчит разработку алгоритмов обработки изображений, упростит анализ экспериментальных данных и выявление общих закономерностей.
П.3.2. УСЛОВИЯ ВЫПОЛНЕНИЯ ПРОГРАММЫ
Программа FingerAnalyser предъявляет следующие требования к техническим средствам:
Программа FingerAnalyser предъявляет следующие требования к программным средствам:
П.3.3. ВЫПОЛНЕНИЕ ПРОГРАММЫ
Интерфейс программы представлен на рис. П.3.1.
Интерфейс программы FingerAnalyser
Рис. П.3.1
На форме программы в визуальном виде представляется, после открытия через пункт «Открыть», исходное изображение, после нажатия на кнопку «Анализ», скорректированное изображение и визуальное представление структурного вида отпечатка. Для вызова работы подсистемы необходимо в оболочке системы на главном окне нажать на кнопку «Сравнить».
При каждом анализе отпечатка создается файл с его структурным описанием. Для того чтобы поместить отпечаток в базу данных отпечатков, для последующего стравнения с ним, необходимо нажать на кнопку «Запомнить в базу». Для запоминания в базу можно выбирать группу файлов для применения операции записи в базу данных для всех выбранных файлов.
П.3.4. СООБЩЕНИЯ ОПЕРАТОРУ
Сообщения, выдаваемые оператору, приведены в табл. П.3.1.
Таблица П.3.1
Сообщения оператору
Сообщение |
Действие оператора |
Отпечаток не обработан |
Прежде чем запускать сравнение необьходимо провести анализ |
База данных пуста |
В базе данных нет информации ни об одном отпечатке. Необходимо заполнить базу данных отпечатков |
Отпечаток не пригоден для сохранения в базу |
На отпечатке либо слишком мало обнаружено минюций, менее 10, либо слишком много, более 80 |
Ни одного отпечатка не найдено |
В результате поиска не совпало ни одного отпечтака |
Невозможно создать базу данных с отпечатками |
Возможно нет прав на запись или нет свободного места на носителе |
Невозможно создать файл |
Возможно нет прав на запись или нет свободного места на носителе |
Невозможно открыть файл |
Возможно нет прав на чтение или не сеществует запрашиваемого файла на носителе |
Обнаружены сходства |
В базе данных были обнаружены отпечатки, имеющие схожее представление. |
Визуализация результатов проведения сравнения приведена на рис. П.3.1.
В табл. П.4.1 приведены результаты сравнения всех отпечатков полученных при испытаниях. Для проверки правильности работы имена файлам давались таким образом, что бы можно было определить принадлежность отпечатка.
Формат результата сравнения: A/B,
где A количество совпавших минюций;
B процент совпадения.
Формат имени файла: <Name><R|L><C>_<E>.bmp
где Name имя человека, которому принадлежит отпечаток;
R отпечаток с правой руки, L отпечаток с левой руки;
С порядковый номер пальца, начиная с большого;
E экземпляр отпечатка.
Таблица П.4.1
Результаты сравнения
vovR2_1.bmp |
1L1_1.BMP |
1L2_1.BMP |
1L3_1.BMP |
1R1_1.BMP |
1R2_1.BMP |
1R3_1.BMP |
1R4_1.bmp |
2l1_1.bmp |
2l2_1.bmp |
2r1_0.bmp |
2r2_0.bmp |
|
1L1_2.bmp |
|
24/100 |
|
|
|
|
|
|
|
|
|
|
1L2_2.BMP |
|
|
9/90 |
|
|
|
|
|
|
|
|
|
1R1_2.BMP |
|
|
|
|
23/100 |
|
|
|
|
|
|
|
1R2_1rotate2.bmp |
|
|
|
|
|
23/100 |
|
|
|
|
|
|
1R2_2.BMP |
|
|
|
|
|
16/100 |
|
|
|
|
|
|
1R3_2.BMP |
|
|
|
|
|
|
1/10 |
3/30 |
|
|
|
|
1R4_2.bmp |
|
|
|
|
|
|
|
15/100 |
|
|
|
|
2l1_2.bmp |
|
|
|
|
|
|
|
|
14/100 |
|
|
|
2l2_2.bmp |
|
|
|
|
|
|
|
|
|
8/80 |
|
|
2r1_1.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
2r2_1.bmp |
|
1/10 |
|
|
|
|
|
|
|
|
|
|
2r3_1.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
3l1_2rotate.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
3l2_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
alexR1_3.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
alexR2_3.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
1L1_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
1L2_2.BMP |
|
|
|
|
|
|
|
|
|
|
|
|
1R1_2.BMP |
|
|
|
|
|
|
|
|
|
|
|
|
1R2_1rotate2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
1R2_2.BMP |
|
|
|
|
|
|
|
|
|
|
|
|
1R3_2.BMP |
|
|
|
|
|
|
|
|
|
|
|
|
1R4_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
2l1_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
2l2_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
2r1_1.bmp |
|
|
|
2/20 |
|
|
|
|
|
|
|
|
2r2_1.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
2r3_1.bmp |
48/100 |
|
|
|
|
|
|
|
|
|
|
|
3l1_2rotate.bmp |
|
24/100 |
|
|
1/10 |
|
|
|
|
|
|
|
3l2_2.bmp |
|
|
21/100 |
|
|
|
|
|
|
|
|
|
alexR1_3.bmp |
|
|
|
|
|
4/40 |
|
|
|
|
|
|
alexR2_3.bmp |
|
|
|
|
|
|
4/40 |
|
|
|
|
|
apmAR1_2.bmp |
|
|
|
|
|
|
|
4/40 |
|
|
|
|
apmAR2_2.bmp |
|
|
|
|
|
|
|
|
9/90 |
|
|
|
apmAR3_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
apmBR1_2.bmp |
|
|
|
|
|
|
|
|
|
|
12/100 |
|
apmBR2_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
20/100 |
apmBR3_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
hedgeR1_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
hedgeR2_3.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
karR1_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
karR2_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
starkyR1_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
starkyR2_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
starR1_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
vasL1_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
vasL2_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
vasR1_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
vovR1_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
1L1_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
1L2_2.BMP |
|
|
|
|
|
|
|
|
|
|
|
|
1R1_2.BMP |
|
|
|
|
|
|
|
|
|
|
|
|
1R2_1rotate2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
1R2_2.BMP |
|
|
|
|
|
|
|
|
|
|
|
|
1R3_2.BMP |
|
|
|
|
|
|
|
|
|
|
|
|
1R4_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
2l1_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
2l2_2.bmp |
|
|
|
|
|
|
|
1/10 |
|
|
|
|
2r1_1.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
2r2_1.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
2r3_1.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
3l1_2rotate.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
3l2_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
alexR1_3.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
alexR2_3.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
apmAR1_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
apmAR2_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
apmAR3_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
apmBR1_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
apmBR2_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
|
apmBR3_2.bmp |
14/100 |
|
|
|
|
|
|
|
|
|
|
|
hedgeR1_2.bmp |
|
7/70 |
|
|
|
|
|
|
|
|
|
|
hedgeR2_3.bmp |
|
|
6/60 |
|
|
|
|
|
|
|
|
|
karR1_2.bmp |
|
|
|
15/100 |
|
|
|
|
|
|
|
|
karR2_2.bmp |
|
|
|
|
2/20 |
|
|
|
|
|
|
|
starkyR1_2.bmp |
|
|
|
|
|
12/100 |
|
|
|
|
|
|
starkyR2_2.bmp |
|
|
|
|
|
|
6/60 |
|
|
|
|
|
starR1_2.bmp |
|
|
|
|
|
|
|
22/100 |
|
|
|
|
vasL1_2.bmp |
|
|
|
|
|
|
|
|
20/100 |
|
|
|
vasL2_2.bmp |
|
|
|
|
|
|
|
|
|
10/100 |
|
|
vasR1_2.bmp |
|
|
|
|
|
|
|
|
|
|
15/100 |
|
vovR1_2.bmp |
|
|
|
|
|
|
|
|
|
|
|
49/100 |
Для тестирования программы было использовано 2 метода распознавания. Метод 1 не зависит от ориентации буквы на плоскости, метод 2 имеет привязанность к вертикальному положению буквы. При распознавании символьной информации было не распознано около 18% по методу 2 и 22% по методу 1. Результат сравнения приведен в табл. П.5.1.
Формат результата сравнения: A/B,
где A количество совпавших минюций;
B процент совпадения.
Таблица П.5.1
Результат распознавания символов
Открытый образ |
Результат сравнения (метод 2) |
Открытый образ |
Результат сравнения (метод 1) |
||
Первое обнаруженное значение |
Второе обнаруженное значение |
Первое обнаруженное значение |
Второе обнаруженное значение |
||
_a1.bmp |
А (4/80) |
Н (5/62) |
_a1.bmp |
Н (2 25) |
Ы (1 20) |
_a2.bmp |
А (5/100) |
Н (3/37) |
_a2.bmp |
А (2 40) |
Ц (1 11) |
_б1.bmp |
Б (5/100) |
Г (3/60) |
_б1.bmp |
Б (5 100) |
Ш (4 44) |
_б2.bmp |
Б (5/83) |
Е (5/55) |
_б2.bmp |
Б (5 83) |
Ш (4 44) |
_в1.bmp |
В (3/100) |
_в1.bmp |
В (3 100) |
Е (1 11) |
|
_в2.bmp |
В (3/100) |
_в2.bmp |
В (3 100) |
Б (1 20) |
|
_г1.bmp |
Г (3/75) |
Б (3/60) |
_г1.bmp |
Г (3 75) |
Б (3 60) |
_г2.bmp |
Г (4/66) |
Е (5/55) |
_г2.bmp |
Г (4 66) |
Щ (3 20) |
_д1.bmp |
Д (8/80) |
Щ (7/46) |
_д1.bmp |
Д (8 80) |
Г (3 30) |
_д2.bmp |
Д (8/80) |
Щ (5/33) |
_д2.bmp |
Д (9 90) |
Щ (3 20) |
_е1.bmp |
Е (7/70) |
Ы (8/61) |
_е1.bmp |
Е (7 70) |
Э (5 50) |
_ж1.bmp |
Ж (10/83) |
Х (7/58) |
_ж1.bmp |
Ж (10 83) |
Х (7 58) |
_ж2.bmp |
Ж (10/83) |
Ж (6/50) |
_ж2.bmp |
Ж (10 83) |
Х (7 58) |
_з1.bmp |
З (5/55) |
Д (4/40) |
_з1.bmp |
З (5 55) |
Э (4 44) |
_з2.bmp |
Э (4/57) |
Щ (3/20) |
_з2.bmp |
Е (5 55) |
Ю (1 14) |
_и1.bmp |
И (5/83) |
Х (4/57) |
_и1.bmp |
И (4 66) |
К (4 57) |
_и2.bmp |
И (4/66) |
Ы (3/50) |
_и2.bmp |
И (4 66) |
М (5 62) |
_к1.bmp |
К (7/100) |
Ж (6/54) |
_к1.bmp |
К (7 100) |
Ж (6 54) |
_к2.bmp |
К (7/100) |
М (4/50) |
_к2.bmp |
К (7 100) |
Ж (7 63) |
_л1.bmp |
П (5/83) |
Л (4/57) |
_л1.bmp |
П (4 66) |
Л (4 57) |
_л2.bmp |
П (5/83) |
Л (4/57) |
_л2.bmp |
П (5 83) |
Л (4 57) |
_м1.bmp |
М (6/75) |
Ж (7/63) |
_м1.bmp |
М (7 87) |
Ж (3 27) |
_м2.bmp |
М (8/100) |
И (6/75) |
_м2.bmp |
М (8 100) |
Ъ (2 25) |
_н1.bmp |
Н (8/100) |
Ю (6/66) |
_н1.bmp |
Н (8 100) |
Ч (6 75) |
_н2.bmp |
Н (8/100) |
Ч (6/75) |
_н2.bmp |
Н (8 100) |
Ч (6 75) |
_о1.bmp |
_о1.bmp |
||||
_о2.bmp |
_о2.bmp |
||||
_п1.bmp |
П (6/100) |
Л (5/71) |
_п1.bmp |
П (6 100) |
Ш (6 66) |
_п2.bmp |
П (6/100) |
Г (3/50) |
_п2.bmp |
П (6 100) |
Ш (6 66) |
_р1.bmp |
Д (3/30) |
Г (1/25) |
_р1.bmp |
Р (1 25) |
П (1 16) |
_р2.bmp |
Х (3/42) |
Н (3/37) |
_р2.bmp |
Р (3 75) |
Х (3 42) |
_с1.bmp |
С (2/40) |
Ц (2/22) |
_с1.bmp |
С (3 60) |
Ц (2 22) |
_с2.bmp |
К (1/14) |
Ж (1/9) |
_с2.bmp |
Щ (1 6) |
|
_т1.bmp |
Т (5/100) |
Г (3/60) |
_т1.bmp |
Т (5 100) |
Г (2 40) |
_т2.bmp |
Т (5/100) |
Г (3/60) |
_т2.bmp |
Т (4 80) |
Г (3 60) |
_у1.bmp |
У (5/83) |
Ч (5/71) |
_у1.bmp |
Ю (4 44) |
Ш (4 44) |
_у2.bmp |
У (4/80) |
Щ (4/26) |
_у2.bmp |
У (1 20) |
К (1 14) |
_ф1.bmp |
Ф (3/100) |
П (3/50) |
_ф1.bmp |
П (3 37) |
Ц (3 33) |
_ф2.bmp |
Ф (3/100) |
П (3/50) |
_ф2.bmp |
Ф (3 100) |
Ц (3 33) |
_х1.bmp |
Х (7/87) |
Ж (7/63) |
_х1.bmp |
Х (7 87) |
Ч (4 50) |
_х2.bmp |
Х (7/87) |
К (6/75) |
_х2.bmp |
Х (6 75) |
К (5 62) |
_ц1.bmp |
Ц (8/88) |
Ш (5/55) |
_ц1.bmp |
Ц (8 88) |
П (4 50) |
_ц2.bmp |
Ц (9/100) |
Ш (6/66) |
_ц2.bmp |
Ц (7 77) |
Ш (6 66) |
_ч1.bmp |
Ч (7/100) |
Ц (7/77) |
_ч1.bmp |
Ч (7 100) |
Н (5 62) |
_ч2.bmp |
Ч (7/100) |
Ц (7/77) |
_ч2.bmp |
Ч (7 100) |
П (5 71) |
_ш1.bmp |
Ш (6/66) |
Ц (5/55) |
_ш1.bmp |
Ш (6 66) |
П (5 62) |
_ш2.bmp |
Ш (6/66) |
Ц (5/55) |
_ш2.bmp |
П (5 62) |
Ы (3 37) |
_щ1.bmp |
Ц (9/81) |
Ю (8/72) |
_щ1.bmp |
Ц (6 54) |
Щ (7 46) |
_ъ1.bmp |
Ъ (5/83) |
Д (3/30) |
_ъ1.bmp |
Ъ (4 66) |
Г (3 60) |
_ъ2.bmp |
Ъ (5/83) |
З (2/33) |
_ъ2.bmp |
Ъ (5 83) |
Ы (4 30) |
_ы1.bmp |
Ы (4/66) |
Ч (4/57) |
_ы1.bmp |
Ь (3 50) |
Ы (2 33) |
_ы2.bmp |
Ы (4/66) |
Ь (3/50) |
_ы2.bmp |
Ы (5 83) |
Ь (3 50) |
_ь1.bmp |
Ь (3/75) |
Ы (3/60) |
_ь2.bmp |
Ь (3 60) |
Н (2 25) |
_ь2.bmp |
Ю (2/22) |
Щ (2/13) |
_ь1.bmp |
Ь (3 75) |
Я (3 42) |
_э1.bmp |
Э (3/50) |
Л (1/14) |
_э1.bmp |
Э (3 50) |
Ш (1 11) |
_э2.bmp |
Э (5/100) |
Щ (1/6) |
_э2.bmp |
Е (5 55) |
Э (1 20) |
_ю1.bmp |
Ю (8/88) |
Н (7/77) |
_ю1.bmp |
Ю (7 77) |
Ч (6 66) |
_ю2.bmp |
Н (7/77) |
Ю (6/66) |
_ю2.bmp |
Н (6 66) |
Ю (5 55) |
_я1.bmp |
Я (5/71) |
Ж (4/36) |
_я1.bmp |
Я (5 71) |
Ж (1 9) |
_я2.bmp |
Я (4/57) |
Ю (4/44) |
_я2.bmp |
Я (3 42) |
Ь (2 33) |
Тестирование на чувствительность к ориентации образа на плоскости: |
|||||
_А_10.bmp |
А (4 80) |
Х (3 42) |
_А_10.bmp |
А (1 20) |
Р (1 20) |
_А_90.bmp |
Е (3 33) |
Б (2 33) |
_А_90.bmp |
А (4 80) |
Ж (3 27) |
_А_30.bmp |
Ю (4 66) |
Ч (3 50) |
_А_30.bmp |
А (4 80) |
Ж (3 25) |
_А_15.bmp |
Ю (3 50) |
Ц (3 42) |
_А_15.bmp |
А (3 60) |
Щ (4 26) |
Итого по методу 2: 11 нераспознано и 15 распознано лучше, чем метод 1.
Итого по методу 1: 13 нераспознано и 6 распознано лучше, чем метод 2.
Начало
fingA пуст
fingR.Convert(fingA);
Да
Нет
compRes пуст
а
Нет
Очистить все элементы списка compRes
compRes = CompareWithBase();
compRes.size=0
Да
Нет
Вывод результата в файл отчет
Отпечаток не обработан;
Конец
Начало
fing пуст
clear();
A1 = fng.begin
Да
Нет
A1 != fng.end
Да
Нет
Конец
A2 = fng.begin
A2 != fng.end
Да
Нет
отн. парам. между A1 и A2.
Сохр. в listDots
A2++
listDots.sort();
push_back(listDots)listDots.clear();
A1++
Начало
Да
Нет
Конец
ibse = bse.begin
Progress = 0
MaxProgress = bse.size
ibse != bse.end
Да
Нет
bse->clear
Progress=0
bse пуст
Загрузить данные из базы данных в bse
добавить в список (fing.Compare)
Progress++
ibse++
Загрузка отпечатка
baseFing;
baseFing.Convert
База данных пуста
Начало
Конец
Да
Нет
Установка допусков.
tFing = begin
Расчет сходства отпечатка
tFing++
tFing !=end
Да
Нет
bFing!= fng.end
bFing = fng.begin
Да
Нет
tIter = tFing.begin
Расчет сходства точки
confirmDot++
bFing++
bIter++
Поиск в bFing совпадающей точки с tIter
confirmVal++
tIter!= tFng.end