Esempio n. 1
0
ho_bitmap *
ho_bitmap_filter_fill (const ho_bitmap * m)
{
  ho_objmap *m_obj;
  ho_bitmap *m_out;
  ho_bitmap *m_temp1;
  ho_bitmap *m_temp2;
  int index;
  int width, height;

  /* allocate memory */
  m_obj = ho_objmap_new_from_bitmap (m);
  if (!m_obj)
    return NULL;

  m_out = ho_bitmap_new (m->width, m->height);
  if (!m_out)
  {
    ho_objmap_free (m_obj);
    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;

  /* loop over all the objects and box them */
  for (index = 0; index < m_obj->obj_list->size; index++)
  {
    /* get a dimention factor */
    width = (((m_obj->obj_list)->objects)[index]).width;
    height = (((m_obj->obj_list)->objects)[index]).height;

    /* copy only the current object to a new bitmap */
    m_temp1 = ho_objmap_to_bitmap_by_index (m_obj, index);

    /* fill the current object */
    m_temp2 = ho_bitmap_hlink (m_temp1, width / 4);
    ho_bitmap_free (m_temp1);
    m_temp1 = ho_bitmap_vlink (m_temp2, height / 4);
    ho_bitmap_free (m_temp2);

    /* add to matrix out */
    ho_bitmap_or (m_out, m_temp1);
    ho_bitmap_free (m_temp1);
  }

  return m_out;
}
Esempio n. 2
0
ho_bitmap *
ho_bitmap_filter_set_height_from_bottom (const ho_bitmap * m,
  const int height, const int top, const int bottom)
{
  ho_objmap *m_obj;
  ho_bitmap *m_out;
  ho_bitmap *m_temp1;
  ho_bitmap *m_temp2;
  int index;

  /* allocate memory */
  m_obj = ho_objmap_new_from_bitmap (m);
  if (!m_obj)
    return NULL;

  m_out = ho_bitmap_new (m->width, m->height);
  if (!m_out)
  {
    ho_objmap_free (m_obj);
    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;

  /* loop over all the objects and box them */
  for (index = 0; index < m_obj->obj_list->size; index++)
  {
    /* copy only the current object to a new bitmap */
    m_temp1 = ho_objmap_to_bitmap_by_index (m_obj, index);
    if (!m_temp1)
      continue;

    /* take height pixels from this object */
    m_temp2 = ho_bitmap_set_height_from_bottom (m_temp1, height, top, bottom);
    ho_bitmap_free (m_temp1);
    if (!m_temp2)
      continue;

    /* add to matrix out */
    ho_bitmap_or (m_out, m_temp2);
    ho_bitmap_free (m_temp2);
  }

  return m_out;
}
Esempio n. 3
0
ho_bitmap *
ho_bitmap_filter_boxes (const ho_bitmap * m, const int leeway_down,
  const int leeway_up)
{
  ho_objmap *m_obj;
  ho_bitmap *m_out;
  int index;
  int x, y, width, height;

  /* allocate memory */
  m_obj = ho_objmap_new_from_bitmap (m);
  if (!m_obj)
    return NULL;
  m_out = ho_bitmap_new (m->width, m->height);
  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;

  if (!m_out)
  {
    ho_objmap_free (m_obj);
    return NULL;
  }

  /* loop over all the objects and box them */
  for (index = 0; index < m_obj->obj_list->size; index++)
  {
    x = (((m_obj->obj_list)->objects)[index]).x;
    y = (((m_obj->obj_list)->objects)[index]).y;
    width = (((m_obj->obj_list)->objects)[index]).width;
    height = (((m_obj->obj_list)->objects)[index]).height;

    y -= leeway_up;
    height += leeway_up + leeway_down;
    if (y < 0)
      y = 0;
    if (y + height >= m->height)
      height = m->height - y - 1;

    ho_bitmap_draw_box (m_out, x, y, width, height);
  }

  return m_out;
}
Esempio n. 4
0
int
ho_bitmap_filter_count_objects (const ho_bitmap * m)
{
  ho_objmap *o_obj;
  int count;

  o_obj = ho_objmap_new_from_bitmap (m);
  if (!o_obj)
    return -1;

  count = ho_objmap_get_size (o_obj);
  ho_objmap_free (o_obj);

  return count;
}
Esempio n. 5
0
ho_bitmap *
ho_bitmap_filter_by_size (const ho_bitmap * m,
  int min_height, int max_height, int min_width, int max_width)
{
  ho_objmap *m_obj;
  ho_bitmap *m_out;

  /* create a new objmap */
  m_obj = ho_objmap_new_from_bitmap (m);

  if (!m_obj)
    return NULL;

  m_out = ho_objmap_to_bitmap_by_size (m_obj,
    min_height, max_height, min_width, max_width);

  /* free objmap */
  ho_objmap_free (m_obj);

  return m_out;
}
Esempio n. 6
0
ho_bitmap *
ho_bitmap_filter_obj_extend_lateraly (const ho_bitmap * m, const int ext_width)
{
  ho_objmap *m_obj;

  ho_bitmap *m_temp;
  ho_bitmap *m_out;

  int x, y;
  int index;
  int width, height;

  m_temp = ho_bitmap_clone (m);
  if (!m_temp)
    return NULL;

  /* loop over all objects and extend them lateraly */
  /* allocate memory */
  m_obj = ho_objmap_new_from_bitmap (m_temp);
  if (!m_obj)
  {
    ho_bitmap_free (m_temp);
    return NULL;
  }

  /* draw stopers */
  for (index = 0; index < m_obj->obj_list->size; index++)
  {
    x = (((m_obj->obj_list)->objects)[index]).x;
    y = (((m_obj->obj_list)->objects)[index]).y;
    width = (((m_obj->obj_list)->objects)[index]).width;
    height = (((m_obj->obj_list)->objects)[index]).height;

    if (x - ext_width < 0)
      x = ext_width;
    if (x + width + ext_width >= m->width)
      width = m->width - x - ext_width - 1;

    ho_bitmap_draw_vline (m_temp, x - ext_width, y, height);
    ho_bitmap_draw_vline (m_temp, x + width + ext_width, y, height);
  }

  /* extend */
  m_out = ho_bitmap_hlink (m_temp, 7 * ext_width / 4);

  ho_bitmap_free (m_temp);
  if (!m_out)
    return NULL;

  /* delete stopers */
  for (index = 0; index < m_obj->obj_list->size; index++)
  {
    x = (((m_obj->obj_list)->objects)[index]).x;
    y = (((m_obj->obj_list)->objects)[index]).y;
    width = (((m_obj->obj_list)->objects)[index]).width;
    height = (((m_obj->obj_list)->objects)[index]).height;

    if (x - ext_width < 0)
      x = ext_width;
    if (x + width + ext_width >= m->width)
      width = m->width - x - ext_width - 1;
    ho_bitmap_delete_vline (m_out, x - ext_width, y, height);
    ho_bitmap_delete_vline (m_out, x + width + ext_width, y, height);
  }

  /* set origin */
  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;

  ho_objmap_free (m_obj);

  return m_out;
}
Esempio n. 7
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;
}
Esempio n. 8
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;
}