OCR 文字识别 API 完整接入指南(Python / Java / PHP / C#)

0 阅读6分钟

本文从实际项目出发,讲清 OCR 文字识别的核心原理、常见方案,以及如何通过 API 在 10 分钟内完成系统接入。

在很多业务系统中,OCR(光学字符识别)已经是一个高频能力,比如:

  • 📄 文档数字化
  • 🧾 发票识别
  • 🪪 身份证识别
  • 📷 图片转文字
  • 🤖 RPA 自动录入

但很多团队在真正落地时会发现:OCR 看起来简单,工程化很复杂。

这篇文章带你一次讲透。

general.jpg

一、OCR 是怎么工作的?(通俗但工程视角)

一个完整的 OCR 流程通常包含 4 个阶段:

图像输入 → 文本检测 → 文本识别 → 结果结构化

我们逐个拆开看。

1️⃣ 图像预处理

目标:让文字“更容易被机器看清”。

常见操作包括:

  • 灰度化
  • 二值化
  • 去噪
  • 倾斜校正
  • 对比度增强

👉 这一步直接影响最终识别率。


2️⃣ 文本检测(Text Detection)

这一阶段解决的问题是:

哪里有文字?

算法会在图片中定位出文本区域(bounding box)。

常见难点:

  • 多行文本
  • 弯曲文本
  • 小字体
  • 复杂背景

3️⃣ 文本识别(Text Recognition)

这一阶段才是:

文字具体是什么?

通常基于深度学习序列模型完成。

难点包括:

  • 多语言
  • 手写体
  • 模糊图片
  • 低分辨率

4️⃣ 结果结构化(工程中非常重要)

真实业务往往不仅要“识别文字”,还要:

  • 按行返回
  • 按字段返回
  • 转成 JSON
  • 做字段映射

👉 这是很多 demo 和生产系统的分水岭。

二、自己做 OCR vs 直接接 API?

很多团队一开始都会纠结这个问题,我给一个非常现实的对比。


🧠 自研 OCR 的成本

如果完全自研,你通常需要:

  • 模型训练
  • 数据集
  • 推理服务
  • GPU 资源
  • 持续优化

保守周期:2–6 个月起

而且还不包含:

  • 版面适配
  • 多语言
  • 稳定性
  • 并发能力

🚀 API 方案的优势

大多数业务场景,更推荐直接接入成熟 OCR API,因为可以:

  • 快速上线
  • 降低算法成本
  • 支持多语言
  • 易于扩展

👉 这也是现在绝大多数 SaaS / 工具站的选择。


三、OCR API 标准接入流程(实战)

下面给出一个通用接入流程,基本所有 OCR 平台都适用。


Step 1:准备图片输入

常见两种方式:

方式 A:上传文件

<input type="file" />

方式 B:传图片 URL

适合服务端批处理场景。


Step 2:调用 OCR API

如果你正在做系统集成,建议优先看完整接口文档(通常包含多语言示例),可以少踩很多坑。

👉 接口文档: market.shiliuai.com/doc/advance…

image.png 下面是调用示例

Python 示例

# -*- coding: utf-8 -*-
import requests
import base64
import json

# 请求接口
URL = "https://ocr-api.shiliuai.com/api/advanced_general_ocr/v1"

# 图片/pdf文件转base64
def get_base64(file_path):
    with open(file_path, "rb") as f:
        data = f.read()
    return base64.b64encode(data).decode("utf8")

def demo(appcode, file_path):
    # 请求头
    headers = {
        "Authorization": "APPCODE %s" % appcode,
        "Content-Type": "application/json"
    }

    # 请求体
    b64 = get_base64(file_path)
    data = {"file_base64": b64}

    # 请求
    response = requests.post(url=URL, headers=headers, json=data)
    content = json.loads(response.content)
    print(content)

if __name__ == "__main__":
    appcode = "你的APPCODE"
    file_path = "本地文件路径"
    demo(appcode, file_path)

java 示例

//main.java
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Base64;

public class Main {
    public static String get_base64(String path) {
        String b64 = "";
        try {
            // 使用Commons IO简化文件读取
            byte[] content = FileUtils.readFileToByteArray(new File(path));
            // 使用JDK自带的Base64
            b64 = Base64.getEncoder().encodeToString(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return b64;
    }

    public static void main(String[] args) {
        String url = "https://ocr-api.shiliuai.com/api/advanced_general_ocr/v1";// 请求接口
        String appcode = "你的APPCODE";
        String imgFile = "本地文件路径";

        Map headers = new HashMap<>();
        headers.put("Authorization", "APPCODE " + appcode);
        headers.put("Content-Type", "application/json");

        // 请求体
        JSONObject requestObj = new JSONObject();
        requestObj.put("file_base64", get_base64(imgFile));
        String bodys = requestObj.toString();

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            // 创建POST请求
            HttpPost httpPost = new HttpPost(url);

            // 设置请求头
            for (Map.Entry entry : headers.entrySet()) {
                httpPost.addHeader(entry.getKey(), entry.getValue());
            }

            // 设置请求体
            StringEntity entity = new StringEntity(bodys, "UTF-8");
            httpPost.setEntity(entity);

            // 执行请求
            HttpResponse response = httpClient.execute(httpPost);
            int stat = response.getStatusLine().getStatusCode();
            if (stat != 200) {
                System.out.println("Http code: " + stat);
                return;
            }
            String res = EntityUtils.toString(response.getEntity());
            JSONObject res_obj = JSON.parseObject(res);

            System.out.println(res_obj.toJSONString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

php 示例

// 图片/pdf转base64
function get_base64($path){
    if($fp = fopen($path, "rb", 0)) {
        $binary = fread($fp, filesize($path));// 文件读取
        fclose($fp);
        $b64 = base64_encode($binary);// 转base64
    }else{
        $b64="";
        printf("%s 文件不存在", $path);
    }
    return $b64;
}

$url = "https://ocr-api.shiliuai.com/api/advanced_general_ocr/v1";
$appcode = "你的appcode";
$img_path = "图片路径";
$method = "POST";

//请求头
$headers = array();
array_push($headers, "Authorization:APPCODE " . $appcode);
array_push($headers, "Content-Type:application/json");

//请求体
$b64 = get_base64($img_path);
$data = array(
    "file_base64" => $b64
);
$post_data = json_encode($data);

// 请求
$curl = curl_init();
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_FAILONERROR, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);

$result = curl_exec($curl);
var_dump($result);

c# 示例

using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace MyCSharpApp
{
    public class Program
    {
        public static string GetBase64(string path)
        {
            string b64 = "";
            try
            {
                // 读取文件内容
                byte[] content = File.ReadAllBytes(path);
                // 转换为Base64
                b64 = Convert.ToBase64String(content);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            return b64;
        }

        public static async Task Main(string[] args)
        {
            string url = "https://ocr-api.shiliuai.com/api/advanced_general_ocr/v1";// 请求接口
            string appcode = "你的APPCODE";
            string imgFile = "本地文件路径";

            // 设置请求头 
            Dictionary headers = new Dictionary
            {
                { "Authorization", "APPCODE " + appcode }
                // Content-Type 将在创建 StringContent 时设置
            };

            // 请求体
            JObject requestObj = new JObject();
            requestObj["file_base64"] = GetBase64(imgFile);
            string body = requestObj.ToString();

            try
            {
                using (HttpClient client = new HttpClient())
                {
                    // 设置请求头
                    foreach (var header in headers)
                    {
                        client.DefaultRequestHeaders.Add(header.Key, header.Value);
                    }
                    // 创建请求内容 
                    StringContent content = new StringContent(body, Encoding.UTF8, "application/json");
                    HttpResponseMessage response = await client.PostAsync(url, content);
                    if (!response.IsSuccessStatusCode)
                    {
                        Console.WriteLine($"Http code: {(int)response.StatusCode}");
                        return;
                    }
                    // 读取响应内容
                    string responseContent = await response.Content.ReadAsStringAsync();
                    JObject resObj = JObject.Parse(responseContent);
                    Console.WriteLine(resObj.ToString(Formatting.Indented));
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}

更多示例

如易语言API接入示例、天诺API接入示例、懒人精灵API接入示例、按键精灵API接入示例等等可以查看代码接入API说明:market.shiliuai.com/doc/advance…

四、返回结果该怎么处理?

一个典型 OCR 返回通常包含:

  • 原始文本
  • 行级结果
  • 坐标信息
  • 置信度

前端常见展示方式:

// 渲染识别文本
result.lines.forEach(line => {
  console.log(line.text)
})

⭐ 实战建议

如果你的业务是结构化场景(如发票 / 身份证),建议:

  • 优先用结构化 OCR
  • 不要自己再做正则解析
  • 能省大量维护成本

五、真实项目中最常见的坑

这些是我见过团队踩得最多的。


❗ 坑 1:直接拿手机原图就识别

问题:

  • 图片过大
  • 倾斜
  • 光照不均

建议至少做:

  • 尺寸压缩
  • 基础预处理

识别率会明显提升。


❗ 坑 2:忽略并发与限流

OCR 属于计算密集型服务。

上线前一定要考虑:

  • QPS 限制
  • 重试机制
  • 超时处理

否则高峰期很容易失败。


❗ 坑 3:只测清晰样本

很多 demo 成功率很高,但线上翻车,因为真实用户会上传:

  • 模糊图
  • 截图
  • 压缩图
  • 夜拍

👉 一定要用“脏数据”压测。


六、什么时候用在线 OCR,什么时候用 API?

一个简单判断:


✅ 适合在线工具

  • 临时识别
  • 人工使用
  • 少量图片
  • 快速验证效果

如果你只是想快速测试一张图片,可以先在线跑一遍看看识别效果。

👉 在线体验: market.shiliuai.com/general-ocr


✅ 适合 API 接入

  • 系统自动化
  • 批量处理
  • 嵌入业务流程
  • RPA / SaaS

七、写在最后

OCR 的技术门槛其实不低,但业务接入门槛已经被 API 极大降低了

真正影响项目成败的,往往不是模型本身,而是:

  • 是否稳定
  • 是否易接入
  • 是否支持结构化
  • 是否能扛并发

如果你正在做:

  • 文档处理系统
  • 自动录入平台
  • AI 工具站
  • RPA 项目

OCR 基本是一个值得尽早接入的基础能力。