【图像识别】识别指定多个指定区域的文字

  • 本文介绍了一种通过OCR识别实现识别指定多个指定区域的文字的方案
  • 本文案例使用python实现,不过其他语言可以通过命令调用的方式接入
  • 文末提供了一种使用Java语言调用的办法

【图像识别】识别指定多个指定区域的文字

一、实现方案

  • 本脚本使用了 Tesseract OCR 引擎。它旨在从图像中识别文本,特别是从指定的图像区域中识别。
  • 为了提高速度,这个还使用了多线程进行识别
  • 脚本通过命令输入图像路径、识别区域,使用命令如下所示:
# 命令说明: python ocrr.py path_to_image.png {x0 y0 w0 h0} {x1 y1 w1 h1} {x2 y2 w2 h2} {......}
# 上方说明中的{}描述了一个区域
python ocrr.py 1712823565608.png 130 478 456 60 195 560 480 60 195 640 480 60 195 727 480 60 195 820 480 60 195 905 480 60 195 995 480 60 195 1085 480 60 195 1176 480 60

二、代码

(一)环境和依赖

  • 需要安装的依赖
pip install Pillow
pip install pytesseract
  • 此外,还需要安装Tesseract OCR ,并填写在下方代码处

(二)python代码和解释

  • 就下方的代码,运行多次了,拿来可以直接用
import sys
import io
import concurrent.futures
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

from PIL import Image
import pytesseract

# 设置Tesseract OCR的路径
pytesseract.pytesseract.tesseract_cmd = r'D:\software\Tesseract-OCR\tesseract.exe'
# 使用英文和中文识别,同时降低处理级别
custom_config = r'--oem 3 --psm 6 -l eng+chi_sim'

def recognize_text(image_path, rectangles):
    """
    识别图片上指定区域的文字
    :param image_path: 图片路径
    :param rectangles: Rectangle的列表,每个Rectangle为(x, y, width, height)
    :return: 一个字典,包含每个Rectangle对应的文字
    """
    # 创建一个字典来存储每个Rectangle对应的文字
    text_dict = {}
    
    with concurrent.futures.ThreadPoolExecutor() as executor:
        futures = []
        for i, rect in enumerate(rectangles):
            future = executor.submit(recognize_text_region, image_path, rect)
            futures.append((i, future))

        for i, future in futures:
            text_dict[i] = future.result()

    return text_dict

def recognize_text_region(image_path, rect):
    x, y, width, height = rect
    # 打开图片
    image = Image.open(image_path)
    # 裁剪出指定区域的图片
    region = image.crop((x, y, x + width, y + height))
    # 使用Tesseract OCR识别文字
    text = pytesseract.image_to_string(region, config=custom_config)
    return text.strip()

def main():
    # 获取图片路径
    if len(sys.argv) < 2:
        print("用法: python script.py <图片路径> <x1> <y1> <宽度1> <高度1> <x2> <y2> <宽度2> <高度2> ...")
        return

    image_path = sys.argv[1]
    # 解析矩形信息
    rectangles = []
    for i in range(2, len(sys.argv), 4):
        try:
            x = int(sys.argv[i])
            y = int(sys.argv[i+1])
            width = int(sys.argv[i+2])
            height = int(sys.argv[i+3])
            rectangles.append((x, y, width, height))
        except ValueError:
            print("矩形坐标输入无效。")
            return

    # 调用识别函数
    result = recognize_text(image_path, rectangles)

    # 按照输入的顺序打印识别结果
    for i in range(len(rectangles)):
        print(result[i])

if __name__ == "__main__":
    main()

三、运行效果

  • 图片不大方便展示,请看下方的执行效果
    在这里插入图片描述

四、Java如何调用


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Test {
    public static void main(String[] args) {
        try {
            long timestamp = System.currentTimeMillis();
            // 构建命令字符串
//            String pythonCommand = "python D:/temp/ocrr.py C:\\Users\\Administrator\\Desktop\\temp\\1712823565608.png 130 478 456 60 310 570 374 40";
            String pythonCommand = "python D:/temp/ocrr.py C:\\Users\\Administrator\\Desktop\\temp\\1712823565608.png " +
                    "130 478 456 60 " +
                    "195 560 480 60 " +
                    "195 640 480 60 " +
                    "195 727 480 60 " +
                    "195 820 480 60 " +
                    "195 905 480 60 " +
                    "195 995 480 60 " +
                    "195 1085 480 60 " +
                    "195 1176 480 60 "
                    ;
            System.out.println(pythonCommand);
            // 执行命令
            Process process = Runtime.getRuntime().exec(pythonCommand);

            // 读取命令执行结果
            InputStream inputStream = process.getInputStream();
//            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "GBK"));
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line.replaceAll(" ",""));
            }

            // 读取命令执行错误信息
            BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            while ((line = errorReader.readLine()) != null) {
                System.err.println(line);
            }

            // 检查命令执行是否成功
            int exitCode = process.waitFor();
            if (exitCode == 0) {
                System.out.println("Command executed successfully");
            } else {
                System.out.println("Command execution failed with error code: " + exitCode);
            }

            System.out.println((System.currentTimeMillis() - timestamp) + "ms.");
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

五、其他

  • 如果各位有需要,我可以封装为API给大家?有需要的在评论区告诉我,
  • 也可以加V保持沟通交流:xujian_cq
  • 在下的小程序“数字续坚”上还有更多有趣的东西,欢迎交流
posted @   成旭元  阅读(41)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示