AI Pettorali
This commit is contained in:
parent
25fdb82d2f
commit
cb41c42bb5
11 changed files with 379 additions and 55 deletions
|
|
@ -5,6 +5,7 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AIFotoONLUS.Core;
|
||||
using ImageCatalog_2.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
|
|
@ -35,36 +36,14 @@ public class AiExtractionService : IAiExtractionService
|
|||
|| f.EndsWith(".gif", StringComparison.OrdinalIgnoreCase))
|
||||
.ToList();
|
||||
|
||||
if (imageFiles.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var extractedResults = new List<AiResultItem>();
|
||||
var modelConfiguration = BuildModelConfiguration(request.ModelsFolderPath, request.UseGpu);
|
||||
|
||||
Type? aiProcessorType = null;
|
||||
object? aiProcessor = null;
|
||||
|
||||
try
|
||||
{
|
||||
var assembly = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.FirstOrDefault(a => a.GetName().Name?.Equals("AIFotoONLUS.Core", StringComparison.OrdinalIgnoreCase) == true);
|
||||
if (assembly != null)
|
||||
{
|
||||
aiProcessorType = assembly.GetType("AIFotoONLUS.Core.AiProcessor");
|
||||
if (aiProcessorType != null)
|
||||
{
|
||||
aiProcessor = Activator.CreateInstance(aiProcessorType);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogDebug(ex, "AIFotoONLUS.Core not available or failed to load via reflection");
|
||||
}
|
||||
using var engine = new NumberRecognitionEngine(modelConfiguration, _logger);
|
||||
|
||||
var processed = 0;
|
||||
var total = imageFiles.Count;
|
||||
var failed = 0;
|
||||
|
||||
foreach (var file in imageFiles)
|
||||
{
|
||||
|
|
@ -72,39 +51,30 @@ public class AiExtractionService : IAiExtractionService
|
|||
|
||||
var extracted = string.Empty;
|
||||
|
||||
if (aiProcessorType is not null && aiProcessor is not null)
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
var method = aiProcessorType.GetMethod("ExtractNumbersFromImage")
|
||||
?? aiProcessorType.GetMethod("ExtractTextFromImage");
|
||||
if (method is not null)
|
||||
{
|
||||
var value = method.Invoke(aiProcessor, new object[] { file });
|
||||
if (value != null)
|
||||
{
|
||||
extracted = value.ToString() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Error invoking AI processor for {File}", file);
|
||||
}
|
||||
extracted = engine.ProcessImage(file).Text;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
failed++;
|
||||
_logger.LogWarning(ex, "Error processing AI OCR for {File}", file);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(extracted))
|
||||
{
|
||||
var result = new AiResultItem { Path = file, Text = extracted };
|
||||
extractedResults.Add(result);
|
||||
await onResult(result).ConfigureAwait(false);
|
||||
}
|
||||
var result = new AiResultItem { Path = file, Text = extracted };
|
||||
extractedResults.Add(result);
|
||||
await onResult(result).ConfigureAwait(false);
|
||||
|
||||
processed++;
|
||||
var percent = total > 0 ? (processed * 100.0 / total) : 100.0;
|
||||
await onProgress(percent).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (imageFiles.Count > 0 && failed == imageFiles.Count)
|
||||
{
|
||||
throw new InvalidOperationException($"AI OCR failed for all {imageFiles.Count} image(s). See previous log entries for details.");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(request.CsvOutputPath))
|
||||
{
|
||||
try
|
||||
|
|
@ -129,4 +99,27 @@ public class AiExtractionService : IAiExtractionService
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ModelConfiguration BuildModelConfiguration(string modelsFolderPath, bool useGpu)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(modelsFolderPath))
|
||||
{
|
||||
throw new InvalidOperationException("AI models folder is not configured.");
|
||||
}
|
||||
|
||||
var modelsRoot = Path.GetFullPath(modelsFolderPath.Trim().Trim('"'));
|
||||
if (!Directory.Exists(modelsRoot))
|
||||
{
|
||||
throw new DirectoryNotFoundException($"AI models folder not found: {modelsRoot}");
|
||||
}
|
||||
|
||||
return new ModelConfiguration
|
||||
{
|
||||
DetectionCfg = Path.Combine(modelsRoot, "detection.cfg"),
|
||||
DetectionWeights = Path.Combine(modelsRoot, "detection.weights"),
|
||||
RecognitionCfg = Path.Combine(modelsRoot, "recognition.cfg"),
|
||||
RecognitionWeights = Path.Combine(modelsRoot, "recognition.weights"),
|
||||
UseGpu = useGpu
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue