PHP调用Tesseract OCR识别流水图片返回空结果求助
解决Tesseract OCR识别银行流水为空及生成指定JSON的方案
一、先排查命令执行的错误信息
默认shell_exec只返回标准输出,无法捕获错误提示,修改命令定位问题:
$output = shell_exec('tesseract "D:/page_2.png" "D:/page_2.txt" -l eng 2>&1'); var_dump($output); // 查看是否存在路径错误、权限不足或Tesseract未找到等问题
二、图片预处理提升识别率
银行流水的表格线、低对比度会导致Tesseract识别失效,先对图片做预处理:
// 用GD库转灰度并提高对比度 $srcImg = imagecreatefrompng('D:/page_2.png'); imagefilter($srcImg, IMG_FILTER_GRAYSCALE); imagefilter($srcImg, IMG_FILTER_CONTRAST, 60); // 可根据实际效果调整对比度数值 imagepng($srcImg, 'D:/page_2_processed.png'); imagedestroy($srcImg);
使用处理后的图片重新执行识别命令(若流水包含印尼语字符,需先安装Tesseract印尼语语言包):
tesseract "D:/page_2_processed.png" "D:/page_2.txt" -l eng+ind
三、直接生成结构化输出,便于转JSON
避免生成无结构的纯文本,改用Tesseract的TSV格式输出,更易解析:
// 获取TSV格式的识别结果 $tsvOutput = shell_exec('tesseract "D:/page_2_processed.png" stdout -l eng+ind tsv'); // 解析TSV提取目标字段 $rows = explode("\n", trim($tsvOutput)); $mutasi = []; $norek = ''; $nama = ''; foreach ($rows as $row) { $cols = explode("\t", $row); // 以下为示例匹配逻辑,需根据实际TSV输出调整字段位置 if (str_contains($cols[1], '046-')) { $norek = trim($cols[1]); } elseif (str_contains($cols[1], 'ANUGERAH')) { $nama = trim($cols[1]); } elseif (preg_match('/\d{2}\/\d{2}/', $cols[1])) { $tgl = preg_match('/\d{2}\/\d{2}/', $cols[1], $matches) ? $matches[0] : ''; $ket = trim($cols[1]); $total = preg_match('/[\d,.]+/', $cols[1], $matches) ? str_replace('.', ',', $matches[0]) : ''; $tipe = str_contains($cols[1], 'CR') ? 'CR' : 'DB'; $mutasi[] = compact('tgl', 'ket', 'total', 'tipe'); } } // 生成目标格式的JSON $result = json_encode(compact('norek', 'nama', 'mutasi'), JSON_PRETTY_PRINT); file_put_contents('D:/bank_statement.json', $result);
四、检查权限问题
确保PHP运行的用户(如Apache的www-data、IIS的IUSR)拥有:
- 读取
D:/page_2.png的权限 - 写入
D:/page_2.txt、处理后图片及最终JSON文件的权限
内容的提问来源于stack exchange,提问作者Lamberto Fredrick Nababan
相关产品推荐
相关产品推荐

