Beispiel #1
0
        internal static DFTWAVES init_dftwaves(List <double> dft_coefs, int nwaves, int blocksize)
        {
            DFTWAVES dftwaves = new DFTWAVES();
            DFTWAVE  dftwaveResult = new DFTWAVE();
            double   pi_factor, freq, x;

            dftwaves.nwaves  = nwaves;
            dftwaves.wavelen = blocksize;
            dftwaves.waves   = new List <DFTWAVE>(); //count = nwaves
            pi_factor        = 2.0 * M_PI / (double)blocksize;

            for (int i = 0; i < nwaves; ++i)
            {
                dftwaveResult     = new DFTWAVE();
                dftwaveResult.sin = new List <double>(); // count = blocksize
                dftwaveResult.cos = new List <double>(); // count = blocksize
                freq = pi_factor * dft_coefs[i];

                for (int j = 0; j < blocksize; ++j)
                {
                    x = freq * j;
                    dftwaveResult.cos.Add(Math.Cos(x));
                    dftwaveResult.sin.Add(Math.Sin(x));
                }

                dftwaves.waves.Add(dftwaveResult);
            }

            return(dftwaves);
        }
        internal static DFTWAVES init_dftwaves(List<double> dft_coefs, int nwaves, int blocksize)
        {
            DFTWAVES dftwaves = new DFTWAVES();
            DFTWAVE dftwaveResult = new DFTWAVE();
            double pi_factor, freq, x;

            dftwaves.nwaves = nwaves;
            dftwaves.wavelen = blocksize;
            dftwaves.waves = new List<DFTWAVE>(); //count = nwaves
            pi_factor = 2.0 * M_PI / (double)blocksize;

            for (int i = 0; i < nwaves; ++i)
            {
                dftwaveResult = new DFTWAVE();
                dftwaveResult.sin = new List<double>(); // count = blocksize
                dftwaveResult.cos = new List<double>(); // count = blocksize
                freq = pi_factor * dft_coefs[i];

                for (int j = 0; j < blocksize; ++j)
                {
                    x = freq * j;
                    dftwaveResult.cos.Add(Math.Cos(x));
                    dftwaveResult.sin.Add(Math.Sin(x));
                }

                dftwaves.waves.Add(dftwaveResult);
            }

            return dftwaves;
        }
Beispiel #3
0
        internal static int lfs_detect_minutiae_V2(ref int[,] odmap, ref int[,] olcmap, ref int[,] olfmap,
                                                   ref int[,] ohcmap, ref int[,] obdata, Bitmap idata, int iw, int ih, ref int mw, ref int mh, string name)
        {
            int[,] pdata = new int[iw, ih];
            int[,] bdata = new int[iw, ih];
            DIR2RAD  dir2rad     = new DIR2RAD();
            DFTWAVES dftwaves    = new DFTWAVES();
            ROTGRIDS dftgrids    = new ROTGRIDS();
            ROTGRIDS dirbingrids = new ROTGRIDS();

            int[,] direction_map    = new int[iw, ih];
            int[,] low_contrast_map = new int[iw, ih];
            int[,] low_flow_map     = new int[iw, ih];
            int[,] high_curve_map   = new int[iw, ih];
            int maxpad = 0;

            int pw = 0, ph = 0;

            // initialization
            maxpad = get_max_padding_V2(lfsparms.windowsize, lfsparms.windowoffset,
                                        lfsparms.dirbin_grid_w, lfsparms.dirbin_grid_h);
            dir2rad  = init_dir2rad(lfsparms.num_directions);
            dftwaves = init_dftwaves(dft_coefs, lfsparms.num_dft_waves, lfsparms.windowsize);
            dftgrids = init_rotgrids(iw, ih, maxpad, lfsparms.start_dir_angle,
                                     lfsparms.num_directions, lfsparms.windowsize, lfsparms.windowsize, RELATIVE2ORIGIN);

            if (maxpad > 0)
            {
                // печать
                pdata = pad_uchar_image(ref pw, ref ph, idata, iw, ih, maxpad, lfsparms.pad_value);
                // PrintMap(pdata, "pdata");
            }
            else
            {
                for (int i = 0; i < iw; i++)
                {
                    for (int j = 0; j < ih; j++)
                    {
                        pdata[i, j] = idata.GetPixel(i, j).R;
                    }
                }

                pw = iw;
                ph = ih;
            }

            gen_image_maps(ref direction_map, ref low_contrast_map, ref low_flow_map, ref high_curve_map,
                           ref mw, ref mh, pdata, pw, ph, dir2rad, dftwaves, dftgrids, name);

            /* Assign results to output pointers. */
            odmap  = direction_map;
            olcmap = low_contrast_map;
            olfmap = low_flow_map;
            ohcmap = high_curve_map;
            obdata = bdata;

            return(0);
        }
    internal static int lfs_detect_minutiae_V2(ref int[,] odmap, ref int[,] olcmap, ref int[,] olfmap,
        ref int[,] ohcmap, ref int[,] obdata, Bitmap idata, int iw, int ih, ref int mw, ref int mh, string name)
    {
      int[,] pdata = new int[iw, ih];
      int[,] bdata = new int[iw, ih];
      DIR2RAD dir2rad = new DIR2RAD();
      DFTWAVES dftwaves = new DFTWAVES();
      ROTGRIDS dftgrids = new ROTGRIDS();
      ROTGRIDS dirbingrids = new ROTGRIDS();
      int[,] direction_map = new int[iw, ih];
      int[,] low_contrast_map = new int[iw, ih];
      int[,] low_flow_map = new int[iw, ih];
      int[,] high_curve_map = new int[iw, ih];
      int maxpad = 0;

      int pw = 0, ph = 0;

      // initialization
      maxpad = get_max_padding_V2(lfsparms.windowsize, lfsparms.windowoffset,
          lfsparms.dirbin_grid_w, lfsparms.dirbin_grid_h);
      dir2rad = init_dir2rad(lfsparms.num_directions);
      dftwaves = init_dftwaves(dft_coefs, lfsparms.num_dft_waves, lfsparms.windowsize);
      dftgrids = init_rotgrids(iw, ih, maxpad, lfsparms.start_dir_angle,
          lfsparms.num_directions, lfsparms.windowsize, lfsparms.windowsize, RELATIVE2ORIGIN);

      if (maxpad > 0)
      {
        // печать
        pdata = pad_uchar_image(ref pw, ref ph, idata, iw, ih, maxpad, lfsparms.pad_value);
        // PrintMap(pdata, "pdata");
      }
      else
      {
        for (int i = 0; i < iw; i++)
        {
          for (int j = 0; j < ih; j++)
          {
            pdata[i, j] = idata.GetPixel(i, j).R;
          }
        }

        pw = iw;
        ph = ih;
      }

      gen_image_maps(ref direction_map, ref low_contrast_map, ref low_flow_map, ref high_curve_map,
          ref mw, ref mh, pdata, pw, ph, dir2rad, dftwaves, dftgrids, name);

      /* Assign results to output pointers. */
      odmap = direction_map;
      olcmap = low_contrast_map;
      olfmap = low_flow_map;
      ohcmap = high_curve_map;
      obdata = bdata;

      return (0);
    }
Beispiel #5
0
    /// <summary>
    /// Проводит DFT анализ для блока.
    /// Блок отбирается по ряду направлений и по нескольким видам сигнала (волн)
    /// различной частоты, применённой для каждого направления.
    /// Для каждого направления пиксели суммируются по строкам и получается 
    /// вектор сумм. Каждый DFT вид сигнала затем применяется индивидуально этому вектору.
    /// Значение мощности DFT вычисляется для каждого типа сигнала.
    /// (frequency) на каждом направлении блока.
    /// Более того итоговый результат - вектор N сигналов * M направлений
    /// Используется для определения доминирующего направления.
    /// </summary>
    /// <param name="powers"></param>
    /// <param name="pdata"></param>
    /// <param name="blkoffset"></param>
    /// <param name="blkoffsetX"></param>
    /// <param name="blkoffsetY"></param>
    /// <param name="pw"></param>
    /// <param name="ph"></param>
    /// <param name="dftwaves"></param>
    /// <param name="dftgrids"></param>
    internal static void dft_dir_powers(ref double[,] powers, ref int[,] pdata,
                int blkoffset, int blkoffsetX, int blkoffsetY, int pw, int ph, DFTWAVES dftwaves, ROTGRIDS dftgrids)
    {
      if (dftgrids.grid_w != dftgrids.grid_h)
      {
        throw new Exception("ERROR : dft_dir_powers : DFT grids must be square\n");
      }

      int[] rowsums = new int[dftgrids.grid_w];

      // для кажого направления
      for (int dir = 0; dir < dftgrids.ngrids; dir++)
      {
        sum_rot_block_rows(ref rowsums, pdata, blkoffsetX, blkoffsetY, dftgrids.grids[dir], dftgrids.grid_w);

        // для каждого варианта сигнала\волны
        for (int w = 0; w < dftwaves.nwaves; w++)
        {
          powers[w, dir] = dft_power(rowsums, dftwaves.waves[w], dftwaves.wavelen);
        }
      }
    }
    /// <summary>
    /// Вычисляем карты для изображения (для Version 2 of the NIST LFS System)
    /// карта направлений (Direction Map) - матрица, целые значения, доминирующее направление
    /// карта контрастов (Low Contrast Map) - матрица, помечены блоки низкого контраста
    /// карта потоков (Low Flow Map) - нет выделенного направления
    /// карта кривизны (High Curve Map) - блоки высокой кривизны
    /// Изображение: произвольное, не квадратное
    /// </summary>
    /// <param name="odmap">карта направлений</param>
    /// <param name="olcmap">карта контраста</param>
    /// <param name="olfmap">карта потоков</param>
    /// <param name="ohcmap">карта кривизны</param>
    /// <param name="omw"> количество блоков по горизонтали</param>
    /// <param name="omh">количество блоков по вертикали</param>
    /// <param name="pdata">padded входное изображение</param>
    /// <param name="pw">padded ширина</param>
    /// <param name="ph">padded высота</param>
    /// <param name="dir2rad">Поисковая таблица преобразования целых направлений</param>
    /// <param name="dftwaves">структура для DFT сигналов (wave forms)</param>
    /// <param name="dftgrids">структура смещений для повёрнутых пикселей окна\грида  (rotated pixel grid offsets)</param>
    internal static void gen_image_maps(ref int[,] odmap, ref int[,] olcmap, ref int[,] olfmap, ref int[,] ohcmap,
       ref int omw, ref int omh, int[,] pdata, int pw, int ph,
       DIR2RAD dir2rad, DFTWAVES dftwaves, ROTGRIDS dftgrids, string name)
    {
      int[,] direction_map = new int[omw, omh];
      int[,] low_contrast_map = new int[omw, omh];
      int[,] low_flow_map = new int[omw, omh];
      int mw = 0, mh = 0;

      if (dftgrids.grid_w != dftgrids.grid_h)
      {
        throw new Exception("ERROR : gen_image_maps : DFT grids must be square\n");
      }

      int iw = pw - (dftgrids.pad << 1);
      int ih = ph - (dftgrids.pad << 1);
      // int blkoffsCount = ((int)Math.Ceiling(iw / (double)lfsparms.blocksize)) *
      //                    (int)Math.Ceiling(ih / (double)lfsparms.blocksize);

      // blkoffsCount = blkoffs.GetLength(0) * blkoffs.GetLength(1)  - проверено
      // считаем смещения для блоков
      // предполагая, что у нас +12 пикселей со всех сторон изображения со значениями 128
      // чтобы нормально считать в окнах
      int[,] blkoffs = block_offsets(ref mw, ref mh, iw, ih, dftgrids.pad, lfsparms.blocksize);

      //  PrintMap(blkoffs, "blkoffs");

      gen_initial_maps(ref direction_map, ref low_contrast_map, ref low_flow_map,
          blkoffs, mw, mh, ref pdata, pw, ph, dftwaves, dftgrids);

      // печать
      //  PrintMap(direction_map, "direction_map");
      //  PrintMap(low_contrast_map, "low_contrast_map");
      //  PrintMap(low_flow_map, "low_flow_map");

      // direction_map не меняется, также low_flow = 0
      // но low_contrast = 1

      morph_TF_map(ref low_flow_map, mw, mh);
      remove_incon_dirs(ref direction_map, mw, mh, dir2rad);
      smooth_direction_map(ref direction_map, ref low_contrast_map, mw, mh, dir2rad);
      interpolate_direction_map(ref direction_map, ref low_contrast_map, mw, mh);
      remove_incon_dirs(ref direction_map, mw, mh, dir2rad);
      smooth_direction_map(ref direction_map, ref low_contrast_map, mw, mh, dir2rad);
      set_margin_blocks(ref direction_map, mw, mh, INVALID_DIR);

      int[,] high_curve_map = gen_high_curve_map(ref direction_map, mw, mh);

      odmap = direction_map;
      olcmap = low_contrast_map;
      olfmap = low_flow_map;
      ohcmap = high_curve_map;
      omw = mw;
      omh = mh;

      // печать
      //PrintMap(direction_map, name + "_direction_map");
      //PrintMap(low_contrast_map, name + "_low_contrast_map");
      //PrintMap(low_flow_map, name + "_low_flow_map");
      //PrintMap(high_curve_map, name + "_high_curve_map");
    }
    /// <summary>
    /// Создаёт начальную карту направлений (Direction Map)
    /// Важно, чтобы были те самые padding - чтобы не вылезти за границы
    /// Странные направления сгладятся и уйдут после основанного на DFT анализа
    /// Валидные значения >=0, невалидные -1
    /// Также возвращаются две карты: 
    /// карта контрастов (Low Contrast Map)
    ///  - помечает блоки с низким контрастом (у них невалидное значение - направление)
    /// карта потоков(Low Flow Map)
    /// - помечает блоки, в которых DFT анализ не нашёл направления (также невалидное направление)
    /// </summary>
    /// <param name="odmap">карта направлений</param>
    /// <param name="olcmap">карта контрастов</param>
    /// <param name="olfmap">карта потоков</param>
    /// <param name="blkoffs">смещения блоков</param>
    /// <param name="mw">количество блоков по горизонтали в padded изображении</param>
    /// <param name="mh">количество блоков по вертикали в padded изображении</param>
    /// <param name="pdata">padded входное изображение</param>
    /// <param name="pw">ширина padded изображения</param>
    /// <param name="ph">высота padded изображения</param>
    /// <param name="dftwaves">структура для DFT сигналов (wave forms)</param>
    /// <param name="dftgrids">структура смещений для повёрнутых пикселей окна\грида (rotated pixel grid offsets)</param>
    internal static void gen_initial_maps(ref int[,] odmap, ref int[,] olcmap, ref int[,] olfmap,
        int[,] blkoffs, int mw, int mh, ref int[,] pdata, int pw, int ph, DFTWAVES dftwaves, ROTGRIDS dftgrids)
    {
      int nstats = dftwaves.nwaves - 1;
      int[,] direction_map = new int[mw, mh];
      int[,] low_contrast_map = new int[mw, mh];
      int[,] low_flow_map = new int[mw, mh];

      double[,] powers = new double[dftwaves.nwaves, dftgrids.ngrids];

      int[] wis = new int[nstats];
      double[] powmaxs = new double[nstats];
      int[] powmax_dirs = new int[nstats];
      double[] pownorms = new double[nstats];

      int xminlimit = dftgrids.pad;
      int xmaxlimit = pw - dftgrids.pad - lfsparms.windowsize - 1;
      int yminlimit = dftgrids.pad;
      int ymaxlimit = ph - dftgrids.pad - lfsparms.windowsize - 1;

      int win_x, win_y, low_contrast_offset;
      int blkdir;
      int dft_offset;

      for (int jndex = 0; jndex < mh; jndex++)
      {
        for (int index = 0; index < mw; index++)
        {
          // инициализируем карты
          // direction_map    -1
          // low_contrast_map  0
          // low_flow_map      0
          direction_map[index, jndex] = INVALID_DIR;
          low_contrast_map[index, jndex] = 0;
          low_flow_map[index, jndex] = 0;
        }
      }

      for (int jndex = 0; jndex < mh; jndex++)
      {
        for (int index = 0; index < mw; index++)
        {
          // dft_offset = blkoffs[bi] - (lfsparms->windowoffset * pw) - lfsparms->windowoffset;
          dft_offset = blkoffs[index, jndex] - (lfsparms.windowoffset * pw) - lfsparms.windowoffset;
          win_x = dft_offset % pw;
          win_y = (int)(dft_offset / pw);

          // проверка на попадание в padding (т.е. рамку)
          win_x = Max(xminlimit, win_x);
          win_x = Min(xmaxlimit, win_x);
          win_y = Max(yminlimit, win_y);
          win_y = Min(ymaxlimit, win_y);
          low_contrast_offset = (win_y * pw) + win_x; // просто передаём координаты

          if (low_contrast_block(low_contrast_offset, win_x, win_y, lfsparms.windowsize, pdata, pw, ph))
          {
            /* block is low contrast ... */
            low_contrast_map[index, jndex] = TRUE;
            continue;
          }

          //  вычислить dft веса // blkoffs[bi] ? low_contrast_offset, win_x, win_y
          dft_dir_powers(ref powers, ref pdata, low_contrast_offset, win_x, win_y, pw, ph, dftwaves, dftgrids);

          // вычислить статистики для dft весов (?)
          dft_power_stats(ref wis, ref powmaxs, ref powmax_dirs, ref pownorms, powers,
              1, dftwaves.nwaves, dftgrids.ngrids);

          // Проведение _первичного_ теста для определения направления
          blkdir = primary_dir_test(ref powers, wis, powmaxs, powmax_dirs, pownorms, nstats);

          if (blkdir != INVALID_DIR)
          {
            direction_map[index, jndex] = blkdir;
            continue;
          }

          // Проведение _вторичного_ теста для определения направления (вилка)
          blkdir = secondary_fork_test(ref powers, wis, powmaxs, powmax_dirs, pownorms, nstats);

          if (blkdir != INVALID_DIR)
          {
            direction_map[index, jndex] = blkdir;
            continue;
          }

          low_flow_map[index, jndex] = TRUE;
        }
      }

      odmap = direction_map;
      olcmap = low_contrast_map;
      olfmap = low_flow_map;
    }
Beispiel #8
0
        /// <summary>
        /// Проводит DFT анализ для блока.
        /// Блок отбирается по ряду направлений и по нескольким видам сигнала (волн)
        /// различной частоты, применённой для каждого направления.
        /// Для каждого направления пиксели суммируются по строкам и получается
        /// вектор сумм. Каждый DFT вид сигнала затем применяется индивидуально этому вектору.
        /// Значение мощности DFT вычисляется для каждого типа сигнала.
        /// (frequency) на каждом направлении блока.
        /// Более того итоговый результат - вектор N сигналов * M направлений
        /// Используется для определения доминирующего направления.
        /// </summary>
        /// <param name="powers"></param>
        /// <param name="pdata"></param>
        /// <param name="blkoffset"></param>
        /// <param name="blkoffsetX"></param>
        /// <param name="blkoffsetY"></param>
        /// <param name="pw"></param>
        /// <param name="ph"></param>
        /// <param name="dftwaves"></param>
        /// <param name="dftgrids"></param>
        internal static void dft_dir_powers(ref double[,] powers, ref int[,] pdata,
                                            int blkoffset, int blkoffsetX, int blkoffsetY, int pw, int ph, DFTWAVES dftwaves, ROTGRIDS dftgrids)
        {
            if (dftgrids.grid_w != dftgrids.grid_h)
            {
                throw new Exception("ERROR : dft_dir_powers : DFT grids must be square\n");
            }

            int[] rowsums = new int[dftgrids.grid_w];

            // для кажого направления
            for (int dir = 0; dir < dftgrids.ngrids; dir++)
            {
                sum_rot_block_rows(ref rowsums, pdata, blkoffsetX, blkoffsetY, dftgrids.grids[dir], dftgrids.grid_w);

                // для каждого варианта сигнала\волны
                for (int w = 0; w < dftwaves.nwaves; w++)
                {
                    powers[w, dir] = dft_power(rowsums, dftwaves.waves[w], dftwaves.wavelen);
                }
            }
        }