int TessDllAPI::BeginPage(uinT32 xsize,uinT32 ysize,unsigned char *buf,uinT8 bpp) {
  inT16 c;

  EndPage();

  if (page_image.create (xsize+800, ysize+800, 1)==-1)
    return 0L;  //make the image bigger to enclose in whitespace

  //copy the passed buffer into the center of the image

  IMAGE tmp;

  tmp.create(xsize, ysize, bpp);

  for (c=0;c<ysize;c++)
    CopyMemory(tmp.get_buffer ()+(c)*((xsize*bpp + 7)/8),
               buf+((ysize-1)-c)*((xsize*bpp + 7)/8),((xsize*bpp + 7)/8));


  copy_sub_image(&tmp, 0, 0, 0, 0, &page_image, 400, 400, false);




  return ProcessPagePass1();
}
Beispiel #2
0
void scale_image_cop_out(                      //scale an image
                         IMAGE &image,         //source image
                         IMAGE &target_image,  //target image
                         float factor,         //scale factor
                         int *hires,
                         int *lores,
                         int *oldhires,
                         int *oldlores) {
  inT32 xsize, ysize, new_xsize, new_ysize;

  xsize = image.get_xsize ();
  ysize = image.get_ysize ();
  new_xsize = target_image.get_xsize ();
  new_ysize = target_image.get_ysize ();

  if (factor <= 0.5)
    reduce_sub_image (&image, 0, 0, xsize, ysize,
      &target_image, 0, 0, (inT32) (1.0 / factor), FALSE);
  else if (factor >= 2)
    enlarge_sub_image (&image, 0, 0, &target_image,
        0, 0, new_xsize, new_ysize, (inT32) factor, FALSE);
  else
    copy_sub_image (&image, 0, 0, xsize, ysize, &target_image, 0, 0, FALSE);
  free(hires);
  free(lores);
  free(oldhires);
  free(oldlores);
}
void sv_show_sub_image(IMAGE*    source,         // Image to show.
                       inT32     xstart,         // Start image coords.
                       inT32     ystart,
                       inT32     xext,           // Size of rectangle to show.
                       inT32     yext,
                       ScrollView*    window,         // Window to draw in.
                       inT32     xpos,           // Place to show bottom-left.
                       inT32     ypos) {         // Y position.
#ifdef HAVE_LIBLEPT
  Pix* pix;
  if (xstart != 0 || ystart != 0 ||
      xext != source->get_xsize() || yext != source->get_ysize()) {
    IMAGE sub_im;
    sub_im.create(xext, yext, source->get_bpp());
    copy_sub_image(source, xstart, ystart, xext, yext, &sub_im, 0, 0, false);
    pix = sub_im.ToPix();
  } else {
    pix = source->ToPix();
  }
#ifndef GRAPHICS_DISABLED
  window->Image(pix, xpos, window->TranslateYCoordinate(yext) + ypos);
#endif
  pixDestroy(&pix);
#endif
}
Beispiel #4
0
// Cut out the requested rectangle of the binary image to the
// tesseract global image ready for recognition.
void TessBaseAPI::CopyBinaryRect(const unsigned char* imagedata,
                                 int bytes_per_line,
                                 int left, int top,
                                 int width, int height) {
  // Copy binary image, cutting out the required rectangle.
  IMAGE image;
  image.capture(const_cast<unsigned char*>(imagedata),
                bytes_per_line*8, top + height, 1);
  page_image.create(width, height, 1);
  copy_sub_image(&image, left, 0, width, height, &page_image, 0, 0, false);
}
int TessDllAPI::BeginPageUpright(uinT32 xsize,uinT32 ysize,unsigned char *buf, uinT8 bpp) {


    EndPage();

//It looks like Adaptive thresholding is disabled so this must be a 1 bpp image
  if (page_image.create (xsize+800, ysize+800, 1)==-1)
    return 0L;  //make the image bigger to enclose in whitespace

  //copy the passed buffer into the center of the image
  IMAGE tmp;

  tmp.capture(buf, xsize, ysize, bpp);


  copy_sub_image(&tmp, 0, 0, 0, 0, &page_image, 400, 400, true);



  return ProcessPagePass1();
}
Beispiel #6
0
// Copy the raw image rectangle, taking all data from the class, to the Pix.
void ImageThresholder::RawRectToPix(Pix** pix) const {
  if (image_bytespp_ < 4) {
    // Go via a tesseract image structure (doesn't copy the data)
    // and use ToPix.
    IMAGE image;
    int bits_per_pixel = image_bytespp_ * 8;
    if (image_bytespp_ == 0)
      bits_per_pixel = 1;
    image.capture(const_cast<uinT8*>(image_data_),
                  image_width_, rect_top_ + rect_height_, bits_per_pixel);
    if (IsFullImage()) {
      *pix = image.ToPix();
    } else {
      IMAGE rect;
      rect.create(rect_width_, rect_height_, bits_per_pixel);
      // The capture chopped the image off at top+height, so copy
      // the rectangle with y = 0 to get a rectangle of height
      // starting at the bottom, since copy_sub_image uses bottom-up coords.
      copy_sub_image(&image, rect_left_, 0, rect_width_, rect_height_,
                     &rect, 0, 0, true);
      *pix = rect.ToPix();
    }
  } else {
    *pix = pixCreate(rect_width_, rect_height_, 32);
    uinT32* data = pixGetData(*pix);
    int wpl = pixGetWpl(*pix);
    const uinT8* imagedata = image_data_ + rect_top_ * image_bytespl_ +
                             rect_left_ * image_bytespp_;
    for (int y = 0; y < rect_height_; ++y) {
      const uinT8* linedata = imagedata;
      uinT32* line = data + y * wpl;
      for (int x = 0; x < rect_width_; ++x) {
        line[x] = (linedata[0] << 24) | (linedata[1] << 16) |
                  (linedata[2] << 8) | linedata[3];
        linedata += 4;
      }
      imagedata += image_bytespl_;
    }
  }
}
Beispiel #7
0
/**********************************************************************
 * SetBlobStrokeWidth
 *
 * Set the horizontal and vertical stroke widths in the blob.
 **********************************************************************/
void SetBlobStrokeWidth(bool debug, BLOBNBOX* blob) {
#ifdef HAVE_LIBLEPT
  // Cut the blob rectangle into a Pix.
  // TODO(rays) make the page_image a Pix so this is more direct.
  const TBOX& box = blob->bounding_box();
  IMAGE blob_im;
  int width = box.width();
  int height = box.height();
  blob_im.create(width, height, 1);
  copy_sub_image(&page_image, box.left(), box.bottom(), width, height,
                 &blob_im, 0, 0, false);
  Pix* pix = blob_im.ToPix();
  Pix* dist_pix = pixDistanceFunction(pix, 4, 8, L_BOUNDARY_BG);
  if (debug) {
    pixWrite("cutpix.png", pix, IFF_PNG);
    pixWrite("distpix.png", dist_pix, IFF_PNG);
  }
  pixDestroy(&pix);
  // Compute the stroke widths.
  uinT32* data = pixGetData(dist_pix);
  int wpl = pixGetWpl(dist_pix);
  // Horizontal width of stroke.
  STATS h_stats(0, width + 1);
  for (int y = 0; y < height; ++y) {
    uinT32* pixels = data + y*wpl;
    int prev_pixel = 0;
    int pixel = GET_DATA_BYTE(pixels, 0);
    for (int x = 1; x < width; ++x) {
      int next_pixel = GET_DATA_BYTE(pixels, x);
      // We are looking for a pixel that is equal to its vertical neighbours,
      // yet greater than its left neighbour.
      if (prev_pixel < pixel &&
          (y == 0 || pixel == GET_DATA_BYTE(pixels - wpl, x - 1)) &&
          (y == height - 1 || pixel == GET_DATA_BYTE(pixels + wpl, x - 1))) {
        if (pixel > next_pixel) {
          // Single local max, so an odd width.
          h_stats.add(pixel * 2 - 1, 1);
        } else if (pixel == next_pixel && x + 1 < width &&
                 pixel > GET_DATA_BYTE(pixels, x + 1)) {
          // Double local max, so an even width.
          h_stats.add(pixel * 2, 1);
        }
      }
      prev_pixel = pixel;
      pixel = next_pixel;
    }
  }
  if (debug) {
    h_stats.print(stderr, true);
  }
  // Vertical width of stroke.
  STATS v_stats(0, height + 1);
  for (int x = 0; x < width; ++x) {
    int prev_pixel = 0;
    int pixel = GET_DATA_BYTE(data, x);
    for (int y = 1; y < height; ++y) {
      uinT32* pixels = data + y*wpl;
      int next_pixel = GET_DATA_BYTE(pixels, x);
      // We are looking for a pixel that is equal to its horizontal neighbours,
      // yet greater than its upper neighbour.
      if (prev_pixel < pixel &&
          (x == 0 || pixel == GET_DATA_BYTE(pixels - wpl, x - 1)) &&
          (x == width - 1 || pixel == GET_DATA_BYTE(pixels - wpl, x + 1))) {
        if (pixel > next_pixel) {
          // Single local max, so an odd width.
          v_stats.add(pixel * 2 - 1, 1);
        } else if (pixel == next_pixel && y + 1 < height &&
                 pixel > GET_DATA_BYTE(pixels + wpl, x)) {
          // Double local max, so an even width.
          v_stats.add(pixel * 2, 1);
        }
      }
      prev_pixel = pixel;
      pixel = next_pixel;
    }
  }
  if (debug) {
    v_stats.print(stderr, true);
  }
  pixDestroy(&dist_pix);
  // Store the horizontal and vertical width in the blob, keeping both
  // widths if there is enough information, otherwse only the one with
  // the most samples.
  // If there are insufficent samples, store zero, rather than using
  // 2*area/perimeter, as the numbers that gives do not match the numbers
  // from the distance method.
  if (debug) {
    tprintf("box=%d,%d->%d,%d, hcount=%d, vcount=%d, target=%d\n",
            box.left(), box.bottom(), box.right(), box.top(),
            h_stats.get_total(), v_stats.get_total(), (width+height) /4);
    tprintf("hstats median=%f, lq=%f, uq=%f, sd=%f\n",
            h_stats.median(), h_stats.ile(0.25f), h_stats.ile(0.75f),
            h_stats.sd());
    tprintf("vstats median=%f, lq=%f, uq=%f, sd=%f\n",
            v_stats.median(), v_stats.ile(0.25f), v_stats.ile(0.75f),
            v_stats.sd());

  }
  if (h_stats.get_total() >= (width + height) / 4) {
    blob->set_horz_stroke_width(h_stats.ile(0.5f));
    if (v_stats.get_total() >= (width + height) / 4)
      blob->set_vert_stroke_width(v_stats.ile(0.5f));
    else
      blob->set_vert_stroke_width(0.0f);
  } else {
    if (v_stats.get_total() >= (width + height) / 4 ||
        v_stats.get_total() > h_stats.get_total()) {
      blob->set_horz_stroke_width(0.0f);
      blob->set_vert_stroke_width(v_stats.ile(0.5f));
    } else {
      blob->set_horz_stroke_width(h_stats.get_total() > 2 ? h_stats.ile(0.5f)
                                                          : 0.0f);
      blob->set_vert_stroke_width(0.0f);
    }
  }
#else
  // Without leptonica present, use the 2*area/perimeter as an approximation.
  float width = 2.0f * blob->cblob()->area();
  width /= blob->cblob()->perimeter();
  blob->set_horz_stroke_width(width);
  blob->set_vert_stroke_width(width);
#endif
}