📄 scanedg.cpp
字号:
/********************************************************************** * File: scanedg.c (Formerly scanedge.c) * Description: Raster scanning crack based edge extractor. * Author: Ray Smith * Created: Fri Mar 22 16:11:50 GMT 1991 * * (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. * **********************************************************************/#include "mfcpch.h"#include "edgloop.h"//#include "dirtab.h"#include "scanedg.h"#define WHITE_PIX 1 /*thresholded colours */#define BLACK_PIX 0 /*W->B->W */#define FLIP_COLOUR(pix) (1-(pix))#define EWSIZE 4 /*edge operator size */#define XMARGIN 2 //margin needed#define YMARGIN 3 //by edge detector /*local freelist */static CRACKEDGE *free_cracks = NULL;/********************************************************************** * block_edges * * Extract edges from a PDBLK. **********************************************************************/DLLSYM void block_edges( //get edges in a block IMAGE *t_image, //threshold image PDBLK *block, //block in image ICOORD page_tr //corner of page ) { UINT8 margin; //margin colour INT16 x; //line coords INT16 y; //current line ICOORD bleft; //bounding box ICOORD tright; ICOORD block_bleft; //bounding box ICOORD block_tright; int xindex; //index to pixel BLOCK_LINE_IT line_it = block; //line iterator IMAGELINE bwline; //thresholded line //lines in progress CRACKEDGE *ptrlinemem[MAXIMAGEWIDTH]; CRACKEDGE **ptrline = ptrlinemem; if (t_image->get_xsize()+1 > MAXIMAGEWIDTH) { ptrline = new CRACKEDGE*[t_image->get_xsize()+1]; } //block box block->bounding_box (bleft, tright); block_bleft = bleft; block_tright = tright; for (x = tright.x () - bleft.x (); x >= 0; x--) ptrline[x] = NULL; //no lines in progress bwline.init (t_image->get_xsize()); margin = WHITE; for (y = tright.y () - 1; y >= bleft.y () - 1; y--) { if (y >= block_bleft.y () && y < block_tright.y ()) { t_image->get_line (bleft.x (), y, tright.x () - bleft.x (), &bwline, 0); make_margins (block, &line_it, bwline.pixels, margin, bleft.x (), tright.x (), y); } else { x = tright.x () - bleft.x (); for (xindex = 0; xindex < x; xindex++) bwline.pixels[xindex] = margin; } line_edges (bleft.x (), y, tright.x () - bleft.x (), margin, bwline.pixels, ptrline); } free_crackedges(free_cracks); //really free them free_cracks = NULL; if (ptrline != ptrlinemem) { delete [] ptrline; }}/********************************************************************** * make_margins * * Get an image line and set to margin non-text pixels. **********************************************************************/void make_margins( //get a line PDBLK *block, //block in image BLOCK_LINE_IT *line_it, //for old style UINT8 *pixels, //pixels to strip UINT8 margin, //white-out pixel INT16 left, //block edges INT16 right, INT16 y //line coord ) { PB_LINE_IT *lines; ICOORDELT_LIST *segments; //bits of a line ICOORDELT_IT seg_it; INT32 start; //of segment INT16 xext; //of segment int xindex; //index to pixel if (block->poly_block () != NULL) { lines = new PB_LINE_IT (block->poly_block ()); segments = lines->get_line (y); if (!segments->empty ()) { seg_it.set_to_list (segments); seg_it.mark_cycle_pt (); start = seg_it.data ()->x (); xext = seg_it.data ()->y (); for (xindex = left; xindex < right; xindex++) { if (xindex >= start && !seg_it.cycled_list ()) { xindex = start + xext - 1; seg_it.forward (); start = seg_it.data ()->x (); xext = seg_it.data ()->y (); } else pixels[xindex - left] = margin; } } else { for (xindex = left; xindex < right; xindex++) pixels[xindex - left] = margin; } delete segments; delete lines; } else { start = line_it->get_line (y, xext); for (xindex = left; xindex < start; xindex++) pixels[xindex - left] = margin; for (xindex = start + xext; xindex < right; xindex++) pixels[xindex - left] = margin; }}/********************************************************************** * whiteout_block * * Extract edges from a PDBLK. **********************************************************************/void whiteout_block( //clean it IMAGE *t_image, //threshold image PDBLK *block //block in image ) { INT16 x; //line coords INT16 y; //current line INT16 xext; //line width int xindex; //index to pixel UINT8 *dest; //destination pixel BOX block_box; //bounding box BLOCK_LINE_IT line_it = block; //line iterator IMAGELINE bwline; //thresholded line block_box = block->bounding_box (); for (y = block_box.bottom (); y < block_box.top (); y++) { //find line limits x = line_it.get_line (y, xext); t_image->get_line (x, y, xext, &bwline, 0); dest = bwline.pixels; //destination pixel for (xindex = 0; xindex < xext; xindex++) *dest++ = 1; t_image->put_line (x, y, xext, &bwline, 0); }}/********************************************************************** * line_edges * * Scan a line for edges and update the edges in progress. * When edges close into loops, send them for approximation. **********************************************************************/voidline_edges ( //scan for edgesINT16 x, //coord of line startINT16 y, //coord of lineINT16 xext, //width of lineUINT8 uppercolour, //start of prev lineUINT8 * bwpos, //thresholded lineCRACKEDGE ** prevline //edges in progress) { int xpos; //current x coord int xmax; //max x coord int colour; //of current pixel int prevcolour; //of previous pixel CRACKEDGE *current; //current h edge CRACKEDGE *newcurrent; //new h edge xmax = x + xext; //max allowable coord prevcolour = uppercolour; //forced plain margin current = NULL; //nothing yet //do each pixel for (xpos = x; xpos < xmax; xpos++, prevline++) { colour = *bwpos++; //current pixel if (*prevline != NULL) { //changed above //change colour uppercolour = FLIP_COLOUR (uppercolour); if (colour == prevcolour) { if (colour == uppercolour) { //finish a line join_edges(current, *prevline); current = NULL; //no edge now }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -