Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 24/03/2023, à 14:48

sr40150

Un script bash qui effectue une OCR

un script bash qui effectue une OCR (reconnaissance optique de caractères) sur des fichiers image ou PDF et génère un fichier ODT (OpenDocument Text) en français, vous pouvez utiliser les outils open source Tesseract et ImageMagick pour les images, et Poppler pour les PDF. Vous devrez les installer avant de poursuivre.

Voici un exemple de script bash fonctionnel pour réaliser cette tâche :

bash

#!/bin/bash

# Vérifier si un argument a été fourni
if [ "$#" -ne 1 ]; then
    echo "Usage: $0 <image_or_pdf>"
    exit 1
fi

file="$1"
extension="${file##*.}"
filename="${file%.*}"
language="fra"
output_odt="${filename}.odt"

# Vérifier si le fichier d'entrée est une image ou un PDF
if [[ "${extension,,}" =~ ^(png|jpg|jpeg)$ ]]; then
    # OCR sur une image
    tesseract "$file" "$filename" -l "$language" --psm 1
    pandoc "${filename}.txt" -o "$output_odt"
elif [[ "${extension,,}" == "pdf" ]]; then
    # Convertir le PDF en images (PNG)
    pdf_name=$(basename "$filename")
    mkdir -p "$pdf_name"
    pdftoppm -png "$file" "${pdf_name}/page"

    # OCR sur les images extraites
    for img in "${pdf_name}"/*.png; do
        img_base="${img%.*}"
        tesseract "$img" "$img_base" -l "$language" --psm 1
    done

    # Fusionner les fichiers texte en un seul
    cat "${pdf_name}"/*.txt > "${pdf_name}.txt"

    # Convertir le fichier texte en ODT
    pandoc "${pdf_name}.txt" -o "$output_odt"

    # Supprimer les fichiers temporaires
    rm -rf "$pdf_name"
else
    echo "Le fichier doit être une image (PNG, JPG, JPEG) ou un PDF."
    exit 1
fi

# Supprimer le fichier texte temporaire
rm "${filename}.txt"

echo "Fichier ODT généré : $output_odt"

Copiez et collez ce script dans un fichier appelé ocr_to_odt.sh, puis rendez-le exécutable avec chmod +x ocr_to_odt.sh. Vous pouvez l'utiliser de la manière suivante :

bash

./ocr_to_odt.sh mon_image.png

ou

bash

./ocr_to_odt.sh mon_document.pdf

Le script convertira le fichier d'entrée en un fichier ODT avec le même nom de base.

Notez que ce script nécessite que Tesseract, ImageMagick et Poppler soient installés sur votre système. Vous pouvez les installer sur un système basé sur Debian/Ubuntu avec la commande suivante :

bash

sudo apt-get install tesseract-ocr tesseract-ocr-fra imagemagick poppler-utils pandoc

Hors ligne

#2 Le 24/03/2023, à 15:07

Watael

Re : Un script bash qui effectue une OCR

Bonjour,

  • $# est un nombre, les guillemets sont donc inutiles. on pourrait se passer de test et faire une évaluation arithmétique : (($# != 1))

  • on ne sait pas si $1 est bien un fichier.

  • lors de l'assignation d'une variable, les substitutions de commandes, et les développements de paramètres n'ont pas besoin d'être entre guillemets : le shell s'occupe de protéger les "espaces"

  • si c'est pour être distribué, le script doit vérifier que les programmes externes sont installés

  • les guillemets sont inutiles entre crochets doubles,

  • et un test simple suffirait ici

  • basename peut être remplacé par un développement de paramètres (comme $extension)

  • la barre oblique ne peut pas faire partie d'un nom de fichier, les accolades, ici, sont inutiles.

  • le point non plus smile


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#3 Le 24/03/2023, à 15:19

sr40150

Re : Un script bash qui effectue une OCR

version 2

#!/bin/bash

# Vérification des dépendances
command -v tesseract >/dev/null 2>&1 || { echo >&2 "tesseract est requis mais n'est pas installé.  Aborting."; exit 1; }
command -v pdftoppm >/dev/null 2>&1 || { echo >&2 "poppler-utils est requis mais n'est pas installé.  Aborting."; exit 1; }
command -v unoconv >/dev/null 2>&1 || { echo >&2 "unoconv est requis mais n'est pas installé.  Aborting."; exit 1; }

if (( $# != 1 ))
then
    echo "Utilisation: $0 <fichier_image_ou_pdf>"
    exit 1
fi

if [ ! -f "$1" ]
then
    echo "Erreur: Le fichier \"$1\" n'existe pas."
    exit 1
fi

file="$1"
extension="${file##*.}"
filename="${file%.*}"

if [ "$extension" = "pdf" ]
then
    # Conversion de PDF en images
    pdftoppm "$file" "${filename}_page" -png
    pages=$(ls "${filename}_page"*".png")

    # OCR pour chaque page
    for page in $pages
    do
        tesseract "$page" "${page%.*}" -l fra
    done

    # Fusion des fichiers texte
    cat "${filename}_page"*".txt" > "${filename}.txt"

    # Conversion du fichier texte en ODT
    unoconv -f odt -o "${filename}.odt" "${filename}.txt"

    # Suppression des fichiers temporaires
    rm "${filename}_page"*.png "${filename}_page"*.txt

elif [ "$extension" = "png" ] || [ "$extension" = "jpg" ] || [ "$extension" = "jpeg" ]
then
    # OCR pour l'image
    tesseract "$file" "${filename}" -l fra

    # Conversion du fichier texte en ODT
    unoconv -f odt -o "${filename}.odt" "${filename}.txt"

    # Suppression du fichier texte temporaire
    rm "${filename}.txt"

else
    echo "Erreur: Extension de fichier non supportée."
    exit 1
fi

echo "Conversion terminée. Fichier ODT créé: ${filename}.odt"

Hors ligne

#4 Le 24/03/2023, à 15:22

bruno

Re : Un script bash qui effectue une OCR

Bonjour,

On peut ajouter que tester l'extension les derniers caractères du nom d'un fichier ne permet pas de connaître à coup sûr son type ; contrairement à la sortie de :

file -b "$fichier"

Hors ligne

#5 Le 24/03/2023, à 16:29

Watael

Re : Un script bash qui effectue une OCR

pour la vérification des dépendances, tu pourrais faire une boucle sur un tableau :

required=( tesseract pdftppm unoconv )
for cmd in "${required[@]}"; do command -v "$cmd" &>/dev/null || { >&2 echo "\"$cmd\" est requis mais n'est pas installé.  Aborting."; exit 1;}; done
    pages=$(ls "${filename}_page"*".png")

oh non, pas ça. tongue utilise un tableau :

pages=( "${filename}_page"*.png )
for page in "${pages[@]}"; do...

plutôt que plusieurs test, il y a une option OU :

elif test "$ext" = "png" -o "$ext" = "jpg" -o ...

mais ici, on pourrait utiliser des crochets doubles et une correspondance de motifs étendue (extglob) :

elif [[ $extension == @(png|jpg|jpeg) ]]...

Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#6 Le 24/03/2023, à 20:42

sputnick

Re : Un script bash qui effectue une OCR

Je ne suis pas d'accord avec Watael. Si on utilise bash explicitement (on ne code pas en mode POSIX), autant utiliser la flexibilité des double crochets: [[ ]].


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#7 Le 24/03/2023, à 21:09

Watael

Re : Un script bash qui effectue une OCR

Si on utilise bash explicitement (on ne code pas en mode POSIX), autant utiliser la flexibilité des double crochets: [[ ]].

oui, quand on utilise ses fonctions avancées, sinon autant utiliser test.
echo -e est un "bashism". Faut-il privilégier son emploi à printf qui, lui, est POSIX ?*

--
* argument très moyen. smile

Dernière modification par Watael (Le 24/03/2023, à 21:09)


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#8 Le 25/03/2023, à 00:33

sputnick

Re : Un script bash qui effectue une OCR

Non, par défaut [[ ]] est bien plus tolérant et pratique que [ ]. Par exemple, pas besoin de "quoter" les variables avec [[ ]] alors que c'est nécessaire dans [ ].

C'est recommandé par les pros de bash, ceux même qui ont créé https://shellcheck.net et le canal IRC bash@libera.irc.

Ils sont à la base du celebre bash FAQ, wiki wooledge, Greg wiki.

D'ailleurs, greybot dit à ce sujet:

[[ is a bash keyword similar to (but more powerful than) the [ command. See <http://mywiki.wooledge.org/BashFAQ/031> and <http://mywiki.wooledge.org/BashGuide/Te … nditionals>. Unless you're writing for POSIX sh, we recommend [[

Ils sont sur IRC depuis plus de 20 ans, j'y ais passé pas mal de temps aussi. C'est des maîtres en shell/bash. Tu trouvera pas plus pointu, à moins d'aller sur https://unix.stackexchange.com où il y a des pointures qui ne me contrediront pas.


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#9 Le 25/03/2023, à 01:19

Watael

Re : Un script bash qui effectue une OCR

je n'impose pas test

Watael a écrit :

si j'ai une chose simple à faire, j'utilise un outil simple.*

et j'exprime, en "brandissant" cet outil simple, que je fais une chose simple.

ils peuvent recommander ce qu'ils veulent, et parce que ce n'est qu'une recommandation**, on a le droit de ne pas s'y arrêter, et de réfléchir par soi-même à ses propres besoins.

--
* n'est-ce pas là du simple bons sens ? smile KISS!
** ce serait une injonction, ce serait pareil yikes mais je parlerais alors de devoir.

Dernière modification par Watael (Le 25/03/2023, à 01:21)


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne