Example #1
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);
    }
Example #3
0
        internal static int[,] binarize_image_V2(ref int bw, ref int bh,
                         int[,] pdata, int pw, int ph, int[,] direction_map, int mw, int mh,
                          int blocksize, ROTGRIDS dirbingrids)
        {
            int bx, by, mapval;

            bw = pw - (dirbingrids.pad << 1);
            bh = ph - (dirbingrids.pad << 1);

            int[,] bdata = new int[bw, bh];
            int bptrX = 0, bptrY = 0; //bdata
            int sptrX = dirbingrids.pad, sptrY = dirbingrids.pad; // pdata
            int pptrX = 0, pptrY = 0; //pdata

            for (int iy = 0; iy < bh; iy++)
            {
                /* Set pixel pointer to start of next row in grid. */
                pptrX = sptrX;
                pptrY = sptrY;

                for (int ix = 0; ix < bw; ix++)
                {
                    /* Compute which block the current pixel is in. */
                    bx = ix / blocksize;
                    by = iy / blocksize;
                    /* Get corresponding value in Direction Map. */
                    mapval = direction_map[bx, by];
                    /* If current block has has INVALID direction ... */
                    if (mapval == INVALID_DIR)
                    {
                        /* Set binary pixel to white (255). */
                        bdata[bptrX, bptrY] = WHITE_PIXEL;
                    }
                    /* Otherwise, if block has a valid direction ... */
                    else
                    {
                        /*if(mapval >= 0)*/
                        /* Use directional binarization based on block's direction. */
                        bdata[bptrX, bptrY] = dirbinarize(pdata, pptrX, pptrY, mapval, dirbingrids);
                    }

                    /* Bump input and output pixel pointers. */
                    // IncrementPointer(ref pptrX, ref pptrY, pdata.GetLength(0), pdata.GetLength(1), 1);
                    pptrX++;
                    IncrementPointer(ref bptrX, ref bptrY, bdata.GetLength(0), bdata.GetLength(1), 1);
                }
                /* Bump pointer to the next row in padded input image. */
                sptrY++;
            }

            return bdata;
        }
Example #4
0
        internal static int[,] binarize_image_V2(ref int bw, ref int bh,
                                                 int[,] pdata, int pw, int ph, int[,] direction_map, int mw, int mh,
                                                 int blocksize, ROTGRIDS dirbingrids)
        {
            int bx, by, mapval;

            bw = pw - (dirbingrids.pad << 1);
            bh = ph - (dirbingrids.pad << 1);

            int[,] bdata = new int[bw, bh];
            int bptrX = 0, bptrY = 0;                             //bdata
            int sptrX = dirbingrids.pad, sptrY = dirbingrids.pad; // pdata
            int pptrX = 0, pptrY = 0;                             //pdata

            for (int iy = 0; iy < bh; iy++)
            {
                /* Set pixel pointer to start of next row in grid. */
                pptrX = sptrX;
                pptrY = sptrY;

                for (int ix = 0; ix < bw; ix++)
                {
                    /* Compute which block the current pixel is in. */
                    bx = ix / blocksize;
                    by = iy / blocksize;
                    /* Get corresponding value in Direction Map. */
                    mapval = direction_map[bx, by];
                    /* If current block has has INVALID direction ... */
                    if (mapval == INVALID_DIR)
                    {
                        /* Set binary pixel to white (255). */
                        bdata[bptrX, bptrY] = WHITE_PIXEL;
                    }
                    /* Otherwise, if block has a valid direction ... */
                    else
                    {
                        /*if(mapval >= 0)*/
                        /* Use directional binarization based on block's direction. */
                        bdata[bptrX, bptrY] = dirbinarize(pdata, pptrX, pptrY, mapval, dirbingrids);
                    }

                    /* Bump input and output pixel pointers. */
                    // IncrementPointer(ref pptrX, ref pptrY, pdata.GetLength(0), pdata.GetLength(1), 1);
                    pptrX++;
                    IncrementPointer(ref bptrX, ref bptrY, bdata.GetLength(0), bdata.GetLength(1), 1);
                }
                /* Bump pointer to the next row in padded input image. */
                sptrY++;
            }

            return(bdata);
        }
Example #5
0
        internal static int dirbinarize(int[,] pdata, int pptrX, int pptrY, int idir, ROTGRIDS dirbingrids)
        {
            int gx, gy;
            int rsum, csum = 0;

            /* Assign nickname pointer. */
            List<int> grid = dirbingrids.grids[idir];

            /* Calculate center (0-oriented) row in grid. */
            double dcy = (dirbingrids.grid_h - 1) / (double)2.0;

            /* Need to truncate precision so that answers are consistent */
            /* on different computer architectures when rounding doubles. */
            dcy = trunc_dbl_precision(dcy, TRUNC_SCALE);

            int cy = Sround(dcy);

            /* Initialize grid's pixel offset index to zero. */
            int gi = 0;
            /* Initialize grid's pixel accumulator to zero */
            int gsum = 0;

            /* Foreach row in grid ... */
            for (gy = 0; gy < dirbingrids.grid_h; gy++)
            {
                /* Initialize row pixel sum to zero. */
                rsum = 0;
                /* Foreach column in grid ... */
                for (gx = 0; gx < dirbingrids.grid_w; gx++)
                {
                    /* Accumulate next pixel along rotated row in grid. */

                    //rsum += *(pptr+grid[gi]);
                    rsum += GetValueOfArray(pdata, pptrX, pptrY, grid[gi]);

                    /* Bump grid's pixel offset index. */
                    gi++;
                }
                /* Accumulate row sum into grid pixel sum. */
                gsum += rsum;
                /* If current row is center row, then save row sum separately. */
                if (gy == cy)
                {
                    csum = rsum;
                }
            }

            /* If the center row sum treated as an average is less than the */
            /* total pixel sum in the rotated grid ...                      */
            return csum * dirbingrids.grid_h < gsum ? BLACK_PIXEL : WHITE_PIXEL;
        }
Example #6
0
        internal static int[,] binarize_V2(int[,] pdata, int pw, int ph, int[,] direction_map, int mw, int mh, ROTGRIDS dirbingrids)
        {
            int[,] bdata = new int[pdata.GetLength(0), pdata.GetLength(1)];
            int bw = 0, bh = 0;

            /* 1. Binarize the padded input image using directional block info. */

            bdata = binarize_image_V2(ref bw, ref bh, pdata, pw, ph, direction_map, mw, mh, lfsparms.blocksize, dirbingrids);

            /* 2. Fill black and white holes in binary image. */
            /* LFS scans the binary image, filling holes, 3 times. */
            for (int i = 0; i < lfsparms.num_fill_holes; i++)
            {
                fill_holes(ref bdata, bw, bh);
            }

            return bdata;
        }
Example #7
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);
        }
      }
    }
Example #8
0
    /// <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");
    }
Example #9
0
    /// <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;
    }
Example #10
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);
                }
            }
        }
Example #11
0
        internal static int dirbinarize(int[,] pdata, int pptrX, int pptrY, int idir, ROTGRIDS dirbingrids)
        {
            int gx, gy;
            int rsum, csum = 0;

            /* Assign nickname pointer. */
            List <int> grid = dirbingrids.grids[idir];

            /* Calculate center (0-oriented) row in grid. */
            double dcy = (dirbingrids.grid_h - 1) / (double)2.0;

            /* Need to truncate precision so that answers are consistent */
            /* on different computer architectures when rounding doubles. */
            dcy = trunc_dbl_precision(dcy, TRUNC_SCALE);

            int cy = Sround(dcy);

            /* Initialize grid's pixel offset index to zero. */
            int gi = 0;
            /* Initialize grid's pixel accumulator to zero */
            int gsum = 0;

            /* Foreach row in grid ... */
            for (gy = 0; gy < dirbingrids.grid_h; gy++)
            {
                /* Initialize row pixel sum to zero. */
                rsum = 0;
                /* Foreach column in grid ... */
                for (gx = 0; gx < dirbingrids.grid_w; gx++)
                {
                    /* Accumulate next pixel along rotated row in grid. */

                    //rsum += *(pptr+grid[gi]);
                    rsum += GetValueOfArray(pdata, pptrX, pptrY, grid[gi]);

                    /* Bump grid's pixel offset index. */
                    gi++;
                }
                /* Accumulate row sum into grid pixel sum. */
                gsum += rsum;
                /* If current row is center row, then save row sum separately. */
                if (gy == cy)
                {
                    csum = rsum;
                }
            }

            /* If the center row sum treated as an average is less than the */
            /* total pixel sum in the rotated grid ...                      */
            return(csum * dirbingrids.grid_h < gsum ? BLACK_PIXEL : WHITE_PIXEL);
        }
Example #12
0
        internal static int[,] binarize_V2(int[,] pdata, int pw, int ph, int[,] direction_map, int mw, int mh, ROTGRIDS dirbingrids)
        {
            int[,] bdata = new int[pdata.GetLength(0), pdata.GetLength(1)];
            int bw = 0, bh = 0;

            /* 1. Binarize the padded input image using directional block info. */

            bdata = binarize_image_V2(ref bw, ref bh, pdata, pw, ph, direction_map, mw, mh, lfsparms.blocksize, dirbingrids);

            /* 2. Fill black and white holes in binary image. */
            /* LFS scans the binary image, filling holes, 3 times. */
            for (int i = 0; i < lfsparms.num_fill_holes; i++)
            {
                fill_holes(ref bdata, bw, bh);
            }

            return(bdata);
        }