Диплом

Диплом на тему Система идентификации личности по отпечаткам пальцев Подсистема анализа изображения

Работа добавлена на сайт bukvasha.net: 2014-06-25

Поможем написать учебную работу

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

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 23.11.2024


Федеральное агентство по образованию
Государственное образовательное учреждение
высшего профессионального образования
«ИЖЕВСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»
Факультет «Информатика и вычислительная техника»
Кафедра «Программное обеспечение»
ПОЯСНИТЕЛЬНАЯ ЗАПИСКА
к дипломной работе на тему:
«Система идентификации личности по отпечаткам пальцев.
Подсистема анализа изображения»
Дипломник
студент группы 10-19-1......................................................... Краснов Н.И.
Руководитель
д.т.н, профессор................................................................... Мурынов А.И.
Консультант по экономической части
к.э.н., доцент......................................................................... Радыгина И.И.
Консультант по безопасности
и экологичности проекта...................................................... Якименко Г.Ф.
Нормоконтроль.................................................................... Соболева В.П.
Рецензент
вед. инженер........................................................................ Кропачева Л.Н.
Заведующий кафедрой
«Программное обеспечение»
д.т.н, профессор................................................................... Мурынов А.И.
ИЖЕВСК
2007

РЕФЕРАТ
Пояснительная записка к дипломной работе на тему «Система идентификации личности по отпечаткам пальцев. Подсистема анализа изображения» оформлена на 121 листе, содержит 31 рисунок, 17 таблиц.
Целью данной работы является разработка подсистемы анализа изображения отпечатка пальца в составе системы идентификации личности по отпечаткам пальцев на основе папиллярного узора для дальнейшего распознавания личности.
Работа включает в себя разработку и реализацию алгоритма устранения искажений в изображении отпечатка пальца полученных при сканировании отпечатка. Разработку и реализацию преобразования монохромного изображения отпечатков пальцев к структурированному виду, пригодному для обработки (сравнения).
Для написания соответствующего программного обеспечения были изучены материалы и публикации в области цифровой обработки изображений, векторизации, биологического строения человека и его биометрических параметров.
В результате проделанной работы было разработано программое обеспечение, предназначенное для автоматизации процесса объектного описания отпечатков пальцев на основе характерных особенносетей любого папиллярного узора. Характеристики локальных особенностей, получаемые в результате работы подсистемы, используются при дальнейшей работе в составе системы.
На сегодняшний день существуют готовые системы для идентификации личности, обладающие высокой степенью защиты, быстродействием, а также удобством в применении. Однако ни одна из существующих разработок не дает объектного описания и метода сравнения отпечатков. Все разработки являются уникальными, обладают собственными нововведениями, «ноу-хау» и составляют коммерческую тайну.
Данная разработка обладает открытым кодом и позволяет проводить структурное описание папиллярного узора. Поэтому данная разработка является уникальной и не имеет аналогов в современной индустрии компьютерной обработки изображений. Необходимо отметить, что используемый метод, пригоден не только для описания изображения отпечатков пальцев, но и для объектного описания других битовых изображений, таких как символьная информация, шрифты и подписи.
Разработанное программное обеспечение является исследовательским, оно направлено на изучение и анализ методов обработки изображений и его описания. С его помощью уже были получены важные экспериментальные данные, использованные в данной работе. Конечным программным продуктом может являться оболочка, представляющая в значительной мере автоматизированный интерфейс для идентификации личности.

СОДЕРЖАНИЕ
ВВЕДЕНИЕ
1.       РАЗРАБОТКА СИСТЕМЫ ИДЕНТИФИКАЦИИ ЛИЧНОСТИ ПО ОТПЕЧАТКАМ ПАЛЬЦЕВ
1.1.    Обоснование целесообразности разработки системы идентификации личности по отпечаткам пальцев
1.1.1. Назначение системы
1.1.2. Характеристика функциональной структуры системы
1.1.3. Обоснование цели создания системы
1.1.4. Обоснование состава автоматизируемых задач
1.2.    Аналитический обзор
1.2.1. Фирма BioLink
1.2.1.1.   Система управления BioLink BioTime 2006
1.2.1.2.   Программный сервер  BioLink 
1.2.2. Microsoft IntelliMouse Explorer with Fingerprint Reader
1.2.3. Сотовый телефон GI100
1.2.4. Редактор Adobe Photoshop
1.2.5. Программа распознавания текста Fine Reader
1.2.6. Вывод по аналитическому обзору
1.3.    Основные требования к системе
1.3.1. Основные цели создания системы и критерии эффективности ее функционирования
1.3.2. Функциональное назначение системы
1.3.3. Особенности системы и условия её эксплуатации
1.3.4. Требования к функциональной структуре
1.3.5. Требования к техническому обеспечению
1.3.6. Требования к информационному обеспечению
1.3.7. Требования к программному обеспечению
1.4.    Основные технические решения проекта системы
1.4.1. Решение по комплексу технических средств
1.4.2. Описание системы программного обеспечения
2.       РАЗРАБОТКА ПОДСИСТЕМЫ АНАЛИЗА ИЗОБРАЖЕНИЯ ОТПЕЧАТКОВ ПАЛЬЦЕВ
2.1.    Описание постановки задачи подсистемы анализа изображения отпечатков пальцев
2.1.1. Характеристика задачи
2.1.2. Входная информация
2.1.3. Выходная информация
2.1.4. Математическая постановка задачи
2.1.5. Функциональная схема подсистемы анализа папиллярного узора
2.2.    Описание постановки задачи выявления дефектов сканирования и их устранение
2.2.1. Характеристика задачи
2.2.2. Входная информация
2.2.3. Выходная информация
2.2.4. Математическая постановка
2.2.5. Алгоритм решения задачи
2.2.5.1.   Описание алгоритма «Формирование списка линий»
2.2.5.2.   Описание алгоритма «ChangeLine»
2.3.    Описание постановки задачи выделение локальных особенностей
2.3.1. Характеристика задачи
2.3.2. Входная информация
2.3.3. Выходная информация
2.3.4. Математическая постановка задачи
2.3.5. Алгоритм решения задачи
2.3.5.1.   Описание алгоритма «Формирование списка линий»
2.3.5.2.   Описание алгоритма «ReadLine»
2.4.    Описание постановки задачи сортировки списка абсолютных параметров, исключение ложных и ненадежных минюций
2.4.1. Характеристика задачи
2.4.2. Входная информация
2.4.3. Выходная информация
2.4.4. Математическая постановка
2.4.5. Алгоритм решения задачи
2.5.    Описание подпрограмм
2.5.1. Подпрограмма NextDotCW
2.5.2. Подпрограмма NextDotCCW
2.5.3. Подпрограмма LookPic
2.5.4. Подпрограмма ChangeLine
2.5.5. Подпрограмма ReadPic
2.5.6. Подпрограмма DotsFilter
2.5.7. Подпрограмма AnalysePicture
2.6.    Описание контрольного примера
2.6.1. Назначение программы
2.6.2. Исходные данные
2.6.3. Контрольный пример
2.6.4. Тестирование программного обеспечения системы распознавания личности по отпечаткам пальцев
3.       ОРГАНИЗАЦИОННО-ЭКОНОМИЧЕСКАЯ ЧАСТЬ
3.1.    Обоснование необходимости разработки системы распознавания личности по отпечаткам пальцев
3.2.    Расчет затрат на разработку системы распознавания личности по отпечаткам пальцев
4.       БЕЗОПАСНОСТЬ И ЭКОЛОГИЧНОСТЬ ПРОЕКТА
4.1.    Анализ опасных и вредных факторов, возникающих при работе на компьютере
4.2.    Техника безопасности при работе на ПК
4.3.    Организация рабочего места оператора
4.4.    Требования к параметрам микроклимата помещения
4.5.    Требования к освещению и расчет искусственного освещения
4.6.    Пожарная безопасность
ЗАКЛЮЧЕНИЕ
ЛИТЕРАТУРА
ПРИЛОЖЕНИЕ 1 ТЕКСТ ПРОГРАММЫ
ПРИЛОЖЕНИЕ 2 РУКОВОДСТВО ПРОГРАММИСТА
ПРИЛОЖЕНИЕ 3 РУКОВОДСТВО ОПЕРАТОРА
ПРИЛОЖЕНИЕ 4 РЕЗУЛЬТАТЫ ТЕСТИРОВАНИЯ
ПРИЛОЖЕНИЕ 5 АЛЬТЕРНАТИВНОЕ ИСПОЛЬЗОВАНИЕ ПРОГРАММЫ
ПЕРЕЧЕНЬ УСЛОВНЫХ ОБОЗНАЧЕНИЙ
СТ                 – специфическая точка (минюция)
БД                 – база данных с отпечатками
PIN               – персональный идентификационный номер
ПЗС              – прибор с зарядовой связью
КМОП          – технология изготовления микросхем (кремний метал оксид полупроводник)
ОП                – отпечаток пальца
dpi                – количество точек на дюйм (dot per inch)
ПО                – программное обеспечение
ОС                – операционная система
ЭВМ             – электронно-вычислительная машина
ПК                – персональный компьютер

ВВЕДЕНИЕ

В наше время пароли, персональные идентификационные номера и специальные идентификационные карточки стали жизненной необходимостью. Например, чтобы получить наличные из банкомата, Вам потребуется код PIN, чтобы получить доступ к почтовой программе или к определенной категории компьютерных данных, необходим пароль. В свете последних событий, происходящих в мире, особенно в связи с ростом активности международного терроризма, вопросам безопасности уделяется все более пристальное внимание.
Таким образом, человек должен хранить в своей памяти огромное количество различных комбинаций цифр и букв. Чтобы облегчить участь современного человека, компании, специализирующиеся на производстве компьютеров, начали заниматься разработкой биометрических технологий. Биометрия – эта наука, изучающая возможности использования различных характеристик человеческого тела (будь то отпечатки пальцев или уникальные свойства человеческого зрачка или голоса) для идентификации каждого конкретного человека. Пользуясь биометрическими технологиями, человек никогда не сможет забыть необходимый ему пароль или код, поскольку его большой палец, голос или зрачок глаза всегда находятся с ним /1/.
Отпечаток пальца образует так называемые папиллярные линии на гребешковых выступах кожи, разделенных бороздками. Из этих линий складываются сложные узоры (дуговые, петлевые и завитковые), которые обладают свойствами индивидуальности и неповторимости, что позволяет абсолютно надежно идентифицировать личность. Хотя процент отказа в доступе уполномоченных пользователей составляет около 3%, процент ошибочного доступа – меньше одного к миллиону. Преимущества доступа по отпечатку пальца – простота использования, удобство и надежность. Весь процесс идентификации занимает мало времени и не требует усилий от тех, кто использует данную систему доступа. Исследования также показали, что использование отпечатка пальца для идентификации личности является наиболее удобным из всех биометрических методов. Вероятность ошибки при идентификации пользователя намного меньше в сравнении с другими биометрическими методами /2/. Кроме того, устройство идентификации по отпечатку пальца не требует много места на клавиатуре или в механизме.
Полученный образ отпечатка пальца – это растр, который можно описать особым образом, основываясь на строении папиллярного узора. Выявив структуру отпечатка его можно сравнить с другими отпечатками и выявить те, которые являются аналогичными или же сказать, что отпечатки различны.
Работа посвящена анализу растра, получение объектной модели, и поиска схожих отпечатков.

1.       РАЗРАБОТКА СИСТЕМЫ ИДЕНТИФИКАЦИИ ЛИЧНОСТИ ПО ОТПЕЧАТКАМ ПАЛЬЦЕВ

1.1.          Обоснование целесообразности разработки системы идентификации личности по отпечаткам пальцев

 

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

Система идентификации личности по отпечаткам пальцев реализует определение личности на основе биометрических параметров человеческого тела, а именно строении отпечатков пальцев. Система предназначена для обработки графических изображений отпечатков. Система позволяет сравнить несколько отпечатков друг с другом по выделенным локальным особенностям. Локальными особенностями являются минюции и их относительные параметры (расположение одних минюций относительно всех остальных), что гарантирует независимость сравнения от параллельного переноса и вращения.
Программный продукт найдет применение в различных прикладных системах /3/, включая:
1)       системы гражданской идентификации;
2)       криминалистические системы идентификации;
3)       крупномасштабные коммерческие приложения.
Системы гражданской идентификации включают в себя:
−         водительские паспорта;
−         национальные идентификационные карты граждан;
−         регистрация избирателей;
−         регистрация для социальных программ;
−         иммиграционная регистрация, визы;
−         идентификация сотрудников государственных учреждений.
Криминалистические системы идентификации включают:
−         находится ли данный гражданин в розыске?;
−         прежние судимости;
−         регистрация заключенных/контроль доступа;
−         мобильные и удаленные приложения;
−         обработка следов отпечатков пальцев, полученных с мест преступления.
Крупномасштабные коммерческие приложения включают:
−         доступ к web-ресурсам, электронная коммерция;
−         доступ для пользователей и сотрудников;
−         финансовые сервисы, проверка оплаты;
−         доступ в здания и помещения;
−         программы лояльности.

1.1.2.  Характеристика функциональной структуры системы

Функциональная схема системы приведена на рис. 1.1.
Обработка изображений состоит из следующих этапов:
1)     ввод изображения в систему идентификации личности по отпечаткам пальцев;
2)     в подсистеме анализа изображения происходит обработка растра с целью подавления шумов, а так же устранение типичных искажений изображения, таких как разрывы или слипания дуг папиллярного узора;
3)     в подсистеме анализа изображения происходит выделение локальных особенностей, таких как окончание и раздвоение, для дальнейшего распознавания отпечатка;
4)     в подсистеме анализа изображения происходит сортировка полученных параметров локальных особенностей;
5)     в подсистеме распознавания происходит преобразование абсолютных параметров специальных точек к относительным параметрам для предотвращения влияния параллельного переноса и поворота пальца при сканировании отпечатка;
6)     распознавание отпечатка по базе с существующими отпечатками происходит на основе относительных параметров каждой точки для каждого хранящегося в базе отпечатка.
Функциональная схема системы распознавания личности по отпечаткам пальцев
- подсистема анализа                - подсистема распознавания
Рис. 1.1

 

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

Задачи структурного анализа изображений имеют широкий спектр применения, начиная от векторизации растров и заканчивая распознаванием образов. Структурный анализ изображений подразумевает выделение из них структурных элементов, таких, например, как линия, область, компактный элемент (буква) и так далее.
На данный момент надежная информационная защита является одним из основных критериев, по которым должны отбираться системы, предназначенные для хранения и обработки важной информации. Это обусловлено существующей вероятностью несанкционированного доступа в такие системы, поскольку они имеют широкое информационное взаимодействие со смежными системами управления через сеть INTRANET. Поэтому обеспечение информационной безопасности должно являться важнейшим этапом при их разработке /3/.
Защита на основе биометрических параметров человеческого тела, в частности по отпечатку пальца, обладает рядом неоспоримых полюсов: простота использования, удобство и надежность. Весь процесс идентификации занимает мало времени и не требует усилий от тех, кто использует данную систему доступа. Исследования также показали, что использование отпечатка пальца для идентификации личности является наиболее удобным из всех биометрических методов. Вероятность ошибки при идентификации пользователя намного меньше в сравнении с другими биометрическими методами. Кроме того, устройство идентификации по отпечатку пальца не требует много места на клавиатуре или в механизме.
};
//класс для хранения _относительных_ параметров точки
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.7 ТЕКСТ МОДУЛЯ 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 divv, next;
             divv = next = abs(baseIter->l - tekIter->l);
             while(
                 divv >= next &&
                 next >= DELTA_L &&
                 baseIter != (*baseFing).end())
             { 
                 divv = next;
                    baseIter++;
                 next = abs(baseIter->l - tekIter->l);
             }
             if(divv >= DELTA_L && divv < 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.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 divvCol;
  int changeN = 0;                //Счетчик произведенных изменений на изображении
  list<TMapElDot> map;            //Карта точек принадлежащих линиям
  list<TMapElDot>::iterator imap;     //Итератор для map
  map = LookPic();                  //сканирование картинки и нахождение линий на ней
  do{
      changeN = 0;
      divvCol = (int)map.size();
      imap = map.begin();
      do{                                //Изображение можно модифицировать
          if(imap->pr1)     //Линия нуждается в обработке
             changeN += ChangeLine(imap, map);  //Обработка (преобразование) изображения
          imap++;                            //Переход для обработки следующей линии
      }while(imap != map.end());              //Изображение можно модифицировать
  }while(divvCol<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 выполняет следующие функции:
1)     модификация изображения, исправление искажений;
2)     выделение локальных особенностей – минюций. формирование списка минюций в абсолютных параметрах;
3)     сортировка списка абсолютных параметров, исключение ложных  и ненадежных минюций;
4)     конвертирование абсолютных параметров в отностительные, формирование списка относительных параметров;
5)     установка системы допусков для учета корреляции изображений;
6)     сравнение одного отпечатка с множеством других.
Данная работа реализует такое преобразование изображения, при котором данные о расположение уникальных особенностей сохраняются наиболее полно и с наименьшим содержанием ложной информации.
Создаваемая система облегчит разработку алгоритмов обработки изображений, упростит анализ экспериментальных данных и выявление общих закономерностей.
П.2.2. УСЛОВИЯ ПРИМЕНЕНИЯ ПРОГРАММЫ
Программа FingerAnalyser предъявляет следующие требования к техническим средствам:
-        стандартный x86-совместимый ПК;
-        тактовая частота процессора 900 МГц или более;
-        объем оперативной памяти не менее 64 Мб;
-        разрешение экрана монитора не менее 1024x768.
Программа FingerAnalyser предъявляет следующие требования к программным средствам:
-          операционная система семейства Windows (Windows 9x/ME/NT/2000/XP);
-          среда для разработки приложений Microsoft Visual Studio C++ 2003.
П.2.3. ХАРАКТЕРИСТИКА ПРОГРАММЫ
Программа FingerAnalyser требует для своего функционирования наличия в проекте файлов, содержащих растровые представления папиллярного узора.
В состав программы входят следующие файлы, необходимые для ее функционирования:
1)     FingerAnalyser.exe – исполняемый файл, содержащий основной интерфейс программы;
2)     MFC[1] – библиотеки для поддержки оконного среды;
3)     blank.bmp – пустое изображение;
4)     report.txt – файл отчет в который записываются все результаты сравнения;
5)     sav/*.sav – файлы со структурным представлением отпечатков;
6)     sav/fingbase.bse – база данных отпечатков;
7)     report.txt – файл-отчет с результатами проведенных сравнений.
Программа является интерактивной, т.е. требующей взаимодействия с пользователем, поэтому время выполнения отдельных этапов обработки не превышает 0.5 с. при использовании требуемых технических средств.

П.2.4. ОБРАЩЕНИЕ К ПРОГРАММЕ
Для запуска программы необходимо убедиться в том, что необходимые библиотеки MFC находятся в том же каталоге, что и исполняемый файл или в каталоге Windows/System32.
Для корректной работы программы она должна находиться в каталоге, к которому есть права на чтение и запись.
Для запуска работы подсистемы необходимо в оболочке системы на главном окне нажать на кнопку «Анализ» - для сравнения нужного отпечатка с набором имеющимся в базе данных, или «Запомнить в базу» - для внесения указанных отпечатков в базу данных.
Интерфейс программы представлен на рис. П.2.2.
Интерфейс программы FingerAnalyser

Рис. П.2.2
На форме программы в визуальном виде представляется, после открытия через пункт «Открыть», исходное изображение, после нажатия на кнопку «Анализ», скорректированное изображение и визуальное представление структурного вида отпечатка. После чего можно нажатием на кнопку «Сравнить» отыскать в базе схожие отпечатки.
При каждом анализе отпечатка создается файл с его структурным описанием. Для того чтобы поместить отпечаток в базу данных отпечатков, для последующего сравнения с ним, необходимо нажать на кнопку «Запомнить в базу». Для запоминания в базу можно выбирать группу файлов для применения операции записи в базу данных для всех выбранных файлов.
П.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
x y alpha type
...
x y alpha type
В каждой строке файла структурного представления содержится описание одной минюции. В табл. П.2.2 приведен формат строки файла структурного описания.
Таблица П.2.2
Формат строки файла со структурным описанием
Поле
Формат
Описание
x
Целое
Абцисса минюции на растре
y
Целое
Ордината минюции на растре
alpha
Целое
Ориентация минюции на растре
type
Байт
Тип минюции. Раздвоение или окончание
Кроме того, в результате работы программы формируется файл-отчет report.txt с результатами всех проведенных сравнений отпечатков.
report.txt имеет следующий формат:
------ Namei ------
Counti1 Pcti1 Sourcei1
Counti2 Pcti2 Sourcei2
...
Countik Pctik Sourceik
Всего в базе: NN
В табл. П.2.3 приведен формат данных файла report.txt.
Таблица П.2.3
Формат данных файла-отчета
Поле
Формат
Описание
Name
Строка
Имя отпечатка
Count
Целое
Абсцисса минюции на растре
Pct
Целое
Степень сходства отпечатков в процентах, принимает значения (0, 100]
Source
Строка
Путь к файлу, из которого были взяты параметры
NN
Целое
Количество отпечатков имеющихся в базе данных
На рис. П.2.1 приведен пример файла отчета.

Файл-отчет
------ 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.1
П.2.6. СООБЩЕНИЯ
Сообщения, выдаваемые программисту, приведены в табл. П.2.4.

Таблица П.2.4
Сообщения программисту
Сообщение
Действие программиста
Отпечаток не обработан
Прежде чем запускать сравнение необьходимо провести анализ
База данных пуста
В базе данных нет информации ни об одном отпечатке. Необходимо заполнить базу данных отпечатков
Отпечаток не пригоден для сохранения в базу
На отпечатке либо слишком мало обнаружено минюций, менее 10, либо слишком много, более 80
Ни одного отпечатка не найдено
В результате поиска не совпало ни одного отпечтака
Невозможно создать базу данных с отпечатками
Возможно нет прав на запись или нет свободного места на носителе
Невозможно создать файл
Возможно нет прав на запись или нет свободного места на носителе
Невозможно открыть файл
Возможно нет прав на чтение или не существует запрашиваемого файла на носителе
Найдены схожие отпечатки
В базе данных были обнаружены отпечатки, имеющие схожее представление.
Визуализация результатов проведения анализа приведена на рис. П.2.2 в правой части экрана.

ПРИЛОЖЕНИЕ 3

РУКОВОДСТВО ОПЕРАТОРА

П.3.1. НАЗНАЧЕНИЕ ПРОГРАММЫ
Программа распознавания личности по отпечаткам пальцев имеет идентификатор FingerAnalyser и предназначена для автоматической идентификации личности по папиллярному узору. Программа FingerAnalyser выполняет следующие функции:
1)     модификация изображения, исправление искажений;
2)     выделение локальных особенностей – минюций. Формирование списка минюций в абсолютных параметрах;
3)     сортировка списка абсолютных параметров, исключение ложных  и ненадежных минюций;
4)     конвертирование абсолютных параметров в относительные, формирование списка относительных параметров;
5)     установка системы допусков для учета корреляции изображений;
6)     сравнение одного отпечатка с множеством других.
Данная работа реализует такое преобразование изображения, при котором данные о расположение уникальных особенностей сохраняются наиболее полно и с наименьшим содержанием ложной информации.
Создаваемая система облегчит разработку алгоритмов обработки изображений, упростит анализ экспериментальных данных и выявление общих закономерностей.
П.3.2. УСЛОВИЯ ВЫПОЛНЕНИЯ ПРОГРАММЫ
Программа FingerAnalyser предъявляет следующие требования к техническим средствам:
-        стандартный x86-совместимый ПК;
-        тактовая частота процессора 900 МГц или более;
-        объем оперативной памяти не менее 64 Мб;
-        разрешение экрана монитора не менее 1024x768.
Программа FingerAnalyser предъявляет следующие требования к программным средствам:
−       операционная система семейства Windows (Windows 9x/ME/NT/2000/XP);
−       dll библиотеки MFC.
П.3.3. ВЫПОЛНЕНИЕ ПРОГРАММЫ
Для вызова программы необходимо в оболочке системы на главном окне нажать на кнопку «Анализ».
Интерфейс программы представлен на рис. П.3.1.
Интерфейс программы FingerAnalyser

Рис. П.3.1
На форме программы в визуальном виде представляется, после открытия через пункт «Открыть», исходное изображение, после нажатия на кнопку «Анализ», скорректированное изображение и визуальное представление структурного вида отпечатка. После чего можно нажатием на кнопку «Сравнить» отыскать в базе схожие отпечатки.
При каждом анализе отпечатка создается файл с его структурным описанием. Для того чтобы поместить отпечаток в базу данных отпечатков, для последующего сравнения с ним, необходимо нажать на кнопку «Запомнить в базу». Для запоминания в базу можно выбирать группу файлов для применения операции записи в базу данных для всех выбранных файлов.
П.3.4. СООБЩЕНИЯ ОПЕРАТОРУ
Сообщения, выдаваемые программисту, приведены в табл. П.3.1.
Таблица П.3.1
Сообщения оператору
Сообщение
Действия оператора
Отпечаток не обработан
Прежде чем запускать сравнение необходимо провести анализ
База данных пуста
В базе данных нет информации ни об одном отпечатке. Необходимо заполнить базу данных отпечатков
Отпечаток не пригоден для сохранения в базу
На отпечатке либо слишком мало обнаружено минюций, менее 10, либо слишком много, более 80
Ни одного отпечатка не найдено
В результате поиска не совпало ни одного отпечатка
Невозможно создать базу данных с отпечатками
Возможно, нет прав на запись или нет свободного места на носителе
Невозможно создать файл
Возможно, нет прав на запись или нет свободного места на носителе
Невозможно открыть файл
Возможно, нет прав на чтение или не существует запрашиваемого файла на носителе
Найдены схожие отпечатки
В базе данных были обнаружены отпечатки, имеющие схожее представление.
Визуализация результатов проведения анализа приведена на рис. П.3.1 в правой части экрана.

ПРИЛОЖЕНИЕ 4

РЕЗУЛЬТАТЫ ТЕСТИРОВАНИЯ

В табл. П.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
 
apmAR1_2.bmp
 
apmAR2_2.bmp
 
apmAR3_2.bmp
 
apmBR1_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
 
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

ПРИЛОЖЕНИЕ 5

АЛЬТЕРНАТИВНОЕ ИСПОЛЬЗОВАНИЕ ПРОГРАММЫ

Для тестирования программы было использовано 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
Х (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.


[1] Microsoft Foundation Class
В большинстве случаев работа с важной информацией подразумевает также своевременное принятие решений и непрерывное управление ходом выполнения. В связи с этим существует необходимость непрерывного подтверждения личности (в случае если человек по какой-то причине покинет свое рабочее место, то любой в это время сможет задавать команды телеуправления или ответственные команды). Такое подтверждение личности метод «единого входа в сеть» предоставить не может, а вводить пароль после каждой команды – обременительно /4/.
Хотя на рынке существуют готовые системы, но на ряду со своими преимуществами они обладают рядом недостатков, таких как закрытость исходного кода и алгоритма, как следствие невозможность применения в своих системах, а также высокая цена. Вследствие чего есть смысл в разработке системы, которая бы предоставляла возможность всем разработчикам иметь готовую базу для разработки собственных проектов на основе биометрических технологий. А также предоставить объектное описание различных, не только папиллярного узора, изображений.
Целью данной работы является разработка и реализация такого преобразования изображения, при котором данные о расположение уникальных особенностей сохраняются наиболее полно и с наименьшим содержанием ложной информации.
Создаваемая система носит поисково-исследовательский характер и направлена на облегчение разработки алгоритмов обработки изображений, упрощение анализа экспериментальных данных и выявление общих закономерностей.

 

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

Реализация системы идентификации личности по отпечаткам позволит интегрировать в едином интерфейсе все этапы обработки изображения отпечатка пальца и сравнения его с другими отпечатками:
1)       анализ параметров изображения, выявление дефектов сканирования и их устранение;
2)       выделение локальных особенностей – минюций. формирование списка минюций в абсолютных параметрах;
3)       сортировка списка абсолютных параметров, исключение ложных  и ненадежных минюций;
4)       конвертирование абсолютных параметров в относительные, формирование списка относительных параметров;
5)       установка системы допусков для учета корреляции изображений;
6)       сравнение одного отпечатка с множеством других;
7)       способ хранения описания отпечатков позволяет применять результат работы программы для различных сфер деятельности.

1.2.         Аналитический обзор

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

 

1.2.1.  Фирма BioLink

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

1.2.1.1.    Система управления BioLink BioTime 2006

Система управления рабочим временем, являющаяся новейшей разработкой компании BioLink. Система BioTime 2006 упрощает обычные задачи учета и управления рабочим временем и обеспечивает простоту, легкость и удобство регистрации прихода и ухода сотрудников компании. Кроме того, система BioTime 2006 предоставляет различные виды отчетов по опозданиям, недоработкам и переработкам сотрудников, времени их прихода и ухода, а также автоматизирует создание табеля учета рабочего времени /5/.

1.2.1.2.    Программный сервер  BioLink

Программный сервер BioLink Authenteon Software Appliance (ASA) - это программное обеспечение для сравнения шаблонов отпечатков пальцев BioLink. ASA объединяет в себе парольную защиту и клиент-серверную аутентификацию при входе в Windows, Novell и NFS при решении одной из самых актуальный на сегодняшний день проблем защиты - положительной идентификации пользователей корпоративной сети. Сервер поддерживает до 300 пользователей /5/.

1.2.2.  Microsoft IntelliMouse Explorer with Fingerprint Reader

Анонсированная Microsoft осенью 2004 г. новая линейка продуктов с использованием биометрических технологий - сканер отпечатков пальцев, клавиатура со встроенным сканером и беспроводная оптическая мышь со сканером обладает возможностями /6/:
1)       снятие отпечатка пальца при кратковременном прикладывании пальца к сканеру;
2)       ведение менеджера паролей для веб интерфейсов;
3)       возможность идентификации личности для входа в систему одним приложением пальца.
Продукт подходит для применения за личным ПК. Программное обеспечение имеет очень ограниченную функциональность. Нет возможности получить параметры отсканированного отпечатка пальца, установить дополнительные действия от того какой палец был приложен.

1.2.3.  Сотовый телефон GI100

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

1.2.4.  Редактор Adobe Photoshop

Профессиональный редактор растровых изображений. Основные возможности:
1)       контроль цвета и тона компонент изображения: возможность подбора палитры, замены цветов, поддержка 32-битного цвета (прозрачности), возможность построения гистограмм распределения цвета;
2)       интеллектуальное редактирование изображений: инструменты контекстной коррекции растра, позволяющие достичь фотореалистичности;
3)       широкий набор фильтров, позволяющих модифицировать и улучшить изображение;
4)       возможность создания многих независимых слоев в одном изображении.
Продукт предназначен для профессионального редактирования фотографических изображений, имеет мощный набор инструментов для улучшения их качества. В меньшей степени подходит для обработки искусственных изображений. Интерфейс обладает некоторой когнитивностью, которая, однако, ограничена сферой применения растровой модели /8/.

1.2.5.  Программа распознавания текста Fine Reader

Профессиональная программа распознавания печатного текста. Основные возможности:
1)       загрузка изображения страницы из файла, получение изображения страницы со сканера;
2)       интеллектуальное определение расположения строк и символов в тексте, распознавание символов при их неточном сканировании или зашумлении;
3)       наличие возможности исправить неправильно распознанные символы;
4)       возможность сохранения распознанного текста в виде документа word или PDF.
Продукт предназначен для распознавания печатного текста различной сложности после сканирования, имеет мощный набор инструментов для улучшения качества распознавания, а также исправления неточно распознанных символов. Не имеет возможности дополнять набор распознаваемых символов, вследствие чего применение ограничивается только распознаванием печатного текста /9/.

1.2.6.  Вывод по аналитическому обзору

Список программных продуктов, безусловно, может быть расширен, но все же самые характерные и популярные разработки в него включены.
Среди программных продуктов, посвященных идентификации по папиллярному узору, можно выделить основные возможности:
1)       программы реализуют возможность доступа по отпечаткам;
2)       возможна обработка стандартными функциями (яркость, контрастность, изменение размера);
3)       распознавание символов;
4)       ни одна программа не позволяет скорректировать изображение, основываясь на типичных характеристиках отпечатка, дать объектное описание отпечатка, а также дать возможность применить алгоритмы обработки в отдельности для собственных задач.
В связи с указанными особенностями существующих программных средств и в силу того, что применение биометрических способов позволяет увеличить защищенность и удобство пользования системами (см. п.п. 1.1.1) для большинства разработчиков будет удобным использование готового модуля работы с отпечатками пальцев. Поэтому актуальной является разработка системы, обладающая открытым кодом и позволяющая проводить структурное описание папиллярного узора. Возможность получать его объектное описание и сравнение. Применение алгоритма не только для описания изображения отпечатков пальцев, но и для объектного описания других битовых изображений, таких как символьная информация, шрифты и подписи.
Эту задачу решает система распознавания личности по отпечаткам пальцев.

1.3.         Основные требования к системе

1.3.1.  Основные цели создания системы и критерии эффективности ее функционирования

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

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

Реализация системы идентификации личности по отпечаткам позволит интегрировать в едином интерфейсе все этапы обработки изображения отпечатка пальца и сравнения его с другими отпечатками:
1)       модификация изображения, исправление искажений;
2)       выделение локальных особенностей – минюций. Формирование списка минюций в абсолютных параметрах;
3)       сортировка списка абсолютных параметров, исключение ложных  и ненадежных минюций;
4)       конвертирование абсолютных параметров в относительные, формирование списка относительных параметров;
5)       установка системы допусков для учета корреляции изображений;
6)       сравнение одного отпечатка с множеством других.

1.3.3.  Особенности системы и условия её эксплуатации

Система идентификации личности по отпечаткам пальцев предназначена для работы с цифровыми изображениями, полученными посредством сканирования.
Получение электронного представления отпечатков пальцев с хорошо различимым папиллярным узором – достаточно сложная задача. Поскольку отпечаток пальца слишком мал, для получения его качественного изображения приходится использовать достаточно изощренные методы.
На сегодняшний момент можно выделить следующие сканеры отпечатков пальцев по используемым ими физическим принципам:
−         оптические;
−         кремниевые;
−         ультразвуковые.
Старейшей технологией сканирования отпечатка является – оптическая. Сканирование отпечатка пальца мини-камерами на ПЗС или КМОП-чипе позволило существенно уменьшить стоимость систем идентификации. Но этот способ снятия отпечатка сталкивается с некоторыми трудноразрешимыми проблемами: получаемый образ зависит от окружающего освещения, на границах образа возможны искажения, датчик может быть относительно легко "обманут" (некоторые дешевые датчики можно "дурачить" печатной копией, сделанной на обычном копире). Остаются проблемы и с размерами сканера. Датчик не может быть меньше, чем фокусное расстояние камеры. Среди главных преимуществ оптических систем можно еще раз упомянуть относительно низкую цену и практическую неуязвимость к воздействию электростатического разряда.
Абсолютно новой является технология использования электромагнитного поля. Датчик излучает слабый электромагнитный сигнал, который следует по гребням и впадинам отпечатка пальца и учитывает изменения этого сигнала для составления образа отпечатка. Такой принцип сканирования позволяет просматривать рисунок кожи под слоем омертвевших клеток, что приводит к хорошим результатам при распознавании бледных или стершихся отпечатков. Остается проблема отсутствия приемлемого соотношения между размером датчика и его разрешающей способностью.
Еще одна перспективная технология, которую следует упомянуть – ультразвуковая. Трехмерный ультразвуковой сканер измеряет пересеченную поверхность пальца своего рода радаром. Этот метод сканирования может быть особенно удобен, например, в здравоохранении. Он не требует касания каких-либо считывающих устройств датчика стерильными руками, а отпечаток легко считывается даже через резиновые или пластиковые перчатки хирурга. Главное неудобство ультразвуковой технологии - ее высокая стоимость и длительное время сканирования /10/.
Существуют и другие методы, либо использовавшиеся в прошлом, либо только разрабатываемые /11/.

1.3.4.  Требования к функциональной структуре

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

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

Задача обработки изображений в системе связана с автоматическим анализом больших массивов графической информации. Преобразования, проводимые в системе, должны проводиться в процессе интерактивного взаимодействия с пользователем, поэтому паузы на обработку не должны превышать нескольких секунд. Исходя из этого, сформулированы требования к техническим характеристикам персонального компьютера, на котором будет функционировать система. Требования сведены в табл. 1.1.
Таблица 1.1
Технические характеристики персонального компьютера
Наименование
Значение
Частота процессора, МГц
от 900
Объем оперативной памяти, Мб
от 64
Разрешение экрана монитора
не менее  1024x768

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

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

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

Систему целесообразно разрабатывать для функционирования под операционной системой семейства Windows, так как ОС данного класса наиболее широко распространены в современном мире. Платформой для разработки выбрана среда для разработки приложений Microsoft Visual Studio C++ 2003. Эта среда поддерживает алгоритмический язык C++ и обладает при этом возможностями быстрой разработки и проектирования визуальных интерфейсов, что особенно важно при работе с графической информацией.

1.4.         Основные технические решения проекта системы

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

Как уже отмечалось в п.п. 1.3.5, для достижения удобного пользователю режима функционирования системы необходимо следующая минимальная конфигурация персонального компьютера: частота процессора 900 МГц, объем оперативной памяти 64 Мб, монитор, поддерживающий разрешение не менее 1024x768 точек. Также желательно наличие следующих периферийных технических средств: сканер отпечатков пальцев, цветной струйный принтер для вывода на печать результатов.

1.4.2.  Описание системы программного обеспечения

Для реализации и функционирования проекта необходимо общесистемное программное обеспечение ОС 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 оптимальным выбором для построения исследовательской системы, какой является система распознавания личности.

2.       РАЗРАБОТКА ПОДСИСТЕМЫ АНАЛИЗА ИЗОБРАЖЕНИЯ ОТПЕЧАТКОВ ПАЛЬЦЕВ

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

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

Графические образы, представляемые окружающим миром человеку, обладают большим разнообразием. Неотъемлемым атрибутом изображения является его пространственная структура. Способность реконструировать эту структуру при визуальном восприятии и обеспечивает предметность восприятия.
Пространственная определенность, которая состоит в том, что любая точка изображения принадлежит единственному и вполне определенному структурному элементу, который может представлять объект либо принадлежит одному или нескольким объектам соответствующей предметной области. Таким образом, любое изображение строится в соответствии с некоторым априорным планом, определяющим место положения и смысловые характеристики его структурных элементов.
Модели представления изображений в ЭВМ можно разделить на два типа: растровые и векторные.
Наиболее распространенная форма представления «сырых» изображений на ЭВМ – это растр. Изображение в этом случае представляет собой матрицу из NxM точек (пикселей). Визуализация растровых изображений достаточно проста и заключается в построчном выводе его пикселей на экран. Однако модель этого типа не несет в себе структурной и тем более семантической информации, что ограничивает сферу ее применения. При вводе изображений из реального мира в ЭВМ они часто предстают в растровой форме.
Векторные модели представления изображений основаны на том, что любую линию можно представить в аналитическом виде, например в виде совокупности векторов – направленных отрезков. Визуализация изображений в векторной модели сложнее, чем в растровой. Но модель приобретает когнитивность за счет включения в нее структурной информации.
Образ отпечатка пальца, как правило, сохраняется в двоичном коде, где каждый пиксель рисунка описывается 8 битами, то есть 256 оттенками серого цвета. В передовых системах сканирования цифровой образ отпечатка обрабатывается с помощью специального алгоритма улучшения изображения. Этот алгоритм обеспечивает обратную связь с датчиком для регулирования параметров сканирования. Когда датчик фиксирует окончательный образ, алгоритм настраивает контрастность и четкость изображения отпечатка для получения наилучшего качества /12/.
Методы опознания отпечатка пальца основаны на сравнении с образцами или на использовании характерных деталей.
При опознании по деталям из образа извлекаются только специфические места, где найдена особенность (деталь). Обычно это либо окончание гребня, либо его раздвоение (рис. 2.1). Содержание шаблона в этом случае составляют относительные координаты и сведения об ориентации детали. Распознающий алгоритм отыскивает и сравнивает между собой соответствующие детали. Ни поворот отпечатка пальца, ни его параллельный перенос (сдвиг) не влияют на функционирование системы, поскольку алгоритм работает с относительными величинами.
Типы минюций

Рис. 2.1
Для сравнения на битовом образе производится поиск локальных особенностей папиллярного узора – минюций. Для поиска используется алгоритм обхода по контуру гребней. В результате подсистема анализа реализует переход от растрового представления к структурному представлению.

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

Входной информацией является битовый растр отпечатка, полученный с помощью сканирования разрешением 600dpi. Расширение битового файла
по-умолчанию *.bmp. Формат bmp (от слов BitMaP - битовая массив) представляет из себя несжатое (в основном), что позволяет не вносить погрешностей, изображение, которое довольно легко читается и выводится в ОС Windows, в которой есть специальные функции API, которые в этом помогают /13/.

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

Выходной информацией является список минюций в абсолютных параметрах, расположенный в памяти, содержащий параметры каждой найденной минюции. Каждый элемент массива содержит все необходимые параметры минюции: координаты целого типа – 2х4 байта, угол направления 8 байт, тип точки 1 байт
Структура массива:


Таблица 2.1
Формат строки файла со структурным описанием
Поле
Формат
Описание
X
Целое
Абсцисса минюции на растре
Y
Целое
Ордината минюции на растре
a
Целое
Ориентация минюции на растре
T
Байт
Тип минюции. Раздвоение или окончание
k
Целое
Количество минюций

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

Работа подсистемы реализуется следующими этапами:
-        корректировка входного образа, устранение дефектов и искажений;
-        поиск минюций и формирование списка их абсолютных параметров;
-        фильтрация полученного списка параметров;
Для решения поставленных задач требуются стандартные операции для работы с массивом, которые представлены в табл. 2.2.
Таблица 2.2
Операции над массивом
Обозначение
Расшифровка
|Array|
количество элементов массива
Array[i]
обращение к i-му элементу массива

операция добавления элемента E в конец массива M
Delete(Array,Pos)
операция удаления элемента на позиции Pos из массива Array
Delete(Array, Element)
операция удаления элемента Element из массива Array
Pos(Array,Element)
операция получения номера элемента Element в массиве Array
Array1ÈArray2
операция добавления в конец массива Array1 не дублируемых элементов массива Array2
Array1ÇArray2
операция пересечения массивов

логическая операция принадлежности элемента E массиву M
Sort(Arrayf)
операция сортировки массива Array по значению поля f

2.1.5.  Функциональная схема подсистемы анализа папиллярного

узора

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

2.2.         Описание постановки задачи выявления дефектов сканирования и их устранение

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

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

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

Входной информацией является битовый растр отпечатка, полученный с помощью сканирования разрешением 600dpi. Расширение битового файла
по-умолчанию *.bmp. Формат bmp (от слов BitMaP - битовый массив) представляет из себя несжатое (в основном), что позволяет не вносить погрешностей, изображение. Формат bmp довольно легко читается и выводится в ОС Windows, в которой есть специальные функции API.
Входной растр представлен форматом BMP, который имеет структуру представленную на рис. 2.1.2 /13/.
Формат BMP

Рис. 2.1.2
В начале стоит заголовок файла – BITMAPFILEHEADER.

typedef struct tagBITMAPFILEHEADER
{
  WORD    bfType;
  DWORD   bfSize;
  WORD    bfReserved1;
  WORD    bfReserved2;
  DWORD   bfOffBits;
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;
Дальше идет структура – BITMAPINFOHEADER
typedef struct tagBITMAPINFOHEADER
{
  DWORD  biSize;
  LONG   biWidth;
  LONG   biHeight;
  WORD   biPlanes;
  WORD   biBitCount;
  DWORD  biComdivssion;
  DWORD  biSizeImage;
  LONG   biXPelsPerMeter;
  LONG   biYPelsPerMeter;
  DWORD  biClrUsed;
  DWORD  biClrImportant;
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;

 

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

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

2.2.4.  Математическая постановка

Поиск минюций происходит по нахождению локальных особенностей. Локальные особенности это сильные искривления контура линий. Искривления, которые являются минюциями – это окончания и раздвоения, но помимо них существуют слипания соседних линий и обрывы одной линии, что не является минюциями.
На рис. 2.2 показан разрыв линии, при этом выполняется следующее условие:
,(1)
где A = {x,y};
B = {x,y};
D – эмпирическая величина.
На рис. 2.3 показано слипание линий, при этом выполняется условие 1 для рис. 2.3.

Разрыв линии

A – сильное искривление контура линии папиллярного узора;
B – вероятная точка продолжения линии папиллярного узора;
C – искривление контура в вероятной точке продолжения;
D1, D2 – прилегающие области;
L1, L2 – вероятные соседние линии папиллярного узора.
Рис. 2.2
Слипание линий

A – сильное искривление контура линии папиллярного узора;
B – вероятная точка продолжения линии папиллярного узора;
C – искривление контура в вероятной точке продолжения;
D1, D2 – прилегающие области;
L1, L2 – вероятные соседние впадины папиллярного узора.
Рис. 2.3

 

2.2.5.  Алгоритм решения задачи

Выделим основные действия по обработке каждой линии на изображении отпечатка:
−       выделить произвольную черную точку на растре, принадлежащую обрабатываемой линии, и произвести обход по контуру линии папиллярного узора, которой принадлежит эта точка;
−       если обнаружена область разрыва, то выполняется восстановление целостности линии;
−       если обнаружена область слипания, то выполняется разъединение линий.
Результатом работы является растр более пригодный для поиска на нем минюций, чем изначальный.
R – Битовый растр
Map – список. Map = {x, y}i
R.GetPixelColor(x,y) – получить значение цвета пикселя с координатами {x,y} на растре R
R.FloodFill(x, y, color) – залить область с цветом R.GetPixelColor(x,y) в цвет color
R.width() – ширина растра в пикселях
R.height() – высота растра в пикселях
R.ChangeLine(Map[i]) – обход по контуру линии из точки Map[i]
1. Начало
2. Формировать из растра R список линий Map
3. "i, : iÎ[1, |Map|] R.ChangeLine(Map[i])
4. Если растр R был изменён, то перейти к п. 2
5. Конец

2.2.5.1.    Описание алгоритма «Формирование списка линий»

Алгоритм для нахождения на растре точек принадлежащих разным папиллярным линиям.
1. Начало
2. x::=0, y::=0
3. Если R.GetPixelColor(x,y) != 0x000000, то перейти к п. 5
4. (x,y) Ì Map; R.FloodFill(x, y, 0xFFFFFF)
5. y++;
6. если y < R.width(), то перейти к п. 3
7. x++; y::=0;
8. если x < R.height(), то перейти к п. 3
9. Конец

2.2.5.2.    Описание алгоритма «ChangeLine»

Алгоритм для поиска слипаний, обрывов и устранение их на растре.
dot0, dot1 –точки принадлежащие контуру линии
vec0, vec1 – локальные направления
GetVec(dot0, dot1) - направление из точки dot0 в dot1
alphaTest – предопределенная константа определяющая сильное искривление контура папиллярной линии
NextDotCW(dot0, step) – получение координат точки следующей через step точек
Условия обрыва и слипания описаны в п.п. 2.2.4
1.          Начало
2.          dot0 ::= начальное значение
3.          dot1 ::= NextDotCW(dot0, step);
4.          vec0 ::= GetVec(dot0, dot1);
5.          dot0 ::= dot1;
6.          dot1 ::= NextDotCW(dot0, step);
7.          vec1 ::= GetVec(dot0, dot1);
8.          Если |vec1 – vec0| < alphaTest, то перейти к п. 11
9.          Если найденная точка является слипанием, то разъединить линии
10.      Если найденная точка является обрывом, то восстановить целостность линии
11.      Если обход по контуру привел к начальной точке, то перейти к п.13
12.      vec0 ::= vec1; перейти к п.5
13.      Конец

2.3.         Описание постановки задачи выделение локальных

особенностей

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

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

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

Входной информацией является битовый растр после предобработки. Растр имеет глубину 1бит на пиксель и разрешение 600dpi. Формат bmp (от слов BitMaP - битовая карта, или, говоря по-русски, битовый массив) представляет из себя несжатое (в основном), что позволяет не вносить погрешностей, изображение. Формат bmp довольно легко читается и выводится в ОС Windows, в которой есть специальные функции API /13/.

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

Выходной информацией является список параметров, где были обнаружены специфические точки (особенность, деталь), в абсолютных параметрах. Список, расположенный в памяти, на данном этапе содержит помимо нужных точек – ложные, которые образуются при некачественном входном образе. Каждый элемент массива содержит все необходимые параметры: координаты целого типа – 2х4 байта, угол направления 8 байт, тип точки 1 байт.
Структура массива:
Xi, Yi – Координаты минюции на растре

ai – Ориентация минюции
T – Тип (окончание либо раздвоение)
k – Количество минюций

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

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

                                                                                                    (2)
                                                                                       ,                        
где A = {x,y};
B = {x,y};
D – эмпирическая величина.
На рис. 2.5 показано «раздвоение», при этом выполняется условие 2 для рис. 2.5.
Окончание

A – сильное искривление контура линии папиллярного узора;
B – вероятная точка продолжения линии папиллярного узора;
C – искривление контура в вероятной точке продолжения;
D1, D2 – прилегающие области;
L1, L2 – вероятные соседние линии папиллярного узора.
Рис. 2.4
Раздвоение

A – сильное искривление контура линии папиллярного узора;
B – вероятная точка продолжения линии папиллярного узора;
C – искривление контура в вероятной точке продолжения;
D1, D2 – прилегающие области;
L1, L2 – вероятные соседние впадины папиллярного узора.
Рис. 2.5
Локальные особенности: разрыв и слипание описаны в п.п. 2.2.4.

2.3.5.  Алгоритм решения задачи

Выделим основные действия по обработке каждой линии на изображении отпечатка:
−       выделить произвольную черную точку на растре, принадлежащую обрабатываемой линии, и произвести обход по контуру линии папиллярного узора, которой принадлежит эта точка;
−       если обнаружена минюция, то запишем ее координаты в список.
Результатом является список параметров, с обнаруженными специфическими точками (особенность, деталь), в абсолютных параметрах. Список на данном этапе содержит помимо нужных точек – ложные, которые образуются при некачественном входном образе.
R – битовый растр
Map – список. Map = {x, y}i
R.GetPixelColor(x,y) – получить значение цвета пикселя с координатами {x,y} на растре R
R.FloodFill(x, y, color) – залить область с цветом R.GetPixelColor(x,y) в цвет color
R.width() – ширина растра в пикселах
R.height() – высота растра в пикселах
R.ReadLine(Map[i]) – обход по контуру линии из точки Map[i], получает список координат минюций
6. Начало
7. Формировать из растра R список линий Map
8. "i, : iÎ[1, |Map|] List ::= R.ReadLine(Map[i])
9. Вывод List
10.       Конец

2.3.5.1.    Описание алгоритма «Формирование списка линий»

Алгоритм для нахождения на растре точек принадлежащих разным папиллярным линиям приведен в п.п. 2.2.5.1.

2.3.5.2.    Описание алгоритма «ReadLine»

Алгоритм для поиска окончаний и раздвоений, формирования списка параметров локальных особенностей.
dot0, dot1 – точки принадлежащие контуру линии
vec0, vec1 – локольные направления
GetVec(dot0, dot1) - направление из точки dot0 в dot1
alphaTest – предопределенная константа
NextDotCW(dot0, step) – получение координат точки следующей через step точек
Return – возвращаемый список
Условия обрыва и слипания описаны в п.п. 2.2.4
1.          Начало
2.          dot0 ::= начальное значение
3.          dot1 ::= NextDotCW(dot0, step);
4.          vec0 ::= GetVec(dot0, dot1);
5.          dot0 ::= dot1;
6.          dot1 ::= NextDotCW(dot0, step);
7.          vec1 ::= GetVec(dot0, dot1);
8.          Если |vec1 – vec0| < alphaTest, то перейти к п. 11
9.          type ::= vec1 < vec0;
alpha ::= предположительное направление продолжения линии;
10.      {dot0, alpha, type} Ì Return
11.      Если обход по контуру привел к начальной точке, то перейти к п.13
12.      vec0 ::= vec1; перейти к п.5
13.      Конец

2.4.          Описание постановки задачи сортировки списка абсолютных параметров, исключение ложных и ненадежных минюций

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

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

 

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

Входной информацией является выходная информация предыдущего этапа описанная в п.п. 2.3.3.

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

Выходной информацией является список минюций в абсолютных параметрах. Данное структурное представление на основе минюций достаточно для распознавания личности по отпечаткам пальцев. Такое представление гораздо меньше растрового по размеру, благодаря чему организуется удобное хранение и быстрая обработка. Каждый элемент массива содержит все необходимые параметры: координаты целого типа - 2х4 байта, угол направления 8 байт, тип точки 1 байт. При среднем количестве точек 50 получаем объем занимаемый одним обработанным отпечатком примерно 850 байт.

2.4.4.  Математическая постановка

Для исключения ненадежных точек определим еще одно положение локальных особенностей на входном растре.
На рис. 2.6 показан вид пореза или складки кожи, при этом выполняется следующее условие:
,                                                 (3)
Порез

D1, D2 – прилегающие области;
L1, L2 – вероятные соседние линии папиллярного узора.
Рис. 2.6
Точки, образованные порезами и инородными телами не являются минюциями и не влияют на сравнение.
Полученный список сортируется по условию:

(4)
где:   i, j    – найденные точки;
x, y – координаты минюции на растре;
a    – угол направления;
T   – тип минюции (раздвоение или окончание);
D1, D2, aMin, aMax – константы (устанавливаются экспериментально).

2.4.5.  Алгоритм решения задачи

1.       Начало
2.     "i,j : i¹j Ù   выполнить Delete(Array,j), Delete(Array,i)
3.     "i,j : i¹j Ù  
4.    
выполнить Delete(Array,j), Delete(Array,i)
Конец

2.5.         Описание подпрограмм

2.5.1.  Подпрограмма NextDotCW

Подпрограмма NextDotCW производит поиска следующей точки на контуре линии «по часовой стрелке», благодаря ей организуется обход линии по контуру. Предназначена для реализации алгоритма исправления искажений и используется при поиске минюций на входном образе. Схема подпрограммы изображена на рис. 2.7.
Синтаксис:
CPoint TFingPicture::NextDotCW(const CPoint dot, int &vec)
Входные данные для данной подпрограммы представлены:
CPoint dot – структура данных – точка {x,y} от которой нужно найти соседствующую точку;
int vec – направление предыдущего перехода при поиске, vecÎ[0..7]. Служит для ускорения поиска;
COLORREF clMas[9] – массив цветов окрестных точек;
Выходные данные для данной подпрограммы представлены:
CPoint incXY[8] – координаты окрестных точек;
CPoint newDot – найденная точка, которая является смежной с точкой dot. Переход от точки dot к найденной смежной точке образует обход «по часовой стрелке».

2.5.2.  Подпрограмма NextDotCCW

Подпрограмма NextDotCCW производит поиска следующей точки на контуре линии «против часовой стрелки», благодаря ей организуется обход линии по контуру. Предназначена для реализации алгоритма исправления искажений и используется при поиске минюций на входном образе. Схема подпрограммы изображена на рис. 2.8.
Синтаксис:
CPoint TFingPicture::NextDotСCW(const CPoint dot, int &vec)
Входные данные для данной подпрограммы представлены:
CPoint dot – структура данных – точка {x,y} от которой нужно найти соседствующую точку;
int vec – направление предыдущего перехода при поиске, vecÎ[0..7]. Служит для ускорения поиска;
COLORREF clMas[9] – массив цветов окрестных точек;
Выходные данные для данной подпрограммы представлены:
CPoint incXY[8] – координаты окрестных точек;
CPoint newDot – найденная точка, которая является смежной с точкой dot. Переход от точки dot к найденной смежной точке образует обход «против часовой стрелки»
Схема подпрограммы «NextDotCW»
 SHAPE  \* MERGEFORMAT
Начало
Конец
i = vec,
step = 0;
newdot = dot;
COLORREF clMas[9];
clMas[i+1] < clMas[i]
vec=(i+1)%8;
newdot.x=dot.x +incXY[vec].x
newdot.y=dot.y +incXY[vec].y
Даа
Нет
i = (i+1)%8;
step++;
step <= 8
Да
Нет

Рис. 2.7
Схема подпрограммы «NextDotСCW»
 SHAPE  \* MERGEFORMAT
Начало
Конец
i = vec,
step = 0;
newdot = dot;
COLORREF clMas[9];
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;
Да
Нет
i = (i+1)%8;
step++;
step <= 8
Да
Нет

Рис. 2.8

2.5.3.  Подпрограмма LookPic

Подпрограмма LookPic предназначена для обработки загруженного изображения и получение из него списка папиллярных линий. Каждая линия определяется одной точкой {x,y}. Схема подпрограммы изображена на рис. 2.9.
Синтаксис:
list<TMapElDot> TAnalysePicture::LookPic()
Входные данные для данной подпрограммы представлены:
TFingPicture *pic – указатель на битовый образ в памяти, который был загружен для обработки
Выходные данные для данной подпрограммы представлены:
list<TMapElDot> Map – список папиллярных линий на растре.
Используемые переменные:
Map – список обрабатываемых линий на папиллярном узоре, каждой линии соответствует точка {x,y}.
Используемые подпрограммы:
Pic.GetPixel(x,y) – возвращает цвет пикселя с координатами {x,y} на растре pic;
ClearLine(pic,x,y) – удаление области с цветом GetPixel(x,y) на растре pic.
Схема подпрограммы «LookPic»

Рис. 2.9
Подпрограмма ChangeLine
Подпрограмма ChangeLine предназначена для модификация линии на растре, производит исправление слипаний и обрывов. Схема подпрограммы изображена на рис. 2.10.
Синтаксис:
int TAnalysePicture::ChangeLine(list<TMapElDot>::iterator _dot, list<TMapElDot> &_map)
Входные данные для данной подпрограммы представлены:
TFingPicture *pic – указатель на битовый образ в памяти, который был загружен для обработки;
list<TMapElDot>::iterator _dot – указатель на текущую обрабатываемую линию;
list<TMapElDot> &_map – список обрабатываемых линий на растре.
Выходные данные для данной подпрограммы представлены:
int changeN – произведенное количество исправлений на растре;
TFingPicture *pic – в результате обработки входной образ подвергается изменениям.
Используемые переменные:
Dot0, dot1 – точки принадлежащие контуру обрабатываемой линии. Начальное значение dot0 = _dot.
vec0, vec1 – локальные направления;
step – шаг получения последующей точки;
alphaTest – предопределенная константа, определяющая сильное искривление контура папиллярной линии.
Используемые подпрограммы:
GetVec(dot0, dot1)– направление из точки dot0 в dot1;
NextDotCW(dot0, step) – получение координат точки следующей через step точек.
Слипание и обрыв описаны в п.п. 2.2.4.
Схема подпрограммы «ChangeLine»

Рис. 2.10

 

2.5.4.  Подпрограмма ReadPic

Подпрограмма ReadPic пердназначена для поиска локальных особенностей на растре. Схема подпрограммы изображена на рис. 2.11.
Синтаксис:
TAbsFing TAnalysePicture::ReadPic(list<TMapElDot>::iterator _dot)
Входные данные для данной подпрограммы представлены:
TFingPicture *pic – указатель на битовый образ в памяти, который был загружен для обработки;
list<TMapElDot>::iterator _dot – указатель на текущую обрабатываемую линию.
Выходные данные для данной подпрограммы представлены:
TAbsFing absfing – список параметров локальных особенностей, формат описан в п.п. 2.1.3.
Используемые переменные:
Dot0, dot1 – точки принадлежащие контуру обрабатываемой линии. Начальное значение dot0 = _dot;
vec0, vec1 – локальные направления;
step – шаг получения последующей точки;
alphaTest – предопределенная константа, определяющая сильное искривление контура папиллярной линии.
Используемые подпрограммы:
GetVec(dot0, dot1)– направление из точки dot0 в dot1;
NextDotCW(dot0, step) – получение координат точки следующей через step точек.
Раздвоение и окончание описаны в п.п. 2.3.4.

2.5.5.  Подпрограмма DotsFilter

Подпрограмма DotsFilter предназначена для сортировки списка найденных локальных особенностей и выделение списка минюций. Схема подпрограммы изображена на рис. 2.12.
Синтаксис:
int TAnalysePicture::DotsFilter(TAbsFing &_dots)
Входные данные для данной подпрограммы представлены:
TAbsFing &_dots – список точек найденный на растре, он содержит помимо нужных точек – минюций, лишние, непостоянные точки, которые не подходят для объектного описания папиллярного узора.
Выходные данные для данной подпрограммы представлены:
TAbsFing _dots – список параметров минюций, формат описан в
п.п. 2.1.3.
Используемые подпрограммы:
Порез(dot) – относится ли данная точка к точкам образованным порезами и инородными телами (см. п.п. 2.4.4);
Filter(dot1, dot2) – условие фильтрования (см. п.п. 2.4.4).
Схема подпрограммы «ReadPic»

Рис. 2.11

Схема подпрограммы «DotsFilter»
Рис. 2.12

2.5.6.  Подпрограмма AnalysePicture

Подпрограмма AnalysePicture предназначена для обработки загруженного изображения и получение из него объектного образа для последующего хранения и сравнения. Схема подпрограммы изображена на рис. 2.13.
Синтаксис:
TAbsFing TAnalysePicture::AnalysePicture()
Входные данные для данной подпрограммы представлены:
TFingPicture *pic – указатель на битовый образ в памяти, который был загружен для обработки.
Выходные данные для данной подпрограммы представлены:
TAbsFing Ret – список координат минюций в абсолютных параметрах, формат описан в п.п. 2.1.3.
Используемые переменные:
Map – список обрабатываемых линий на папиллярном узоре, каждой линии соответствует точка {x,y};
ChangeN – хранит количество сделанных изменений на растре.
Используемые подпрограммы:
LookPic – возвращает список линий на отпечатке;
ChangeLine(i, Map) – корректировка линии на растре, избавление от слипаний и обрывов;
ReadPic – возвращает список параметров специфических точек, см. формат в п.п. 2.1.3;
DotsFilter(Ret) – сортировка специфических точек, см. условия в п.п. 2.4.

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

2.6.1.  Назначение программы

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

Рис. 2.13

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

Для теста использовалось около 50 отпечатков разных людей и разного возраста. На рис. 2.14, 2.15, 2.16 приведены несколько изображений папиллярного узора, которые предполагается сравнить между собой и другими отпечатками в базе данных отпечатков. Данные изображения получены посредством зачернения пальца и приложения его к листу белой бумаги, после чего отпечатки были отсканированы и сохранены в виде bmp файлов на компьютере. Полученные таким образом отпечатки имеют не высокое качество, поэтому можно полностью проверить все этапы работы программы.
На рис. 2.14, 2.15 представлены отпечатки одного и того же пальца, а значит, в результате работы программы они должны совпасть. Рис. 2.16 это отпечаток другого пальца, нежели предыдущие два отпечатка.
Исходный образ A1

Рис. 2.14
Исходный образ A2

Рис. 2.15
Исходный образ B

Рис. 2.16

 

2.6.3.  Контрольный пример

Результат работы подсистемы приведен на рис. 2.17, 2.18, 2.19 – это визуализированные структурные представления входных отпечатков.
Структурное представление A1

Рис. 2.17
Структурное представление A2

Рис. 2.18
Структурное представление B

Рис. 2.19

2.6.4.  Тестирование программного обеспечения системы

распознавания личности по отпечаткам пальцев

Для испытания программного обеспечения системы на вход были поданы тестовые образы, описанные в п.2.6.2. Испытания проводились согласно руководству программиста, приведенному в приложении 2, и руководству оператора, приведенному в приложении 3. В результате были получены структурные описания представленные на рис. 2.17, 2.18, 2.19.
Полученные структурные представления точно описывают входные образы, что не трудно проверить визуальным сравнением с входными образами. Статистически было выявлено, что на отпечатках имеется около 40..50 минюций, эта величина может варьироваться в больших пределах в зависимости от размеров пальца. На тестовых образах найдено 19, 40, 37 соответственно. Меньшее количество объясняется тем, что тестовые образы это лишь фрагменты полного отпечатка, а образ B это указательный палец, который меньше по размерам, чем большой.
В приложении 4 можно увидеть, что отпечатки A1 (1.bmp), A2 (R1_3rotate2.bmp) схожи между собой и схожи с отпечатком 1R1_1.bmp, что является верным, так как все они являются образами большого пальца правой руки одного и того же человека. Отпечаток B (3l2_2.bmp) не совпадает ни с одним из A1 и A2, но совпадает с 3l2_1.bmp, что является также верным результатом, это отпечатки указательного пальца правой руки другого человека.
Тестирование показало, что разработанное программное обеспечение способно сравнивать и отыскивать схожие отпечатки, а значит и есть возможность определить человека, которому принадлежит обрабатываемый отпечаток. Полученные результаты совпадают с ожидаемыми результатами и совпадают с ручным сравнением. Для проверки этого в приложении 4 приведено полное сравнение всех имеющихся отпечатков.
А также программа, после небольшой корректировки параметров анализа и сравнения, была настроена для распознавания символов алфавита. Для проверки был введен в базу данных набор символов изображенных на рис. 2.20, который в последующем сравнивался с алфавитом на рис. 2.21.
Алфавит для базы данных
                                                       Рис. 2.20
Алфавит для сравнения

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

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

3.1.         Обоснование необходимости разработки системы

распознавания личности по отпечаткам пальцев

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

3.2.         Расчет затрат на разработку системы распознавания личности по отпечаткам пальцев

Для определения величины расходов на создание подсистемы, используем прямой метод калькуляции.
Расчет сметы затрат осуществляется по следующим статьям
-        расходы на основные и вспомогательные материалы;
-        расходы на оплату труда исполнителей;
-        расходы на социальные программы;
-        расходы на содержание и амортизацию основных фондов;
-        накладные расходы;
-        прочие расходы.
К статье «Расходы на основные и вспомогательные материалы» относятся покупные изделия, необходимые для выполнения работы, перечисленные в табл. 3.1.
Таблица 3.1
Расходы на основные и вспомогательные материалы
Наименование материала
Количество
Стоимость, р.
Матрица CD-R
1 шт.
20
Матрица CD-RW
3 шт.
75
Бумага писчая 80 г.
250 листов
60
Тонер для принтера
1 шт.
70
Прочие канцелярские товары
25
Итого
250
Оклад инженера-программиста в период разработки составлял 5500 р. в месяц. Продолжительность разработки 3 месяца.
                                              ЗП = ЗПММ                                                                (3.1)
ЗП = 5500 * 3 = 16500 руб.
К окладу начисляется премия. Процент премиальных составил 15% в месяц.
                                              ЗП,% = ЗП*1.15                                     (3.2)
ЗП,% = 16500 * 1.15 = 18975 руб.
Плановые накопления в фонд резерва отпусков (ЗД) рассчитывается в размере 10% от тарифной платы:
                                              ЗПД = ЗП * 0.10                                   (3.3)
ЗПД = 16500 * 0.10 = 1650 руб.
В расходы на оплату труда необходимо включить уральский коэффициент (15%). Районный коэффициент рассчитывается от оклада вместе с премиальными и дополнительной заработной платой.
КУР = (16500 + 1650) * 0.15 = 2722,50 руб.
Следовательно, расходы на оплату труда с учетом зонального коэффициента составят:
                                         ЗПОСН = ЗП,% + ЗПД + КУР                                       (3.4)
ЗПОСН = 18975 + 1650 + 2722.50 = 23347.50 руб.
Сумма налоговой базы не превышает 280000 руб., поэтому статья «Расходы на социальные налоги» включает в себя отчисления в пенсионный фонд (20%), на медицинское (3.1%) и социальное страхование (2.9%), отчисления в фонд страхования от несчастных случаев (0.2%), что составляет 26.2% /33/. Отчисления производятся от общих расходов на оплату труда и сумма отчислений составляет:
                                         СОТЧ = ЗПОСН * 0.262                              (3.5)
СОТЧ = 23347.50 * 0.262 = 3117.05 руб.
Статья «Расходы на амортизацию и содержание ВТ» включает расходы, связанные с эксплуатацией вычислительной техники. Стоимость одного машинного часа рассчитывается по формуле:
                                         АЧ = СИСП / (ЧМ * КЧ),                             (3.6)
где    АЧ – аренда за час использования;
СИСП – общая стоимость использования ЭВМ (рассчитывается по
формуле (3.7));
ЧМ – число месяцев в году;
КЧ – количество рабочих  часов  в  месяце.
                           СИСП = АКОМП + ЗПОБСЛ + СЗЧ + СЭЛ + АПО,          (3.7)
где    АКОМП – амортизация компьютера за год эксплуатации;
ЗПОБСЛ – расходы на оплату труда обслуживающего персонала за год эксплуатации;
ЗПОБСЛ = 1000 руб/мес
СЗЧ – стоимость запчастей для компьютера за год эксплуатации;
СЗЧ = 800 руб/год
СЭЛ – стоимость израсходованной электроэнергии за год эксплуатации;
СЭЛ = 1000 руб/год
АПО – годовая амортизация программного обеспечения.
                                           АКОМП = СКОМП / СПИ,                            (3.8)
где    СКОМП – стоимость компьютера;
СПИ – срок полезного использования (в годах);
АКОМП = 19000 / 5 = 3800 руб
                                         АПО = СТПО / СПИ,                                    (3.9)
где    СТПО – стоимость программного обеспечения;
СПИ – срок полезного использования (в годах);
АПО = 4000 / 5 = 800 руб
СИСП = 3800 + 1000*12 + 800 + 1000 + 800 = 18400 руб
АЧ = 18400 / (12 * 176) = 8,71 руб
ЭВМ использовалась на этапах проектирования (40 час), программирования (80 часов), отладки (320 часов) и документирования (160 часов), т.е. всего 600 часов. Следовательно, сумма амортизационных отчислений составит:
                                         САР = Эч * Ач                                          (3.10)
САР = 600 * 14.394 = 5227.40 руб.
Статья «Прочие расходы» содержит расходы, неучтенные в предыдущих статьях (до 50 % от расходов на оплату труда) :
                                       ПР = ЗПОСН * 0.5                                        (3.11)
ПР = 21337.50 * 0.5 = 10668.75 руб.
Статья «Накладные расходы» включает в себя расходы по управлению (заработная плата управления, расходы на все виды командировок управленческого аппарата), содержание пожарной и сторожевой охраны, содержание и текущий ремонт зданий, сооружений, инвентаря; содержание персонала, не относящегося к аппарату управления; расходы по изобретательству и рационализации; по подготовке кадров; расходы на содержание ВЦ; канцелярские, почтово-телеграфные расходы и др. общехозяйственные расходы; непроизводственные расходы. Накладные расходы составляют 130% от расходов на оплату труда, таким образом, получаем:
                                       НР = ЗПОСН * 1.3                                        (3.12)
НР = 23347.50 * 1.3 = 30351.75 руб.
Сумма затрат на разработку подсистемы в целом составила 76970 руб. Табл. 3.2 отражает затраты по статьям и структуру этих затрат в общей сумме.
Таблица 3.2
Смета затрат на разработку подсистемы
Статья затрат
Сумма затрат, руб.
Структура затрат, %
Расходы на материалы
250
0,3
Расходы на оплату труда
23350
30,3
Отчисления на социальные налоги
6120
8,0
Расходы на содержание и амортизацию ВТ
5230
6,8
Накладные расходы
30350
39,4
Прочие расходы
11670
15,2
Итого
76970
100
Округлим полученную сумму до тысяч для учета непредвиденных затрат. Получим, что сумма затрат на разработку системы составит 77000 руб.
Структура затрат на разработку ПО приведена на рис. 3.1.
Структура затрат на разработку ПО

Рис. 3.1

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

4.1.         Анализ опасных и вредных факторов, возникающих при работе на компьютере

Исследовательская работа в рамках данного проекта заключается в выполнении многих этапов, практически все из которых проходят в тесном контакте с ЭВМ. Длительная работа инженера-программиста с компьютером сопряжена с целым рядом вредных и опасных факторов. Рассмотрим некоторые из них.
Постоянное напряжение глаз
Работа с компьютером характеризуется высокой напряженностью зрительной работы. В выполняемом исследовании значительный объем информации на разных стадиях обработки представлен в графической форме с большим количеством мелких деталей, что дает серьезную нагрузку на зрение. Постоянное напряжение глаз может привести к снижению остроты зрения. Экран видеомонитора должен находиться от глаз пользователя на оптимальном расстоянии 600…700 мм, но не ближе 500 мм с учетом размеров алфавитно-цифровых знаков и символов. Также для снижения утомляемости рекомендуется делать 15-минутные перерывы в работе за компьютером в течение каждого часа.
Влияние электростатических и электромагнитных полей
Большинство ученых считают, что как кратковременное, так и длительное воздей­ст­вие всех видов излучения от экрана мони­тора не опасно для здоровья персонала, об­слу­живающего ком­пьютеры. Однако исчерпывающих данных относительно опасно­сти воз­действия излучения от мониторов на работающих с ком­пьютерами не сущест­вует и ис­следования в этом направлении продолжаются.
Допустимые значения параметров неионизирую­щих электромагнитных излучений от монитора компьютера представлены в табл. 4.1 /32/.
Максимальный уровень рентгеновского излучения на рабочем месте оператора ком­пьютера обычно не превышает 10 мкбэр/ч, а интенсивность ультрафиолетового и ин­фра­красного излучений от экрана монитора лежит в пределах 10…100 мВт/м2  /31/.
Таблица 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.2.         Техника безопасности при работе на ПК

Техника безопасности на ПК тесно связана с электробезопасностью. Большинство компьютеров имеют трехштырьковый разъем кабеля питания (в отличие от двухштырьковой вилки большинства бытовых приборов). Третий разъем – это так называемая «земля». В грамотно оборудованных компьютеризированных помещениях существует настоящая земля — заземляющий контур, который через металлическую ленту выводится на заземляющий штырь. Все это довольно громоздкое и дорогостоящее оборудование и часто разъем заземления не используется или используется «земляная» фаза обычной электросети. Результатом неправильного заземления могут быть удары статического напряжения от корпуса ПК. Частенько из-за этого сгорает сетевое оборудование компьютеров. Следует соблюдать не только правила электробезопасности, но и следить за состоянием здоровья обслуживающего персонала и пользователей ПК, защищая их от вредного воздействия электромагнитных излучений, заботясь о зрении, так как именно оно испытывает основные нагрузки при работе с вычислительной техникой.
Важно также следить за состоянием техники и соблюдать основные правила обращения с ней.
Системный блок следует включать как можно реже (обычно включается в начале рабочего дня и выключается, выключается работа на нем — в конце дня). Для того чтобы не выгорал экран и не расходовалась лишняя энергия, в компьютере предусмотрен специальный режим гашения экрана — через определенное время, если никто не работает на нем, т.е. нет обращения к клавиатуре или мыши, он выключается. Если монитор получает питание от системного блока, включая системный блок, включаем и монитор. Если соединение монитора и системного блока параллельно, то сначала необходимо включить монитор, потом системный блок. Выключать в обратной последовательности.
Экран монитора стеклянный, а потому и хрупкий, и поэтому надо обращаться с ним осторожно. Недопустимо попадание жидкости за заднюю часть экрана может замкнуть проводка, что выведет его из строя и может привести к возникновению пожара. В случае попадания жидкости следует отключить электропитание.
Защита от излучения расположена только на экране, поэтому, находясь прямо перед экраном, пользователь наиболее защищен от вредного воздействия излучения. На заднюю и боковые части монитора в целях экономии защиту не устанавливают. Следовательно, находясь сбоку или сзади монитора, можно получить максимально вредное воздействие.
При работе с клавиатурой стоит придерживаться следующих правил:
1)     сильно не ударять по клавишам, это приводит к быстрой изнашиваемости прибора.
2)     не распивать напитки над клавиатурой, так как попадание жидкости в нее приводит к короткому замыканию и выводит из строя клавиатуру, в случае попадания необходимо обесточить компьютер.
3)     не кушать над клавиатурой бутерброды, семечки, так как крошки, попадающие в клавиатуру, нарушают ее работу.
4)     при наличии защитной панели следует закрывать клавиатуру, тем самым, защищая ее от пыли.

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

Разработка данного дипломного проекта проводится одним автором на персональном компьютере. Проведем расчет параметров рабочего места инженера-программиста с точки зрения эргономических требований.
В табл. 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 мм.

Таблица 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
Стул, которым оборудовано рабочее место автора данного проекта, является подъемно-поворотным и обладает возможностью регулирования по высоте и углам наклона сиденья и спинки, а также расстоянию спинки от переднего края сиденья. Стул имеет стационарные подлокотники длиной 250 мм и шириной 50 мм. Параметры, которые могли быть настроены в зависимости от роста инженера-программиста, были настроены. Остальные параметры стула (ширина и глубина сиденья и т.д.) удовлетворяют допустимым нормам.
Рабочее место должно быть оборудовано подставкой для ног, имеющей ширину не менее 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° относительно вертикали, в левом и правом направлениях.
Большое значение также придается правильной рабочей позе пользователя. При не­удобной рабочей позе могут появиться боли в мышцах, суставах и сухожилиях. Требо­ва­ния к рабочей позе пользователя видеотерминала следующие:
1)       голова не должна быть нак­лонена более чем на 20°;
2)       плечи должны быть расслаблены;
3)       локти - под углом 80°…100°;
4)       предплечья и кисти рук - в горизонтальном  положении.
Причина неправильной позы пользователей обусловлена следующими факторами: нет хорошей подставки для документов, клавиатура находится слишком высоко, а до­кумен­ты - низко, некуда положить руки и кисти, недостаточно пространство для ног.
В целях преодоления указанных недостатков даются общие рекомендации: лучше пе­редвижная клавиатура; должны быть предусмотрены специальные приспособления для регулирования высоты стола, клавиатуры и экрана, а также подставка для рук.
Существенное значение для производительной и качествен­ной работы на компью­тере имеют размеры знаков, плотность их размещения, контраст и соотношение яркос­тей символов и фона экрана. Если расстояние от глаз оператора до экрана дисплея сос­тавля­ет 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 м/с
На исследуемом предприятии температура воздуха, влажность и скорость движения воздуха держится в рамках оптимальных параметров. Вредные вещества в воздухе рабочей зоны не превышают предельной допустимой концентрации.

4.5.         Требования к освещению и расчет искусственного освещения

Организация рационального освещения рабочих мест является одним из основных вопросов охраны труда. Основные параметры освещения приведены в СНиП 23-05-95 "Естественное и искусственное освещение". Правильно спроектированное и выполненное производственное освещение сохраняет зрение рабочего, снижает утомляемость, способствует повышению производительности труда, качеству выпускаемой продукции, безопасности труда и снижению травматизма. Неправильно выбранные при проектировании осветительные приборы и аппаратура, а также нарушение правил их технической эксплуатации могут быть причиной пожара, взрыва, аварии на предприятии.
К современному освещению помещений, где работают с вычислительной техникой, предъявляют высокие требования как гигиенического, так и технического характера. Правильно спроектированное и выполненное освещение обеспечивает высокий уровень работоспособности, оказывает положительное психологическое воздействие, способствует повышению производительности труда. Условия деятельности пользователя в системе «человек-машина» связаны с явным преобладанием зрительной информации - до 90% общего объема.
В помещениях с компьютерной техникой применяется совмещенная система освещения. К таким системам предъявляют следующие требования:
1)     соответствие уровня освещенности рабочих мест характеру выполняемых зрительных работ;
2)     достаточно равномерное распределение яркости на рабочих поверхностях и в окружающем пространстве;
3)     отсутствие резких теней, прямой и отраженной блеклости.
4)     постоянство освещенности во времени;
5)     оптимальная направленность излучаемого осветительными приборами светового потока;
6)     долговечность, экономичность, пожаробезопасность, эстетичность, удобство и простота эксплуатации.
Искусственное освещение в помещениях эксплуатации ЭВМ должно осуществляться системой общего равномерного освещения. В производственных и административно-общественных помещениях, в случаях преимущественной работы с документами, допускается применение системы комбинированного освещения (к общему освещению дополнительно устанавливаются светильники местного освещения, предназначенные для освещения зоны расположения документов).
Согласно СНиП /34/ освещенность при системе общего освещения составляет 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=4´5=20 (м2);
Z – поправочный коэффициент, численно равный отношению средней освещенности к минимальной, Еср/Emin – Z=1,1;
n – количество источников света - n=12;
И – коэффициент использования осветительной установки, значение которого зависит от типа светильника, коэффициента отражения стен rс, потолка rп, рабочей поверхности rр, размеров освещаемого помещения (индекса помещения).
Для определения индекса помещения следует применять уравнение:
,
где b, ln – соответственно ширина и длина освещаемого помещения;
Нр – высота подвеса светильников над рабочей поверхностью.
Коэффициент использования светового потока светильников с лампами накаливания И определяем по таблице, приведенной в СНиП 23-05-95, с помощью следующих значений:
; rр=0,1; rс=0,2; rп=0,7.
В итоге И = 0,73.
Соответственно:

Для полученного значения светового потока источника света FЛ=3130 лм наиболее подходят два типа ламп накаливания: ЛБ40-М и ЛД65-7.
Все необходимые данные определены в СНиП 23-05-95.

4.6.         Пожарная безопасность

Помещение, в котором установлено рабочее место инженера-программиста, относится к категории “Д” по взрывопожароопасности, так как не содержит горючих веществ, но лишь негорючие вещества и материалы в холодном состоянии.
Пожары в помещении, в котором находится ЭВМ, представляют особую опасность, так как сопряжены с большими материальными потерями. Площадь помещения, в котором ведется проектирование, невелика и составляет 8 м2. Как известно пожар может возникнуть при взаимодействии горючих веществ, окисления и источников зажигания. В помещении присутствуют все три основные фактора, необходимые для возникновения пожара. Горючими компонентами являются: строительные материалы для акустической и эстетической отделки помещений, двери, полы, бумага, изоляция кабелей и др.
Противопожарная защита - это комплекс организационных и технических мероприятий, направленных на обеспечение безопасности людей, на предотвращение пожара, ограничение его распространения, а также на создание условий для успешного тушения пожара.
Источниками зажигания в помещении, содержащем ЭВМ, могут быть электронные схемы от ЭВМ, приборы, применяемые для технического обслуживания, устройства электропитания, где в результате различных нарушений образуются перегретые элементы, электрические искры и дуги, способные вызвать загорания горючих материалов.
В современных ЭВМ очень высока плотность размещения элементов электронных схем. В непосредственной близости друг от друга располагаются соединительные провода, кабели. При протекании по ним электрического тока выделяется значительное количество теплоты. При этом возможно оплавление изоляции. Для отвода избыточной теплоты от ЭВМ служат системы вентиляции и кондиционирования воздуха. При постоянном действии эти системы представляют собой дополнительную пожарную опасность.
Одной из наиболее важных задач пожарной защиты является защита строительных помещений от разрушений и обеспечение их достаточной прочности в условиях воздействия высоких температур при пожаре. Учитывая высокую стоимость электронного оборудования, а также категорию его пожарной опасности, здания, в которых предусмотрено размещение ЭВМ должны быть 1 и 2 степени огнестойкости.
К средствам тушения пожара, предназначенных для локализации небольших возгорании, относятся пожарные стволы, внутренние пожарные водопроводы, огнетушители, сухой песок, асбестовые одеяла и т. п.
В соответствии с “Типовыми правилами пожарной безопасности для промышленных предприятий” залы ЭВМ, помещения для внешних запоминающих устройств, подготовки данных, сервисной аппаратуры, архивов, копировально-множительного оборудования и т.п. необходимо оборудовать дымовыми пожарными извещателями. В этих помещениях в начале пожара при горении различных пластмассовых, изоляционных материалов и бумажных изделий выделяется значительное количество дыма и мало теплоты.
Помещение, в котором производится разработка данного проекта, необходимо оборудовать средствами оповещения о пожаре, а также средствами для тушения пожара.
В данном разделе дипломной работы был проведен анализ вредных и опасных производственных факторов, действующих на рабочем месте инженера-программиста. Среди них были выделены: постоянное напряжение глаз, влияние электростатических и электромагнитных полей, длительное неизменное положение тела, шум. Был проведен анализ и указан комплекс мер по пожаробезопасности и электробезопасности. Проведен расчет эргономических требований к рабочему месту инженера-программиста. Созданные условия должны обеспечивать комфортную ра­бо­ту. На основании изученной литературы по данной проблеме, были указаны опти­маль­ные размеры рабочего стола и кресла, параметры рабочей поверхности, а также сформулированы предложения по улучшению параметров рабочего места. Соблюдение условий, определяющих оптимальную организацию рабочего места инженера-программиста, позволит сохранить хорошую работоспособность в течение всего рабочего дня, повысит как в количественном, так и в качественном отношениях производительность труда программиста, что в свою очередь будет способствовать быстрейшей разработке и отладке программного продукта.

ЗАКЛЮЧЕНИЕ

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

ЛИТЕРАТУРА

1)           Биометрические технологии – альтернатива персональным идентификационным номерам и паролям // k2kapital.com Аналитические обзоры 8 мая 2000. http://www.k2kapital.com/archives/research/rs20000508.html  Проверено: 16.05.06.
2)           Завгородний В.И. Комплексная защита информации в компьютерных системах // Учебное пособие. - М.: Мир, 2001. – 264 с.
3)           Виталий Задорожный. Области применения и принципы построения биометрических систем // PC Magazine/Russian Edition 21 апреля 2004. http://www.pcmag.ru/?ID=447314&4Print=1. Проверено 16.05.06.
4)           Долгий И.Д. Ковалев С.М., Кулькин С.А. К вопросу об идентификации личности в системе «Диспетчерской централизации» // Ростовский государственный университет путей сообщения, 2003. http://pitis.tsure.ru/files24/03.pdf. Проверено 16.05.06.
5)           ООО «Биолинк Технолоджис». Продукты: BioLink BioTime 2006; BioLink Authenteon Software Appliance (ASA) // BioLink, 2001. biolink.ru Проверено 16.05.06.
6)           Документация «Microsoft IntelliMouse Explorer with Fingerprint Reader» // Microsoft, 2004.
7)           Первый телефон с функцией распознавания отпечатков пальцев.  // ИА Клерк.Ру, 04.08.2004. http://www.klerk.ru/soft/n/?11433.  Проверено 16.05.06.
8)           Бойер, П. Флостер Д. Использование Adobe Photoshop 7. Специальное издание. – М.: Вильямс, 2004.
9)           Руководство пользователя для FineReader 8.0 // 1996-2006 ABBYY Software. http://www.abbyy.com/DLCenter/downloadcentermanager.aspx?file=/fr80/guides/Guide_Russian.pdf. Проверено 16.05.06.
10)      Сканеры отпечатков пальцев. // BIOMETRICS.RU 2002-2006,  http://cyberdefend.narod.ru/biometric_devices.htm Проверено 16.05.06.
11)      Задорожный В.В. Идентификация по отпечаткам пальцев. //  PC Magazine/Russian Edition №1, 2004, - C. 25 - 35.
12)      Геннадий Рябов. Современные технологии идентификации личности по отпечатку пальца с использованием емкостных датчиков. //  radioradar.net, 2004. http://www.radioradar.net/staty/identif_otpech.php.  Проверено 16.05.06.
13)      Гончаров Д., Салихов Т. DirectX 7.0 для программистов //  - С.-Пб.: Питер, 2001. - 528 с.
14)      Прэтт У. Цифровая обработка изображений. Т. 1. - М.: Мир, 1982. – 312 с.
15)      Дуда Р., Харт П. Распознавание образов и анализ сцен. - М.: Мир, 1976. – 511 с.
16)      Аммерал Л. Принципы программирования в машинной графике. - М.: Сол Систем, 1992.
17)      Анисимов Б.В., Курганов В.Д., Злобин В.К. Распознавание и цифровая обработка изображений. - М.: Высшая школа, 1983. - 256 с.
18)      Бутаков А., Островский В. И., Фадеев И.Л. Обработка изображений на ЭВМ. - М.: Радио и связь, 1987.
19)      Гренандер У. Лекции по теории образов. - М.: Мир, 1979. – Т. 1-3.
20)      Павлидис Т. Алгоритмы машинной графики и обработки изображений. - М.: Радио и связь, 1986.
21)      Ту Дж., Гонсалес Р. Принципы распознавания образов. - М.: Мир, 1976.
22)      Файн В.С. Опознавание изображений. – М.: Наука, 1970.
23)      Розенфельд А. Распознавание и обработка изображений с помощью ЭВМ. - М.: Мир, 1972.
24)      Строустрап Б. Язык программирования С++. – М.: Мир, 1994. – 278 с.
25)      Кнут Д. Искусство программирования для ЭВМ. - М.: Мир, 1976. – Т. 1-3.
26)      Шилдт Г. Самоучитель С++. - С-Пб.: БВХ-Петербург, 2002. 3 издание.
27)      Тихомиров Ю. OpenGL Программирование трехмерной графики.  - С-Пб.: БВХ-Петербург, 2002г. 2 издание.
28)      Шибаева И.В., Мурынов А.И., Пивоваров И.В. Математические и программные средства распознавания графических изображений для передачи по цифровым каналам связи // Информационные технологии в науке, образовании, телекоммуникациях и бизнесе: Материалы 31 Междунар. конф. – Украина, Крым, Ялта–Гурзуф: Ж. «Успехи современного естествознания» №5, 2004, Прилож. №1. – 114 c.
29)      Соболева В.П. Методические указания по оформлению курсовых работ, курсовых и дипломных проектов. – Ижевск: Издательство ИМИ, 2003.
30)      Эйнджел Э. Интерактивная компьютерная графика. – М.: Вильямс, 2001. – 592 с.
31)      ГОСТ 12.1.006–84. ССБТ. Электромагнитные поля радиочастот. Допустимые уровни  на рабочих местах и требования к проведению контроля. – М.: Издательство стандартов, 1985.
32)      СанПиН 2.2.2.542-96. Гигиенические требования к видео-дисплейным терминалам, персонально-вычислительным машинам и организация работ. – М.: Госкомсанэпиднадзор России, 1996.
33)      Налоговый кодекс РФ. – М.: ГроссМедиа Ферлаг, 2004. – 432 с.
34)      ГОСТ 12.1.009-76. ССБТ. Электробезопасность. Термины и определения.
– М.: Издательство стандартов, 1985.
35)      ГОСТ 19.505-79 ЕСПД. Руководство оператора. Требования к содержанию и оформлению. – М.: Издательство стандартов, 1979.
36)      ГОСТ 19.504-79 ЕСПД. Руководство программиста. Требования к содержанию и оформлению. – М.: Издательство стандартов, 1979.
37)      ГОСТ 19.701-90 ЕСПД. Схемы алгоритмов и программ. Правила выполнения. – М.: Издательство стандартов, 1991.
38)      Технико-экономическое обоснование дипломных проектов при разработке приборов и методов контроля качества. Методические указания для студентов. – Ижевск: Издательство ИжГТУ, 2001.
39)      Почерняев С.В., Килин И.В. Методические указания по дипломному  проектированию. – Ижевск: Издательство ИжГТУ, 1994.

ПРИЛОЖЕНИЕ 1

 

ТЕКСТ ПРОГРАММЫ

П.1.1. ТЕКСТ МОДУЛЯ 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.2. ТЕКСТ МОДУЛЯ 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.3. ТЕКСТ МОДУЛЯ 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.4. ТЕКСТ МОДУЛЯ FingAnalyserDlg.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 ТЕКСТ МОДУЛЯ FingAnalyserDlg.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
//    fp->Load(dlg.GetFileName());
  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.6 ТЕКСТ МОДУЛЯ 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;}

1. Доклад Анализ и аудит финансово-хозяйственной деятельности
2. Курсовая на тему Отряд Крокодилы
3. Реферат на тему Hannibal Essay Research Paper HannibalIn 237 BC
4. Реферат 580-е до н. э.
5. Реферат на тему Mama Day Essay Research Paper Meredith Kirkland4999The
6. Контрольная работа Финансовый механизм управления формированием операционной прибыли
7. Реферат Земли казачьих войск и сообществ на территории Украины
8. Курсовая на тему Разработка алгоритма работы интеллектуальной информационной системы Расчет меню
9. Лабораторная работа Исследование потока в неподвижном криволинейном канале
10. Кодекс и Законы Организация бухгалтерского учета на предприятии 7