📑 فهرست مطالب
📦 گام ۱: نصب پکیج NuGet Tesseract
برای استفاده از Tesseract در پروژه .NET، پکیج زیر را نصب کنید:
# در Package Manager Console: Install-Package Tesseract # یا در .NET CLI: dotnet add package Tesseract
Tesseract به صورت خودکار Native DLL های مورد نیاز را نیز دانلود و در پوشه output کپی میکند.
📥 گام ۲: دانلود فایلهای Trained Data
Tesseract برای تشخیص متن به فایلهای traineddata نیاز دارد. این فایلها مدلهای زبانی هستند که برای هر زبان جداگانه آموزش دیدهاند.
۲.۱. دانلود فایلها:
از لینک زیر فایلهای مورد نیاز را دانلود کنید:
https://github.com/tesseract-ocr/tessdata
۲.۲. فایلهای مورد نیاز:
| فایل | زبان | حجم تقریبی | کاربرد |
|---|---|---|---|
fas.traineddata |
فارسی | ~۱۰ MB | تشخیص متن فارسی |
eng.traineddata |
انگلیسی | ~۴ MB | تشخیص متن انگلیسی |
ara.traineddata |
عربی | ~۵ MB | تشخیص متن عربی (اختیاری) |
۲.۳. ساختار پوشهها:
فایلهای دانلود شده را در مسیر زیر قرار دهید:
xAiApi/
└── tessdata/
├── fas.traineddata
├── eng.traineddata
└── ara.traineddata (اختیاری)
tessdata باید در زمان اجرا در دسترس باشد. میتوانید آن را در appsettings.json پیکربندی کنید.
⚙️ گام ۳: پیکربندی در appsettings.json
تنظیمات Tesseract را در فایل appsettings.json اضافه کنید:
{
"AiApiConfiguration": {
"FileExtraction": {
"OCR": {
"TessDataPath": "tessdata",
"DefaultLanguage": "fas+eng",
"EngineMode": "LstmOnly"
}
},
"Models": [ ... ],
"Prompts": [ ... ]
}
}
توضیح پارامترها:
| پارامتر | توضیح | مقادیر مجاز |
|---|---|---|
TessDataPath |
مسیر پوشه فایلهای traineddata | مسیر نسبی یا مطلق |
DefaultLanguage |
زبانهای پیشفرض برای OCR | fas, eng, ara (ترکیب با +) |
EngineMode |
حالت موتور Tesseract | TesseractOnly, LstmOnly, TesseractAndLstm, Default |
🔄 گام ۴: بازنویسی کلاس XImageFileContentExtractor
اکنون کلاس XImageFileContentExtractor را بازنویسی میکنیم تا از Tesseract برای OCR استفاده کند:
using System;
using System.IO;
using System.Linq;
using System.Threading;
using Tesseract;
using xAiModels.Models;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using xAiApi.Interfaces.Extractors;
namespace xAiApi.Providers.Extractors
{
/// <summary>
/// Extracts content from image files using Tesseract OCR ...
/// </summary>
public class XImageFileContentExtractor : IXImageFileContentExtractor
{
/// <summary>
/// Supported MIME Types ...
/// </summary>
private static readonly string[] SupportedMimeTypes =
[
"image/png",
"image/jpeg",
"image/jpg",
"image/gif",
"image/webp",
"image/bmp"
];
/// <summary>
/// مسیر پوشه tessdata ...
/// </summary>
private readonly string _tessDataPath;
/// <summary>
/// زبان پیشفرض برای OCR ...
/// </summary>
private readonly string _defaultLanguage;
/// <summary>
/// حالت موتور Tesseract ...
/// </summary>
private readonly OcrEngineMode _engineMode;
/// <summary>
/// Logger ...
/// </summary>
private readonly ILogger<XImageFileContentExtractor> _logger;
/// <summary>
/// Constructor با پیکربندی پیشفرض ...
/// </summary>
public XImageFileContentExtractor(
ILogger<XImageFileContentExtractor> logger,
string tessDataPath = "tessdata",
string defaultLanguage = "fas+eng",
OcrEngineMode engineMode = OcrEngineMode.LstmOnly
)
{
_logger = logger;
_tessDataPath = tessDataPath;
_defaultLanguage = defaultLanguage;
_engineMode = engineMode;
}
/// <summary>
/// Check if this extractor supports the specified MIME type ...
/// </summary>
public bool CanExtract(string mimeType)
{
return SupportedMimeTypes.Contains(
mimeType?.ToLowerInvariant() ?? string.Empty
);
}
/// <summary>
/// Extract text content from file stream ...
/// </summary>
public async Task<string> ExtractAsync(
Stream fileStream,
string mimeType,
CancellationToken cancellationToken = default
)
{
var result = await ExtractRichAsync(
fileStream,
"image",
mimeType,
cancellationToken
);
return result.Text;
}
/// <summary>
/// Extract content from stream as Rich Result ...
/// </summary>
public async Task<XFileExtractionResult> ExtractRichAsync(
Stream fileStream,
string fileName,
string mimeType,
CancellationToken cancellationToken = default
)
{
var result = new XFileExtractionResult
{
FileName = fileName,
MimeType = mimeType
};
// خواندن بایتهای تصویر
using var memoryStream = new MemoryStream();
await fileStream.CopyToAsync(memoryStream, cancellationToken);
var imageBytes = memoryStream.ToArray();
// افزودن تصویر به عنوان DataContent (برای Vision Models)
result.Images.Add(new XExtractedImage
{
Bytes = imageBytes,
MimeType = mimeType,
Description = $"Attached image: {fileName}"
});
// انجام OCR برای استخراج متن
try
{
var ocrText = await PerformOcrAsync(imageBytes, cancellationToken);
if (!string.IsNullOrWhiteSpace(ocrText))
{
result.Text = ocrText;
_logger.LogInformation(
"OCR completed successfully for file: {FileName}, extracted {Length} characters",
fileName,
ocrText.Length
);
}
else
{
_logger.LogWarning("OCR completed but no text was extracted from file: {FileName}", fileName);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "OCR failed for file: {FileName}", fileName);
result.ErrorMessage = $"OCR failed: {ex.Message}";
// تصویر همچنان برای Vision Models در دسترس است
}
return result;
}
/// <summary>
/// انجام OCR روی تصویر با استفاده از Tesseract ...
/// </summary>
private async Task<string> PerformOcrAsync(
byte[] imageBytes,
CancellationToken cancellationToken
)
{
return await Task.Run(() =>
{
// بررسی وجود مسیر tessdata
if (!Directory.Exists(_tessDataPath))
{
throw new DirectoryNotFoundException(
$"TessData directory not found at: {_tessDataPath}. " +
"Please download traineddata files from https://github.com/tesseract-ocr/tessdata"
);
}
// ایجاد Tesseract Engine
using var engine = new TesseractEngine(
datapath: _tessDataPath,
language: _defaultLanguage,
mode: _engineMode
);
// بارگذاری تصویر از byte array
using var pix = Pix.LoadFromMemory(imageBytes);
// تنظیم CancellationToken
cancellationToken.ThrowIfCancellationRequested();
// انجام OCR
using var page = engine.Process(pix);
// استخراج متن
var text = page.GetText();
// پاکسازی متن (حذف فاصلههای اضافی)
text = text?.Trim();
return text ?? string.Empty;
}, cancellationToken);
}
}
}
🔧 گام ۵: جزئیات پیادهسازی متد PerformOcrAsync
۵.۱. مراحل کار متد:
۱. بررسی مسیر tessdata
- اطمینان از وجود پوشه tessdata
- پرتاب خطا در صورت عدم وجود
۲. ایجاد Tesseract Engine
- بارگذاری مدل زبانی
- تنظیم حالت موتور (LSTM)
۳. بارگذاری تصویر
- تبدیل byte[] به Pix object
- پشتیبانی از فرمتهای مختلف
۴. انجام OCR
- پردازش تصویر
- استخراج متن
۵. پاکسازی متن
- حذف فاصلههای اضافی
- بررسی CancellationToken
۵.۲. ویژگیهای کلیدی پیادهسازی:
| ویژگی | توضیح |
|---|---|
| پشتیبانی چند زبانه | استفاده از fas+eng برای تشخیص همزمان فارسی و انگلیسی |
| حالت LSTM | استفاده از موتور LSTM برای دقت بالاتر در متون فارسی |
| مدیریت خطا | بررسی وجود tessdata و مدیریت استثناها |
| Logging | ثبت موفقیت/شکست OCR با جزئیات |
| Cancellation Support | پشتیبانی از لغو عملیات در میانه کار |
| Resource Management | استفاده از using برای آزادسازی منابع |
💡 گام ۶: نکات مهم و عیبیابی
۶.۱. مشکلات رایج و راهحلها:
| مشکل | علت | راهحل |
|---|---|---|
DirectoryNotFoundException |
پوشه tessdata یافت نشد | دانلود traineddata و قرار دادن در مسیر صحیح |
TesseractException |
فایل traineddata خراب یا ناسازگار | دانلود مجدد از منبع رسمی |
| دقت پایین OCR | کیفیت پایین تصویر | پیشپردازش تصویر (افزایش کنتراست، resize) |
| تشخیص نادرست فارسی | ترکیب نامناسب زبانها | استفاده از fas به تنهایی یا fas+eng |
| کندی عملکرد | تصاویر بزرگ | تغییر EngineMode به TesseractOnly |
۶.۲. بهینهسازی عملکرد:
🚀 افزایش سرعت
- استفاده از
OcrEngineMode.TesseractOnly - کاهش DPI تصویر (مثلاً 150 به جای 300)
- استفاده از یک زبان به جای چند زبان
🎯 افزایش دقت
- استفاده از
OcrEngineMode.LstmOnly - افزایش DPI تصویر (300 یا بالاتر)
- پیشپردازش تصویر (binarization)
۶.۳. پیشپردازش تصویر (اختیاری):
برای افزایش دقت OCR، میتوانید قبل از پردازش، تصویر را پیشپردازش کنید:
// مثال: افزایش کنتراست و تبدیل به سیاه و سفید using var pix = Pix.LoadFromMemory(imageBytes); using var enhanced = pix.ConvertTo1(); // تبدیل به 1-bit using var page = engine.Process(enhanced);
۶.۴. ثبت در Startup.cs:
اکنون XImageFileContentExtractor را با پیکربندی صحیح ثبت کنید:
public void ConfigureServices(IServiceCollection services)
{
// ... سایر ثبتها
// ثبت XImageFileContentExtractor با پیکربندی
services.AddSingleton<IXFileContentExtractor>(sp =>
{
var logger = sp.GetRequiredService<ILogger<XImageFileContentExtractor>>();
var configuration = sp.GetRequiredService<IConfiguration>();
var tessDataPath = configuration.GetValue<string>(
"AiApiConfiguration:FileExtraction:OCR:TessDataPath"
) ?? "tessdata";
var defaultLanguage = configuration.GetValue<string>(
"AiApiConfiguration:FileExtraction:OCR:DefaultLanguage"
) ?? "fas+eng";
return new XImageFileContentExtractor(
logger: logger,
tessDataPath: tessDataPath,
defaultLanguage: defaultLanguage,
engineMode: OcrEngineMode.LstmOnly
);
});
// ... سایر ثبتها
}
- 🔍 OCR کامل: استخراج متن از تصاویر با دقت بالا
- 🌐 چند زبانه: پشتیبانی از فارسی، انگلیسی و عربی
- ⚡ بهینه: استفاده از موتور LSTM برای دقت بالاتر
- 🛡️ مقاوم: مدیریت خطا و logging کامل
- 🔄 قابل لغو: پشتیبانی از CancellationToken
- 📦 منعطف: پیکربندی از طریق appsettings.json
اگر نیاز به دقت بالاتر برای متون فارسی دارید، میتوانید از مدلهای آموزشدیدهشده خاص فارسی استفاده کنید یا از ترکیب Tesseract با مدلهای deep learning (مانند CRNN) بهره ببرید.