本文目录导读:

我将为您介绍几种PHP识别图形验证码的方法,从简单到复杂:
使用OCR库(最简单)
Tesseract OCR
<?php
// 使用Tesseract OCR识别验证码
try {
$tesseract = new TesseractOCR('captcha.png');
$text = $tesseract->run();
echo "识别结果: " . $text;
} catch (Exception $e) {
echo "识别失败: " . $e->getMessage();
}
安装Tesseract
# Ubuntu/Debian sudo apt-get install tesseract-ocr # CentOS/RHEL sudo yum install tesseract # 使用Composer安装PHP库 composer require thiagoalessio/tesseract_ocr
图像预处理+OCR(提高准确率)
<?php
class CaptchaRecognizer {
public function recognize($imagePath) {
// 1. 图片预处理
$processedImage = $this->preprocess($imagePath);
// 2. 使用OCR识别
$tesseract = new TesseractOCR($processedImage);
$result = $tesseract->run();
return $this->cleanResult($result);
}
private function preprocess($imagePath) {
// 使用GD库处理图片
$img = imagecreatefrompng($imagePath);
// 转换为灰度
imagefilter($img, IMG_FILTER_GRAYSCALE);
// 增加对比度
imagefilter($img, IMG_FILTER_CONTRAST, -50);
// 二值化处理
$width = imagesx($img);
$height = imagesy($img);
for ($x = 0; $x < $width; $x++) {
for ($y = 0; $y < $height; $y++) {
$rgb = imagecolorat($img, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
// 简单二值化
$gray = ($r + $g + $b) / 3;
$value = $gray > 128 ? 255 : 0;
imagesetpixel($img, $x, $y, imagecolorallocate($img, $value, $value, $value));
}
}
// 保存处理后的图片
$processedPath = tempnam(sys_get_temp_dir(), 'captcha_') . '.png';
imagepng($img, $processedPath);
imagedestroy($img);
return $processedPath;
}
private function cleanResult($text) {
// 去除空格和特殊字符
$text = preg_replace('/[^a-zA-Z0-9]/', '', $text);
return strtoupper($text);
}
}
// 使用示例
$recognizer = new CaptchaRecognizer();
$result = $recognizer->recognize('captcha.png');
echo "识别结果: " . $result;
使用第三方API服务(最准确)
<?php
class CaptchaAPIService {
// 方法1:使用Google Cloud Vision API
public function recognizeWithGoogle($imagePath) {
$apiKey = 'YOUR_GOOGLE_API_KEY';
$imageData = base64_encode(file_get_contents($imagePath));
$requestData = [
'requests' => [
[
'image' => ['content' => $imageData],
'features' => [
['type' => 'TEXT_DETECTION']
]
]
]
];
$ch = curl_init('https://vision.googleapis.com/v1/images:annotate?key=' . $apiKey);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($requestData));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
// 提取识别文本
if (isset($result['responses'][0]['textAnnotations'][0]['description'])) {
return trim($result['responses'][0]['textAnnotations'][0]['description']);
}
return '';
}
// 方法2:使用通用API服务
public function recognizeWithAPI($imagePath) {
$apiUrl = 'https://api.ocr.space/parse/image';
$apiKey = 'YOUR_API_KEY';
$ch = curl_init();
$data = [
'apikey' => $apiKey,
'language' => 'eng',
'isOverlayRequired' => 'false',
];
// 上传文件
$file = new CURLFile($imagePath);
$data['file'] = $file;
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
if (isset($result['ParsedResults'][0]['ParsedText'])) {
return trim($result['ParsedResults'][0]['ParsedText']);
}
return '';
}
}
// 使用示例
$apiService = new CaptchaAPIService();
$result = $apiService->recognizeWithAPI('captcha.png');
echo "API识别结果: " . $result;
基于机器学习的自定义识别
<?php
// 使用PHP-ML进行数字/字母分类器
require_once __DIR__ . '/vendor/autoload.php';
use Phpml\Classification\KNearestNeighbors;
use Phpml\Dataset\CsvDataset;
class MLRecognizer {
private $classifier;
private $trainingData = [];
private $labels = [];
public function __construct() {
$this->classifier = new KNearestNeighbors();
}
// 创建训练数据集
public function train($samples, $labels) {
$this->classifier->train($samples, $labels);
}
// 提取特征
public function extractFeatures($imagePath) {
$img = imagecreatefrompng($imagePath);
$width = imagesx($img);
$height = imagesy($img);
// 调整为固定大小
$resized = imagecreatetruecolor(20, 20);
imagecopyresampled($resized, $img, 0, 0, 0, 0, 20, 20, $width, $height);
// 提取像素特征
$features = [];
for ($x = 0; $x < 20; $x++) {
for ($y = 0; $y < 20; $y++) {
$rgb = imagecolorat($resized, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$features[] = ($r + $g + $b) / 3; // 灰度值
}
}
imagedestroy($img);
imagedestroy($resized);
return $features;
}
// 识别验证码
public function recognize($imagePath) {
// 分割单个字符(需要实现字符分割算法)
$charImages = $this->segmentCharacters($imagePath);
$result = '';
foreach ($charImages as $charImage) {
$features = $this->extractFeatures($charImage);
$prediction = $this->classifier->predict($features);
$result .= $prediction;
}
return $result;
}
private function segmentCharacters($imagePath) {
// 字符分割逻辑(根据连通域或投影法)
// 这里需要实现具体的分割算法
return [];
}
}
简单验证码识别(特定模式)
<?php
class SimpleCaptchaRecognizer {
// 针对特定类型的验证码
public function recognizeArithmetic($imagePath) {
// 识别数学表达式验证码
$ocr = new TesseractOCR($imagePath);
$text = $ocr->run();
// 解析数学表达式
if (preg_match('/(\d+)\s*([+\-*\/])\s*(\d+)/', $text, $matches)) {
$num1 = (int)$matches[1];
$operator = $matches[2];
$num2 = (int)$matches[3];
switch ($operator) {
case '+': return $num1 + $num2;
case '-': return $num1 - $num2;
case '*': return $num1 * $num2;
case '/': return $num2 != 0 ? $num1 / $num2 : 0;
}
}
return null;
}
// 识别纯数字验证码
public function recognizeNumeric($imagePath) {
// 预处理图片
$img = imagecreatefrompng($imagePath);
imagefilter($img, IMG_FILTER_GRAYSCALE);
imagefilter($img, IMG_FILTER_CONTRAST, -100);
// 保存临时文件
$tempFile = tempnam(sys_get_temp_dir(), 'captcha') . '.png';
imagepng($img, $tempFile);
// OCR识别
$ocr = new TesseractOCR($tempFile);
$ocr->setWhitelist(range(0, 9)); // 只识别数字
$result = $ocr->run();
// 清理
unlink($tempFile);
imagedestroy($img);
return preg_replace('/[^0-9]/', '', $result);
}
}
完整示例:综合解决方案
<?php
class ComprehensiveCaptchaRecognizer {
private $debug = false;
public function recognize($imagePath) {
$methods = [
'tesseract' => [$this, 'recognizeWithTesseract'],
'imagePreprocess' => [$this, 'recognizeWithPreprocess'],
'apiService' => [$this, 'recognizeWithAPI']
];
$results = [];
// 尝试所有方法
foreach ($methods as $name => $method) {
try {
$result = call_user_func($method, $imagePath);
if (!empty($result)) {
$results[$name] = $result;
}
} catch (Exception $e) {
if ($this->debug) {
echo "方法 $name 失败: " . $e->getMessage() . "\n";
}
}
}
// 统计分析结果
$counts = array_count_values($results);
arsort($counts);
// 返回出现次数最多的结果
return key($counts) ?? '';
}
private function recognizeWithTesseract($imagePath) {
$tesseract = new TesseractOCR($imagePath);
$result = $tesseract->run();
return $this->cleanResult($result);
}
private function recognizeWithPreprocess($imagePath) {
// 预处理增强识别
$img = imagecreatefrompng($imagePath);
// 多种预处理方式
$variants = [];
// 原图
$variants['original'] = $imagePath;
// 灰度+对比度
$img1 = $img;
imagefilter($img1, IMG_FILTER_GRAYSCALE);
imagefilter($img1, IMG_FILTER_CONTRAST, -30);
$variants['gray'] = $this->saveTemp($img1);
// 二值化
$img2 = $img;
imagefilter($img2, IMG_FILTER_GRAYSCALE);
imagefilter($img2, IMG_FILTER_CONTRAST, -100);
$this->binarize($img2);
$variants['binarized'] = $this->saveTemp($img2);
// 尝试所有预处理变体
$results = [];
foreach ($variants as $variant) {
$tesseract = new TesseractOCR($variant);
$result = $tesseract->run();
$results[] = $this->cleanResult($result);
}
// 清理临时文件
foreach ($variants as $variant) {
if ($variant !== $imagePath && file_exists($variant)) {
unlink($variant);
}
}
// 返回最可能的结果
$counts = array_count_values($results);
arsort($counts);
return key($counts) ?? '';
}
private function recognizeWithAPI($imagePath) {
// 使用免费API或付费服务
// 这里以OCR.Space API为例
$apiKey = 'YOUR_API_KEY';
$ch = curl_init('https://api.ocr.space/parse/image');
$file = new CURLFile($imagePath);
$data = [
'file' => $file,
'apikey' => $apiKey,
'language' => 'eng'
];
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
if (isset($result['ParsedResults'][0]['ParsedText'])) {
return $this->cleanResult($result['ParsedResults'][0]['ParsedText']);
}
return '';
}
private function cleanResult($text) {
// 清除OCR常见错误
$text = strtoupper($text);
$text = preg_replace('/[^A-Z0-9]/', '', $text);
// 修正常见OCR错误
$replacements = [
'O' => '0',
'I' => '1',
'L' => '1',
'S' => '5',
'B' => '8'
];
// 根据实际情况决定是否替换
// $text = strtr($text, $replacements);
return $text;
}
private function saveTemp($image) {
$tempFile = tempnam(sys_get_temp_dir(), 'captcha') . '.png';
imagepng($image, $tempFile);
return $tempFile;
}
private function binarize($image) {
$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 = ($r + $g + $b) / 3;
$value = $gray > 128 ? 255 : 0;
imagesetpixel($image, $x, $y, imagecolorallocate($image, $value, $value, $value));
}
}
}
}
// 使用示例
$recognizer = new ComprehensiveCaptchaRecognizer();
$result = $recognizer->recognize('captcha.png');
echo "最终识别结果: " . $result;
使用建议
- 简单验证码:使用Tesseract OCR + 基本图像预处理
- 复杂验证码:使用第三方API服务(如Google Vision、OCR.Space)
- 特定类型:针对特定验证码模式进行定制开发
- 生产环境:建议使用成熟的OCR服务,准确率更高
注意事项
- 识别准确率取决于验证码的复杂程度
- 过度的图像处理可能会降低准确率
- 考虑使用机器学习提高识别率
- 遵守网站的使用条款和法律规定
选择哪种方案取决于您的具体需求和验证码的复杂程度,对于简单的数字验证码,Tesseract OCR通常就足够了;对于复杂的图形验证码,建议使用专业OCR服务。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播