php使用TesseractOcr对阿里云OSS图片敏感词处理

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];

© 版权声明

相关文章

暂无评论

none
暂无评论...