📄 pitsync1.cpp
字号:
/********************************************************************** * File: pitsync1.cpp (Formerly pitsync.c) * Description: Code to find the optimum fixed pitch segmentation of some blobs. * Author: Ray Smith * Created: Thu Nov 19 11:48:05 GMT 1992 * * (C) Copyright 1992, 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. * **********************************************************************/#include "mfcpch.h"#ifdef __UNIX__#include <assert.h>#endif#include <math.h>#include "memry.h"#include "pitsync1.h"#include "notdll.h"ELISTIZE (FPSEGPT) CLISTIZE (FPSEGPT_LIST)#define EXTERNEXTERNINT_VAR (pitsync_linear_version, 6, "Use new fast algorithm");EXTERNdouble_VAR (pitsync_joined_edge, 0.75,"Dist inside big blob for chopping");EXTERNdouble_VAR (pitsync_offset_freecut_fraction, 0.25,"Fraction of cut for free cuts");EXTERNINT_VAR (pitsync_fake_depth, 1, "Max advance fake generation");/********************************************************************** * FPSEGPT::FPSEGPT * * Constructor to make a new FPSEGPT. * The existing FPCUTPT is duplicated. **********************************************************************/FPSEGPT::FPSEGPT( //constructor FPCUTPT *cutpt //create from new form ) { pred = NULL; mean_sum = cutpt->sum (); sq_sum = cutpt->squares (); cost = cutpt->cost_function (); faked = cutpt->faked; terminal = cutpt->terminal; fake_count = cutpt->fake_count; xpos = cutpt->position (); mid_cuts = cutpt->cheap_cuts ();}/********************************************************************** * FPSEGPT::FPSEGPT * * Constructor to make a new FPSEGPT. **********************************************************************/FPSEGPT::FPSEGPT ( //constructorINT16 x //position):xpos (x) { pred = NULL; mean_sum = 0; sq_sum = 0; cost = 0; faked = FALSE; terminal = FALSE; fake_count = 0; mid_cuts = 0;}/********************************************************************** * FPSEGPT::FPSEGPT * * Constructor to make a new FPSEGPT. **********************************************************************/FPSEGPT::FPSEGPT ( //constructorINT16 x, //positionBOOL8 faking, //faking this oneINT16 offset, //dist to gapINT16 region_index, //segment numberINT16 pitch, //proposed pitchINT16 pitch_error, //allowed toleranceFPSEGPT_LIST * prev_list //previous segment):xpos (x) { INT16 best_fake; //on previous FPSEGPT *segpt; //segment point INT32 dist; //from prev segment double sq_dist; //squared distance double mean; //mean pitch double total; //total dists double factor; //cost function FPSEGPT_IT pred_it = prev_list;//for previuos segment cost = MAX_FLOAT32; pred = NULL; faked = faking; terminal = FALSE; best_fake = MAX_INT16; mid_cuts = 0; for (pred_it.mark_cycle_pt (); !pred_it.cycled_list (); pred_it.forward ()) { segpt = pred_it.data (); if (segpt->fake_count < best_fake) best_fake = segpt->fake_count; dist = x - segpt->xpos; if (dist >= pitch - pitch_error && dist <= pitch + pitch_error && !segpt->terminal) { total = segpt->mean_sum + dist; sq_dist = dist * dist + segpt->sq_sum + offset * offset; //sum of squarees mean = total / region_index; factor = mean - pitch; factor *= factor; factor += sq_dist / (region_index) - mean * mean; if (factor < cost) { cost = factor; //find least cost pred = segpt; //save path mean_sum = total; sq_sum = sq_dist; fake_count = segpt->fake_count + faked; } } } if (fake_count > best_fake + 1) pred = NULL; //fail it}/********************************************************************** * check_pitch_sync * * Construct the lattice of possible segmentation points and choose the * optimal path. Return the optimal path only. * The return value is a measure of goodness of the sync. **********************************************************************/double check_pitch_sync( //find segmentation BLOBNBOX_IT *blob_it, //blobs to do INT16 blob_count, //no of blobs INT16 pitch, //pitch estimate INT16 pitch_error, //tolerance STATS *projection, //vertical FPSEGPT_LIST *seg_list //output list ) { INT16 x; //current coord INT16 min_index; //blob number INT16 max_index; //blob number INT16 left_edge; //of word INT16 right_edge; //of word INT16 right_max; //max allowed x INT16 min_x; //in this region INT16 max_x; INT16 region_index; INT16 best_region_index = 0; //for best result INT16 offset; //dist to legal area INT16 left_best_x; //edge of good region INT16 right_best_x; //right edge BOX min_box; //bounding box BOX max_box; //bounding box BOX next_box; //box of next blob FPSEGPT *segpt; //segment point FPSEGPT_LIST *segpts; //points in a segment double best_cost; //best path double mean_sum; //computes result FPSEGPT *best_end; //end of best path BLOBNBOX_IT min_it; //copy iterator BLOBNBOX_IT max_it; //copy iterator FPSEGPT_IT segpt_it; //iterator //output segments FPSEGPT_IT outseg_it = seg_list; FPSEGPT_LIST_CLIST lattice; //list of lists //region iterator FPSEGPT_LIST_C_IT lattice_it = &lattice; // tprintf("Computing sync on word of %d blobs with pitch %d\n", // blob_count, pitch); // if (blob_count==8 && pitch==27) // projection->print(stdout,TRUE); if (pitch < 3) pitch = 3; //nothing ludicrous if ((pitch - 3) / 2 < pitch_error) pitch_error = (pitch - 3) / 2; min_it = *blob_it; min_box = box_next (&min_it); //get box // if (blob_count==8 && pitch==27) // tprintf("1st box at (%d,%d)->(%d,%d)\n", // min_box.left(),min_box.bottom(), // min_box.right(),min_box.top()); //left of word left_edge = min_box.left () + pitch_error; for (min_index = 1; min_index < blob_count; min_index++) { min_box = box_next (&min_it); // if (blob_count==8 && pitch==27) // tprintf("Box at (%d,%d)->(%d,%d)\n", // min_box.left(),min_box.bottom(), // min_box.right(),min_box.top()); } right_edge = min_box.right (); //end of word max_x = left_edge;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -