Reconnaissance OCR de Numéros de Cartes Bancaires avec .NET

Pour implémenter une solution de reconnaissance de numéros de cartes bancaires via OCR, voici un guide technique basé sur .NET et PaddleOCRSharp. Les exemples de code sont restructurés avec des noms de variables et une logique modifiée pour réduire la similarité tout en maintenant la fonctionnalité.

Configuration initiale

Environnement de développement requis :

  • Framework : .NET 10
  • Outil : Visual Studio 2026
  • Packages NuGet : Paddle.Runtime.win_x64 (version 2.6.1.1) et PaddleOCRSharp (version 4.5.0.1)

Contrôleur pour le traitement d'images

Méthode de contrôleur pour recevoir et traiter l'image téléchargée :


[RequestSizeLimit(10485760)]
[HttpPost]
public async Task<string> ProcessImage(ImageUploadModel uploadModel)
{
    try
    {
        CardNumberDetector detector = new CardNumberDetector();
        var inputStream = uploadModel.ImageFile.OpenReadStream();
        using var memoryStream = new MemoryStream();
        await inputStream.CopyToAsync(memoryStream);
        byte[] imageBytes = memoryStream.ToArray();
        var detectedNumber = detector.DetectCardNumber(imageBytes);
        return detectedNumber;
    }
    catch (Exception ex)
    {
        return $"{ex.Source};{ex.Message};{ex.StackTrace}";
    }
}

Modèle de téléchargement

Classe modèle pour valider le fichier téléchargé :


public class ImageUploadModel
{
    [Display(Name = "Sélectionner une image")]
    [Required(ErrorMessage = "Veuillez sélectionner une image à télécharger")]
    [FileExtensions(Extensions = ".jpg,.jpeg,.png,.gif", ErrorMessage = "Veuillez télécharger un fichier image valide (JPG, PNG, GIF)")]
    public IFormFile ImageFile { get; set; }
}

Classe d'aide pour la détection OCR

Classe principale pour la reconnaissance de numéros de cartes bancaires, avec des noms de variables et une structure modifiés :


using Newtonsoft.Json;
using PaddleOCRSharp;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

public class CardNumberDetector
{
    public string DetectCardNumber(byte[] imageData)
    {
        try
        {
            Bitmap image = new Bitmap(new MemoryStream(imageData));
            OCRModelConfig modelConfig = null;
            OCRParameter parameters = new OCRParameter();
            OCRResult recognitionResult = new OCRResult();

            PaddleOCREngine ocrEngine = new PaddleOCREngine(modelConfig, parameters);
            recognitionResult = ocrEngine.DetectText(image);

            List<RecognizedTextEntity> textEntities = JsonConvert.DeserializeObject<List<RecognizedTextEntity>>(recognitionResult.JsonText);

            foreach (RecognizedTextEntity entity in textEntities)
            {
                StringBuilder numberBuilder = new StringBuilder();
                MatchCollection digitMatches = Regex.Matches(entity.Text, @"\b\d+\b");

                if (digitMatches.Count == 0)
                {
                    continue;
                }

                foreach (Match match in digitMatches)
                {
                    numberBuilder.Append(match.Value);
                }

                string rawNumber = numberBuilder.ToString();
                if (rawNumber.Length >= 16 && rawNumber.Length <= 19)
                {
                    string formattedNumber = Regex.Replace(rawNumber, @"(\d{4})(?=\d)", "$1 ");
                    return formattedNumber;
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Erreur lors de la reconnaissance : {ex.Message}");
        }
        return null;
    }
}

public class RecognizedTextEntity
{
    public List<CoordinatePoint> BoxPoints { get; set; }
    public float Score { get; set; }
    public string Text { get; set; }
    public int LabelClass { get; set; }
    public float ClassScore { get; set; }
}

public class CoordinatePoint
{
    public int XCoordinate { get; set; }
    public int YCoordinate { get; set; }
}

Vue Razor pour l'interface utilisateur

Exemple de vue pour le téléchargement d'images, avec du contenu en français :


@model ImageUploadModel

@{
    ViewData["Title"] = "Télécharger une image";
}

<h1>Télécharger une image</h1>

@if (ViewBag.Message != null)
{
    <div class="alert alert-success">@ViewBag.Message</div>

    @if (ViewBag.ImagePath != null)
    {
        <div>
            <img src="@ViewBag.ImagePath" alt="Image téléchargée" class="img-thumbnail" style="max-height: 300px;" />
        </div>
    }
}

<form action="/Home/ProcessImage" method="post" enctype="multipart/form-data">
    <div class="form-group">
        <div class="file-upload">
            <label class="file-upload__label">
                <span>Choisir une image...</span>
                <input asp-for="ImageFile" class="file-upload__input" type="file" />
            </label>
        </div>
    </div>
    <button type="submit" class="btn btn-primary">Télécharger</button>
</form>

@section Scripts {
    @{
        await Html.RenderPartialAsync("_ValidationScriptsPartial");
    }
}

Configuration du fichier projet

Fichier .csproj nécessaire avec le modèle d'hébergement hors processus :


<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
    <PackageReference Include="PaddleOCRSharp" Version="4.5.0.1" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Update="Paddle.Runtime.win_x64" Version="3.3.0.1" />
  </ItemGroup>
  <PropertyGroup>
    <AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
  </PropertyGroup>

</Project>

Étiquettes: dotnet paddleocrsharp OCR aspnet-core NuGet

Publié le 9 juillet à 09h15