@scanmate/ocr 0.0.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -3
- package/dist/index.esm.js +743 -25
- package/dist/src/index.d.ts +4 -2
- package/dist/src/page-reading/index.d.ts +2 -2
- package/dist/src/page-reading/match-words.use-case.d.ts +6 -1
- package/dist/src/page-reading/ocr-report.contract.d.ts +23 -0
- package/dist/src/page-reading/recheck-run.use-case.d.ts +24 -8
- package/dist/src/print-verification/glyph-cells.use-case.d.ts +86 -0
- package/dist/src/print-verification/glyph-templates.use-case.d.ts +40 -0
- package/dist/src/print-verification/index.d.ts +10 -0
- package/dist/src/print-verification/merge-reading.mapper.d.ts +19 -0
- package/dist/src/print-verification/print-polarity.policy.d.ts +11 -0
- package/dist/src/print-verification/verify-print.use-case.d.ts +122 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,20 +1,34 @@
|
|
|
1
|
-

|
|
1
|
+

|
|
2
2
|
|
|
3
3
|
# `@scanmate/ocr`
|
|
4
4
|
|
|
5
5
|
Measures how closely a scan's text matches the original's: a score per page and for the document, ten measures, both texts in full, and every difference with its position on the page.
|
|
6
6
|
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
*A printed account number, and the same line on the returned scan where one digit has been replaced by another of the same run. `@scanmate/ocr` matches printed figures against the original's own glyphs, so it reads this for what it is. Made from the [IRS Form W-9](https://www.irs.gov/pub/irs-pdf/fw9.pdf) (a work of the United States government, in the public domain): filled in as a generator would, printed, signed by hand and scanned crooked.*
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @scanmate/ocr @scanmate/extract @scanmate/align
|
|
15
|
+
```
|
|
16
|
+
|
|
7
17
|
```ts
|
|
8
18
|
import { alignPages } from '@scanmate/align'
|
|
9
19
|
import { extractPair } from '@scanmate/extract'
|
|
10
20
|
import { ocrPages } from '@scanmate/ocr'
|
|
11
21
|
|
|
12
|
-
const { pages } = await extractPair({ original: '
|
|
22
|
+
const { pages } = await extractPair({ original: 'fw9-issued.pdf', scanned: 'fw9-returned.pdf' })
|
|
13
23
|
const report = await ocrPages(await alignPages(pages))
|
|
14
24
|
|
|
25
|
+
// The account number above, read for what it is:
|
|
26
|
+
report.pages[0].differences // [{ kind: 'changed', expected: 'Account 4412-9087-3355',
|
|
27
|
+
// found: 'Account 4412-9987-3355', reason: 'numbers',
|
|
28
|
+
// verified: true, x, y, width, height }]
|
|
29
|
+
report.pages[0].printChecks // { checked, different }: figures matched against the original's glyphs
|
|
15
30
|
report.score // document score, weighted by characters
|
|
16
31
|
report.pages[0].metrics // levenshtein, jaccard, dice, cosine, CER, WER, word recall, ...
|
|
17
|
-
report.pages[0].differences // { kind: 'changed' | 'missing' | 'added', expected, found, x, y, ... }
|
|
18
32
|
report.pages[0].original.text // the original's text
|
|
19
33
|
report.pages[0].scanned.text // the scan's
|
|
20
34
|
```
|
|
@@ -25,6 +39,8 @@ report.pages[0].scanned.text // the scan's
|
|
|
25
39
|
- **The scan** is read with tesseract, at 300 dpi (it is enlarged first if lower), or from its `enhanced` image when `@scanmate/enhance` ran first.
|
|
26
40
|
- **Matching by place, not order.** Alignment puts the scan on the original's canvas, so each word read is claimed by the run of the original printed where it was read. A two-column page read column by column is therefore not a page of errors, and every difference has a position.
|
|
27
41
|
- **Figures must keep their digits.** A run whose digits read back differently has changed, however similar the rest is: "Total 1,250.00" read as "Total 7,250.00" is 93% similar. A figure whose separators alone differ ("5.768.700 00") is the same figure. Words keep OCR's tolerance (`matchThreshold`, 0.8).
|
|
42
|
+
- **Figures are matched, not only read.** Every printed figure is checked glyph by glyph against the original's own ink and against the other digits the page prints, at the scan's own sharpness. That settles what no reading of a coarse scan can: whether this is still the digit that was printed. On real returned scans it verified 35 of 40 printed figures at 125 dpi with no false calls, and read a digit replaced by another of the same run for what it is.
|
|
43
|
+
- **It abstains rather than confirm.** A page that prints too few digits to offer a full set of rivals, a run too small to segment, a cell too soft to call: each is left to the reading, and the answer is applied only to the cells it actually decided. Confirming a digit that had in fact been altered would be worse than saying nothing, so every threshold is set to fail that way.
|
|
28
44
|
- **What is not an addition.** Words over something the original prints without text, such as a logo, are not additions. Nor are specks under 4 pt tall.
|
|
29
45
|
|
|
30
46
|
## The recheck
|
|
@@ -75,3 +91,7 @@ Nothing is downloaded and, by default, nothing is written. This matters where de
|
|
|
75
91
|
| `matchThreshold` | `0.8` | Word similarity below which a run has changed. |
|
|
76
92
|
| `minWordConfidence` | `60` | For words to count as added. |
|
|
77
93
|
| `recheck` | on | `{ passes, agree }`, or `false`. |
|
|
94
|
+
|
|
95
|
+
## How it decides
|
|
96
|
+
|
|
97
|
+
[`documentation/algorithms.md`](./documentation/algorithms.md) has the algorithms in full: what each step measures, the decision flows, every constant with the measurement behind it, and what the package deliberately does not do.
|