php代码:
<?php
namespace AppCorePluginsOcrLib;
use HyperfUtilsExceptionParallelExecutionException;
use HyperfUtilsParallel;
use SwooleAtomic;
use thiagoalessioTesseractOCRUnsuccessfulCommandException;
class TesseractOcr
{
private $path = BASE_PATH . /public/ocr_processing ;
/**
* Notes: 图片下载
* @param $image
* @return false|string
*/
public function downImage($remoteImageUrl)
{
// 本地保存图片的路径及文件名
$localImagePath = $this->path . / . time() . .jpg ;
// 创建临时目录
if (!file_exists($this->path)) {
mkdir($this->path, 0777, true);
}
// 读取远程图片
$imageContent = @file_get_contents($remoteImageUrl);
if ($imageContent === false) {
// echo "无法下载图片,请检查图片 URL 或网络连接。";
return false;
} else {
// 将图片保存到本地文件
$result = file_put_contents($localImagePath, $imageContent);
if ($result === false) {
// echo "无法保存图片到本地,请检查本地文件路径的权限。";
return false;
}
}
return $localImagePath;
}
/**
* 删除指定目录下的所有文件和子目录
* @param string $path 要处理的目录路径
* @return bool 删除操作是否成功
*/
function deleteFilesInDirectory($path = )
{
if (!empty($path)) {
$dir = $path;
} else {
$dir = $this->path;
}
// 检查目录是否存在
if (!is_dir($dir)) {
return false;
}
// 打开目录
$handle = opendir($dir);
if (!$handle) {
return false;
}
// 遍历目录中的所有文件和子目录
while (($file = readdir($handle)) !== false) {
if ($file === . || $file === .. ) {
continue;
}
$fullPath = $dir . / . $file;
// 如果是目录,则递归调用该函数删除子目录中的文件
if (is_dir($fullPath)) {
$this->deleteFilesInDirectory($fullPath);
// 删除空的子目录
rmdir($fullPath);
} else {
// 如果是文件,则直接删除
unlink($fullPath);
}
}
// 关闭目录句柄
closedir($handle);
return true;
}
/**
* Notes: 图片预处理
* 灰度化:转换图像为灰度图,去除多余的颜色信息。
* 二值化:将图像转换为黑白图像,这有助于减少噪音。
* 去噪声:去除图像中的多余点状噪声。
* User: ning
* Date: 2025/3/8
* Time: 15:28
* @param $img_str
*/
public function pretreatment($img_str)
{
// 载入图像
$image = imagecreatefromjpeg($img_str); // 获取图像的宽度和高度
$width = imagesx($image);
$height = imagesy($image); // 将图像转换为灰度图
for ($x = 0; $x < $width; $x++) {
for ($y = 0; $y < $height; $y++) {
$rgb = imagecolorat($image, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF; // 计算灰度值
$gray = (int)(0.299 * $r + 0.587 * $g + 0.114 * $b);
$color = imagecolorallocate($image, $gray, $gray, $gray); // 将像素设置为灰度值
imagesetpixel($image, $x, $y, $color);
}
}
// 保存预处理后的图像
imagejpeg($image, $img_str);
// 释放内存
imagedestroy($image);
}
/**
* Notes: orc脚本执行
* User: ning
* Date: 2025/3/8
* Time: 16:25
* @param $imageUrls
* @return array|bool
*/
public function ocrHandle($imageUrls)
{
//上次的临时图片删除
$this->deleteFilesInDirectory();
$parallel = new Parallel(2);
// 创建一个原子标志,初始值为 0 表明继续执行
$shouldStop = new Atomic(0);
foreach ($imageUrls as $imageUrl) {
$parallel->add(function () use ($imageUrl, $shouldStop) {
// 检查标志,如果已经设置为 1 则直接返回
if ($shouldStop->get() === 1) {
return false;
}
//图片下载到本地
$tempImagePath = $this->downImage($imageUrl);
if (!$tempImagePath || !file_exists($tempImagePath)) {
// 图片下载失败或者文件不存在,跳过
return false;
}
// 修改文件权限
chmod($tempImagePath, 0644);
//图片灰度处理
try {
$this->pretreatment($tempImagePath);
} catch (ErrorException $e) {
// 处理图片读取错误
unlink($tempImagePath);
return false;
}
try {
// 使用Tesseract OCR提取文字
$tesseract = new hiagoalessioTesseractOCRTesseractOCR($tempImagePath);
$tesseract->executable( /usr/bin/tesseract ); // 根据实际情况修改路径
$tesseract->lang( chi_sim , eng ); // 简体中文
// 执行OCR并获取识别结果
$ocrResult = $tesseract->run();
$prohibitedWord = $this->checkProhibited(str_replace(" ", "", $ocrResult));
if (!empty($prohibitedWord)) {
// 设置标志为 1 表明停止后续任务
$shouldStop->set(1);
return [$imageUrl, $prohibitedWord];
}
return false;
} catch (UnsuccessfulCommandException $e) {
// 图片识别失败 大致率是图片没有内容
return false;
}
});
}
try {
$res = $parallel->wait();
foreach ($res as $v) {
if (is_array($v) && !empty($v)) {
return $v;
}
}
} catch (ParallelExecutionException $e) {
echo 协程处理异常 . $e->getMessage();
return false;
}
return false;
}
/**
* Notes: 不使用携程
* @param $imageUrls
* @return array|void
* @throws hiagoalessioTesseractOCRTesseractOcrException
*/
public function ocrHandleNew($imageUrls)
{
//上次的临时图片删除
$this->deleteFilesInDirectory();
foreach ($imageUrls as $imageUrl) {
//图片下载到本地
$tempImagePath = $this->downImage($imageUrl);
if (!$tempImagePath || !file_exists($tempImagePath)) {
// 图片下载失败或者文件不存在,跳过
continue;
}
// 修改文件权限
chmod($tempImagePath, 0644);
//图片灰度处理
try {
$this->pretreatment($tempImagePath);
} catch (ErrorException $e) {
continue;
}
try {
// 使用Tesseract OCR提取文字
$tesseract = new hiagoalessioTesseractOCRTesseractOCR($tempImagePath);
$tesseract->executable( /usr/bin/tesseract ); // 根据实际情况修改路径
$tesseract->lang( chi_sim , eng ); // 简体中文
// 执行OCR并获取识别结果
$ocrResult = $tesseract->run();
$prohibitedWord = $this->checkProhibited(str_replace(" ", "", $ocrResult));
if (!empty($prohibitedWord)) {
return [$imageUrl, $prohibitedWord];
}
continue;
} catch (UnsuccessfulCommandException $e) {
// 图片识别失败 大致率是图片没有内容
continue;
}
}
}
/**
* Notes: 违禁词检测
* User: ning
* Date: 2025/3/8
* Time: 16:16
* @param $ocrResult
* @return string
*/
public function checkProhibited($ocrResult)
{
if(!empty($ocrResult)){
// 定义违禁词列表
$forbiddenWords = ["器具", "性用品"];
// 检查违禁词
foreach ($forbiddenWords as $word) {
if (mb_stripos($ocrResult, $word) !== false) {
//图片包含违禁词
return $word;
}
}
}
return ;
}
}
调用方法:
//使用orc功能
$imageUrls = array(
"https://cbu01.alicdn.com/img/ibank/O1CN01IDDL2C1h4BUjT04gK_!!2214913144223-0-cib.jpg"
);
list($image, $word) = (new TesseractOcr())->ocrHandle($imageUrls);
return [ img => $image, word => $word];
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
暂无评论...