传入Tesseract OCR前的图片预处理:JS端cropper.js裁剪后文本识别不准问题咨询
基于JS的OCR前置图片预处理方案
以下方案针对裁剪后图片的常见缺陷优化,全部基于原生Canvas和常用JS库实现,实测可以大幅提升简单文本场景的OCR识别率:
- 裁剪边缘优化
cropper.js导出的裁剪图经常出现边缘卡文字、半透明像素残留的问题,会直接干扰OCR的文本定位逻辑,建议裁剪后先给画布四周添加15px左右的同背景色补白,同时清理边缘的半透明像素。
function addPaddingToCroppedImage(originCanvas, padding = 15, bgColor = '#ffffff') { const newWidth = originCanvas.width + padding * 2; const newHeight = originCanvas.height + padding * 2; const newCanvas = document.createElement('canvas'); newCanvas.width = newWidth; newCanvas.height = newHeight; const ctx = newCanvas.getContext('2d'); ctx.fillStyle = bgColor; ctx.fillRect(0, 0, newWidth, newHeight); ctx.drawImage(originCanvas, padding, padding); return newCanvas; }
- 自适应二值化处理
低对比度、背景有杂色的图片OCR识别率极低,通过自适应阈值二值化可以把文字和背景完全分离,大幅提升识别精度。
function adaptiveThreshold(canvas, blockSize = 11, C = 2) { const ctx = canvas.getContext('2d'); const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); const data = imgData.data; const width = canvas.width; const height = canvas.height; // 先转灰度图 for (let i = 0; i < data.length; i += 4) { const gray = 0.299 * data[i] + 0.587 * data[i+1] + 0.114 * data[i+2]; data[i] = data[i+1] = data[i+2] = gray; } // 自适应阈值计算 const halfBlock = Math.floor(blockSize / 2); for (let y = 0; y < height; y++) { for (let x = 0; x < width; x++) { let sum = 0, count = 0; for (let dy = -halfBlock; dy <= halfBlock; dy++) { for (let dx = -halfBlock; dx <= halfBlock; dx++) { const nx = x + dx, ny = y + dy; if (nx >= 0 && nx < width && ny >=0 && ny < height) { sum += data[(ny * width + nx) * 4]; count++; } } } const threshold = sum / count - C; const idx = (y * width + x) *4; const val = data[idx] > threshold ? 255 : 0; data[idx] = data[idx+1] = data[idx+2] = val; } } ctx.putImageData(imgData, 0, 0); return canvas; }
- 分辨率适配
OCR引擎对单字高度低于20px的小字体识别率非常差,裁剪后如果文字太小,先等比放大到单字高度30px以上,缩放时使用高画质平滑算法保证文字边缘清晰。
function scaleImageForOCR(originCanvas, scale = 1.5) { const newCanvas = document.createElement('canvas'); newCanvas.width = originCanvas.width * scale; newCanvas.height = originCanvas.height * scale; const ctx = newCanvas.getContext('2d'); // 开启高画质图像平滑 ctx.imageSmoothingEnabled = true; ctx.imageSmoothingQuality = 'high'; ctx.drawImage(originCanvas, 0, 0, newCanvas.width, newCanvas.height); return newCanvas; }
- 倾斜校正
裁剪时如果存在2°以上的倾斜,会大幅降低OCR识别率,可以调用Tesseract.js自带的倾斜检测能力校正后再识别。
async function deskewImage(canvas) { const { data } = await Tesseract.detect(canvas); const angle = data.rotate; if (Math.abs(angle) < 0.5) return canvas; const newCanvas = document.createElement('canvas'); const ctx = newCanvas.getContext('2d'); const rad = angle * Math.PI / 180; const cos = Math.cos(rad); const sin = Math.sin(rad); newCanvas.width = Math.abs(canvas.width * cos) + Math.abs(canvas.height * sin); newCanvas.height = Math.abs(canvas.width * sin) + Math.abs(canvas.height * cos); ctx.translate(newCanvas.width / 2, newCanvas.height / 2); ctx.rotate(rad); ctx.drawImage(canvas, -canvas.width / 2, -canvas.height / 2); return newCanvas; }
以上步骤可以按「补白→缩放→倾斜校正→二值化」的顺序串成处理流水线,处理后的图片再传给OCR引擎识别即可。
内容的提问来源于stack exchange,提问作者bytzu
相关产品推荐
相关产品推荐

