Exemplo n.º 1
0
ho_bitmap *
ho_bitmap_dilation_n (const ho_bitmap * m, const unsigned char n)
{
  ho_bitmap *m_out;
  int x, y;
  unsigned char sum;

  if (!m)
    return NULL;
  
  /* 
   * allocate memory 
   */
  m_out = ho_bitmap_new (m->width, m->height);
  if (!m_out)
    return NULL;
  m_out->x = m->x;
  m_out->y = m->y;

  m_out->type = m->type;
  m_out->font_height = m->font_height;
  m_out->font_width = m->font_width;
  m_out->font_spacing = m->font_spacing;
  m_out->line_spacing = m->line_spacing;
  m_out->avg_line_fill = m->avg_line_fill;
  m_out->com_line_fill = m->com_line_fill;
  m_out->nikud = m->nikud;

  /* 
   * do dilation 
   */
  for (x = 1; x < m->width - 1; x++)
    for (y = 1; y < m->height - 1; y++)
    {
      /* 
       * if white pixel 
       */
      if (!ho_bitmap_get (m, x, y))
      {
        sum = ho_bitmap_get (m, x - 1, y - 1) +
          ho_bitmap_get (m, x - 1, y) +
          ho_bitmap_get (m, x - 1, y + 1) +
          ho_bitmap_get (m, x, y - 1) +
          ho_bitmap_get (m, x, y + 1) +
          ho_bitmap_get (m, x + 1, y - 1) +
          ho_bitmap_get (m, x + 1, y) + ho_bitmap_get (m, x + 1, y + 1);
        if (sum >= n)
          ho_bitmap_set (m_out, x, y);
      }
      else
        ho_bitmap_set (m_out, x, y);
    }

  return m_out;
}
Exemplo n.º 2
0
ho_bitmap *
ho_bitmap_set_height_from_bottom (const ho_bitmap * m, const int height,
  const int top, const int bottom)
{
  ho_bitmap *m_out;
  int x, y, locale_top, locale_bottom, locale_height;

  /* 
   * allocate memory 
   */
  m_out = ho_bitmap_new (m->width, m->height);
  if (!m_out)
    return NULL;

  m_out->x = m->x;
  m_out->y = m->y;

  m_out->type = m->type;
  m_out->font_height = m->font_height;
  m_out->font_width = m->font_width;
  m_out->font_spacing = m->font_spacing;
  m_out->line_spacing = m->line_spacing;
  m_out->avg_line_fill = m->avg_line_fill;
  m_out->com_line_fill = m->com_line_fill;
  m_out->nikud = m->nikud;

  /* 
   * do max_height 
   */
  for (x = 0; x < m->width; x++)
    for (y = m->height - 1; y >= 0; y--)
    {
      /* 
       * if black pixel 
       */
      if (ho_bitmap_get (m, x, y))
      {
        y -= height;
        locale_height = height;
        locale_top = top;
        locale_bottom = bottom;

        if (y - top < 0)
          locale_top = y;
        if (y + height + bottom > m->height)
        {
          locale_bottom = 0;
          locale_height = m->height - y - 1;
        }

        ho_bitmap_draw_vline (m_out, x, y - locale_top,
          locale_height + locale_bottom);
        y = -1;
      }
    }

  return m_out;
}
Exemplo n.º 3
0
ho_bitmap *
ho_bitmap_herode (const ho_bitmap * m, const int size)
{
  ho_bitmap *m_out;
  int x, y;
  int k;
  int l, last;

  /* 
   * allocate memory 
   */
  m_out = ho_bitmap_new (m->width, m->height);
  if (!m_out)
    return NULL;
  m_out->x = m->x;
  m_out->y = m->y;

  m_out->type = m->type;
  m_out->font_height = m->font_height;
  m_out->font_width = m->font_width;
  m_out->font_spacing = m->font_spacing;
  m_out->line_spacing = m->line_spacing;
  m_out->avg_line_fill = m->avg_line_fill;
  m_out->com_line_fill = m->com_line_fill;
  m_out->nikud = m->nikud;

  /* 
   * set all bitmap black 
   */
  memset ((void *) (m_out->data), 0xff, m_out->height * m_out->rowstride);

  for (y = 0; y < m->height; y++)
  {
    last = -size;
    for (x = 0; x < m->width; x++)
    {
      if (!ho_bitmap_get (m, x, y)) /* white pixel */
      {
        ho_bitmap_unset (m_out, x, y);
        l = (int) x - last;
        if ((l > 1) && (l < size))
        {
          if (last < 0)
            last = 0;
          for (k = last; k < x; k++)
            ho_bitmap_unset (m_out, k, y);
        }
        last = x;
      }
    }
  }

  return m_out;
}
Exemplo n.º 4
0
ho_bitmap *
ho_bitmap_hlink (const ho_bitmap * m, const int size)
{
  ho_bitmap *m_out;
  int x, y;
  int k;
  int l, last;

  /* 
   * allocate memory 
   */
  m_out = ho_bitmap_new (m->width, m->height);
  if (!m_out)
    return NULL;
  m_out->x = m->x;
  m_out->y = m->y;

  m_out->type = m->type;
  m_out->font_height = m->font_height;
  m_out->font_width = m->font_width;
  m_out->font_spacing = m->font_spacing;
  m_out->line_spacing = m->line_spacing;
  m_out->avg_line_fill = m->avg_line_fill;
  m_out->com_line_fill = m->com_line_fill;
  m_out->nikud = m->nikud;

  for (y = 0; y < m->height; y++)
  {
    last = -size;
    for (x = 0; x < m->width; x++)
    {
      if (ho_bitmap_get (m, x, y))  /* black pixel */
      {
        ho_bitmap_set (m_out, x, y);
        l = (int) x - last;
        if ((l > 1) && (l < size))
        {
          if (last < 0)
            last = 0;
          for (k = last; k < x; k++)
            ho_bitmap_set (m_out, k, y);
        }
        last = x;
      }
    }
  }

  return m_out;
}
Exemplo n.º 5
0
double
ho_bitmap_get_fill (const ho_bitmap * m, const int x, const int y,
  const int width, const int height)
{
  int current_x, current_y;
  int fill;

  if (!width || !height || x < 0 || y < 0 || (x + width) > m->width
    || (y + height) > m->height)
    return -1.0;

  fill = 0;
  for (current_y = y; current_y < y + height; current_y++)
    for (current_x = x; current_x < x + width; current_x++)
      fill += ho_bitmap_get (m, current_x, current_y);

  return (double) fill / (double) (width * height);
}
Exemplo n.º 6
0
ho_bitmap *
ho_bitmap_clone_window (const ho_bitmap * m, const int x, const int y,
  const int width, const int height)
{
  ho_bitmap *m_out;
  int x1, y1;

  /* 
   * allocate memory 
   */
  m_out = ho_bitmap_new (width, height);
  if (!m_out)
    return NULL;

  /* 
   * set origin of sub window 
   */
  m_out->x = m->x + x;
  m_out->y = m->y + y;

  m_out->type = m->type;
  m_out->font_height = m->font_height;
  m_out->font_width = m->font_width;
  m_out->font_spacing = m->font_spacing;
  m_out->line_spacing = m->line_spacing;
  m_out->avg_line_fill = m->avg_line_fill;
  m_out->com_line_fill = m->com_line_fill;
  m_out->nikud = m->nikud;

  /* 
   * copy data 
   */
  for (x1 = 0; x1 < width && x1 < m->width; x1++)
    for (y1 = 0; y1 < height && y1 < m->height; y1++)
    {
      if ((x + x1) > 0 && (y + y1) > 0 && ho_bitmap_get (m, x + x1, y + y1))
        ho_bitmap_set (m_out, x1, y1);
    }
  
  return m_out;
}
Exemplo n.º 7
0
ho_bitmap *
ho_bitmap_rotate (const ho_bitmap * m, const double angle)
{
  ho_bitmap *m_out;
  int x, y;
  int xtag, ytag;
  double xtag_part, ytag_part;
  double angle_rads;
  double new_point;
  unsigned char neighbors[2][2];
  double affine_matrix[2][2];

  /* 
   * allocate memory 
   */
  m_out = ho_bitmap_new (m->width, m->height);
  if (!m_out)
    return NULL;
  m_out->x = m->x;
  m_out->y = m->y;

  m_out->type = m->type;
  m_out->font_height = m->font_height;
  m_out->font_width = m->font_width;
  m_out->font_spacing = m->font_spacing;
  m_out->line_spacing = m->line_spacing;
  m_out->avg_line_fill = m->avg_line_fill;
  m_out->com_line_fill = m->com_line_fill;
  m_out->nikud = m->nikud;

  /* get angle in radians */
  angle_rads = angle *(2.0 * M_PI / 360);

  /* fill rotation matrix */
  affine_matrix[0][0] = cos (angle_rads);
  affine_matrix[0][1] = sin (angle_rads);
  affine_matrix[1][0] = -affine_matrix[0][1];
  affine_matrix[1][1] = affine_matrix[0][0];

  /* 
   * copy data 
   */
  for (x = 0; x < m->width; x++)
    for (y = 0; y < m->height; y++)
    {

      xtag_part = x * affine_matrix[0][0] + y * affine_matrix[0][1];
      ytag_part = x * affine_matrix[1][0] + y * affine_matrix[1][1];
      xtag = (int) xtag_part;
      ytag = (int) ytag_part;
      xtag_part = xtag_part - (double) xtag;
      ytag_part = ytag_part - (double) ytag;

      /* get neighbors */
      if (xtag < 1 || ytag < 1 || xtag >= m->width || ytag >= m->height)
      {
        new_point = 0;
      }
      else
      {
        neighbors[0][0] = ho_bitmap_get (m, xtag - 1, ytag - 1);
        neighbors[0][1] = ho_bitmap_get (m, xtag - 1, ytag - 0);
        neighbors[1][0] = ho_bitmap_get (m, xtag - 0, ytag - 1);
        neighbors[1][1] = ho_bitmap_get (m, xtag - 0, ytag - 0);

        new_point =
          (double) neighbors[0][0] * (1.0 - xtag_part) * (1.0 - ytag_part) +
          (double) neighbors[0][1] * (1.0 - xtag_part) * ytag_part +
          (double) neighbors[1][0] * xtag_part * (1.0 - ytag_part) +
          (double) neighbors[1][1] * xtag_part * ytag_part;
      }

      /* get new point */
      if (new_point > 0.5)
        ho_bitmap_set (m_out, x, y);
    }

  return m_out;
}
Exemplo n.º 8
0
ho_bitmap *
ho_bitmap_filter_remove_dots (const ho_bitmap * m,
  const unsigned char erosion_n, const unsigned char dilation_n)
{
  int x, y;
  unsigned char sum;
  ho_bitmap *m_temp;
  ho_bitmap *m_out;
  ho_objmap *m_obj;
  int index;
  int width, height;

  /* allocate memory */
  m_out = ho_bitmap_new (m->width, m->height);
  if (!m_out)
    return NULL;
  m_out->x = m->x;
  m_out->y = m->y;

  m_out->type = m->type;
  m_out->font_height = m->font_height;
  m_out->font_width = m->font_width;
  m_out->font_spacing = m->font_spacing;
  m_out->line_spacing = m->line_spacing;
  m_out->avg_line_fill = m->avg_line_fill;
  m_out->com_line_fill = m->com_line_fill;
  m_out->nikud = m->nikud;

  /* connect all the small dots */
  m_temp = ho_bitmap_dilation (m);

  /* check the size of objects */
  m_obj = ho_objmap_new_from_bitmap (m_temp);
  ho_bitmap_free (m_temp);

  for (x = 1; x < (m->width - 1); x++)
    for (y = 1; y < (m->height - 1); y++)
    {

      /* check the size of this pixel's object */
      index = ho_objmap_get (m_obj, x, y);
      if (index)
      {
        width = (((m_obj->obj_list)->objects)[index - 1]).width;
        height = (((m_obj->obj_list)->objects)[index - 1]).height;
      }
      else
      {
        width = 0;
        height = 0;
      }

      /* in a big object do erosion */
      if (width > m->width / 4 || height > m->height / 4)
      {
        if (ho_bitmap_get (m, x, y))  /* black pixel */
        {
          sum = ho_bitmap_get (m, x - 1, y - 1) +
            ho_bitmap_get (m, x - 1, y) +
            ho_bitmap_get (m, x - 1, y + 1) +
            ho_bitmap_get (m, x, y - 1) +
            ho_bitmap_get (m, x, y + 1) +
            ho_bitmap_get (m, x + 1, y - 1) +
            ho_bitmap_get (m, x + 1, y) + ho_bitmap_get (m, x + 1, y + 1);
          /* n number of white pixels or more */
          if ((8 - sum) < erosion_n)
            ho_bitmap_set (m_out, x, y);
        }
      }
      else                      /* if in a small object do dilation */
      {
        if (!ho_bitmap_get (m, x, y)) /* white pixel */
        {
          sum = ho_bitmap_get (m, x - 1, y - 1) +
            ho_bitmap_get (m, x - 1, y) +
            ho_bitmap_get (m, x - 1, y + 1) +
            ho_bitmap_get (m, x, y - 1) +
            ho_bitmap_get (m, x, y + 1) +
            ho_bitmap_get (m, x + 1, y - 1) +
            ho_bitmap_get (m, x + 1, y) + ho_bitmap_get (m, x + 1, y + 1);
          /* n number of black neighbors or more */
          if (sum >= dilation_n)
            ho_bitmap_set (m_out, x, y);
        }
        else
          ho_bitmap_set (m_out, x, y);
      }
    }

  ho_objmap_free (m_obj);

  return m_out;
}
Exemplo n.º 9
0
int
ho_recognize_nikud_dimentions (const ho_bitmap * m_text,
  const ho_bitmap * m_mask, double *height,
  double *width, double *top, double *bottom,
  double *top_left, double *top_mid, double *top_right,
  double *mid_left, double *mid_right,
  double *bottom_left, double *bottom_mid,
  double *bottom_right,
  double *dots_above, double *dots_below, double *dots_inside,
  double *objs_above, double *objs_below, double *objs_inside,
  double *main_obj_height, double *main_obj_width,
  double *top_dot_x, double *inside_dot_x, double *font_width_by_height)
{
  int i, x, y;
  int obj_width, obj_height;
  int obj_x, obj_y;
  int obj_w, obj_h;
  int line_start, line_end, line_height;
  int sum, font_start_x, font_end_x, font_height, font_width;
  int font_start_y, font_end_y;
  ho_objmap *o_obj = NULL;
  unsigned char is_dot, is_obj;

  /* init values to zero */
  *height = 0.0;
  *width = 0.0;
  *top = 0.0;
  *bottom = 0.0;
  *top_left = 0.0;
  *top_mid = 0.0;
  *top_right = 0.0;
  *mid_left = 0.0;
  *mid_right = 0.0;
  *bottom_left = 0.0;
  *bottom_mid = 0.0;
  *bottom_right = 0.0;
  *dots_above = 0.0;
  *dots_below = 0.0;
  *dots_inside = 0.0;
  *objs_above = 0.0;
  *objs_below = 0.0;
  *objs_inside = 0.0;
  *top_dot_x = 0.0;
  *inside_dot_x = 0.0;
  *font_width_by_height = 0.0;

  /* get line start and end */
  x = m_mask->width / 2;
  for (y = 0; y < m_mask->height && !ho_bitmap_get (m_mask, x, y); y++) ;
  line_start = y - 1;
  for (; y < m_mask->height && ho_bitmap_get (m_mask, x, y); y++) ;
  line_end = y;
  line_height = line_end - line_start;

  if (line_height < 4 || m_text->width < 4)
    return TRUE;

  *font_width_by_height = (double) m_mask->width / (double) line_height;

  /* get all the objects of nikud */
  o_obj = ho_objmap_new_from_bitmap (m_text);
  if (!o_obj)
    return TRUE;

  /* if no nikud just return */
  if (ho_objmap_get_size (o_obj) == 0)
  {
    ho_objmap_free (o_obj);

    return FALSE;
  }

  /* count points and objects above/in/below font */
  obj_x = 0;
  obj_y = 0;
  obj_w = 0;
  obj_h = 0;

  for (i = 0; i < ho_objmap_get_size (o_obj); i++)
  {
    /* is this object inside line ? */
    y = ho_objmap_get_object (o_obj, i).y;
    x = ho_objmap_get_object (o_obj, i).x;
    obj_width = ho_objmap_get_object (o_obj, i).width;
    obj_height = ho_objmap_get_object (o_obj, i).height;

    is_dot = (obj_height < line_height / 4 && obj_height > line_height / 16
      && obj_width < line_height / 4 && obj_width > line_height / 16);

    is_obj = (obj_height > line_height / 4 || obj_width > line_height / 4);

    if (is_dot)
    {
      /* count */
      if ((y + obj_height / 2) < line_start)
      {
        (*dots_above) += 0.1;
        *top_dot_x = (double) x / (double) (m_text->width);
      }
      else if ((y + obj_height / 2) > line_end)
      {
        (*dots_below) += 0.1;
      }
      else
      {
        (*dots_inside) += 0.1;
        *inside_dot_x = (double) x / (double) (m_text->width);
      }
    }
    else if (is_obj)
    {
      /* count */
      if ((y + obj_height / 2) < line_start)
      {
        (*objs_above) += 0.1;
      }
      else if ((y + obj_height / 2) > line_end)
      {
        (*objs_below) += 0.1;

        /* get metrics of bigest obj under font */
        if (obj_width > *width)
        {
          obj_x = x;
          obj_y = y;
          obj_w = obj_width;
          obj_h = obj_height;
        }
      }
      else
      {
        (*objs_inside) += 0.1;
      }
    }
  }

  /* free obj map */
  ho_objmap_free (o_obj);

  /* if nothing below font we are finished */
  if (!(*objs_below) && !(*dots_below))
    return FALSE;

  /* get nikud metrics */
  *main_obj_height = 2.0 * (double) obj_h / (double) line_height;
  *main_obj_width = 2.0 * (double) obj_w / (double) line_height;

  if (obj_y && obj_h)
  {
    *top = 2.0 * (double) (obj_y - line_end) / (double) line_height;
    *bottom =
      2.0 * (double) ((obj_y + obj_h) - line_end) / (double) line_height;
  }

  /* get nikud start and end */
  sum = 0;
  for (y = line_end + 1; y < m_text->height && sum == 0; y++)
    for (sum = 0, x = 1; x < (m_text->width - 1); x++)
      sum += ho_bitmap_get (m_text, x, y);
  font_start_y = y - 1;
  sum = 0;
  for (y = m_text->height - 1; y > font_start_y && sum == 0; y--)
    for (sum = 0, x = 1; x < (m_text->width - 1); x++)
      sum += ho_bitmap_get (m_text, x, y);
  font_end_y = y + 1;
  font_height = font_end_y - font_start_y;

  if (!font_height)
    return TRUE;

  *height = 2.0 * (double) font_height / (double) line_height;

  sum = 0;
  for (x = 2; x < m_text->width && sum == 0; x++)
    for (sum = 0, y = line_end; y < (m_text->height - 1); y++)
      sum += ho_bitmap_get (m_text, x, y);
  font_start_x = x - 1;
  sum = 0;

  for (sum = 0, x = m_text->width - 2; x > (font_start_x + 1) && sum == 0; x--)
    for (sum = 0, y = line_end; y < (m_text->height - 1); y++)
      sum += ho_bitmap_get (m_text, x, y);
  font_end_x = x + 1;
  font_width = font_end_x - font_start_x;

  if (!font_width)
    return TRUE;

  *width = 2.0 * (double) font_width / (double) line_height;

  /* get nikud egdes */
  for (y = font_start_y, x = font_start_x;
    x < font_end_x && y < (font_end_y)
    && !ho_bitmap_get (m_text, x, y); x++, y++) ;
  *top_left = (double) (x - font_start_x) / (double) (line_height / 4);

  if (*top_left > 1.0)
    *top_left = 1.0;

  for (y = font_end_y, x = font_start_x;
    x < font_end_x && y > (font_start_y)
    && !ho_bitmap_get (m_text, x, y); x++, y--) ;
  *bottom_left = (double) (x - font_start_x) / (double) (line_height / 4);

  if (*bottom_left > 1.0)
    *bottom_left = 1.0;

  for (y = font_start_y, x = font_end_x - 1;
    x > font_start_x && y < (font_end_y)
    && !ho_bitmap_get (m_text, x, y); x--, y++) ;
  *top_right = (double) (font_end_x - x) / (double) (line_height / 4);

  if (*top_right > 1.0)
    *top_right = 1.0;

  for (y = font_end_y, x = font_end_x - 1;
    x > font_start_x && y > font_start_y
    && !ho_bitmap_get (m_text, x, y); x--, y--) ;
  *bottom_right = (double) (font_end_x - x) / (double) (line_height / 4);

  if (*bottom_right > 1.0)
    *bottom_right = 1.0;

  for (y = font_start_y, x = font_start_x + font_width / 2;
    y < (font_start_y + font_height) && !ho_bitmap_get (m_text, x, y); y++) ;
  *top_mid = (double) (y - font_start_y) / (double) (line_height / 4);

  if (*top_mid > 1.0)
    *top_mid = 1.0;

  for (y = font_end_y, x = font_start_x + font_width / 2;
    y > (font_start_y + font_height) && !ho_bitmap_get (m_text, x, y); y--) ;
  *bottom_mid = (double) (font_end_y - y) / (double) (line_height / 4);

  if (*bottom_mid > 1.0)
    *bottom_mid = 1.0;

  for (y = font_start_y + font_height / 2, x = font_start_x;
    x < (font_end_x) && !ho_bitmap_get (m_text, x, y); x++) ;
  *mid_left = (double) (x - font_start_x) / (double) (line_height / 4);

  if (*mid_left > 1.0)
    *mid_left = 1.0;

  for (y = font_start_y + font_height / 2, x = font_end_x - 1;
    x > (font_start_x) && !ho_bitmap_get (m_text, x, y); x--) ;
  *mid_right = (double) (font_end_x - x) / (double) (line_height / 4);

  if (*mid_right > 1.0)
    *mid_right = 1.0;

  return FALSE;
}