Смекни!
smekni.com

Система идентификации личности по отпечаткам пальцев (стр. 19 из 21)

}

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 вероятное направление поиска

{

inti = 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 вероятное направление поиска

{

inti = 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);

- среда для разработки приложений MicrosoftVisualStudioC++ 2003.

Интерфейс программы представлен на рис. П.2.1.

Интерфейс программы FingerAnalyser

Рис. П.2.1

На форме программы в визуальном виде представляется, после открытия через пункт «Открыть», исходное изображение, после нажатия на кнопку «Анализ», скорректированное изображение и визуальное представление структурного вида отпечатка. После чего можно нажатием на кнопку «Сравнить» отыскать в базе схожие отпечатки.

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