[根目录](../CLAUDE.md) > **src**
# src 模块
## 模块职责
包含 macOS OCR MCP Server 的核心实现代码,包括:
- MCP 服务器启动与工具注册(`server.py`)
- OCR 识别与布局分析(`ocr.py`)
- 文本块聚类算法
- 样式分析(区分印刷体和强调文本)
- PDF 多页处理
## 入口与启动
### 服务器入口
**文件**: `server.py`
使用 FastMCP 框架启动 MCP 服务器,注册 OCR 工具。
```python
from mcp.server.fastmcp import FastMCP
import json
import os
from .ocr import recognize_text, recognize_text_with_layout
# Initialize FastMCP server
mcp = FastMCP("macos-ocr")
@mcp.tool()
def read_image_text(image_path: str) -> str:
"""
Read text from an image using macOS native OCR.
Args:
image_path: Absolute path to the local image file.
"""
if not os.path.exists(image_path):
raise FileNotFoundError(f"Image file not found: {image_path}")
try:
return recognize_text(image_path)
except Exception as e:
return f"Error processing image: {str(e)}"
@mcp.tool()
def read_image_layout(image_path: str) -> str:
"""
Read text with layout information (bounding boxes) from an image.
Returns a JSON string containing a list of text blocks with their content, confidence, and normalized bounding boxes.
Args:
image_path: Absolute path to the local image file.
"""
if not os.path.exists(image_path):
raise FileNotFoundError(f"Image file not found: {image_path}")
try:
data = recognize_text_with_layout(image_path)
return json.dumps(data, ensure_ascii=False)
except Exception as e:
return json.dumps({"error": str(e)})
def main():
mcp.run()
if __name__ == "__main__":
main()
```
### 启动命令
```bash
# 方式 1: 使用 uv
uv run src/server.py
# 方式 2: 使用 uvx(无需克隆仓库)
uvx --from git+https://github.com/wenjiazhu/macos-ocr-mcp.git macos-ocr
# 方式 3: 直接运行 OCR 测试
uv run src/ocr.py path/to/image.png
```
## 对外接口
### read_image_text
- **功能**: 读取图片或 PDF 中的纯文本,自动进行段落合并和表格优化
- **输入**: `image_path` - 图片或 PDF 的绝对路径
- **输出**: 识别后的纯文本字符串
### read_image_layout
- **功能**: 读取图片或 PDF 中的文本及布局信息,包含样式分析
- **输入**: `image_path` - 图片或 PDF 的绝对路径
- **输出**: JSON 字符串,包含文本块、边界框、样式类型(print/emphasized)、置信度等信息
## 关键依赖与配置
### 依赖库
**requirements.txt**:
```
mcp
pyobjc-framework-Vision
pyobjc-framework-Cocoa
pyobjc-framework-Quartz
pillow>=12.0.0
numpy>=2.2.6
```
### 主要依赖说明
- `mcp`: MCP 服务器框架(FastMCP)
- `pyobjc-framework-Vision`: macOS Vision 框架的 Python 绑定,用于原生 OCR
- `pyobjc-framework-Cocoa` 和 `pyobjc-framework-Quartz`: macOS 系统框架绑定,用于 PDF 处理
- `pillow` 和 `numpy`: 用于图像处理和样式分析
## 数据模型
### 文本块结构
```python
# recognize_text_with_layout 返回的每个文本块
block_data = {
"id": int, # 块编号
"page": int, # 页码
"text": str, # 合并后的文本(智能纠错)
"bbox": { # 边界框(归一化坐标)
"x": float, # x 坐标(0-1)
"y": float, # y 坐标(0-1,原点在左下角)
"w": float, # 宽度(0-1)
"h": float # 高度(0-1)
},
"type": str, # 样式类型:"print"(印刷体)或 "emphasized"(强调文本)
"lines": list # 构成块的原始行信息
}
```
### 样式分析原理
样式分析通过计算文本像素的 RGB 通道差异来判断文字类型:
```python
# 计算像素的彩色度偏差
diff = np.mean(np.abs(r - g) + np.abs(r - b) + np.abs(g - b))
# 阈值判断
if diff > 10:
block["type"] = "emphasized" # 高饱和度(红色、蓝色等)- 强调文本
else:
block["type"] = "print" # 低饱和度(黑色)- 印刷体
```
### OCR 结果格式
```python
# recognize_text 返回
"识别到的纯文本内容..."
# recognize_text_with_layout 返回
[
{
"id": 1,
"page": 1,
"text": "段落1",
"bbox": {"x": 0.1, "y": 0.2, "w": 0.8, "h": 0.1},
"type": "print",
"lines": [...]
},
...
]
```
## 核心算法
### 区块聚类算法
使用并查集算法将相邻的文本行聚合成语义块:
1. **垂直连接判断**:检查两个文本块在垂直方向是否连续(允许合理的行间距)
2. **水平对齐判断**:检查两个文本块在水平方向是否有重叠或对齐
3. **并查集合并**:满足条件的块合并为同一语义块
```python
def cluster_into_blocks(layout_items):
# 使用并查集将相邻的文本行聚合成语义块
# 优化的 N^2 算法(N 通常 < 1000)
...
```
### 块排序算法
按照阅读顺序(从上到下、从左到右)对语义块进行排序:
```python
def sort_blocks(blocks):
# 1. 按 Y 坐标(从上到下)排序
# 2. 使用分带逻辑处理同一行的块(按 X 坐标排序)
...
```
### 智能文本合并
自动修复中文被错误换行的问题:
```python
def smart_merge_text(text):
# 匹配被换行分隔的中文汉字
pattern = r'([\u4e00-\u9fa5])[\n\s]+([\u4e00-\u9fa5])'
return re.sub(pattern, r'\1\2', text)
```
## 测试与质量
### 测试方式
1. **直接运行 OCR**:
```bash
uv run src/ocr.py path/to/image.png
```
2. **集成测试**:
- 将服务器配置到 Claude Desktop 中
- 使用提供的提示词示例进行测试
- 参考 `skills/macos-ocr-helper/` 中的最佳实践
3. **样式分析测试**:
- 使用包含彩色文本的图片测试样式分析功能
- 验证 "emphasized" 和 "print" 类型的区分准确性
- PDF 文件会跳过样式分析(预期行为)
### 质量保证
- 使用 macOS Vision 框架的准确模式进行 OCR
- 支持中文简体、繁体和英文的混合识别
- 自动语言纠错启用
- 智能区块聚合优化表格和段落识别
## 常见问题 (FAQ)
### 1. OCR 不支持哪些格式?
目前支持常见的图片格式(PNG、JPG、GIF、TIFF 等)和 PDF 文件。不支持扫描质量极差的文档。
### 2. 如何提高识别准确率?
- 确保图片清晰度足够(推荐 300 DPI 或更高)
- 避免倾斜的图片
- 对于文字密集的文档,考虑分割成多个区域
- 增加图片对比度
### 3. 样式分析的原理是什么?
样式分析通过计算文本像素的 RGB 通道差异来判断文字类型:
- 高饱和度文字(如红色、蓝色)被识别为 "emphasized"(强调文本/手写注释)
- 低饱和度文字(如黑色)被识别为 "print"(印刷体)
- PDF 文件会跳过样式分析,默认使用 "print" 类型
### 4. 坐标系统是如何工作的?
Vision 框架使用归一化归一化坐标 [0, 1]:
- 原点 (0, 0) 在左下角
- X 轴向右增长
- Y 轴向上增长
- 这与 Pillow 的坐标系(原点在左上角)不同,需要转换
### 5. 如何处理多页 PDF?
项目内置 PDF 渲染引擎,自动处理多页 PDF:
- 使用 Quartz 框架将 PDF 每页转换为图像
- 对每页分别进行 OCR 识别
- 结果中包含页码信息用于区分
## 相关文件清单
| 文件 | 描述 |
|------|------|
| `server.py` | MCP 服务器实现与工具注册 |
| `ocr.py` | OCR 核心逻辑、布局分析、样式分析 |
|`__init__.py` | 模块初始化文件 |
| `../requirements.txt` | 项目依赖 |
| `../pyproject.toml` | 项目配置与构建设置 |
| `../skills/macos-ocr-helper/` | Claude Skill 定义与最佳实践 |
## 变更记录 (Changelog)
### 2026-01-18
- 更新模块文档,补充核心算法说明
- 添加样式分析原理和坐标系统说明
- 完善测试指南和常见问题解答
### 2025年12月
- 为 OCR 文本块添加样式分析,区分印刷体和强调文本
- 引入 Pillow (>=12.0.0) 和 NumPy (>=2.2.6) 依赖
- 实现智能区块聚合,优化表格和段落识别
- 支持多语言识别(中文简繁/英文)
- 集成 macOS Vision 框架实现离线 OCR