Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add way to configure TessEngine in ITesseract #16

Closed
henrivain opened this issue Sep 15, 2023 · 1 comment
Closed

Add way to configure TessEngine in ITesseract #16

henrivain opened this issue Sep 15, 2023 · 1 comment
Labels
enhancement New feature or request

Comments

@henrivain
Copy link
Owner

Problem

User cannot configure Tesseract parameters of the injected ITesseract api and must use underlying TessEngine api.
Because of this dependency injection cannot be used when user wants to change for example tessedit_char_whitelist or tessedit_char_blacklist.

Current way of doing

string traineddataFolder = FileSystem.Current.CacheDirectory;

// Load data
var tranineddataPath = Path.Combine(traineddataFolder , "eng.traineddata");
if (!File.Exists(tranineddataPath)) 
{
    using Stream traineddata = await FileSystem.OpenAppPackageFileAsync("eng.traineddata");
    FileStream fileStream = File.Create(tranineddataPath);
    traineddata.CopyTo(fileStream);
}

// Create and configure engine
using var engine = new TessEngine("eng", traineddataFolder );
bool success = engine.SetVariable("tessedit_char_whitelist", "mychars");

// Recognize text
using var image = Pix.LoadFromFile(@"\path\to\file.png");
using var result = engine.ProcessImage(image);
string text = result.GetText();

Suggested fix

Addition to ITesseract API

Add optional configuration Property to pass into ITesseract

public interface ITesseract
{
    ...

    Action<TessEngine> EngineConfiguration { get; set; }
}

Changes in Tesseract.cs

Method internal RecognizionResult Recognize(Pix pix, string tessDataFolder, string[] traineddataFileNames)

Change

try
{
    using var engine = new TessEngine(languages, tessDataFolder, Logger);
    using var page = engine.ProcessImage(pix);
    
    confidence = page.GetConfidence();
    text = page.GetText();
}
...

To

try
{
    using var engine = new TessEngine(languages, tessDataFolder, Logger);
    // Configure
    EngineConfiguration(engine);

    using var page = engine.ProcessImage(pix);
    confidence = page.GetConfidence();
    text = page.GetText();
}
...

Intended use

Set configuration func before running process

Tesseract.EngineConfiguration = engine => 
{
    // These characters are not recognized
    engine.SetVariable("tessedit_char_blacklist", "bad");
}
var result = await Tesseract.RecognizeTextAsync(@"my\image\path.png");
@henrivain henrivain added the enhancement New feature or request label Sep 15, 2023
@henrivain henrivain changed the title Add way to configure TessEngine ITesseract is using Add way to configure TessEngine in ITesseract Sep 16, 2023
@henrivain
Copy link
Owner Author

Pull request #19 fixes this issue

Example

private async void DEMO_Recognize_AsConfigured(object sender, EventArgs e)
{
    // Select image (Not important)
    var path = await GetUserSelectedPath();
    if (path is null)
    {
        return;
    }

    // this Tesseract is injected property
    Tesseract.EngineConfiguration = (engine) =>
    {
        // Engine uses DefaultSegmentationMode, if no other is passed as method parameter.
        // If ITesseract is injected to page, this is only way of setting PageSegmentationMode.
        // PageSegmentationMode defines how ocr tries to look for text, for example singe character or single word.
        // By default uses PageSegmentationMode.Auto.
        engine.DefaultSegmentationMode = TesseractOcrMaui.Enums.PageSegmentationMode.Auto;
        
        engine.SetCharacterWhitelist("abcdefgh");   // These characters ocr is looking for
        engine.SetCharacterBlacklist("abc");        // These characters ocr is not looking for
        // Now ocr should be only finding characters 'defgh'
    };

    // Recognize image 
    var result = await Tesseract.RecognizeTextAsync(path);

    // For this example I reset engine configuration, because same Object is used in other examples
    Tesseract.EngineConfiguration = null;

    // Show output (Not important)
    ShowOutput("FromPath, Configured", result);

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant