0

0

优化 Tesseract.js 处理多栏图像的文本识别

碧海醫心

碧海醫心

发布时间:2025-11-21 14:44:38

|

1020人浏览过

|

来源于php中文网

原创

优化 tesseract.js 处理多栏图像的文本识别

本文旨在解决 Tesseract.js 在处理多栏图像时文本识别混淆的问题。核心在于调整 Tesseract 的页面分段模式(PSM)。通过将默认的 PSM_SINGLE_BLOCK 更改为更适合多栏布局的模式,如 PSM_AUTO_OSD,可以显著提高识别准确性,实现按列分离的文本输出。文章将详细介绍 PSM 的概念、不同模式的应用以及如何在 React.js 项目中集成这一优化。

Tesseract.js 多栏图像文本识别优化指南

在使用 Tesseract.js 进行光学字符识别(OCR)时,开发者经常会遇到一个挑战:当处理包含两列或三列文本的图像时,Tesseract 可能会将不同列的文本混淆在一起,导致识别结果难以阅读和使用。这通常不是 Tesseract 引擎本身的问题,而是其默认的页面分段模式(Page Segmentation Mode, PSM)不适用于此类复杂布局。

理解页面分段模式 (PSM)

Tesseract OCR 引擎在进行文本识别之前,会先对图像进行页面布局分析,将图像分割成不同的文本块、行和单词。这个过程由页面分段模式(PSM)控制。不同的 PSM 模式指示 Tesseract 应该如何理解和分析页面的整体结构。

  • PSM_SINGLE_BLOCK (默认模式): 这是 Tesseract.js 的默认 PSM 模式。它假设图像中的所有文本都构成一个单一的、统一的文本块。对于单列文档或简单的图像,这种模式通常工作良好。然而,对于多列布局,它会导致 Tesseract 尝试将所有文本作为一个整体来处理,从而混淆不同列的内容。
  • 多栏布局的挑战: 在多栏文档中,文本是按垂直列排布的。如果 Tesseract 误认为这是一个单一的文本块,它会从左到右扫描整个宽度,将第一列的底部与第二列的顶部混淆,最终导致文本逻辑混乱。

针对多栏布局的 PSM 选择

为了解决多栏图像的文本混淆问题,我们需要选择一个更适合复杂布局的 PSM 模式。推荐尝试以下几种:

  1. PSM_AUTO_OSD (自动页面方向和脚本检测,然后进行图像分割): 这是一个非常强大的模式,它会首先尝试检测图像的页面方向和脚本,然后根据检测到的布局自动进行页面分割。对于多栏文档,PSM_AUTO_OSD 通常能更好地识别出独立的列并按顺序处理它们。根据实际测试,此模式能够成功地先识别左列,再识别右列。

  2. PSM_AUTO (自动页面分割,但无 OSD): 类似于 PSM_AUTO_OSD,但不会进行页面方向和脚本检测。如果确定图像方向和脚本是正确的,可以尝试此模式。

  3. PSM_SINGLE_COLUMN (将图像视为一个单一的列): 如果图像确实是单列但可能包含其他非文本元素,或者希望 Tesseract 强制将其视为一列,可以使用此模式。但这不适用于真正的多列情况。

    Magic AI Avatars
    Magic AI Avatars

    神奇的AI头像,获得200多个由AI制作的自定义头像。

    下载
  4. PSM_SPARSE_TEXT (稀疏文本,允许任意顺序): 当图像中包含少量不规则分布的文本时,此模式可能有用。它不会尝试对文本进行严格的块或列分析。

在 Tesseract.js 中应用 PSM

在 Tesseract.js 中设置 PSM 非常简单,可以通过 Tesseract.recognize() 函数的第三个参数(配置对象)来传递。

示例代码:修改 handleSubmit 函数

以下是基于提供的 React.js 代码片段,展示如何修改 handleSubmit 函数以集成 PSM 配置:

import React, { useState, useEffect } from "react";
import Tesseract from "tesseract.js";
import ClipboardJS from "clipboard";
import Select from "react-select";

// ... (languageOptions 和其他组件代码保持不变)

const ImagesToText = () => {
  const [isLoading, setIsLoading] = useState(false);
  const [images, setImages] = useState([]);
  const [texts, setTexts] = useState([]);
  const [progress, setProgress] = useState(0);
  const [currentImageIndex, setCurrentImageIndex] = useState(0);
  const [errorMessage, setErrorMessage] = useState("");
  const [errorLanguagesMessage, setErrorLanguagesMessage] = useState("");
  const [selectedLanguages, setSelectedLanguages] = useState([]);

  // ... (handleImageUpload, handleCopyText, handleDownloadText, useEffect, handleReset 等函数保持不变)

  const handleSubmit = async () => {
    if (images.length === 0) {
      setErrorMessage("Select an image to convert.");
      return;
    }

    if (selectedLanguages.length === 0) {
      setErrorLanguagesMessage("Select any language.");
      return;
    }

    setIsLoading(true);
    setProgress(0);
    setTexts([]);
    setCurrentImageIndex(0);
    setErrorMessage("");
    setErrorLanguagesMessage("");

    const totalImages = images.length;
    let processedImages = 0;

    if (Array.isArray(images)) {
      for (const [index, image] of images?.entries()) {
        setCurrentImageIndex(index + 1);

        try {
          const result = await Tesseract.recognize(
            image,
            selectedLanguages.map((lang) => lang.value).join("+"),
            {
              // 在这里添加 PSM 配置
              // 推荐使用 psm: 3 (PSM_AUTO_OSD) 来处理多栏布局
              // 你也可以尝试其他值,例如 psm: 1 (PSM_AUTO)
              logger: (m) => {
                // 可选:添加 logger 追踪 Tesseract 进程
                if (m.status === "recognizing") {
                  // console.log(`Progress: ${m.progress}`);
                }
              },
              // 关键配置:设置页面分段模式
              // PSM_AUTO_OSD 对应的值是 3
              // PSM_AUTO 对应的值是 1
              // 更多 PSM 值可以参考 Tesseract 官方文档
              psm: 3 // 尝试 PSM_AUTO_OSD
            }
          );
          // 原有的文本处理逻辑
          const paragraphs = result.data.text.split("\n\n");
          const formattedParagraphs = paragraphs.map((paragraph) => {
            const sentences = paragraph.split(/[.|?]\s/);
            return sentences.join(" ");
          });
          setTexts((prevTexts) => [...prevTexts, ...formattedParagraphs]);
        } catch (err) {
          console.error(err);
          // Clear texts and stop conversion process immediately on error
          setTexts([]);
          setProgress(0);
          setIsLoading(false);
          return;
        } finally {
          processedImages++;
          const currentProgress = (processedImages / totalImages) * 100;
          setProgress(currentProgress);
        }
      }
    } else {
      console.error("Images is not an array.");
    }

    setIsLoading(false);
  };

  // ... (return 语句保持不变)
};

export default ImagesToText;

在上述代码中,关键的改动是在 Tesseract.recognize() 函数的第三个参数中添加了一个配置对象 { psm: 3 }。这里的 psm: 3 对应的是 PSM_AUTO_OSD 模式。

注意事项与最佳实践

  1. 实验与测试: 不同的文档类型和图像质量可能需要不同的 PSM 模式。强烈建议对您的具体用例进行实验,尝试 psm: 1 (PSM_AUTO)、psm: 3 (PSM_AUTO_OSD) 等值,以找到最适合的配置。
  2. 图像预处理: 尽管 PSM 可以解决布局问题,但良好的图像预处理仍然至关重要。这包括:
    • 二值化: 将彩色或灰度图像转换为黑白图像,提高文本与背景的对比度。
    • 去噪: 移除图像中的杂点和干扰。
    • 去倾斜: 纠正图像的倾斜角度,使文本行保持水平。
    • 缩放: 确保文本有足够的分辨率,通常建议文本高度至少为 20-30 像素。
  3. 语言包: 确保您加载了正确的语言包。Tesseract.js 需要对应的语言数据才能准确识别文本。
  4. 错误处理: 在实际应用中,完善的错误处理机制是必不可少的,以应对识别失败或图像损坏的情况。

总结

Tesseract.js 是一个强大的 OCR 工具,但在处理多栏图像时,其默认的页面分段模式可能会导致文本混淆。通过理解并正确配置 psm 参数,特别是使用 PSM_AUTO_OSD (对应 psm: 3),可以显著提高多栏文档的识别准确性,确保文本按逻辑顺序输出。结合适当的图像预处理和持续的测试,您可以在 React.js 应用中实现高效且准确的 OCR 功能。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

530

2023.06.20

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

576

2023.07.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

6208

2023.08.17

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

492

2023.09.01

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

Js中concat和push的区别
Js中concat和push的区别

Js中concat和push的区别:1、concat用于将两个或多个数组合并成一个新数组,并返回这个新数组,而push用于向数组的末尾添加一个或多个元素,并返回修改后的数组的新长度;2、concat不会修改原始数组,是创建新的数组,而push会修改原数组,将新元素添加到原数组的末尾等等。本专题为大家提供concat和push相关的文章、下载、课程内容,供大家免费下载体验。

240

2023.09.14

js截取字符串的方法介绍
js截取字符串的方法介绍

JavaScript字符串截取方法,包括substring、slice、substr、charAt和split方法。这些方法可以根据具体需求,灵活地截取字符串的不同部分。在实际开发中,根据具体情况选择合适的方法进行字符串截取,能够提高代码的效率和可读性 。

303

2023.09.21

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 6万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1万人学习

React核心原理新老生命周期精讲
React核心原理新老生命周期精讲

共12课时 | 1.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号