Leptonica  1.54
Файл src/readbarcode.c
#include <string.h>
#include "allheaders.h"
#include "readbarcode.h"

Макросы

#define DEBUG_DESKEW   1
#define DEBUG_WIDTHS   0

Функции

static PIXpixGenerateBarcodeMask (PIX *pixs, l_int32 maxspace, l_int32 nwidth, l_int32 nheight)
static NUMApixAverageRasterScans (PIX *pixs, l_int32 nscans)
static l_int32 numaGetCrossingDistances (NUMA *nas, NUMA **pnaedist, NUMA **pnaodist, l_float32 *pmindist, l_float32 *pmaxdist)
static NUMAnumaLocatePeakRanges (NUMA *nas, l_float32 minfirst, l_float32 minsep, l_float32 maxmin)
static NUMAnumaGetPeakCentroids (NUMA *nahist, NUMA *narange)
static NUMAnumaGetPeakWidthLUT (NUMA *narange, NUMA *nacent)
static l_int32 numaEvalBestWidthAndShift (NUMA *nas, l_int32 nwidth, l_int32 nshift, l_float32 minwidth, l_float32 maxwidth, l_float32 *pbestwidth, l_float32 *pbestshift, l_float32 *pbestscore)
static l_int32 numaEvalSyncError (NUMA *nas, l_int32 ifirst, l_int32 ilast, l_float32 width, l_float32 shift, l_float32 *pscore, NUMA **pnad)
SARRAYpixProcessBarcodes (PIX *pixs, l_int32 format, l_int32 method, SARRAY **psaw, l_int32 debugflag)
PIXApixExtractBarcodes (PIX *pixs, l_int32 debugflag)
SARRAYpixReadBarcodes (PIXA *pixa, l_int32 format, l_int32 method, SARRAY **psaw, l_int32 debugflag)
NUMApixReadBarcodeWidths (PIX *pixs, l_int32 method, l_int32 debugflag)
BOXApixLocateBarcodes (PIX *pixs, l_int32 thresh, PIX **ppixb, PIX **ppixm)
PIXpixDeskewBarcode (PIX *pixs, PIX *pixb, BOX *box, l_int32 margin, l_int32 threshold, l_float32 *pangle, l_float32 *pconf)
NUMApixExtractBarcodeWidths1 (PIX *pixs, l_float32 thresh, l_float32 binfract, NUMA **pnaehist, NUMA **pnaohist, l_int32 debugflag)
NUMApixExtractBarcodeWidths2 (PIX *pixs, l_float32 thresh, l_float32 *pwidth, NUMA **pnac, l_int32 debugflag)
NUMApixExtractBarcodeCrossings (PIX *pixs, l_float32 thresh, l_int32 debugflag)
NUMAnumaQuantizeCrossingsByWidth (NUMA *nas, l_float32 binfract, NUMA **pnaehist, NUMA **pnaohist, l_int32 debugflag)
NUMAnumaQuantizeCrossingsByWindow (NUMA *nas, l_float32 ratio, l_float32 *pwidth, l_float32 *pfirstloc, NUMA **pnac, l_int32 debugflag)

Переменные

static const l_int32 MAX_SPACE_WIDTH = 19
static const l_int32 MAX_NOISE_WIDTH = 50
static const l_int32 MAX_NOISE_HEIGHT = 30

Макросы

#define DEBUG_DESKEW   1
#define DEBUG_WIDTHS   0

Функции

static l_int32 numaEvalBestWidthAndShift ( NUMA nas,
l_int32  nwidth,
l_int32  nshift,
l_float32  minwidth,
l_float32  maxwidth,
l_float32 pbestwidth,
l_float32 pbestshift,
l_float32 pbestscore 
) [static]

numaEvalBestWidthAndShift()

Input: nas (numa of crossing locations) nwidth (number of widths to consider) nshift (number of shifts to consider for each width) minwidth (smallest width to consider) maxwidth (largest width to consider) &bestwidth (<return> best size of window) &bestshift (<return> best shift for the window) &bestscore (<optional return>=""> average squared error of dist of crossing signal from the center of the window) Return: 0 if OK, 1 on error

Notes: (1) This does a linear sweep of widths, evaluating at shifts for each width, finding the (width, shift) pair that gives the minimum score.

static l_int32 numaEvalSyncError ( NUMA nas,
l_int32  ifirst,
l_int32  ilast,
l_float32  width,
l_float32  shift,
l_float32 pscore,
NUMA **  pnad 
) [static]

numaEvalSyncError()

Input: nas (numa of crossing locations) ifirst (first crossing to use) ilast (last crossing to use; use 0 for all crossings) width (size of window) shift (of center of window w/rt first crossing) &score (<optional return>=""> average squared error of dist of crossing signal from the center of the window) &nad (<optional return>=""> numa of 1s and 0s for crossings) Return: 0 if OK, 1 on error

Notes: (1) The score is computed only on the part of the signal from the to crossings. Use 0 for both of these to use all the crossings. The score is normalized for the number of crossings and with half-width of the window. (2) The optional return is a sequence of 0s and 1s, where a '1' indicates a crossing in the window.

static l_int32 numaGetCrossingDistances ( NUMA nas,
NUMA **  pnaedist,
NUMA **  pnaodist,
l_float32 pmindist,
l_float32 pmaxdist 
) [static]

numaGetCrossingDistances()

Input: nas (numa of crossing locations) &naedist (<optional return>=""> even distances between crossings) &naodist (<optional return>=""> odd distances between crossings) &mindist (<optional return>=""> min distance between crossings) &maxdist (<optional return>=""> max distance between crossings) Return: 0 if OK, 1 on error

static NUMA * numaGetPeakCentroids ( NUMA nahist,
NUMA narange 
) [static]

numaGetPeakCentroids()

Input: nahist (numa of histogram of crossing widths) narange (numa of ranges of x-values for the peaks in ) Return: nad (centroids for each peak found; max of 4, corresponding to 4 different barcode line widths), or null on error

static NUMA * numaGetPeakWidthLUT ( NUMA narange,
NUMA nacent 
) [static]

numaGetPeakWidthLUT()

Input: narange (numa of x-val ranges for the histogram width peaks) nacent (numa of centroids of each peak -- up to 4) Return: nalut (lookup table from the width of a bar to one of the four integerized barcode units), or null on error

Notes: (1) This generates the lookup table that maps from a sequence of widths (in some units) to the integerized barcode units (1, 2, 3, 4), which are the output integer widths between transitions. (2) The smallest width can be lost in float roundoff. To avoid losing it, we expand the peak range of the smallest width.

static NUMA * numaLocatePeakRanges ( NUMA nas,
l_float32  minfirst,
l_float32  minsep,
l_float32  maxmin 
) [static]

numaLocatePeakRanges()

Input: nas (numa of histogram of crossing widths) minfirst (min location of center of first peak) minsep (min separation between peak range centers) maxmin (max allowed value for min histo value between peaks) Return: nad (ranges for each peak found, in pairs), or null on error

Notes: (1) Units of are the index into nas. This puts useful constraints on peak-finding. (2) If maxmin == 0.0, the value of nas[i] must go to 0.0 (or less) between peaks. (3) All calculations are done in units of the index into nas. The resulting ranges are therefore integers. (4) The output nad gives pairs of range values for successive peaks. Any location [i] for which maxmin = nas[i] = 0.0 will NOT be included in a peak range. This works fine for histograms where if nas[i] == 0.0, it means that there are no samples at [i]. (5) For barcodes, when this is used on a histogram of barcode widths, use maxmin = 0.0. This requires that there is at least one histogram bin corresponding to a width value between adjacent peak ranges that is unpopulated, making the separation of the histogram peaks unambiguous.

NUMA* numaQuantizeCrossingsByWidth ( NUMA nas,
l_float32  binfract,
NUMA **  pnaehist,
NUMA **  pnaohist,
l_int32  debugflag 
)

numaQuantizeCrossingsByWidth()

Input: nas (numa of crossing locations, in pixel units) binfract (histo binsize as a fraction of minsize; e.g., 0.25) &naehist (<optional return>=""> histo of even (black) bar widths) &naohist (<optional return>=""> histo of odd (white) bar widths) debugflag (1 to generate plots of histograms of bar widths) Return: nad (sequence of widths, in unit sizes), or null on error

Notes: (1) This first computes the histogram of black and white bar widths, binned in appropriate units. There should be well-defined peaks, each corresponding to a specific width. The sequence of barcode widths (namely, the integers from the set {1,2,3,4}) is returned. (2) The optional returned histograms are binned in width units that are inversely proportional to . For example, if = 0.25, there are 4.0 bins in the distance of the width of the narrowest bar.

NUMA* numaQuantizeCrossingsByWindow ( NUMA nas,
l_float32  ratio,
l_float32 pwidth,
l_float32 pfirstloc,
NUMA **  pnac,
l_int32  debugflag 
)

numaQuantizeCrossingsByWindow()

Input: nas (numa of crossing locations) ratio (of max window size over min window size in search; typ. 2.0) &width (<optional return>=""> best window width) &firstloc (<optional return>=""> center of window for first xing) &nac (<optional return>=""> array of window crossings (0, 1, 2)) debugflag (1 to generate various plots of intermediate results) Return: nad (sequence of widths, in unit sizes), or null on error

Notes: (1) The minimum size of the window is set by the minimum distance between zero crossings. (2) The optional return signal is a sequence of 0s, 1s, and perhaps a few 2s, giving the number of crossings in each window. On the occasion where there is a '2', it is interpreted as ending two runs: the previous one and another one that has length 1.

static NUMA * pixAverageRasterScans ( PIX pixs,
l_int32  nscans 
) [static]

pixAverageRasterScans()

Input: pixs (input image; 8 bpp) nscans (number of adjacent scans, about the center vertically) Return: numa (of average pixel values across image), or null on error

PIX* pixDeskewBarcode ( PIX pixs,
PIX pixb,
BOX box,
l_int32  margin,
l_int32  threshold,
l_float32 pangle,
l_float32 pconf 
)

pixDeskewBarcode()

Input: pixs (input image; 8 bpp) pixb (binarized edge-filtered input image) box (identified region containing barcode) margin (of extra pixels around box to extract) threshold (for binarization; ~20) &angle (<optional return>=""> in degrees, clockwise is positive) &conf (<optional return>=""> confidence) Return: pixd (deskewed barcode), or null on error

Note: (1) The (optional) angle returned is the angle in degrees (cw positive) necessary to rotate the image so that it is deskewed.

NUMA* pixExtractBarcodeCrossings ( PIX pixs,
l_float32  thresh,
l_int32  debugflag 
)

pixExtractBarcodeCrossings()

Input: pixs (input image; 8 bpp) thresh (estimated pixel threshold for crossing white <--> black; typ. ~120) debugflag (use 1 to generate debug output) Return: numa (of crossings, in pixel units), or null on error

PIXA* pixExtractBarcodes ( PIX pixs,
l_int32  debugflag 
)

pixExtractBarcodes()

Input: pixs (8 bpp, no colormap) debugflag (use 1 to generate debug output) Return: pixa (deskewed and cropped barcodes), or null if none found or on error

NUMA* pixExtractBarcodeWidths1 ( PIX pixs,
l_float32  thresh,
l_float32  binfract,
NUMA **  pnaehist,
NUMA **  pnaohist,
l_int32  debugflag 
)

pixExtractBarcodeWidths1()

Input: pixs (input image; 8 bpp) thresh (estimated pixel threshold for crossing white <--> black; typ. ~120) binfract (histo binsize as a fraction of minsize; e.g., 0.25) &naehist (<optional return>=""> histogram of black widths; NULL ok) &naohist (<optional return>=""> histogram of white widths; NULL ok) debugflag (use 1 to generate debug output) Return: nad (numa of barcode widths in encoded integer units), or null on error

Note: (1) The widths are alternating black/white, starting with black and ending with black. (2) This method uses the widths of the bars directly, in terms of the (float) number of pixels between transitions. The histograms of these widths for black and white bars is generated and interpreted.

NUMA* pixExtractBarcodeWidths2 ( PIX pixs,
l_float32  thresh,
l_float32 pwidth,
NUMA **  pnac,
l_int32  debugflag 
)

pixExtractBarcodeWidths2()

Input: pixs (input image; 8 bpp) thresh (estimated pixel threshold for crossing white <--> black; typ. ~120) &width (<optional return>=""> best decoding window width, in pixels) &nac (<optional return>=""> number of transitions in each window) debugflag (use 1 to generate debug output) Return: nad (numa of barcode widths in encoded integer units), or null on error

Notes: (1) The widths are alternating black/white, starting with black and ending with black. (2) The optional best decoding window width is the width of the window that is used to make a decision about whether a transition occurs. It is approximately the average width in pixels of the narrowest white and black bars (i.e., those corresponding to unit width). (3) The optional return signal is a sequence of 0s, 1s, and perhaps a few 2s, giving the number of crossings in each window. On the occasion where there is a '2', it is interpreted as as ending two runs: the previous one and another one that has length 1.

static PIX * pixGenerateBarcodeMask ( PIX pixs,
l_int32  maxspace,
l_int32  nwidth,
l_int32  nheight 
) [static]

pixGenerateBarcodeMask()

Input: pixs (1 bpp) maxspace (largest space in the barcode, in pixels) nwidth (opening 'width' to remove noise) nheight (opening 'height' to remove noise) Return: pixm (mask over barcodes), or null if none found or on error

Notes: (1) For noise removal, 'width' and 'height' are referred to the barcode orientation. (2) If there is skew, the mask will not cover the barcode corners.

BOXA* pixLocateBarcodes ( PIX pixs,
l_int32  thresh,
PIX **  ppixb,
PIX **  ppixm 
)

pixLocateBarcodes()

Input: pixs (any depth) thresh (for binarization of edge filter output; typ. 20) &pixb (<optional return>=""> binarized edge filtered input image) &pixm (<optional return>=""> mask over barcodes) Return: boxa (location of barcodes), or null if none found or on error

SARRAY* pixProcessBarcodes ( PIX pixs,
l_int32  format,
l_int32  method,
SARRAY **  psaw,
l_int32  debugflag 
)

pixProcessBarcodes()

Input: pixs (any depth) format (L_BF_ANY, L_BF_CODEI2OF5, L_BF_CODE93, ...) method (L_USE_WIDTHS, L_USE_WINDOWS) &saw (<optional return>=""> sarray of bar widths) debugflag (use 1 to generate debug output) Return: sarray (text of barcodes), or null if none found or on error

SARRAY* pixReadBarcodes ( PIXA pixa,
l_int32  format,
l_int32  method,
SARRAY **  psaw,
l_int32  debugflag 
)

pixReadBarcodes()

Input: pixa (of 8 bpp deskewed and cropped barcodes) format (L_BF_ANY, L_BF_CODEI2OF5, L_BF_CODE93, ...) method (L_USE_WIDTHS, L_USE_WINDOWS); &saw (<optional return>=""> sarray of bar widths) debugflag (use 1 to generate debug output) Return: sa (sarray of widths, one string for each barcode found), or null on error

NUMA* pixReadBarcodeWidths ( PIX pixs,
l_int32  method,
l_int32  debugflag 
)

pixReadBarcodeWidths()

Input: pixs (of 8 bpp deskewed and cropped barcode) method (L_USE_WIDTHS, L_USE_WINDOWS); debugflag (use 1 to generate debug output) Return: na (numa of widths (each in set {1,2,3,4}), or null on error


Переменные

const l_int32 MAX_NOISE_HEIGHT = 30 [static]
const l_int32 MAX_NOISE_WIDTH = 50 [static]
const l_int32 MAX_SPACE_WIDTH = 19 [static]