LOCALIZATION, BEFORE DECODING

Free Barcode Localization Comparator

Feed one image to two localization strategies. Each panel overlays the quads its strategy proposes and decodes those regions one by one; pass 03 then runs the prioritized list production uses.

How the three passes fit together
This is a comparison, not a benchmark. Both panels run the same SDK build on the same pixels. The localization templates contain no decoding stage, so every quad below is the localization stage's own output — a hypothesis, not a barcode. The two families are only separated here so you can see each one; in production they sit in one prioritized list, which is what pass 03 runs.

Classic localization

Idle

Shape-based detectors over the binarized image. Cheap enough to sit first in a production list — which is where they belong.

LocalizationMode

Shape rules only. Each one reads the same binarized image and can propose a region on its own.

Pick an image to run this pass.

Hypotheses
—
Regions
—
Localize
—
Decoded
—

Neural network localization

Idle

A model trained on labeled symbols. It normally sits last in that same list: worth its cost only on frames the shape rules could not read.

LocalizationMode

Introduced in bundle 11.2.2000. It is the only mode in this panel on purpose: one strategy against one strategy.

Pick an image to run this pass.

Hypotheses
—
Regions
—
Localize
—
Decoded
—

A quad that hugs the symbol too tightly cuts its quiet zone. Padding grows the crop outward from the quad's centre; the border pixels around the quad are the only thing added.

Where the two passes disagree

Decoded regions, classic vs neural—

Classic only—
In both lists—
Neural only—
Mean overlap of matches—

Load an image and both passes will run.

One list, not either/or

Applications do not choose between the two families. LocalizationModes is a prioritized list: the shape rules go first because they are cheap, the neural model goes last because it is not. The engine walks the list and stops as soon as it has the barcode count it was told to expect — with the default of 0, the first mode that produces a barcode ends the search. The model therefore costs time only on the frames the cheap rules could not read.

  • Cheap first. Connected blocks, lines and statistics answer most well-lit, well-printed frames before the model is ever loaded into the flow.
  • Escalate, don't pre-empt. Put the model first and every frame pays for it, including the ones the shape rules would have returned in a fraction of the time.
  • One capture, one result. No second SDK call, no merge logic in your code: the fallback happens inside the same decode.
Three passes, each run twice: classic only, neural only, then the list.

Pick an image first.

Why are these rows often faster than passes 01 and 02? Because they may stop. The decode section gives the engine something to succeed at, so the first mode that reads a barcode ends the localization loop and the rest of the list never starts. A localization-only template has nothing to decode, so it runs every mode it is given.

The flip side is real too: when nothing reads early, the row pays for every mode plus the decode attempts and becomes the slowest number on the page — load the crumpled sample to watch that happen. The panels are the microscope; this table is the machine. Every number on this page comes from the same clock: the SDK call only, with the canvas copy and intermediate-result settling outside it.

Loads when you pick an image — no camera, no sign-up

WHAT THIS PAGE ACTUALLY MEASURES

Localization answers “where”. Decoding answers “what”.

Most barcode demos collapse those two questions into one result. Here they are separated: a localization template with no decoding section produces quads, and a second pass reads only the quad it was given.

01

Localize with one strategy

The template holds a single ST_BARCODE_LOCALIZATION section. capture() returns no barcodes at all, so the quads come from the intermediate result of the localization stage — before any decoding has run.

02

Read the quad, not the image

Each region is cut out of the source canvas and handed to the decoder as its own small image. The full frame is never decoded again, so a decoded string can be traced back to the exact region that proposed it.

03

Compare, then distrust

Agreement between the two lists is not correctness. Both can propose the same false region, and either can find the one the other misses. The decode column is what separates a hypothesis from a read.

Two strategies, same image, same SDK build
 Classic modesNeural network
Looks atBinarized geometry: connected dark blocks, groups of parallel lines, repeating module patterns, optional direct scan lines.A trained model over image appearance, with no explicit contour or line rule to explain a single decision.
Cost on one imageUsually a few tens of milliseconds on a phone-sized photo.Higher, and the first run in a session also pays for the model download. This page warms both passes before the first visible run.
Typical failureDense text and thin rules look like bars; a busy background can produce dozens of candidates.Extreme glare or motion blur can remove the appearance cue entirely and return nothing.
Reasonable defaultConnected blocks first, then lines for 1D, then statistics for 2D.When contrast or background makes shape rules unreliable, and the extra milliseconds are affordable.

THE ORDER IS THE DESIGN

Cheap first, model last, inside one capture

Dynamsoft Barcode Reader does not ask you to pick a family. One barcode task holds one LocalizationModes list, and the engine walks it in order. Because the list is ordered, the model is a fallback rather than a tax on every frame.

  1. ExpectedBarcodesCount = 0, the default: the first mode that turns up a barcode ends the localization loop, and the remaining modes are never started.
  2. ExpectedBarcodesCount = N: keep escalating until N barcodes are read or the list runs out. Setting it above the number of codes on the frame forces every mode to run.
  3. Order is the cost model. Put the model first and every frame pays for it, including the ones the shape rules would have answered immediately.

One catch: a localization-only template has nothing to decode, so it can never satisfy that early exit and every listed mode runs. That is exactly why passes 01 and 02 exist — they isolate a family by switching the fallback off — and why pass 03 decodes the full frame instead.

LocalizationMode reference
Label sheet
The shape rules read the sheet before the model is reached, so the list finishes in classic time.
Crumpled pouch
Classic comes back empty, the list continues into the model, and pays for both families.
Direct glare
Classic reads the EAN-13. The model is in the list and is never started.

Swap the two families and every one of those frames pays the model price first. That is the whole argument for the order.

TEMPLATE GOTCHA

The modes are not a top-level key

In Barcode Reader 11.x a flat LocalizationModes on a task setting is accepted and then ignored — the capture quietly runs the preset defaults, and two “different” templates return identical quads. The modes belong to the localization section's stage. Both panels verify the modes the router reports back before showing a result.

Read the SDK guide on regions and templates
{
  "CaptureVisionTemplates": [{
    "Name": "classic-localization",
    "ImageROIProcessingNameArray": ["classic-localization-roi"]
  }],
  "BarcodeReaderTaskSettingOptions": [{
    "Name": "classic-localization-task",
    "SectionArray": [{
      "Section": "ST_BARCODE_LOCALIZATION",
      "StageArray": [{
        "Stage": "SST_LOCALIZE_CANDIDATE_BARCODES",
        "LocalizationModes": [
          { "Mode": "LM_CONNECTED_BLOCKS" },
          { "Mode": "LM_LINES" },
          { "Mode": "LM_STATISTICS" }
        ]
      }]
    }]
  }]
}
Why does a quad sometimes fail to decode?

A quad is a hypothesis about where a symbol is, not proof that one is there. Text blocks, logos and rounded corners can pass a shape rule. If a region is genuinely a barcode but still fails, look at its crop: a cut quiet zone, glare across the modules or a symbol smaller than a few pixels per module will all defeat the read.

Why decode a crop instead of re-running on the full image?

Because it is the only way to attribute a read to a region. It also removes the rest of the frame from the problem: a decode that fails on a crop failed for a reason inside that crop. The cost is that a badly placed quad cannot be rescued by context outside it.

Does a higher region count mean worse localization?

Not by itself. More regions can mean more redundant passes over the same symbol, or more false candidates. That is why the panel shows hypotheses and regions separately, and why the decode column exists: 15 regions that produce 11 reads are not obviously worse than 6 regions that produce 6.

So should I ship classic or neural?

Neither on its own. Ship one prioritized list with the shape rules first and LM_NEURAL_NETWORK last, then set ExpectedBarcodesCount to what the frame should contain — 1 for interactive scanning, 0 if you do not know. Frames the cheap rules can read never touch the model; frames they cannot get the second opinion automatically, in the same capture.

Why do the panels propose more regions than pass 03?

Because the panels run a localization-only template and list every mode of their family, so nothing can stop them early. Pass 03 decodes the frame, so the engine can stop as soon as it has an answer. Fewer regions there is not a better scan — it is a scan that had something to succeed at.

Can I reuse the exported templates?

Yes. Each panel exports a self-contained document you can pass to initSettings() in your own page, then run with capture(image, templateName). Self-hosting the SDK needs your own license; the hosted demo relies on a domain-bound one.

Classic — localization template