如何用PHP项目实现OCR文字识别?

wen java案例 2

本文目录导读:

如何用PHP项目实现OCR文字识别?

  1. 使用Tesseract OCR(推荐方案)
  2. 使用PHP扩展(php-tesseract)
  3. 调用云OCR服务API
  4. 完整项目示例:图片上传+OCR识别
  5. 性能优化建议
  6. 选择合适的方案

我来详细介绍几种在PHP项目中实现OCR文字识别的方法:

使用Tesseract OCR(推荐方案)

环境安装

# Ubuntu/Debian
sudo apt-get install tesseract-ocr
sudo apt-get install tesseract-ocr-chi-sim  # 中文语言包
# CentOS/RHEL
sudo yum install tesseract
sudo yum install tesseract-langpack-chi-sim
# macOS
brew install tesseract
brew install tesseract-lang

PHP实现代码

<?php
class OCRService {
    private $tesseractPath;
    private $language;
    public function __construct($language = 'chi_sim+eng') {
        $this->tesseractPath = '/usr/bin/tesseract'; // 根据系统调整
        $this->language = $language;
    }
    /**
     * 使用Tesseract进行OCR识别
     */
    public function recognizeImage($imagePath) {
        $outputFile = tempnam(sys_get_temp_dir(), 'ocr_');
        $command = sprintf(
            '%s %s %s -l %s 2>&1',
            escapeshellcmd($this->tesseractPath),
            escapeshellarg($imagePath),
            escapeshellarg($outputFile),
            escapeshellarg($this->language)
        );
        exec($command, $output, $returnCode);
        if ($returnCode !== 0) {
            throw new Exception('OCR识别失败: ' . implode("\n", $output));
        }
        $result = file_get_contents($outputFile . '.txt');
        unlink($outputFile . '.txt');
        return trim($result);
    }
}
// 使用示例
$ocr = new OCRService();
$text = $ocr->recognizeImage('/path/to/image.jpg');
echo $text;
?>

使用PHP扩展(php-tesseract)

安装扩展

# 编译安装
git clone https://github.com/thiagoalessio/tesseract-ocr-for-php.git
cd tesseract-ocr-for-php
composer install
# 或使用Composer
composer require thiagoalessio/tesseract_ocr

实现代码

<?php
require_once 'vendor/autoload.php';
use thiagoalessio\TesseractOCR\TesseractOCR;
class PHPOCRService {
    public function recognize($imagePath) {
        try {
            $text = (new TesseractOCR($imagePath))
                ->lang('chi_sim+eng')
                ->psm(6)  // 页面分割模式
                ->run();
            return $text;
        } catch (Exception $e) {
            return '识别失败: ' . $e->getMessage();
        }
    }
    // 图片预处理优化
    public function preprocessImage($imagePath) {
        $image = new Imagick($imagePath);
        // 转为灰度
        $image->setImageType(Imagick::IMGTYPE_GRAYSCALE);
        // 调整对比度
        $image->contrastImage(true);
        // 二值化
        $image->thresholdImage(0.5 * Imagick::getQuantum());
        // 去除噪点
        $image->medianFilterImage(2);
        $processedPath = tempnam(sys_get_temp_dir(), 'processed_') . '.jpg';
        $image->writeImage($processedPath);
        $image->destroy();
        return $processedPath;
    }
}
// 使用示例
$service = new PHPOCRService();
$processedImage = $service->preprocessImage('input.jpg');
$text = $service->recognize($processedImage);
unlink($processedImage);
echo $text;
?>

调用云OCR服务API

百度云OCR示例

<?php
class BaiduOCRService {
    private $appId;
    private $apiKey;
    private $secretKey;
    private $accessToken;
    public function __construct($appId, $apiKey, $secretKey) {
        $this->appId = $appId;
        $this->apiKey = $apiKey;
        $this->secretKey = $secretKey;
        $this->getAccessToken();
    }
    private function getAccessToken() {
        $url = 'https://aip.baidubce.com/oauth/2.0/token';
        $postData = [
            'grant_type' => 'client_credentials',
            'client_id' => $this->apiKey,
            'client_secret' => $this->secretKey
        ];
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $response = curl_exec($ch);
        curl_close($ch);
        $result = json_decode($response, true);
        $this->accessToken = $result['access_token'];
    }
    public function recognizeGeneral($imagePath) {
        $image = base64_encode(file_get_contents($imagePath));
        $url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token=' . $this->accessToken;
        $postData = [
            'image' => $image
        ];
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/x-www-form-urlencoded'
        ]);
        $response = curl_exec($ch);
        curl_close($ch);
        return json_decode($response, true);
    }
}
// 使用
$ocr = new BaiduOCRService('your_app_id', 'your_api_key', 'your_secret_key');
$result = $ocr->recognizeGeneral('test.jpg');
print_r($result);
?>

完整项目示例:图片上传+OCR识别

<?php
// index.php
class OCRWebApp {
    private $uploadDir;
    private $ocrService;
    public function __construct() {
        $this->uploadDir = __DIR__ . '/uploads/';
        if (!file_exists($this->uploadDir)) {
            mkdir($this->uploadDir, 0755, true);
        }
        $this->ocrService = new TesseractOCRService();
    }
    public function handleRequest() {
        if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['image'])) {
            return $this->processUpload();
        }
        return $this->renderForm();
    }
    private function processUpload() {
        $file = $_FILES['image'];
        // 验证文件
        $allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
        if (!in_array($file['type'], $allowedTypes)) {
            return ['error' => '只支持JPG、PNG、GIF格式'];
        }
        // 保存文件
        $filename = uniqid() . '_' . basename($file['name']);
        $filepath = $this->uploadDir . $filename;
        move_uploaded_file($file['tmp_name'], $filepath);
        // OCR识别
        try {
            $text = $this->ocrService->recognize($filepath);
            return [
                'success' => true,
                'text' => $text,
                'filename' => $filename
            ];
        } catch (Exception $e) {
            return ['error' => '识别失败: ' . $e->getMessage()];
        } finally {
            // 清理临时文件
            unlink($filepath);
        }
    }
    private function renderForm($result = null) {
        ?>
        <!DOCTYPE html>
        <html>
        <head>
            <title>OCR文字识别</title>
            <meta charset="utf-8">
            <style>
                body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
                .container { border: 1px solid #ddd; padding: 20px; border-radius: 5px; }
                .result { margin-top: 20px; padding: 10px; background: #f5f5f5; border-radius: 3px; white-space: pre-wrap; }
                .error { color: red; }
                .success { color: green; }
            </style>
        </head>
        <body>
            <div class="container">
                <h1>OCR文字识别</h1>
                <form method="post" enctype="multipart/form-data">
                    <input type="file" name="image" accept="image/*" required>
                    <button type="submit">识别文字</button>
                </form>
                <?php if ($result): ?>
                    <?php if (isset($result['error'])): ?>
                        <div class="result error"><?php echo $result['error']; ?></div>
                    <?php else: ?>
                        <div class="result success">
                            <h3>识别结果:</h3>
                            <?php echo htmlspecialchars($result['text']); ?>
                        </div>
                    <?php endif; ?>
                <?php endif; ?>
            </div>
        </body>
        </html>
        <?php
    }
}
class TesseractOCRService {
    public function recognize($imagePath) {
        $outputFile = tempnam(sys_get_temp_dir(), 'ocr_');
        $command = sprintf(
            'tesseract %s %s -l chi_sim+eng 2>&1',
            escapeshellarg($imagePath),
            escapeshellarg($outputFile)
        );
        exec($command, $output, $returnCode);
        if ($returnCode !== 0) {
            throw new Exception(implode("\n", $output));
        }
        $result = file_get_contents($outputFile . '.txt');
        unlink($outputFile . '.txt');
        return trim($result);
    }
}
// 运行应用
$app = new OCRWebApp();
$result = $app->handleRequest();
echo $result;
?>

性能优化建议

图片预处理优化

<?php
class ImagePreprocessor {
    public function optimizeForOCR($imagePath) {
        $image = new Imagick($imagePath);
        // 调整大小(保持宽高比)
        $image->resizeImage(2000, 0, Imagick::FILTER_LANCZOS, 1);
        // 增强对比度
        $image->contrastImage(true);
        $image->normalizeImage();
        // 锐化
        $image->sharpenImage(0, 1);
        // 去噪
        $image->reduceNoiseImage(1);
        // 输出优化后的图片
        $optimizedPath = tempnam(sys_get_temp_dir(), 'optimized_') . '.jpg';
        $image->setImageCompressionQuality(95);
        $image->writeImage($optimizedPath);
        $image->destroy();
        return $optimizedPath;
    }
}
?>

选择合适的方案

  1. Tesseract OCR:免费、本地运行,适合对隐私要求高的场景
  2. 云服务API:识别准确率高,但需要付费和网络
  3. 混合方案:小图片用本地OCR,大图片或复杂场景用云API

建议从Tesseract开始,如果准确率不够再考虑升级到云服务。

抱歉,评论功能暂时关闭!