Система идентификации личности по отпечаткам пальцев

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

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 23.06.2008
Размер файла 4,0 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

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

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

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

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

Одной из наиболее важных задач пожарной защиты является защита строительных помещений от разрушений и обеспечение их достаточной прочности в условиях воздействия высоких температур при пожаре. Учитывая высокую стоимость электронного оборудования, а также категорию его пожарной опасности, здания, в которых предусмотрено размещение ЭВМ должны быть 1 и 2 степени огнестойкости.

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

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

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

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

ЗАКЛЮЧЕНИЕ

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

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

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

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

ЛИТЕРАТУРА

1. http://www.k2kapital.com/archives/research/rs20000508.html Биометрические технологии - альтернатива персональным идентификационным номерам и паролям.// 22.05.2006

2. Завгородний В.И. Комплексная защита информации в компьютерных системах // Учебное пособие. -М.: Логос, 2001, - 264 с.

3. http://www.klerk.ru/soft/n/?11433 Первый телефон с функцией распознавания отпечатков пальцев. // Проверено 22.05.2006

4. http://russian-samsung.com/publications/1093261352/ Система распознавания отпечатков пальцев в телефоне: все не так хорошо, как кажется. // Проверено 22.05.2006

5. Бойер П., Флостер Д.. Использование Adobe Photoshop 7. Специальное издание. - М.: Вильямс, 2004.

6. http://www.abbyy.com/DLCenter/downloadcentermanager.aspx?file=/fr80/guides/Guide_Russian.pdf. Руководство пользователя для FineReader 8.0// 1996-2006 ABBYY Software // Проверено 16.05.06

7. Налоговый кодекс РФ. - М.: ГроссМедиа Ферлаг, 2004. - 432 с.

8. СанПиН 2.2.2.542-96. Гигиенические требования к видео-дисплейным терминалам, персонально-вычислительным машинам и организация работ. - М.: Госкомсанэпиднадзор России, 1996.

9. ГОСТ 12.1.006-84. ССБТ. Электромагнитные поля радиочастот. Допустимые уровни на рабочих местах и требования к проведению контроля. - М.: Издательство стандартов, 1985.

10. ГОСТ 12.1.009-76 ССБТ Электробезопасность. Термины и определения. - М.: Издательство стандартов, 1985.

11. Прэтт У. Цифровая обработка изображений. Т. 1. - М.: Мир, 1982. - 312 с.

12. Дуда Р., Харт П. Распознавание образов и анализ сцен. - М.: Мир, 1976. - 511 с.

13. Аммерал Л. Принципы программирования в машинной графике. - М.: Сол Систем, 1992.

14. Анисимов Б.В., Курганов В.Д., Злобин В.К. Распознавание и цифровая обработка изображений. - М.: Высшая школа, 1983. - 256 с.

15. Бутаков А., Островский В. И., Фадеев И.Л. Обработка изображений на ЭВМ. - М.: Радио и связь, 1987.

16. Гренандер У. Лекции по теории образов. - М.: Мир, 1979. - Т. 1-3.

17. Павлидис Т. Алгоритмы машинной графики и обработки изображений. - М.: Радио и связь, 1986.

18. Ту Дж., Гонсалес Р. Принципы распознавания образов. - М.: Мир, 1976.

19. Файн В.С. Опознавание изображений. - М.: Наука, 1970.

20. Розенфельд А. Распознавание и обработка изображений с помощью ЭВМ. - М.: Мир, 1972.

21. Хуанг Г.С. Быстрые алгоритмы цифровой обработки изображений. - М.: Радио и связь, 1984.

22. Крамер Г. Математические методы статистики. - М.: Мир, 1975.

23. Патрик Э. Основы теории распознавания образов. - М.: Советсткое радио, 1980.

24. Строустрап Б. Язык программирования С++. - М.: Мир, 1994. - 278 с.

25. Кнут Д. Искусство программирования для ЭВМ. - М.: Мир, 1976. - Т. 1-3.

26. Лялин В.Е., Мурынов А.И., Шибаева И.В. Модели представления и кодирования пространственных объектов для передачи изображений сцен по цифровым каналам связи // Информационные технологии в науке, образовании, телекоммуникациях и бизнесе: Материалы 31 Междунар. конф. - Украина, Крым, Ялта-Гурзуф: Ж. «Успехи современного естествознания», №5, 2004, Прилож. №1. - С. 123-125.

27. Шибаева И.В., Мурынов А.И., Пивоваров И.В. Математические и программные средства распознавания графических изображений для передачи по цифровым каналам связи // Информационные технологии в науке, образовании, телекоммуникациях и бизнесе: Материалы 31 Междунар. конф. - Украина, Крым, Ялта-Гурзуф: Ж. «Успехи современного естествознания» №5, 2004, Прилож. №1. - С. 114-117.

28. Гусейнов П.М. Методы статистической классификации многозональной видеоинформации с обучением по тестовому участку // Исследование Земли из космоса. - 1987. - № 4. - С. 21-28.

29. Корн Г., Корн Т. Справочник по математике для научных работников и инженеров. - М.: Наука, 1979. - 720с.

30. Эйнджел Э. Интерактивная компьютерная графика. - М.: Вильямс, 2001. - 592 с.

31. Левкович О.А., Шелкоплясов Е.С., Шелкоплясов Т.Н. Основы компьютерной грамотности: Учебное пособие. - М.: ТетраСистемс, 2004. - 528 с.

32. ГОСТ 19.505-79 ЕСПД. Руководство оператора. Требования к содержанию и оформлению. - М.: Издательство стандартов, 1979.

33. ГОСТ 19.504-79 ЕСПД. Руководство программиста. Требования к содержанию и оформлению. - М.: Издательство стандартов, 1979.

34. ГОСТ 19.701-90 ЕСПД. Схемы алгоритмов и программ. Правила выполнения. - М.: Издательство стандартов, 1991.

35. Технико-экономическое обоснование дипломных проектов при разработке приборов и методов контроля качества. Методические указания для студентов. - Ижевск: Издательство ИжГТУ, 2001.

36. Соболева В.П. Методические указания по оформлению курсовых работ, курсовых и дипломных проектов. - Ижевск: Издательство ИМИ, 2003.

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

П.1.1. ТЕКСТ МОДУЛЯ FING.H

#pragma once

#include "stdafx.h"

using namespace std;

//Элемент "карты точек"

//"Карта точек" - список точек для обработки

class TMapElDot{

public:

CPoint coord; //координаты точки

bool pr1, pr2; //признаки точки

public:

TMapElDot(CPoint dot){pr1 = true; pr2 = true; coord = dot;};

TMapElDot(){pr1 = true; pr2 = true;};

~TMapElDot(){};

};

//"Карта точек" - список точек для обработки

class TMapDot{

public:

list<TMapElDot> map; //карта точек на изображении

TMapDot(){};

~TMapDot(){map.clear();};

};

//сопроводительна информация

class TInfo{

public:

short kol; //количество точек

short dpi; //качество исходного отпечатка (dot per inch)

CString src; //путь к образу из которого была получена информация

CTime date; //дата отпечатка

CString description; //описание

bool operator==(const TInfo &inf){return src == inf.src;}; //сравнение расположения изображений на диске

TInfo(){kol = -1; dpi = -1; /*src = ""; description = "";*/};

void Printf(FILE *fout) //запись данных в файл

{

fwrite((void *)(&kol), sizeof(kol), 1, fout);

fwrite((void *)(&dpi), sizeof(dpi), 1, fout);

int strlen = src.GetLength();

fwrite((void *)(&strlen), sizeof(int), 1, fout);

fwrite((void *)(src.GetBuffer()), strlen, 1, fout);

};

void Scanf(FILE *fin) //чтение данных из файла

{

fread((void *)(&kol), sizeof(kol), 1, fin);

fread((void *)(&dpi), sizeof(dpi), 1, fin);

int strlen;

fread((void *)(&strlen), sizeof(int), 1, fin);

char * text = new char[strlen+1];

fread((void *)(text), strlen, 1, fin);

text[strlen] = '\0';

src = text;

delete(text);

};

};

//абсолютные параметры точки

class TAbsDot{

public:

CPoint coord; //координаты

double alpha; //направление в точке

bool type; //тип точки (1- окончание, 0- раздвоение)

bool show; //видимость точки (1- видима, 0- скрыта)

public:

TAbsDot(){coord.x = -1; coord.y = -1; alpha = 0; type = false; show = false;};

~TAbsDot(){};

bool operator==(const TAbsDot &f){return (coord.x == f.coord.x && coord.y == f.coord.y && alpha == f.alpha);};

bool operator <(const TAbsDot &f){return (alpha < f.alpha);};

bool operator >(const TAbsDot &f){return (alpha > f.alpha);};

bool operator!=(const TAbsDot &f){return false;};

bool operator<=(const TAbsDot &f){return false;};

bool operator>=(const TAbsDot &f){return false;};

CString toStr()

{

CString str;

str.Format("%d %d %f %d %d\n", coord.x, coord.y, alpha, type, show);

return str;

};

};

//класс для хранения точек в _абсолютных_ параметрах

//Описание отпечатка в абсолютных параметрах

class TAbsFing: public list<TAbsDot>

{

public:

TAbsFing(){this->clear();};

~TAbsFing(){this->clear();};

bool LoadFing(CString src); //Загрузка отпечатка из файла *.sav

bool SaveFing(CString fsav); //Сохранение отпечатка в файл *.sav

};

//относительные параметры точки

class TRelDot{

public:

short l,a1,a2; //координаты точки

//l - растояние между точками

//a1 - угол между собственным направлением точки А и направлением A -> B [0, 2*M_PI)

//a2 - угол между собственным направлением точки В и направлением A -> B [0, 2*M_PI)

TAbsDot absDot; //ее абсолютные параметры (необходимо для отображения на экране совпавших точек)

public:

bool operator<(const TRelDot &f){return this->l < f.l;}

bool sortByA1(TRelDot &f){return a1 < f.a1;} //эта функция нужна для сортировки, но сортировка так и не реализованна

bool operator==(const TRelDot &f){return (this->l == f.l && this->a1 == f.a1 && this->a2 == f.a2);}

CString toStr(){CString s; s.Format("%d %d %d\n", l, a1, a2); return s;}

};

//класс для хранения _относительных_ параметров точки

typedef list<TRelDot> listTRelDot;

//Шаблон для хранения пары значений {first, second}

template <class data_t1, class data_t2> struct TPair{

data_t1 first;

data_t2 second;

TPair(data_t1 _f, data_t2 _s){first = _f; second = _s;};

};

typedef TPair<TAbsDot, TAbsDot> TPairAbsDot;

typedef TPair<listTRelDot*, listTRelDot*> TPairSur;

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

struct TCompareFing{

double val; //уровень схожести отпечатков

short cDot; //количество совпавших точек

short nfng; //номер отпечатка

CString name; //файл отпечатка

list<TPairAbsDot> dots; //first - совпавшие точки на отпечатке в базе

//second - совпавшие точки на открытом отпечатке

list<TPairSur> surdots;

//окружения на одинаковых отпечатках должны быть одинаковыми,

//на этом основано сравнение "роз"

};

//Описание отпечатка в _относительных_ параметрах

class TRelFing: public list<listTRelDot>{

private:

inline double GetS(const CPoint A, const CPoint B); //растояние между точками

double GetAlpha(const CPoint A, const CPoint B); //Направлени из точки А в В [-pi,pi)

public:

TRelFing(){};

~TRelFing(){};

TRelFing *Convert(TAbsFing &fng); //конвертировать абсолютные параметры к относительным

TCompareFing Compare(TRelFing &fng); //сравнить отпечатки

};

П.1.2. ТЕКСТ МОДУЛЯ FING.CPP

#include "stdafx.h"

#include "fing.h"

bool TAbsFing::SaveFing(CString fsav)

//Сохранение отпечатка в файл *.sav

{

if(!this->size()) return false;

TAbsFing::iterator iter;

FILE *fingfile = fopen(fsav, "wb");

if(fingfile == NULL)

{

MessageBox(NULL,"Невозможно создать файл: '"+fsav+"'", "Ошибка работы с файлом", MB_OK);

return false;

}

for(iter = this->begin(); iter != this->end(); iter++)

{

TAbsDot dot = *iter;

if(iter->show) fwrite((void *)&dot, 1, sizeof(dot), fingfile);

}

fclose(fingfile);

return true;

}

bool TAbsFing::LoadFing(CString src)

//Загрузка отпечатка из файла *.sav

{

TAbsDot dot;

FILE *fingfile = fopen(src, "rb");

if(fingfile == NULL)

{

MessageBox(NULL,"Невозможно открыть файл: '"+src+"'", "Ошибка работы с файлом", MB_OK);

return false;

}

this->clear();

while(!feof(fingfile))

{

fread((void *)&dot, 1, sizeof(dot), fingfile);

this->push_back(dot);

}

this->pop_back();

fclose(fingfile);

return true;

}

///////////////////////////////////////////////////////////////////////////////////////

///TRelFing//TRelFing/TRelFing/TRelFing/TRelFing/TRelFing/TRelFing/TRelFing/TRelFing///

///////////////////////////////////////////////////////////////////////////////////////

TRelFing *TRelFing::Convert(TAbsFing &fng)

//конвертировать абсолютные параметры к относительным

{

if(fng.empty()) return this;

this->clear();

TAbsFing::iterator iterA1, iterA2;

TRelDot tmpR;

listTRelDot listDots;

double tmpa, vecAB;

for(iterA1 = fng.begin(); iterA1 != fng.end(); iterA1++)

{

for(iterA2 = fng.begin(); iterA2 != fng.end(); iterA2++)

{

if(iterA2 == iterA1) continue;

tmpR.l = (short)(GetS(iterA1->coord, iterA2->coord)+0.5); //l - растояние между точками

vecAB = GetAlpha(iterA2->coord, iterA1->coord);

tmpa = iterA1->alpha - vecAB;

if(tmpa < 0) tmpa = 2*M_PI + tmpa;

tmpR.a1 = (short)(tmpa * 180.0/M_PI +0.5); //a1 - угол между собственным направлением точки А и направлением A -> B

tmpa = iterA2->alpha - vecAB;

if(tmpa < 0) tmpa = 2*M_PI + tmpa;

tmpR.a2 = (short)(tmpa * 180.0/M_PI +0.5); //a2 - угол между собственным направлением точки В и направлением A -> B

tmpR.absDot = *iterA1; //Во всех точках хранятся одни и те же данные!(необходимо для отображения совпавших точек)

listDots.push_back(tmpR);

}

listDots.sort();

this->push_back(listDots);

listDots.clear();

}

return this;

}

inline double TRelFing::GetS(const CPoint A, const CPoint B)

//растояние между точками

{

return sqrt( (double)((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)) );

}

double TRelFing::GetAlpha(const CPoint A, const CPoint B)

//Направлени из точки А в В [-pi,pi)

{

if(A == B) return 0.0;

double alpha;

if (A.x - B.x == 0)

{

if (A.y > B.y) alpha = M_PI_2;

else alpha = -M_PI_2;

}else

{

double a = ((double)A.y-B.y)/((double)B.x-A.x);

alpha = atan(a);

if (A.x > B.x)

{

if (alpha < 0) alpha += M_PI;

else alpha -= M_PI;

if (A.y == B.y) alpha = -M_PI;

}

}

return alpha;

}

TCompareFing TRelFing::Compare(TRelFing &fng)

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

{

TCompareFing ret;

ret.nfng = (short)fng.size();

const short CONFIRM_VAL = 9;

const double DELTA_L = 10.0; //ограничитель

const double DELTA_A = 10.0; //ограничитель

short confirmDot = 0; //количество совпавших СТ (спец точек)

short confirmVal = 0; //количество совпавших сопряженных СТ с текущей СТ

short needVal = (short)(min(this->size(),fng.size())/3.0 +0.5);

if(needVal > CONFIRM_VAL) needVal = CONFIRM_VAL;

listTRelDot *surroundDots1, *surroundDots2;

listTRelDot::iterator baseIter;

for(TRelFing::iterator tekFing = this->begin();

tekFing != this->end();

tekFing++)

{

for(TRelFing::iterator baseFing = fng.begin();

baseFing != fng.end();

baseFing++)

{

confirmVal = 0;

surroundDots1 = new(listTRelDot);

surroundDots2 = new(listTRelDot);

for(listTRelDot::iterator tekIter = (*tekFing).begin();

tekIter != (*tekFing).end();

tekIter++)

{

baseIter = (*baseFing).begin();

short prev, next;

prev = next = abs(baseIter->l - tekIter->l);

while(

prev >= next &&

next >= DELTA_L &&

baseIter != (*baseFing).end())

{

prev = next;

baseIter++;

next = abs(baseIter->l - tekIter->l);

}

if(prev >= DELTA_L && prev < next) continue; //нет смысла сравнивать дальше т.к. всегда будет next >= DELTA_L

for(;

baseIter != (*baseFing).end();

baseIter++)

{

int len = abs(tekIter->l - baseIter->l);

if(len >= DELTA_L) break; //нет смысла сравнивать дальше т.к. всегда будет next >= DELTA_L

int delta_a = DELTA_A;

if(

((abs(tekIter->a1 - baseIter->a1)<delta_a)||(abs(tekIter->a1 - baseIter->a1) > 360-delta_a))&&

((abs(tekIter->a2 - baseIter->a2)<delta_a)||(abs(tekIter->a2 - baseIter->a2) > 360-delta_a)))

{

confirmVal++;

surroundDots1->push_back(*baseIter);

surroundDots2->push_back(*tekIter);

break;

}

}

if(confirmVal > needVal)

{

///////////////////////////

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

ret.dots.push_back(TPairAbsDot(baseFing->back().absDot, tekFing->back().absDot));

ret.surdots.push_back(TPairSur(surroundDots1,surroundDots2));

baseFing->clear();

fng.erase(baseFing);

confirmDot++;

break;

}

}

if(confirmVal > needVal){break;}

else{

ret.dots.push_back(TPairAbsDot(baseFing->back().absDot, tekFing->back().absDot));

ret.surdots.push_back(TPairSur(surroundDots1,surroundDots2));

surroundDots1->clear();

surroundDots2->clear();

}

}

}

ret.cDot = confirmDot;

ret.val = 0;

return ret;

}

П.1.3. ТЕКСТ МОДУЛЯ FINGERANALYSERDLG.CPP

// FingerAnalyserDlg.cpp : implementation file

//

#include "stdafx.h"

#include "FingerAnalyser.h"

#include "FingerAnalyserDlg.h"

#include "TAnalysePicture.h"

#include ".\fingeranalyserdlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

CString sav_path, db_file;

TAnalysePicture *picture;

TAbsFing fingA;

TRelFing fingR;

// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog

{

public:

CAboutDlg();

// Dialog Data

enum { IDD = IDD_ABOUTBOX };

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

// Implementation

protected:

DECLARE_MESSAGE_MAP()

};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

END_MESSAGE_MAP()

// CFingerAnalyserDlg dialog

CFingerAnalyserDlg::CFingerAnalyserDlg(CWnd* pParent /*=NULL*/)

: CDialog(CFingerAnalyserDlg::IDD, pParent)

, m_kolDots(0)

, m_workFile(_T(""))

, m_scantime(0)

, m_show_base(FALSE)

, m_mouse_x(0)

, m_mouse_y(0)

{

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

CFingerAnalyserDlg::~CFingerAnalyserDlg()

{

delete(fp);

delete(picture);

if(compareResult)

{

for(list<TCompareFing>::iterator i = compareResult->begin();

i != compareResult->end();

i++)

{

list<TPairSur>::iterator j;

for(j=i->surdots.begin(); j!=i->surdots.end(); j++)

{

j->first->clear(); delete(j->first);

j->second->clear(); delete(j->second);

}

}

compareResult->clear();

delete(compareResult);

compareResult = NULL;

}

}

void CFingerAnalyserDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

DDX_Text(pDX, IDC_SPEC_DOT, m_kolDots);

DDX_Control(pDX, IDC_LOAD_PROGRESS, loadProgress);

DDX_Text(pDX, IDC_WORK_FILE, m_workFile);

DDX_Control(pDX, IDC_LOAD_COMPARE_PROGRESS, compare_progress);

DDX_Text(pDX, IDC_TEMESCAN, m_scantime);

DDX_Check(pDX, IDC_SHOW_BASE, m_show_base);

}

BEGIN_MESSAGE_MAP(CFingerAnalyserDlg, CDialog)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

//}}AFX_MSG_MAP

ON_BN_CLICKED(IDC_OPEN_FILE, OnBnClickedOpenFile)

ON_BN_CLICKED(IDC_EXIT, OnBnClickedExit)

ON_WM_CLOSE()

ON_WM_ACTIVATE()

ON_BN_CLICKED(IDC_ANALYSE, OnBnClickedAnalyse)

ON_BN_CLICKED(IDC_COMPARE, OnBnClickedCompare)

ON_WM_TIMER()

ON_BN_CLICKED(IDC_SAVE_TO_DB, OnBnClickedSaveToDb)

ON_BN_CLICKED(IDC_BUTTON_PREV, OnBnClickedButtonPrev)

ON_BN_CLICKED(IDC_BUTTON_NEXT, OnBnClickedButtonNext)

ON_BN_CLICKED(IDC_SHOW_BASE, OnBnClickedShowBase)

ON_WM_MOUSEMOVE()

ON_WM_LBUTTONDOWN()

END_MESSAGE_MAP()

// CFingerAnalyserDlg message handlers

BOOL CFingerAnalyserDlg::OnInitDialog()

{

CDialog::OnInitDialog();

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != NULL)

{

CString strAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBOX);

if (!strAboutMenu.IsEmpty())

{

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

}

}

// Set the icon for this dialog. The framework does this automatically

// when the application's main window is not a dialog

SetIcon(m_hIcon, TRUE); // Set big icon

SetIcon(m_hIcon, FALSE); // Set small icon

fp = new TFingPicture(this->GetDC());

char fullpath[200];

_fullpath(fullpath, NULL, 200);

sav_path = fullpath;

sav_path += "\\sav\\";

db_file = sav_path + "fingbase.bse";

compareResult = NULL;

return TRUE; // return TRUE unless you set the focus to a control

}

void CFingerAnalyserDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

if ((nID & 0xFFF0) == IDM_ABOUTBOX)

{

CAboutDlg dlgAbout;

dlgAbout.DoModal();

}

else

{

CDialog::OnSysCommand(nID, lParam);

}

}

// If you add a minimize button to your dialog, you will need the code below

// to draw the icon. For MFC applications using the document/view model,

// this is automatically done for you by the framework.

void CFingerAnalyserDlg::OnPaint()

{

CPaintDC dc(this); // device context for painting

if(m_show_base)

{//режим просмотра базы

ShowBase(true, false);

}

else

{//режим просмотра открытого образа

if (picture != NULL)

{

picture->GetPic1()->Show(110, 45);

picture->GetPic2()->Show(545, 45);

}

m_kolDots = (int)fingA.size();

UpdateData(false);

}

CDialog::OnPaint();

}

// The system calls this function to obtain the cursor to display while the user drags

// the minimized window.

HCURSOR CFingerAnalyserDlg::OnQueryDragIcon()

{

return static_cast<HCURSOR>(m_hIcon);

}

void CFingerAnalyserDlg::OnBnClickedOpenFile()

{

char szFilters[]= "Образы (*.bmp)|*.bmp|All Files (*.*)|*.*||";

CFileDialog dlg(TRUE, "bmp", "*.bmp", OFN_FILEMUSTEXIST| OFN_HIDEREADONLY, szFilters, this);

if(dlg.DoModal() != IDOK)

return; //никаких файлов не открыли

if(dlg.GetFileExt().CompareNoCase("bmp"))

return; //открытый файл не имеет расширеня .bmp

CString fileName = dlg.GetFileName();

delete(picture);

picture = new TAnalysePicture(fileName, this->GetDC());

m_workFile = fileName;

if(compareResult)

{

for(list<TCompareFing>::iterator i = compareResult->begin();

i != compareResult->end();

i++)

{

list<TPairSur>::iterator j;

for(j=i->surdots.begin(); j!=i->surdots.end(); j++)

{

j->first->clear();

delete(j->first);

j->second->clear();

delete(j->second);

}

}

compareResult->clear();

}

m_show_base = false;

Invalidate();

}

void CFingerAnalyserDlg::OnBnClickedExit()

{

CDialog::SendMessage(WM_CLOSE);

}

void CFingerAnalyserDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)

{

CDialog::OnActivate(nState, pWndOther, bMinimized);

// pWndOther->SetProperty(

}

void CFingerAnalyserDlg::OnBnClickedAnalyse()

{

if(picture == NULL) return;

LPSYSTEMTIME mTime;

mTime = new SYSTEMTIME;

GetSystemTime(mTime);

long int workTime;

workTime = mTime->wSecond*1000+mTime->wMilliseconds;

fingA = picture->AnalysePicture();

fingA.SaveFing(GetSAV(picture->getPathSrc()));

GetSystemTime(mTime);

workTime = mTime->wSecond*1000+mTime->wMilliseconds - workTime;

workTime = (workTime<0)?60000+workTime:workTime;

delete(mTime);

m_scantime = workTime;

Invalidate();

}

void CFingerAnalyserDlg::OnBnClickedCompare()

{

if(fingA.size() == 0)

{

MessageBox("Отпечаток не обработан", "Ошибка");

return;

}

fingR.Convert(fingA);

if(compareResult)

{

for(list<TCompareFing>::iterator i = compareResult->begin();

i != compareResult->end();

i++)

{

list<TPairSur>::iterator j;

for(j=i->surdots.begin(); j!=i->surdots.end(); j++)

{

j->first->clear(); delete(j->first);

j->second->clear(); delete(j->second);

}

}

compareResult->clear();

delete(compareResult);

compareResult = NULL;

showIter = NULL;

}

compareResult = CompareWithBase();

if(compareResult->size() == 0) return;

CString sOut="";

for(list<TCompareFing>::iterator i = compareResult->begin();

i != compareResult->end();

i++)

{

CString s="";

int mlevel = min(i->nfng,m_kolDots);

int percent;

if(mlevel > 10) mlevel = 10;

if(i->cDot > mlevel) percent = 100;

else percent = (int)(100.0*i->cDot/(double)mlevel + 0.5);

if(percent == 0) continue;

s.Format("%d %d %% %s\n", i->cDot, percent, i->name);

sOut += s;

}

if(sOut.GetLength()==0) sOut = "Ни одного отпечатка не найдено!\n";

CString kol; kol.Format("\n Всего в базе: %d", compareResult->size());

sOut += kol;

PrintReport(picture->getPathSrc(), sOut);

MessageBox(sOut, picture->getPathSrc());

}

void CFingerAnalyserDlg::OnTimer(UINT nIDEvent)

{

Invalidate();

CDialog::OnTimer(nIDEvent);

}

void CFingerAnalyserDlg::OnBnClickedSaveToDb()

{

char szFilters[] = "Образы (*.bmp)|*.bmp|All Files (*.*)|*.*||";

CFileDialog dlg( TRUE, "bmp", "*.bmp",

OFN_FILEMUSTEXIST| OFN_HIDEREADONLY| OFN_ALLOWMULTISELECT,

szFilters, this);

if(dlg.DoModal() == IDOK)

{

listTInfo *fingDB = LoadDB(db_file);

FILE *fbse = fopen(db_file, "wb");

if(fbse == NULL)

{

MessageBox("Невозможно создать базу данных с отпечатками", "Ошибка создания БД", MB_OK);

return;

}

POSITION pos, posStart;

TInfo newFingInDB;

pos = posStart = dlg.GetStartPosition();

int kolFile = 0;

while(pos)

{

dlg.GetNextPathName(pos);

kolFile++;

}

pos = posStart;

loadProgress.SetRange(0, kolFile);

int progressPos = 1;

while(pos)

{

CString fileName = dlg.GetNextPathName(pos).MakeLower();

if(fileName.Find(".bmp") == -1) continue;

TAnalysePicture *loadingPic;

loadingPic = new TAnalysePicture(fileName, this->GetDC());

m_workFile = fileName;

fingA = loadingPic->AnalysePicture();

if(fingA.size() < MIN_SIZE)

{

MessageBox("Отпечаток не пригоден для сохраниения в базу!", fileName);

continue;

}

if(fingA.size() > MAX_SIZE)

{

MessageBox("Отпечаток не пригоден для сохраниения в базу!", fileName);

continue;

}

fingA.SaveFing(GetSAV(fileName));

newFingInDB.src = fileName;

fingDB->remove(newFingInDB);

fingDB->push_back(newFingInDB);

loadProgress.SetPos(progressPos);

progressPos++;

Invalidate();

delete(loadingPic);

}

loadProgress.SetPos(0);

int count = 0;

fwrite((void*)&count, sizeof(count), 1, fbse);

for(list<TInfo>::iterator iter = fingDB->begin(); iter != fingDB->end(); iter++)

{

iter->Printf(fbse);

count++;

}

fseek(fbse, 0, SEEK_SET);

fwrite((void*)&count, sizeof(count), 1, fbse);

fingDB->clear();

delete(fingDB);

fclose(fbse);

}

}

listTInfo *CFingerAnalyserDlg::LoadDB(CString dbFile)

//загрузить точки из БД

{

listTInfo *bse = new listTInfo();

TInfo finf; //данные по отпечатку

FILE *fbse = fopen(dbFile, "rb");

if(fbse == NULL)

{

// MessageBox("Невозможно загрузить базу данных с отпечатками", "Ошибка загрузки БД", MB_OK);

return bse;

}

int count = 0;

fread((void*)&count, sizeof(count), 1, fbse);

for(;count > 0; count--)

{

finf.Scanf(fbse);

bse->push_back(finf);

}

fclose(fbse);

return bse;

}

list<TCompareFing> *CFingerAnalyserDlg::CompareWithBase()

//сравнить точку с точками в БД

{

listTInfo *bse;

list<TCompareFing> *cFng;

cFng = new list<TCompareFing>;

bse = LoadDB(db_file);

if(bse->empty())

{

MessageBox("База данных отпечатков пуста", "Сообщение", MB_OK);

return cFng;

}

TAbsFing aFng;

TRelFing baseFng;

compare_progress.SetRange(0, (short)bse->size());

for(list<TInfo>::iterator ibse = bse->begin();

ibse != bse->end(); ibse++)

{

if(!aFng.LoadFing(GetSAV(ibse->src))) continue;

baseFng.Convert(aFng);

TCompareFing compareRes = fingR.Compare(baseFng);

compareRes.name = ibse->src;

cFng->push_back(compareRes);

compare_progress.SetPos((int)cFng->size());

}

bse->clear();

compare_progress.SetPos(0);

delete(bse);

return cFng;

}

void CFingerAnalyserDlg::OnBnClickedButtonPrev(){ ShowBase(false);}

void CFingerAnalyserDlg::OnBnClickedButtonNext(){ ShowBase(true);}

void CFingerAnalyserDlg::ShowBase(bool key, bool next)

//key - направление перемотки по базе (влево, вправо)

//next - нужно ли переходить к следующему отпечатку

{

if(!compareResult) return;

if(compareResult->size() == 0)

{

MessageBox("База данных отпечатков пуста", "Сообщение", MB_OK);

return;

}

if(showIter == NULL) showIter = compareResult->begin();

else

{

if(next)

if(key)

{

showIter++;

if(showIter == compareResult->end())

showIter = compareResult->begin();

}

else

{

if(showIter == compareResult->begin())

showIter = compareResult->end();

showIter--;

}

}

TFingPicture *pic;

pic = new TFingPicture(this->GetDC());

if(!pic->Load(BLANK)) return;

CPaintDC dc(this); // device context for painting

list<TPairSur>::iterator is = showIter->surdots.begin();

list<TPairAbsDot>::iterator id = showIter->dots.begin();

for(; id != showIter->dots.end(); id++, is++)

{

COLORREF col;

if(is->first->empty()) col = 0xBBBBBB;

else col = (id->first.type)?0xff0000:0x000000;

pic->Line(id->first.coord, id->first.coord, 5, col);

pic->Line(id->first.coord,

CPoint(id->first.coord.x+(int)(10.0*cos(id->first.alpha)),id->first.coord.y-(int)(10.0*sin(id->first.alpha))),

2, col);

if(is->first->empty()) continue; //окружения для этой точки нет

//проверка, что "мышь" находится над точкой

if( abs(mouse_pos.x-id->first.coord.x)<6 && abs(mouse_pos.y-id->first.coord.y)<6 )

{

TFingPicture pic2(this->GetDC());

if(!pic2.Load(BLANK)) return;

pic2.Copy(*picture->GetPic2());

for(listTRelDot::iterator ii = is->first->begin(); ii != is->first->end(); ii++)

{

COLORREF cl = 0x554444;

CPoint cd;

cd.x = (long)(id->first.coord.x - ii->l * cos(ii->a1*M_PI/180.0 - id->first.alpha));

cd.y = (long)(id->first.coord.y - ii->l * sin(ii->a1*M_PI/180.0 - id->first.alpha));

pic->Line(id->first.coord, cd, 1, cl);

}

for(listTRelDot::iterator ii = is->second->begin(); ii != is->second->end(); ii++)

{

COLORREF cl = 0x554444;

CPoint cd;

cd.x = (long)(id->second.coord.x - ii->l * cos(ii->a1*M_PI/180.0 - id->second.alpha));

cd.y = (long)(id->second.coord.y - ii->l * sin(ii->a1*M_PI/180.0 - id->second.alpha));

pic2.Line(id->second.coord, cd, 1, cl);

}

pic2.Show(545, 45);

}

}

if (pic != NULL)

{

pic->Show(110, 45);

m_workFile = showIter->name;

}

UpdateData(false);

delete(pic);

}

void CFingerAnalyserDlg::PrintReport(CString file, CString report)

{

FILE *outf = fopen("report.txt", "a");

CString msg = "\n------ "+file+" ------\n"+report;

fprintf(outf, msg);

fclose(outf);

}

CString CFingerAnalyserDlg::GetSAV(CString srcName)

{

CString fsav = srcName.Left(srcName.GetLength() - 3) + "sav";

while(fsav.Find("\\") != -1){ fsav = fsav.Right(fsav.GetLength() - fsav.Find("\\")-1); }

return sav_path + fsav;

}

void CFingerAnalyserDlg::OnBnClickedShowBase()

{

m_show_base =! m_show_base;

UpdateData(false);

if(m_show_base)

{

ShowBase(true, false);

}

else

{

OnPaint();

}

}

void CFingerAnalyserDlg::OnLButtonDown(UINT nFlags, CPoint point)

{

if(!m_show_base) return;

mouse_pos = point;

mouse_pos.x -= 110;

mouse_pos.y -= 45;

ShowBase(true, false);

CDialog::OnLButtonDown(nFlags, point);

}

П.1.4. ТЕКСТ МОДУЛЯ FINGERANALYSERDLG.H

// FingerAnalyserDlg.h : header file

//

#pragma once

#include "TFingPicture.h"

#include "afxcmn.h"

typedef list<TInfo> listTInfo;

// CFingerAnalyserDlg dialog

class CFingerAnalyserDlg : public CDialog

{

// Construction

public:

CFingerAnalyserDlg(CWnd* pParent = NULL); // standard constructor

~CFingerAnalyserDlg(); // деструктор

// Dialog Data

enum { IDD = IDD_FINGERANALYSER_DIALOG };

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

// Implementation

protected:

HICON m_hIcon;

CDC memDC;

CBitmap bm;

BITMAP bmp;

UINT timer;

TFingPicture *fp;

// Generated message map functions

virtual BOOL OnInitDialog();

afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

afx_msg void OnPaint();

afx_msg HCURSOR OnQueryDragIcon();

DECLARE_MESSAGE_MAP()

public:

afx_msg void OnBnClickedOpenFile();

afx_msg void OnBnClickedExit();

afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);

afx_msg void OnBnClickedAnalyse();

afx_msg void OnBnClickedCompare();

afx_msg void OnTimer(UINT nIDEvent);

afx_msg void OnEnChangeSpecDot();

int m_kolDots;

afx_msg void OnBnClickedSaveToDb();

CProgressCtrl loadProgress;

public:

listTInfo *LoadDB(CString dbFile);

list<TCompareFing> *CompareWithBase();

CString m_workFile;

CProgressCtrl compare_progress;

long m_scantime;

afx_msg void OnBnClickedButtonPrev();

list<TCompareFing> *compareResult;

list<TCompareFing>::iterator showIter;

afx_msg void OnBnClickedButtonNext();

void ShowBase(bool key, bool next = true);

void PrintReport(CString file, CString report);

CString GetSAV(CString srcName); //получение пути к sav файлу

BOOL m_show_base;

afx_msg void OnBnClickedShowBase();

afx_msg void OnMouseMove(UINT nFlags, CPoint point);

CPoint mouse_pos;

int m_mouse_x;

int m_mouse_y;

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

};

П.1.5. ТЕКСТ МОДУЛЯ Resource.h

//{{NO_DEPENDENCIES}}

// Microsoft Visual C++ generated include file.

// Used by FingerAnalyser.rc

//

#define IDM_ABOUTBOX 0x0010

#define IDD_ABOUTBOX 100

#define IDS_ABOUTBOX 101

#define IDD_FINGERANALYSER_DIALOG 102

#define IDR_MAINFRAME 128

#define IDR_TOOLBAR 130

#define IDI_FING_ICON 135

#define IDR_MENU1 138

#define IDC_OPEN_FILE 1000

#define IDC_ANALYSE 1001

#define IDC_COMPARE 1002

#define IDC_EXIT 1003

#define IDC_SAVE_TO_DB 1004

#define IDC_SPEC_DOT 1005

#define IDC_LOAD_PROGRESS 1006

#define IDC_WORK_FILE 1007

#define IDC_LOAD_COMPARE_PROGRESS 1008

#define IDC_TEMESCAN 1009

#define IDC_BUTTON_PREV 1012

#define IDC_BUTTON_NEXT 1013

#define IDC_SHOW_BASE 1014

#define IDC_EDIT1 1015

#define ID_BASE 32771

#define ID_PROPERTY 32772

// Next default values for new objects

//

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NEXT_RESOURCE_VALUE 139

#define _APS_NEXT_COMMAND_VALUE 32774

#define _APS_NEXT_CONTROL_VALUE 1016

#define _APS_NEXT_SYMED_VALUE 101

#endif

#endif

П.1.6. ТЕКСТ МОДУЛЯ FingAnalyser.h

// FingerAnalyser.h : main header file for the PROJECT_NAME application

//

#pragma once

#ifndef __AFXWIN_H__

#error include 'stdafx.h' before including this file for PCH

#endif

#include "resource.h" // main symbols

// CFingerAnalyserApp:

// See FingerAnalyser.cpp for the implementation of this class

//

class CFingerAnalyserApp : public CWinApp

{

public:

CFingerAnalyserApp();

// Overrides

public:

virtual BOOL InitInstance();

// Implementation

DECLARE_MESSAGE_MAP()

};

extern CFingerAnalyserApp theApp;

П.1.7. ТЕКСТ МОДУЛЯ FingAnalyser.cpp

// FingerAnalyser.cpp : Defines the class behaviors for the application.

//

#include "stdafx.h"

#include "FingerAnalyser.h"

#include "FingerAnalyserDlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

// CFingerAnalyserApp

BEGIN_MESSAGE_MAP(CFingerAnalyserApp, CWinApp)

ON_COMMAND(ID_HELP, CWinApp::OnHelp)

END_MESSAGE_MAP()

// CFingerAnalyserApp construction

CFingerAnalyserApp::CFingerAnalyserApp()

{

// TODO: add construction code here,

// Place all significant initialization in InitInstance

}

// The one and only CFingerAnalyserApp object

CFingerAnalyserApp theApp;

// CFingerAnalyserApp initialization

BOOL CFingerAnalyserApp::InitInstance()

{

CWinApp::InitInstance();

// Standard initialization

// If you are not using these features and wish to reduce the size

// of your final executable, you should remove from the following

// the specific initialization routines you do not need

// Change the registry key under which our settings are stored

// TODO: You should modify this string to be something appropriate

// such as the name of your company or organization

SetRegistryKey(_T("Local AppWizard-Generated Applications"));

CFingerAnalyserDlg dlg;

m_pMainWnd = &dlg;

INT_PTR nResponse = dlg.DoModal();

if (nResponse == IDOK)

{

// TODO: Place code here to handle when the dialog is

// dismissed with OK

}

else if (nResponse == IDCANCEL)

{

// TODO: Place code here to handle when the dialog is

// dismissed with Cancel

}

// Since the dialog has been closed, return FALSE so that we exit the

// application, rather than start the application's message pump.

return FALSE;

}

П.1.8 ТЕКСТ МОДУЛЯ TAnalysePicture.h

#pragma once

#include "TFingPicture.h"

//MESSAGEOUT отображать отладочную информацию с помощью popup окон

//#define MESSAGEOUT true

#define MESSAGEOUT false

#define OUT_FILE "fingAnalyserOut.txt" //файл отчет

#define BLANK "blank.bmp" //пустое изображение

///////////////////////////////////////////////////////////////////////////////////

//важные параметры для обхода изображения

#define LEN_S 3 //длина малого вектора (LEN_S точек)

#define LEN_L 4 //длина большого вектора (LEN_L малых векторов)

#define KOL_L 2 //необходимое количество больших векторов

#define KOL_S LEN_L*KOL_L //необходимое количество точек

#define TEST_ALPHA 130.0 //тест на разворот вектора. Указывается угол в градусах

///////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////

// Класс АНАЛИЗА ИЗОБРАЖЕНИЯ

///////////////////////////////////////////////////////////////////////////////////

class TAnalysePicture

{

private:

TFingPicture *pic; //Собственно сама картинка

TFingPicture *tmpPic; //копия картинки

TFingPicture *pic2; //изображение для отображения в окне

int height, width; //высота и ширина изображения

CString srcImg; //путь к изображению

int err; //Код состояния картинки

TInfo info; //сопроводительная информация

private:

int ChangeLine(list<TMapElDot>::iterator _dot, list<TMapElDot> &_map);//Обработка картинки, ее изменение

TAbsFing ReadPic(list<TMapElDot>::iterator _dot); //Нахождение на изображении спец точек

list<TMapElDot> LookPic(); //Сканирование картинки и нахождение линий на ней

inline double GetAlpha(const CPoint A, const CPoint B); //Направлени из точки А в В [-pi,pi)

inline double GetS(CPoint A, CPoint B); //растояние между точками

CPoint FindAcceptDot(CPoint dot, double alpha, bool type); //Поиск продолжения из окончания/раздвоения

bool TestFindDot(int _x, int _y);//тест точки: Разность направлений вперед и назад должно быть меньше 110 градусов

double ChangeAlphaInterval(double _alpha); //Приведение итрервала к [-pi,pi)

int DotsFilter(TAbsFing &_dots);

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

а так же точки слева и справа от которых нет линий*/

bool LeftDot(TAbsFing::iterator &iter);

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

public:

TAnalysePicture(const CString src, CDC *screen);

~TAnalysePicture(void);

int getErr();

CString getErrMsg();

CString getPathSrc(){return srcImg;};

TAbsFing AnalysePicture(); //Обработка загруженного изображения и получение образа

bool Show(int x, int y, int xt=-1, int yt=-1);

TFingPicture *GetPic1();

TFingPicture *GetPic2();

};

П.1.9 ТЕКСТ МОДУЛЯ TAnalysePicture.cpp

#include "StdAfx.h"

#include "TAnalysePicture.h"

TAnalysePicture::TAnalysePicture(const CString src, CDC *screen)

{

pic = new TFingPicture(screen);

err = -1;

if(!pic->Load(src)) err = 0;

pic->Rectangle(CPoint(0, 0), pic->GetSize(), 10);

srcImg = src;

tmpPic = new TFingPicture(screen);

tmpPic->Load(src);

pic2 = new TFingPicture(screen);

pic2->Load(BLANK);

}

TAnalysePicture::~TAnalysePicture(void)

{

delete(tmpPic);

delete(pic2);

delete(pic);

}

//Код ошибки

int TAnalysePicture::getErr()

{

return err;

}

//Сообщение ошибки

CString TAnalysePicture::getErrMsg()

{

CString msg = "";

switch (err)

{

case -1: {msg = "Ошибок при загрузке изображения нет"; break;}

case 0: {msg = "Изображение не загружено"; break;}

case 1: {msg = "Возникла ошибка при загрузке изображения"; break;}

default: {msg = "Нераспознанная ошибка";}

}

return msg;

}

// Обработка загруженного изображения и получение образа

TAbsFing TAnalysePicture::AnalysePicture()

{

TAbsFing ret, ret2;

if(err != -1)

{

if(MESSAGEOUT) MessageBox(NULL, getErrMsg(), "Ошибка", MB_OK);

return ret;

}

int prevCol;

int changeN = 0; //Счетчик произведенных изменений на изображении

list<TMapElDot> map; //Карта точек принадлежащих линиям

list<TMapElDot>::iterator imap; //Итератор для map

map = LookPic(); //сканирование картинки и нахождение линий на ней

do{

changeN = 0;

prevCol = (int)map.size();

imap = map.begin();

do{ //Изображение можно модифицировать

if(imap->pr1) //Линия нуждается в обработке

changeN += ChangeLine(imap, map); //Обработка (преобразование) изображения

imap++; //Переход для обработки следующей линии

}while(imap != map.end()); //Изображение можно модифицировать

}while(prevCol<0.1*map.size()); //Изображение можно модифицировать

map = LookPic(); //сканирование картинки и нахождение линий на ней

imap = map.begin();

do{ //Изображение можно модифицировать

ret.merge(ReadPic(imap));

imap++; //Переход для обработки следующей линии

}while(imap != map.end()); //Изображение можно модифицировать

////////////////////////////////////////////////////////////////////

/////////////////////Фильтрование полученных точек//////////////////

///отсеиваются близкостоящие направленные в противоположные строки//

//////////а так же точки слева и справа от которых нет линий////////

int leftDots = 0; //число отсеянных точек

leftDots = DotsFilter(ret); //Фильтрование полученных точек

////////////////////////////////////////////////////////////////////

ret2.clear();

for(TAbsFing::iterator iter = ret.begin(); iter != ret.end(); iter++)

{

if(!iter->show) continue;

//рисование найденных точек (цвет окончания и раздвоения различный)

COLORREF col = (iter->type)?0xFF0000:0x000000;

pic2->Line(iter->coord, iter->coord, 5, col);

pic2->Line(iter->coord,

CPoint(iter->coord.x+(int)(10.0*cos(iter->alpha)),iter->coord.y-(int)(10.0*sin(iter->alpha))),

2, col);

ret2.push_back(*iter);

}

ret.clear();

return ret2;

}

TAbsFing TAnalysePicture::ReadPic(list<TMapElDot>::iterator _dot)

//Нахождение на изображении спец точек

{

TAbsFing retFing; //Образ отпечатка в абсолютных координатах

int kol = 0; //количество пройденных точек

int vec = 0; //направление поиска очередной точки

int tekS = 0; //Текущее количество коротких векторов

CPoint A, //Начало вектора

B; //Конец вектора

TAbsFing vecDotS; //массив точек для коротких векторов

TAbsFing vecDotL; //массив точек для длинных векторов

TAbsFing historyDotL; //история точек для длинных векторов

TAbsDot _tmpDotFing, bestDot;

TAbsFing::iterator iter;

double alpha; //направление вектора (в радианах)

int stopKol = 2000; //предел шагов

int ret = 0; //счетчик шагов после прохождения начальной точки

bool homeOver = false; //признак окончания обработки

A = _dot->coord; B = _dot->coord;

CPoint olddot, dot = _dot->coord; //Текущая точка на линии

do{

//основной цикл обработки,

//варианты завершения цикла

//продолжается до тех пор, пока вся линия не будет пройдена (нормальный вариант)

//зацикливание (не нормальный вариант, их несколько)

//

olddot = dot;

dot = pic->NextDotCW(dot, vec); //Поиск следующей точки _по часовой_ стрелке

if(dot.x == olddot.x && dot.y == olddot.y)

{//положение точки не изменилось => выход//

CString s;

s.Format("x = %d, y = %d, kol= %d", dot.x, dot.y, kol);

if(MESSAGEOUT)MessageBox(0, "положение точки не изменилось => выход\n" + s, "", MB_OK);

return retFing;

}

kol++; //подсчет пройденных точек

if(kol % LEN_S == 0)

{//появился новый короткий вектор

tekS++;

A = B;

B = dot;

pic2->Line(A,B, 1, 0x999999);

_tmpDotFing.coord = A;

alpha = GetAlpha(A, B); //расчет локального направления между KOL_S пикселями (направление короткого вектора)//

double dAlpha = 0.0; //Разница углов

if(vecDotS.size() > 0) //в списке можно взять предыдущее значение

dAlpha = alpha - vecDotS.begin()->alpha;

/**/ if (abs(dAlpha) >= M_PI) //разница между новым углом и предыдущим не нормальная!

{//необходимо скорректировать текущую alpha

/**/ if (dAlpha < 0.0)

{

while (abs(dAlpha) > M_PI)

{

alpha += 2.0 * M_PI;

dAlpha += 2.0 * M_PI;

}

}else

{

while (dAlpha >= M_PI)

{

alpha -= 2.0 * M_PI;

dAlpha -= 2.0 * M_PI;

}

}

}

_tmpDotFing.alpha = alpha; //запоминание направления из точки А//

vecDotS.push_front(_tmpDotFing);

///////////////////////////////////////////////////////////////////////

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

///////пройдено достаточно точек, чтоб сравнивать длнинные вектора/////

if(vecDotS.size() < KOL_S) continue;

//Вычисление среднего направления LEN_L коротких векторов//

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

double sumAlpha = 0.0;

iter = vecDotS.begin();

vecDotL.clear(); //пересчитаем длинные вектора

for(int i = 0; i < KOL_S; i++)

{

sumAlpha += iter->alpha;

if ((i+1) % LEN_L == 0)

{

_tmpDotFing = *iter;

_tmpDotFing.alpha = sumAlpha / LEN_L;

vecDotL.push_back(_tmpDotFing);

sumAlpha = 0.0;

}

iter++;

}

if (abs(vecDotL.begin()->alpha) > 3*2*M_PI)

{//слишком много оборотов//

CString s;

s.Format("alpha = %.2f", vecDotL.begin()->alpha*180);

if(MESSAGEOUT)MessageBox(0, "слишком много оборотов\n"+s, "", MB_OK);

return retFing;

}

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

dAlpha = vecDotL.begin()->alpha - (++vecDotL.begin())->alpha;

if (abs(dAlpha) > (TEST_ALPHA / 180.0 * M_PI)) //сильный изгиб//

{

if (historyDotL.empty())

{ //сохранение состояния//

bestDot.alpha = 0.0;

}

if (dAlpha > 0) //раздвоение

alpha = (vecDotL.begin()->alpha - M_PI + (++vecDotL.begin())->alpha) / 2.0;

else //окончание

alpha = (vecDotL.begin()->alpha + M_PI + (++vecDotL.begin())->alpha) / 2.0;

_tmpDotFing = vecDotL.front();

_tmpDotFing.alpha = alpha; //направление в СТ (специфичная точка)//

_tmpDotFing.type = dAlpha<0; //тип СТ//

historyDotL.push_front(_tmpDotFing);

if(bestDot.alpha <= abs(dAlpha))

{

bestDot.coord = _tmpDotFing.coord;

bestDot.alpha = abs(dAlpha);

}

}

else //сильный изгиб//

{

if (!historyDotL.empty()) //был _пройден_ сильный изгиб

{

alpha = 0;

for(iter = historyDotL.begin(); iter != historyDotL.end(); iter++)

alpha += iter->alpha;

alpha /= historyDotL.size(); //среднее значение в пройденной СТ

iter = historyDotL.begin();

for(unsigned int i = 0; i<(historyDotL.size()/2); i++) iter++;

//CPoint wdot = iter->coord; //наиболее вероятная точка для СТ

CPoint wdot = bestDot.coord; //наиболее вероятная точка для СТ

//Если раскомментировать эти строки, то исключатся точки имеющие продолжение

//CPoint dotForAccept = FindAcceptDot(wdot, alpha, iter->type);

//if (dotForAccept.x == -1)

{ //точка не имеет продолжения, запомним ее//

_tmpDotFing.alpha = ChangeAlphaInterval(alpha);

_tmpDotFing.coord = wdot;

_tmpDotFing.show = true;

_tmpDotFing.type = historyDotL.begin()->type;

retFing.push_back(_tmpDotFing);

}

historyDotL.clear();

stopKol += (kol*1.5 > stopKol)?1000:0;

}

}

}

if (dot.x == _dot->coord.x && dot.y == _dot->coord.y)

{//вероятно обход линии завершен

if (kol <= 2)

{//Линия подозрительно короткая

CString s;

s.Format("%d", kol);

if(MESSAGEOUT)MessageBox(0, "kol<=2 kol = " + s, "", MB_OK);

return retFing;

}else

{

homeOver = true; //пройти необходимо дальше начала

stopKol = kol + KOL_L*LEN_L*LEN_S;

}

}

if (homeOver) ret++;

}while(ret < (LEN_L*LEN_S*KOL_L) && ret < stopKol && kol <= stopKol);

_dot->pr1 = false;

_dot->pr2 = false;

return retFing;

}

list<TMapElDot> TAnalysePicture::LookPic()

//Попиксельное "пробегание" по картинке и

//запоминание черных точек, после нахождения черной точки

//заливка всей линии в цвет фона (удаление линии с картинки)

{

list<TMapElDot> map;

TMapElDot dot;

tmpPic->Copy(*pic);

for(int j = 0; j < pic->GetSize().y; j++)

for(int i = 0; i < pic->GetSize().x; i++)

{

if(!tmpPic->GetPixel(i,j)) //найден черный пиксель

{

dot.coord.x = i; dot.coord.y = j;

dot.pr1 = dot.pr2 = true;

map.push_back(dot);

tmpPic->FloodFill(i, j, 0xffffff); //удаление линии

}

}

tmpPic->Copy(*pic);

return map;

}

int TAnalysePicture::ChangeLine(list<TMapElDot>::iterator _dot, list<TMapElDot> &_map)


Подобные документы

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.