// -*- C++ -*- // Copyright 2006 Deutsches Forschungszentrum fuer Kuenstliche Intelligenz // or its licensors, as applicable. // // You may not use this file except under the terms of the accompanying license. // // Licensed under the Apache License, Version 2.0 (the "License"); you // may not use this file except in compliance with the License. You may // obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Project: // File: ocr-utils.h // Purpose: miscelaneous routines // Responsible: mezhirov // Reviewer: // Primary Repository: // Web Sites: www.iupr.org, www.dfki.de /// \file ocr-utils.h /// \brief Miscelaneous routines #ifndef h_ocr_segmentations_ #define h_ocr_segmentations_ #include "colib.h" #include "imglib.h" #include "sysutil.h" #include "idmap.h" #include "deprecation.h" #include "imgio.h" namespace ocropus { using namespace colib; using namespace iulib; /// Assert that all items of this array of arrays are not empty. template void assert_all_items_nonempty(narray > &a) { for(int i=0;i 0); } /// Remove from the segmentation those pixels which are white in gray_image. void binarize_in_segmentation(intarray &segmentation, /* const */ bytearray &gray_image); /// Set line number for all foreground pixels in a character segmentation. void set_line_number(intarray &a, int lnum); /// Unpack page segmentation into separate line masks with bounding boxes. void extract_lines(narray &lines,narray &rboxes,intarray &image); /// If the line is too small or too large, rescale it (with the mask) /// to a decent height (30-60 pixels). void rescale_if_needed(bytearray &bin_line, bytearray &gray_line); /// Make a binary image from a line segmentation. void forget_segmentation(bytearray &image, intarray &segmentation); /// Returns true if there's a mapping between s1's colors and s2's colors. bool is_oversegmentation_of(intarray &s1, intarray &s2); /// Return true if there are no zeros in the array. bool has_no_black_pixels(intarray &); void blit_segmentation_line(intarray &page, rectangle bbox, intarray &line, int line_no); /// Blit the segmentation of src onto dst shifted by (x,y) and shifted by /// values by max(dst). void concat_segmentation(intarray &dst, intarray &src, int x, int y); // Enlarge segmentation and AND it with line_mask. // Don't pass binarized grayscale image as line_mask, // otherwise you might get debris not from the line. // (that means we cannot really call this from inside LineOCR) void normalize_segmentation(intarray &segmentation, bytearray &line_mask); int max_cnum(intarray &seg); // FIXME use these creation/accessor functions more widely inline int pseg_pixel(int column,int paragraph,int line) { ASSERT((column > 0 && column < 32) || column == 254 || column == 255); ASSERT((paragraph >= 0 && paragraph < 64) || (paragraph >=251 && paragraph <= 255)); ASSERT(line>=0 && line<256); return (column<<16) | (paragraph<<8) | line; } inline int pseg_pixel(int column,int line) { ASSERT(column>0 && column<32); ASSERT(line>=0 && line<64*256); return (column<<16) | line; } inline int pseg_column(int pixel) { return (pixel>>16)&0xff; } inline int pseg_paragraph(int pixel) { return (pixel>>8) & 0x3f; } inline int pseg_line(int pixel) { return pixel & 0xff; } inline int pseg_pline(int pixel) { return pixel & 0x3fff; } inline int cseg_pixel(int chr) { ASSERT(chr>0 && chr<4096); return (1<<12) | chr; } inline void pseg_columns(intarray &a) { for(int i=0;i=32) value = 0; a.at1d(i) = value; } } inline void pseg_plines(intarray &a) { for(int i=0;i=32) value = 0; value = pseg_pline(value); a.at1d(i) = value; } } void check_line_segmentation_old(intarray &cseg, bool allow_zero=true, bool allow_gaps=true,bool allow_lzero=true); void check_line_segmentation(intarray &cseg); void check_page_segmentation(intarray &cseg); void make_line_segmentation_black(intarray &a); void make_line_segmentation_white(intarray &a); void make_page_segmentation_black(intarray &a); void make_page_segmentation_white(intarray &a); void get_recoloring_map(intarray &recolor, intarray &image); void remove_gaps_by_recoloring(intarray &image); void ocr_bboxes_to_charseg(intarray &cseg,narray &bboxes,intarray &segmentation); void evaluate_segmentation(int &nover,int &nunder,int &nmis, intarray &model_raw,intarray &image_raw,float tolerance); void align_segmentation(intarray &segmentation,narray &bboxes); // idmaps are deprecated void idmap_of_correspondences(idmap &result,intarray &charseg,intarray &overseg) DEPRECATED; void idmap_of_bboxes(idmap &result,intarray &segmentation,narray &bboxes) DEPRECATED; void segmentation_to_cseg(intarray &cseg,idmap &map,intarray &ids,intarray &segmentation) DEPRECATED; void ocr_result_to_charseg(intarray &cseg,idmap &map,intarray &ids, intarray &segmentation,bool map_all=true) DEPRECATED; // these are convenient classes for checking whether arguments // are valid page segmentations, line segmentations, and/or // binary images template struct imageref { narray ℑ imageref(narray &image) : image(image) { CHECK(image.rank()==2); } int &operator()(int x,int y) { return image(x,y); } int dim(int i) { return image.dim(i); } void resize(int w,int h) { image.resize(w,h); } operator narray&() { return image; } narray &operator*() { return image; } narray *operator->() { return ℑ } }; struct pageseg : imageref { pageseg(intarray &a):imageref(a) { validate(); } void validate() { check_page_segmentation(image); } }; struct lineseg : imageref { lineseg(intarray &a):imageref(a) { validate(); } void validate() { check_line_segmentation(image); } }; struct binimage : imageref { binimage(bytearray &a):imageref(a) { validate(); } void validate() { } }; inline void write_line_segmentation(FILE *stream,intarray &a) { check_line_segmentation(a); make_line_segmentation_white(a); write_image_packed(stream,a,"png"); } inline void read_line_segmentation(intarray &a,FILE *stream) { read_image_packed(a,stream,"png"); check_line_segmentation(a); make_line_segmentation_black(a); } inline void write_page_segmentation(FILE *stream,intarray &a) { check_page_segmentation(a); write_image_packed(stream,a,"png"); } inline void read_page_segmentation(intarray &a,FILE *stream) { read_image_packed(a,stream,"png"); check_page_segmentation(a); } } #endif