#include "grphics.h"
#include "varable.h"
#include "img.h"
#include "pdblock.h"
#include "coutln.h"
#include "crakedge.h"
Go to the source code of this file.
#define BUCKETSIZE 16 |
* (C) Copyright 1991, Hewlett-Packard Ltd. ** 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.
Certify outline.
start | Start of loop |
The return value is:
Here's what this function does for an upper-case "B" (see table for specific letters used). 'B' has three outlines: an outer outline, which is the longest (and ends last), and two inner outlines, one on top (which ends first) and second on the bottom (which ends second).
This just establishes some terms - the following table should be useful:
Exact sample in testing/edges/<item>.tif Item Outline do{}while length chainsum ===== ======== ========== ====== ======== edges_5B top 6 iter 12 -4 edges_5B bottom 8 iter 18 -4 edges_5B outer 18 iter 42 4 edges_5T outer 8 iter 40 4 edges_1O inner 38 iter 38 -4 edges_1O outer 54 iter 54 4 edges_2O inner 26 iter 26 -4 edges_2O outer 34 iter 34 4 edges_5O inner 20 iter 34 -4 edges_5O outer 28 iter 46 4 (shape with 8 inner voids/9 outlines, which tess dislikes :-) bugeyes 1 8 8 -4 bugeyes 2 12 12 -4 bugeyes 3* 6 8 -4 bugeyes 4 8 8 -4 bugeyes 5 10 10 -4 bugeyes 6* 6 6 -4 bugeyes 7 8 8 -4 bugeyes 8* 6 6 -4 bugeyes outer 40 40 4 [* = returned YELLOW not the usual RED]
Observations:
Definition at line 197 of file edgloop.cpp.
References BLUE, cprintf(), ERRCODE::error(), GREEN, LOG, long_edges, MAGENTA, MINEDGELENGTH, CRACKEDGE::next, CRACKEDGE::prev, RED, short_edges, CRACKEDGE::stepdir, and YELLOW.
Referenced by complete_edge().
00199 { 00200 int lastchain; //last chain code 00201 int chaindiff; //chain code diff 00202 INT32 length; //length of loop 00203 INT32 chainsum; //sum of chain diffs 00204 CRACKEDGE *edgept; //current point 00205 const ERRCODE ED_ILLEGAL_SUM = "Illegal sum of chain codes"; 00206 00207 length = 0; 00208 chainsum = 0; //sum of chain codes 00209 edgept = start; 00210 lastchain = edgept->prev->stepdir; //previous chain code 00211 00212 int c = 0; 00213 do { 00214 length++; 00215 if (edgept->stepdir != lastchain) { 00216 //chain code difference 00217 chaindiff = edgept->stepdir - lastchain; 00218 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSF) 00219 cprintf("1(%d,%d,%d)",edgept->stepdir,lastchain,chaindiff); // , see ccmain/tessvars.h 00220 #endif 00221 if (chaindiff > 2) 00222 chaindiff -= 4; 00223 else if (chaindiff < -2) 00224 chaindiff += 4; 00225 chainsum += chaindiff; //sum differences 00226 lastchain = edgept->stepdir; 00227 } 00228 edgept = edgept->next; 00229 c++; 00230 } 00231 while (edgept != start && length < edges_maxedgelength); 00232 00233 if (chainsum != 4 && chainsum != -4 00234 || edgept != start || length < MINEDGELENGTH) { 00235 if (edgept != start) { 00236 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSF) 00237 cprintf("\n2(Y:%d,%d,iter=%d)",length,chainsum,c); // , see ccmain/tessvars.h 00238 #endif 00239 long_edges++; 00240 return YELLOW; 00241 } 00242 else if (length < MINEDGELENGTH) { 00243 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSF) 00244 cprintf("3(M:%d,%d,iter=%d)",length,chainsum,c); // , see ccmain/tessvars.h 00245 #endif 00246 short_edges++; 00247 return MAGENTA; 00248 } 00249 else { 00250 ED_ILLEGAL_SUM.error ("check_path_legal", LOG, "chainsum=%d", 00251 chainsum); 00252 return GREEN; 00253 } 00254 } 00255 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSF) 00256 cprintf("4(%s:%d,%d,iter=%d)",(chainsum < 0 ? "B" : "R"), 00257 length,chainsum,c); // , see ccmain/tessvars.h 00258 #endif 00259 //colour on inside 00260 return chainsum < 0 ? BLUE : RED; 00261 }
void complete_edge | ( | CRACKEDGE * | start | ) |
Clean and approximate.
start | Start of loop |
Definition at line 99 of file edgloop.cpp.
References BLUE, C_OUTLINE, check_path_legal(), cprintf(), draw_raw_edge(), edge_win, loop_bounding_box(), outline_it, and RED.
Referenced by join_edges().
00101 { 00102 COLOUR colour; //colour to draw in 00103 INT16 looplength; //steps in loop 00104 ICOORD botleft; //bounding box 00105 ICOORD topright; 00106 C_OUTLINE *outline; //new outline 00107 00108 //check length etc. 00109 colour = check_path_legal (start); 00110 #ifndef GRAPHICS_DISABLED 00111 if (edges_show_paths) { 00112 //in red 00113 draw_raw_edge(edge_win, start, colour); 00114 } 00115 #endif 00116 00117 if (colour == RED || colour == BLUE) { 00118 looplength = loop_bounding_box (start, botleft, topright); 00119 outline = new C_OUTLINE (start, botleft, topright, looplength); 00120 //add to list 00121 outline_it->add_after_then_move (outline); 00122 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSF) 00123 cprintf("Z"); // , see ccmain/tessvars.h 00124 #endif 00125 } 00126 }
DLLSYM void get_outlines | ( | WINDOW | window, | |
IMAGE * | image, | |||
IMAGE * | t_image, | |||
ICOORD | page_tr, | |||
PDBLK * | block, | |||
C_OUTLINE_IT * | out_it | |||
) |
Edge detect.
window | Window for output | |
image | Image to scan | |
t_image | Thresholded image | |
page_tr | Corner of page | |
block | Block to scan | |
out_it | Output iterator |
Definition at line 68 of file edgloop.cpp.
References block_edges(), edge_win, NO_WINDOW, outline_it, overlap_picture_ops, and TRUE.
Referenced by extract_edges().
00077 { 00078 #ifndef GRAPHICS_DISABLED 00079 edge_win = window; //set statics 00080 #endif 00081 outline_it = out_it; 00082 block_edges(t_image, block, page_tr); 00083 out_it->move_to_first (); // reset iterator to first outline 00084 #ifndef GRAPHICS_DISABLED 00085 if (window != NO_WINDOW) 00086 overlap_picture_ops(TRUE); //update window 00087 #endif 00088 }
Gets length of outline and its bounding box.
start | Edge loop | |
botleft | Bounding box, X1,Y1 | |
topright | Bounding box, X2,Y2 |
Definition at line 274 of file edgloop.cpp.
References CRACKEDGE::next, CRACKEDGE::pos, ICOORD::set_x(), ICOORD::set_y(), and ICOORD::y().
Referenced by complete_edge().
00277 { 00278 INT16 length; //length of loop 00279 INT16 leftmost; //on top row 00280 CRACKEDGE *edgept; //current point 00281 CRACKEDGE *realstart; //topleft start 00282 00283 edgept = start; 00284 realstart = start; 00285 botleft = topright = ICOORD (edgept->pos.x (), edgept->pos.y ()); 00286 leftmost = edgept->pos.x (); 00287 length = 0; //coutn length 00288 do { 00289 edgept = edgept->next; 00290 if (edgept->pos.x () < botleft.x ()) 00291 //get bounding box 00292 botleft.set_x (edgept->pos.x ()); 00293 else if (edgept->pos.x () > topright.x ()) 00294 topright.set_x (edgept->pos.x ()); 00295 if (edgept->pos.y () < botleft.y ()) 00296 //get bounding box 00297 botleft.set_y (edgept->pos.y ()); 00298 else if (edgept->pos.y () > topright.y ()) { 00299 realstart = edgept; 00300 leftmost = edgept->pos.x (); 00301 topright.set_y (edgept->pos.y ()); 00302 } 00303 else if (edgept->pos.y () == topright.y () 00304 && edgept->pos.x () < leftmost) { 00305 //leftmost on line 00306 leftmost = edgept->pos.x (); 00307 realstart = edgept; 00308 } 00309 length++; //count elements 00310 } 00311 while (edgept != start); 00312 start = realstart; //shift it to topleft 00313 return length; 00314 }