PHP项目身份证识别如何解析正反面信息

wen PHP项目 29

本文目录导读:

PHP项目身份证识别如何解析正反面信息

  1. 使用第三方OCR接口(推荐,准确率高)
  2. 使用开源OCR库(Tesseract)
  3. 身份证信息验证
  4. 完整使用示例
  5. 推荐方案

在PHP项目中解析身份证正反面信息,通常有以下几种主流方案:

使用第三方OCR接口(推荐,准确率高)

百度AI身份证识别

<?php
// 使用百度AI接口
require_once 'AipOcr.php'; // 百度PHP SDK
class IdCardOCR {
    private $client;
    public function __construct($appId, $apiKey, $secretKey) {
        $this->client = new AipOcr($appId, $apiKey, $secretKey);
    }
    // 解析身份证
    public function recognize($imagePath) {
        $image = file_get_contents($imagePath);
        // 正面识别
        $frontResult = $this->client->idcard($image, 'front');
        // 反面识别
        $backResult = $this->client->idcard($image, 'back');
        return [
            'front' => $frontResult['words_result'] ?? [],
            'back'  => $backResult['words_result'] ?? []
        ];
    }
}
// 使用示例
$ocr = new IdCardOCR('your_app_id', 'your_api_key', 'your_secret_key');
$result = $ocr->recognize('idcard.jpg');
// 正面信息
$frontInfo = $result['front'];
echo "姓名:" . $frontInfo['姓名']['words'] . "\n";
echo "身份证号:" . $frontInfo['公民身份号码']['words'] . "\n";
// 反面信息
$backInfo = $result['back'];
echo "签发机关:" . $backInfo['签发机关']['words'] . "\n";
echo "有效期限:" . $backInfo['有效期限']['words'] . "\n";
?>

腾讯云OCR

<?php
require_once 'vendor/autoload.php';
use TencentCloud\Common\Credential;
use TencentCloud\Ocr\V20181119\OcrClient;
use TencentCloud\Ocr\V20181119\Models\IDCardOCRRequest;
class TencentIdCardOCR {
    private $client;
    public function __construct($secretId, $secretKey) {
        $cred = new Credential($secretId, $secretKey);
        $this->client = new OcrClient($cred, "ap-guangzhou");
    }
    public function recognize($imageBase64, $cardSide = 'FRONT') {
        $req = new IDCardOCRRequest();
        $req->ImageBase64 = $imageBase64;
        $req->CardSide = $cardSide; // FRONT 或 BACK
        $resp = $this->client->IDCardOCR($req);
        return json_decode($resp->toJsonString(), true);
    }
}
// 使用示例
$ocr = new TencentIdCardOCR('your_secret_id', 'your_secret_key');
// 识别正面
$frontImage = base64_encode(file_get_contents('idcard_front.jpg'));
$frontResult = $ocr->recognize($frontImage, 'FRONT');
// 识别反面
$backImage = base64_encode(file_get_contents('idcard_back.jpg'));
$backResult = $ocr->recognize($backImage, 'BACK');
?>

阿里云OCR

<?php
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
class AliyunIdCardOCR {
    public function recognize($imageUrl, $side = 'face') {
        AlibabaCloud::accessKeyClient('your_access_key_id', 'your_access_key_secret')
            ->regionId('cn-shanghai')
            ->asDefaultClient();
        try {
            $result = AlibabaCloud::rpc()
                ->product('ocr')
                ->scheme('https')
                ->version('2019-12-30')
                ->action('RecognizeIdentityCard')
                ->method('POST')
                ->options([
                    'query' => [
                        'Side' => $side, // face 或 back
                        'ImageURL' => $imageUrl
                    ],
                ])
                ->request();
            return $result->toArray();
        } catch (ClientException $e) {
            echo $e->getErrorMessage() . PHP_EOL;
        } catch (ServerException $e) {
            echo $e->getErrorMessage() . PHP_EOL;
        }
    }
}
?>

使用开源OCR库(Tesseract)

<?php
class SimpleIdCardOCR {
    // 使用Tesseract OCR(需要安装Tesseract)
    public function recognizeWithTesseract($imagePath) {
        // 先进行图像预处理
        $processedImage = $this->preprocessImage($imagePath);
        // 执行OCR
        $command = "tesseract " . escapeshellarg($processedImage) . " stdout -l chi_sim";
        $output = shell_exec($command);
        return $this->parseResult($output);
    }
    private function preprocessImage($imagePath) {
        // 使用ImageMagick进行图像处理
        $processed = 'processed_' . basename($imagePath);
        // 转灰度、二值化、去噪
        exec("convert $imagePath -colorspace Gray -negate -threshold 50% $processed");
        return $processed;
    }
    private function parseResult($text) {
        // 简单正则匹配身份证信息
        $result = [
            'name' => '',
            'id_number' => '',
            'address' => '',
            'issue_date' => '',
            'expiry_date' => ''
        ];
        // 匹配姓名
        if (preg_match('/姓名[::]\s*(\S+)/u', $text, $matches)) {
            $result['name'] = $matches[1];
        }
        // 匹配身份证号
        if (preg_match('/\d{17}[\dXx]/', $text, $matches)) {
            $result['id_number'] = $matches[0];
        }
        return $result;
    }
}
?>

身份证信息验证

<?php
class IdCardValidator {
    // 验证身份证号码有效性
    public static function validateIdNumber($idNumber) {
        // 去除空格和字母大写
        $idNumber = strtoupper(trim($idNumber));
        // 长度验证
        if (strlen($idNumber) != 18) {
            return false;
        }
        // 格式验证
        if (!preg_match('/^\d{17}[\dX]$/', $idNumber)) {
            return false;
        }
        // 校验码验证
        $factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
        $parity = '10X98765432';
        $sum = 0;
        for ($i = 0; $i < 17; $i++) {
            $sum += intval($idNumber[$i]) * $factor[$i];
        }
        $parityIndex = $sum % 11;
        $expectedParity = $parity[$parityIndex];
        return $idNumber[17] == $expectedParity;
    }
    // 提取日期信息
    public static function extractDate($idNumber) {
        $birthday = substr($idNumber, 6, 8);
        return [
            'year' => substr($birthday, 0, 4),
            'month' => substr($birthday, 4, 2),
            'day' => substr($birthday, 6, 2)
        ];
    }
    // 提取性别
    public static function extractGender($idNumber) {
        $genderDigit = intval($idNumber[16]);
        return $genderDigit % 2 == 1 ? '男' : '女';
    }
}
?>

完整使用示例

<?php
// 1. 前端上传图片
if ($_FILES['idcard']['error'] == UPLOAD_ERR_OK) {
    $tmpName = $_FILES['idcard']['tmp_name'];
    // 2. 获取图片类型(正面/反面)
    $side = $_POST['side']; // front 或 back
    // 3. 调用OCR识别
    $ocr = new IdCardOCR('app_id', 'api_key', 'secret_key');
    $result = $ocr->recognize($tmpName);
    // 4. 提取信息
    if ($side == 'front') {
        $info = [
            'name' => $result['front']['姓名']['words'] ?? '',
            'gender' => $result['front']['性别']['words'] ?? '',
            'ethnicity' => $result['front']['民族']['words'] ?? '',
            'birth' => $result['front']['出生']['words'] ?? '',
            'address' => $result['front']['住址']['words'] ?? '',
            'id_number' => $result['front']['公民身份号码']['words'] ?? ''
        ];
    } else {
        $info = [
            'issue_authority' => $result['back']['签发机关']['words'] ?? '',
            'valid_period' => $result['back']['有效期限']['words'] ?? ''
        ];
    }
    // 5. 验证身份证号
    if (isset($info['id_number'])) {
        $isValid = IdCardValidator::validateIdNumber($info['id_number']);
        if (!$isValid) {
            // 处理无效身份证号
        }
    }
    // 6. 返回结果
    echo json_encode([
        'success' => true,
        'data' => $info
    ]);
}
?>

推荐方案

对于生产环境,推荐使用第三方OCR接口,因为:

  1. 准确率高:通常能达到99%以上
  2. 稳定性好:有专业团队维护
  3. 功能完善:支持模糊、倾斜、反光等复杂情况
  4. 自动识别正反面:部分接口支持自动识别

价格参考

  • 百度AI:每月1000次免费
  • 腾讯云:每月500次免费
  • 阿里云:按量计费,约0.01元/次

选择时根据预算和准确率要求来决定。

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