📄 findseam.cpp
字号:
/* -*-C-*- ******************************************************************************** * * File: findseam.c (Formerly findseam.c) * Description: * Author: Mark Seaman, OCR Technology * Created: Fri Oct 16 14:37:00 1987 * Modified: Tue Jul 30 15:44:59 1991 (Mark Seaman) marks@hpgrlt * Language: C * Package: N/A * Status: Reusable Software Component * * (c) Copyright 1987, Hewlett-Packard Company. ** 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. * *********************************************************************************//*---------------------------------------------------------------------- I n c l u d e s----------------------------------------------------------------------*/#include "findseam.h"#include "gradechop.h"#include "olutil.h"#include "plotedges.h"#include "outlines.h"#include "freelist.h"#include "seam.h"/*---------------------------------------------------------------------- T y p e s----------------------------------------------------------------------*/#define SPLIT_CLOSENESS 20/* Difference in x value */ /* How many to keep */#define MAX_NUM_SEAMS 150 /* How many to keep */#define MAX_OLD_SEAMS 150#define NO_FULL_PRIORITY -1/* Special marker for pri. */ /* Evalute right away */#define GOOD_PARTIAL_PRIORITY good_split#define BAD_PRIORITY 9999.0/*---------------------------------------------------------------------- M a c r o s----------------------------------------------------------------------*//********************************************************************** * add_seam_to_queue * * Add this seam value to the seam queue. If the heap is already full * then nothing is done. **********************************************************************/#define add_seam_to_queue(seams,seam,priority) \if (seam)\{\ if (HeapFull(seams))\ junk_worst_seam(seams,seam,priority);\ else\ HeapPush (seams, priority, (char*) seam);\ }/********************************************************************** * best_seam_priority * * Return the best priority value on the queue. **********************************************************************/#define best_seam_priority(seam_queue) \(HeapEmpty (seam_queue) ? \ NO_FULL_PRIORITY : \ ((SEAM*) seam_queue_element(seam_queue, 0))->priority)/********************************************************************** * create_seam_queue * * Create a new seam queue with no elements in it. **********************************************************************/#define create_seam_queue(seam_queue) \(seam_queue = MakeHeap (MAX_NUM_SEAMS))/********************************************************************** * create_seam_pile * * Create a new seam pile with no elements in it. **********************************************************************/#define create_seam_pile(seam_pile) \(seam_pile = array_new (MAX_OLD_SEAMS))/********************************************************************** * delete_seam_queue * * Delete a seam queue along with all the seam structures associated * with it. **********************************************************************/#define delete_seam_queue(seam_queue) \(FreeHeapData (seam_queue, delete_seam), \ seam_queue = NULL) \/********************************************************************** * pop_next_seam * * Remove the next seam from the queue. Put the seam and priority * values in the requested variables. If there was nothing to pop * then return FALSE, else return TRUE. **********************************************************************/#define pop_next_seam(seams,seam,priority) \(HeapPop (seams,&priority,&seam) == OK) \/********************************************************************** * seam_queue_element * * Return the element from the seam queue at the requested index. **********************************************************************/#define seam_queue_element(seam_queue,index) \((index < SizeOfHeap (seam_queue)) ? \ HeapDataFor (seam_queue, index) : \ NULL) \/*---------------------------------------------------------------------- F u n c t i o n s----------------------------------------------------------------------*//********************************************************************** * junk_worst_seam * * Delete the worst seam from the queue because it is full. **********************************************************************/void junk_worst_seam(SEAM_QUEUE seams, SEAM *new_seam, float new_priority) { SEAM *seam; float priority; HeapPopWorst(seams, &priority, &seam); if (priority > new_priority) { delete_seam(seam); /*get rid of it */ HeapPush (seams, new_priority, (char *) new_seam); } else { delete_seam(new_seam); HeapPush (seams, priority, (char *) seam); }}/********************************************************************** * choose_best_seam * * Choose the best seam that can be created by assembling this a * collection of splits. A queue of all the possible seams is * maintained. Each new split received is placed in that queue with * its partial priority value. These values in the seam queue are * evaluated and combined until a good enough seam is found. If no * further good seams are being found then this function returns to the * caller, who will send more splits. If this function is called with * a split of NULL, then no further splits can be supplied by the * caller. **********************************************************************/void choose_best_seam(SEAM_QUEUE seam_queue, SEAM_PILE *seam_pile, SPLIT *split, PRIORITY priority, SEAM **seam_result, TBLOB *blob) { SEAM *seam; TPOINT topleft; TPOINT botright; char str[80]; float my_priority; /* Add seam of split */ my_priority = priority; if (split != NULL) { seam = new_seam (my_priority, (split->point1->pos.x + split->point1->pos.x) / 2, split, NULL, NULL); if (chop_debug > 1) print_seam ("Partial priority ", seam); add_seam_to_queue (seam_queue, seam, (float) my_priority); if (my_priority > GOOD_PARTIAL_PRIORITY) return; } blob_bounding_box(blob, &topleft, &botright); /* Queue loop */ while (pop_next_seam (seam_queue, seam, my_priority)) { /* Set full priority */ my_priority = seam_priority (seam, topleft.x, botright.x); if (chop_debug) { sprintf (str, "Full my_priority %0.0f, ", my_priority); print_seam(str, seam); } if ((*seam_result == NULL || /* Replace answer */ (*seam_result)->priority > my_priority) && my_priority < ok_split) { /* No crossing */ if (constrained_split (seam->split1, blob)) { delete_seam(*seam_result); clone_seam(*seam_result, seam); (*seam_result)->priority = my_priority; } else { delete_seam(seam); seam = NULL; my_priority = BAD_PRIORITY; } } if (my_priority < good_split) { if (seam) delete_seam(seam); return; /* Made good answer */ } if (seam) { /* Combine with others */ if (array_count (*seam_pile) < MAX_NUM_SEAMS /*|| tessedit_truncate_chopper==0 */ ) { combine_seam(seam_queue, *seam_pile, seam); *seam_pile = array_push (*seam_pile, seam); } else delete_seam(seam); } my_priority = best_seam_priority (seam_queue); if ((my_priority > ok_split) || (my_priority > GOOD_PARTIAL_PRIORITY && split)) return; }}/********************************************************************** * combine_seam * * Find other seams to combine with this one. The new seams that result * from this union should be added to the seam queue. The return value * tells whether or not any additional seams were added to the queue. **********************************************************************/void combine_seam(SEAM_QUEUE seam_queue, SEAM_PILE seam_pile, SEAM *seam) { register INT16 x; register INT16 dist; INT16 bottom1, top1; INT16 bottom2, top2; SEAM *new_one; SEAM *this_one; bottom1 = seam->split1->point1->pos.y; if (seam->split1->point2->pos.y >= bottom1) top1 = seam->split1->point2->pos.y; else { top1 = bottom1; bottom1 = seam->split1->point2->pos.y; } if (seam->split2 != NULL) { bottom2 = seam->split2->point1->pos.y; if (seam->split2->point2->pos.y >= bottom2) top2 = seam->split2->point2->pos.y; else { top2 = bottom2; bottom2 = seam->split2->point2->pos.y; } } else { bottom2 = bottom1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -