Leptonica 1.68
C Image Processing Library
|
Early beta code for locating and identifying line widths in 1d barcodes. More...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "allheaders.h"
#include "readbarcode.h"
Go to the source code of this file.
Early beta code for locating and identifying line widths in 1d barcodes.
Basic operations to locate and identify the line widths in 1D barcodes. Top level SARRAY *pixProcessBarcodes() Next levels PIXA *pixExtractBarcodes() SARRAY *pixReadBarcodes() l_int32 pixReadBarcodeWidths() Location BOXA *pixLocateBarcodes() static PIX *pixGenerateBarcodeMask() Extraction and deskew PIXA *pixDeskewBarcodes() Process to get line widths NUMA *pixExtractBarcodeWidths1() NUMA *pixExtractBarcodeWidths2() NUMA *pixExtractBarcodeCrossings() Average adjacent rasters static NUMA *pixAverageRasterScans() Signal processing for barcode widths NUMA *numaQuantizeCrossingsByWidth() static l_int32 numaGetCrossingDistances() static NUMA *numaLocatePeakRanges() static NUMA *numaGetPeakCentroids() static NUMA *numaGetPeakWidthLUT() NUMA *numaQuantizeCrossingsByWindow() static l_int32 numaEvalBestWidthAndShift() static l_int32 numaEvalSyncError() NOTE CAREFULLY: This is "early beta" code. It has not been tuned to work robustly on a large database of barcode images. I'm putting it out so that people can play with it, find out how it breaks, and contribute decoders for other barcode formats. Both the functional interfaces and ABI will almost certainly change in the coming few months. The actual decoder, in bardecode.c, at present only works on the following codes: Code I2of5, Code 2of5, Code 39, Code 93 Codabar and UPCA. To add another barcode format, it is necessary to make changes in readbarcode.h and bardecode.c. The program prog/barcodetest shows how to run from the top level (image --> decoded data).
Definition in file readbarcode.c.
#define DEBUG_DESKEW 1 |
Definition at line 105 of file readbarcode.c.
#define DEBUG_WIDTHS 0 |
Definition at line 106 of file readbarcode.c.
static PIX * pixGenerateBarcodeMask | ( | PIX * | pixs, |
l_int32 | maxspace, | ||
l_int32 | nwidth, | ||
l_int32 | nheight | ||
) | [static] |
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.
Definition at line 433 of file readbarcode.c.
References ERROR_PTR, NULL, pixCloseBrick(), pixDestroy(), pixGetDepth(), pixOpenBrick(), pixOr(), pixXor(), and PROCNAME.
Referenced by pixLocateBarcodes().
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
Definition at line 755 of file readbarcode.c.
References L_Queue::array, ERROR_PTR, GET_DATA_BYTE, L_NOCOPY, NULL, numaCreate(), numaGetFArray(), numaSetCount(), pixGetData(), pixGetDepth(), pixGetDimensions(), pixGetWpl(), and PROCNAME.
Referenced by pixExtractBarcodeCrossings().
static l_int32 numaGetCrossingDistances | ( | NUMA * | nas, |
NUMA ** | pnaedist, | ||
NUMA ** | pnaodist, | ||
l_float32 * | pmindist, | ||
l_float32 * | pmaxdist | ||
) | [static] |
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
Definition at line 984 of file readbarcode.c.
References ERROR_INT, L_INFO_FLOAT2, L_MAX, L_MIN, NULL, numaAddNumber(), numaCreate(), numaDestroy(), numaGetCount(), numaGetFValue(), numaGetMax(), numaGetMin(), and PROCNAME.
Referenced by numaQuantizeCrossingsByWidth(), and numaQuantizeCrossingsByWindow().
static NUMA * numaLocatePeakRanges | ( | NUMA * | nas, |
l_float32 | minfirst, | ||
l_float32 | minsep, | ||
l_float32 | maxmin | ||
) | [static] |
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.
Definition at line 1072 of file readbarcode.c.
References ERROR_PTR, FALSE, NULL, numaAddNumber(), numaCreate(), numaGetCount(), numaGetFValue(), numaSetValue(), PROCNAME, and TRUE.
Referenced by numaQuantizeCrossingsByWidth().
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
Definition at line 1127 of file readbarcode.c.
References ERROR_PTR, NULL, numaAddNumber(), numaCreate(), numaGetCount(), numaGetFValue(), numaGetIValue(), and PROCNAME.
Referenced by numaQuantizeCrossingsByWidth().
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.
Definition at line 1177 of file readbarcode.c.
References ERROR_PTR, L_NOCOPY, L_WARNING_FLOAT, NULL, numaCreate(), numaGetCount(), numaGetFArray(), numaGetIValue(), numaGetMax(), numaSetCount(), numaSetValue(), and PROCNAME.
Referenced by numaQuantizeCrossingsByWidth().
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] |
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.
Definition at line 1367 of file readbarcode.c.
References ERROR_INT, NULL, numaEvalSyncError(), and PROCNAME.
Referenced by numaQuantizeCrossingsByWindow().
static l_int32 numaEvalSyncError | ( | NUMA * | nas, |
l_int32 | ifirst, | ||
l_int32 | ilast, | ||
l_float32 | width, | ||
l_float32 | shift, | ||
l_float32 * | pscore, | ||
NUMA ** | pnad | ||
) | [static] |
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.
Definition at line 1437 of file readbarcode.c.
References ERROR_INT, numaCreate(), numaDestroy(), numaGetCount(), numaGetFValue(), numaGetIValue(), numaSetCount(), numaSetValue(), and PROCNAME.
Referenced by numaEvalBestWidthAndShift(), and numaQuantizeCrossingsByWindow().
SARRAY* pixProcessBarcodes | ( | PIX * | pixs, |
l_int32 | format, | ||
l_int32 | method, | ||
SARRAY ** | psaw, | ||
l_int32 | debugflag | ||
) |
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
Definition at line 124 of file readbarcode.c.
References barcodeFormatIsSupported(), ERROR_PTR, L_BF_ANY, L_USE_WIDTHS, L_USE_WINDOWS, NULL, pixaDestroy(), pixClone(), pixConvertTo8(), pixDestroy(), pixExtractBarcodes(), pixGetColormap(), pixGetDepth(), pixReadBarcodes(), and PROCNAME.
Referenced by main().
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
Definition at line 172 of file readbarcode.c.
References boxaDestroy(), boxaGetBox(), boxaGetCount(), boxaWriteStream(), boxDestroy(), ERROR_PTR, IFF_PNG, L_CLONE, L_INFO_FLOAT2, L_INFO_INT, L_INSERT, NULL, pixaAddBox(), pixaAddPix(), pixaCreate(), pixaDisplayTiledInRows(), pixDeskewBarcode(), pixDestroy(), pixDisplay(), pixGetColormap(), pixGetDepth(), pixLocateBarcodes(), pixWrite(), and PROCNAME.
Referenced by pixProcessBarcodes().
SARRAY* pixReadBarcodes | ( | PIXA * | pixa, |
l_int32 | format, | ||
l_int32 | method, | ||
SARRAY ** | psaw, | ||
l_int32 | debugflag | ||
) |
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
Definition at line 245 of file readbarcode.c.
References barcodeDispatchDecoder(), barcodeFormatIsSupported(), CALLOC, ERROR_INT, ERROR_PTR, L_BF_ANY, L_CLONE, L_COPY, L_INSERT, L_USE_WIDTHS, L_USE_WINDOWS, NULL, numaDestroy(), numaGetCount(), numaGetIValue(), pixaGetCount(), pixaGetPix(), pixDestroy(), pixReadBarcodeWidths(), PROCNAME, sarrayAddString(), sarrayCreate(), sarrayDestroy(), and sarrayGetCount().
Referenced by pixProcessBarcodes().
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
Definition at line 326 of file readbarcode.c.
References ERROR_PTR, L_USE_WIDTHS, L_USE_WINDOWS, NULL, numaWriteStream(), pixExtractBarcodeWidths1(), pixExtractBarcodeWidths2(), pixGetDepth(), and PROCNAME.
Referenced by pixReadBarcodes().
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
Definition at line 375 of file readbarcode.c.
References ERROR_PTR, L_ALL_EDGES, MAX_NOISE_HEIGHT, MAX_NOISE_WIDTH, MAX_SPACE_WIDTH, NULL, pixClone(), pixConnComp(), pixConvertTo8(), pixDestroy(), pixGenerateBarcodeMask(), pixGetColormap(), pixGetDepth(), pixInvert(), pixSobelEdgeFilter(), pixThresholdToBinary(), and PROCNAME.
Referenced by pixDeskewBarcode(), and pixExtractBarcodes().
PIX* pixDeskewBarcode | ( | PIX * | pixs, |
PIX * | pixb, | ||
BOX * | box, | ||
l_int32 | margin, | ||
l_int32 | threshold, | ||
l_float32 * | pangle, | ||
l_float32 * | pconf | ||
) |
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.
Definition at line 487 of file readbarcode.c.
References boxaCopy(), boxaDestroy(), boxaGetBox(), boxaGetCount(), boxaSort(), boxCreate(), boxDestroy(), boxGetGeometry(), ERROR_PTR, L_ABS, L_BRING_IN_WHITE, L_CLONE, L_ROTATE_AREA_MAP, L_SORT_BY_AREA, L_SORT_DECREASING, L_WARNING_INT, NULL, pixClipRectangle(), pixClone(), pixDestroy(), pixFindSkewSweepAndSearchScore(), pixGetDepth(), pixLocateBarcodes(), pixRotate(), pixRotateOrth(), and PROCNAME.
Referenced by pixExtractBarcodes().
NUMA* pixExtractBarcodeWidths1 | ( | PIX * | pixs, |
l_float32 | thresh, | ||
l_float32 | binfract, | ||
NUMA ** | pnaehist, | ||
NUMA ** | pnaohist, | ||
l_int32 | debugflag | ||
) |
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.
Definition at line 615 of file readbarcode.c.
References ERROR_PTR, NULL, numaDestroy(), numaQuantizeCrossingsByWidth(), pixExtractBarcodeCrossings(), pixGetDepth(), and PROCNAME.
Referenced by pixReadBarcodeWidths().
NUMA* pixExtractBarcodeWidths2 | ( | PIX * | pixs, |
l_float32 | thresh, | ||
l_float32 * | pwidth, | ||
NUMA ** | pnac, | ||
l_int32 | debugflag | ||
) |
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.
Definition at line 666 of file readbarcode.c.
References ERROR_PTR, NULL, numaDestroy(), numaQuantizeCrossingsByWindow(), pixExtractBarcodeCrossings(), pixGetDepth(), and PROCNAME.
Referenced by pixReadBarcodeWidths().
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
Definition at line 700 of file readbarcode.c.
References ERROR_PTR, GPLOT_LINES, GPLOT_X11, gplotAddPlot(), gplotCreate(), gplotDestroy(), gplotMakeOutput(), L_QUADRATIC_INTERP, NULL, numaCrossingsByThreshold(), numaDestroy(), numaInterpolateEqxInterval(), numaSelectCrossingThreshold(), pixAverageRasterScans(), pixGetDepth(), pixGetWidth(), and PROCNAME.
Referenced by pixExtractBarcodeWidths1(), and pixExtractBarcodeWidths2().
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.
Definition at line 822 of file readbarcode.c.
References ERROR_PTR, GPLOT_LINES, GPLOT_X11, gplotAddPlot(), gplotCreate(), gplotDestroy(), gplotMakeOutput(), L_WARNING, maxsize, NULL, numaAddNumber(), numaCreate(), numaDestroy(), numaGetCount(), numaGetCrossingDistances(), numaGetFValue(), numaGetIValue(), numaGetPeakCentroids(), numaGetPeakWidthLUT(), numaLocatePeakRanges(), numaMakeHistogramClipped(), numaWriteStream(), and PROCNAME.
Referenced by pixExtractBarcodeWidths1().
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.
Definition at line 1267 of file readbarcode.c.
References ERROR_PTR, FALSE, L_INFO_FLOAT2, L_WARNING_INT, NULL, numaAddNumber(), numaCreate(), numaDestroy(), numaEvalBestWidthAndShift(), numaEvalSyncError(), numaGetCount(), numaGetCrossingDistances(), numaGetFValue(), numaGetIValue(), PROCNAME, and TRUE.
Referenced by pixExtractBarcodeWidths2().
const l_int32 MAX_SPACE_WIDTH = 19 [static] |
Definition at line 78 of file readbarcode.c.
Referenced by pixLocateBarcodes().
const l_int32 MAX_NOISE_WIDTH = 50 [static] |
Definition at line 79 of file readbarcode.c.
Referenced by pixLocateBarcodes().
const l_int32 MAX_NOISE_HEIGHT = 30 [static] |
Definition at line 80 of file readbarcode.c.
Referenced by pixLocateBarcodes().