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

//Обработка картинки, ее изменение

//Обработка линии на которую указывает 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;

Страницы: 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, 30



2012 © Все права защищены
При использовании материалов активная ссылка на источник обязательна.