{
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)
// 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; //сопроводительная информация
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()); //Изображение можно модифицировать
ret.merge(ReadPic(imap));
////////////////////////////////////////////////////////////////////
/////////////////////Фильтрование полученных точек//////////////////
///отсеиваются близкостоящие направленные в противоположные строки//
//////////а так же точки слева и справа от которых нет линий////////
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; //Текущая точка на линии
//основной цикл обработки,
//варианты завершения цикла
//продолжается до тех пор, пока вся линия не будет пройдена (нормальный вариант)
//зацикливание (не нормальный вариант, их несколько)
//
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)
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29