Смекни!
smekni.com

Система идентификации личности по отпечаткам пальцев Подсистема анализа изображения (стр. 16 из 20)

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] = '&bsol;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&bsol;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&bsol;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.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 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.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);

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