tesseract fallback engine
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
import type { Stroke, RecognitionCandidate } from './types'
|
||||
import { strokesToCanvas } from './preprocess'
|
||||
import type Tesseract from 'tesseract.js'
|
||||
import type { PSM } from 'tesseract.js'
|
||||
|
||||
let worker: Tesseract.Worker | null = null
|
||||
let loading = false
|
||||
|
||||
export function isReady(): boolean {
|
||||
return worker !== null
|
||||
}
|
||||
|
||||
export async function init(): Promise<void> {
|
||||
if (worker || loading) return
|
||||
loading = true
|
||||
|
||||
try {
|
||||
const Tesseract = await import('tesseract.js')
|
||||
worker = await Tesseract.createWorker('eng')
|
||||
await worker.setParameters({
|
||||
tessedit_char_whitelist: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
// SAFETY: '10' is exactly PSM.SINGLE_CHAR, so the literal lands inside the enum's value set
|
||||
tessedit_pageseg_mode: '10' as PSM, // single character
|
||||
})
|
||||
} catch (e) {
|
||||
console.warn('Tesseract init failed:', e)
|
||||
worker = null
|
||||
}
|
||||
loading = false
|
||||
}
|
||||
|
||||
export async function recognize(strokes: Stroke[]): Promise<RecognitionCandidate[]> {
|
||||
if (!worker) return []
|
||||
|
||||
try {
|
||||
const imageData = strokesToCanvas(strokes, 128)
|
||||
|
||||
// convert ImageData to canvas for tesseract
|
||||
const canvas = new OffscreenCanvas(128, 128)
|
||||
const ctx = canvas.getContext('2d')!
|
||||
ctx.putImageData(imageData, 0, 0)
|
||||
const blob = await canvas.convertToBlob({ type: 'image/png' })
|
||||
|
||||
const result = await worker.recognize(blob)
|
||||
const text = result.data.text.trim().toUpperCase()
|
||||
|
||||
if (text.length === 1 && text >= 'A' && text <= 'Z') {
|
||||
const confidence = result.data.confidence / 100
|
||||
return [{ letter: text, confidence }]
|
||||
}
|
||||
|
||||
return []
|
||||
} catch (e) {
|
||||
console.warn('Tesseract recognition failed:', e)
|
||||
return []
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user