Simple Beginner questions

#4
by Linushug - opened

Hello,
Two simple questions to make it easier to get started and provide a basis for further experimentation.

  1. Is this image even suitable for this model? (This is a German text published in 1905.)

P11_OCR_test
2. Is there a simple Python script to transcribe this image into text?
thanks and regrds
Linus

sorry mistake

Digital Humanities @ University of Bern org

Although the model can be used for printed black letters/Fraktur (like the one provided), it's not necessary.
I would advise using a Tesseract model: deu_frak.traineddata (https://github.com/tesseract-ocr/tessdata)
Otherwise, most VLMs are capable of dealing with Fraktur.

thodel changed discussion status to closed
Digital Humanities @ University of Bern org
edited 29 days ago

HI Linus,

This is what I did

import os
import warnings
import logging
import re

Suppress warnings

warnings.filterwarnings("ignore", category=FutureWarning)
warnings.filterwarnings("ignore", category=UserWarning)
os.environ["TRANSFORMERS_VERBOSITY"] = "error"
logging.getLogger("transformers").setLevel(logging.ERROR)

import pytesseract
from PIL import Image
from transformers import pipeline

def ocr_and_translate(image_path):
pytesseract.pytesseract.tesseract_cmd = r'/opt/homebrew/bin/tesseract'
custom_config = r'--tessdata-dir "/opt/homebrew/share/tessdata"'

try:
    raw_text = pytesseract.image_to_string(image_path, lang='deu', config=custom_config)
except Exception as e:
    print(f"Error: {e}")
    return None

# Enhanced Fraktur Cleaning
# First: Manual fixes for non-pattern errors
text = raw_text.replace('ift', 'ist').replace('fie', 'sie').replace('fich', 'sich') \
                     .replace('fo ', 'so ').replace(' fit ', ' sitzt ').replace('gelommen', 'gekommen') \
                     .replace('Deranlaffung', 'Veranlassung').replace('auzsieht', 'aussieht') \
                     .replace('felbit', 'selbst').replace('feine', 'keine').replace('Gie ', 'Sie ') \
                     .replace('fchlaft', 'schläft').replace('leidenjchaftslo', 'leidenschaftslos') \
                     .replace('fühle Blonde', 'kühle Blonde').replace('Wigger3', 'Wiggers') \
                     .replace('Wassermolch3', 'Wassermolchs').replace('Staat3eramen', 'Staatsexamen') \
                     .replace('gegeschlüpft', 'geschlüpft').replace('Google', '')

# Second: Regex to fix the "long s" (f) followed by consonants (t, ch, p, k)
# This catches: ift -> ist, fie -> sie, fchlaft -> schlaft, ftimmt -> stimmt, etc.
clean_text = re.sub(r'f(t|ch|p|k|i|o|u|a)', r's\1', text)

print(f"Detected German Text (Cleaned):\n{clean_text}")
print("-" * 20)

translator = pipeline("translation_de_to_en", model="Helsinki-NLP/opus-mt-de-en")

# Split into sentences for better quality
sentences = re.split(r'(?<=[.!?])\s+', clean_text.replace('\n', ' '))
translated_parts = [translator(s, max_length=512)[0]['translation_text'] for s in sentences if s.strip()]

return " ".join(translated_parts)

if name == "main":
image_file = "Xhai0seGEt6rmLIOwnZIA.png"
if os.path.exists(image_file):
print(f"Translated English Text:\n{ocr_and_translate(image_file)}")
else:
print(f"Error: File {image_file} not found.")

My system is mac M1. I ran this in conda/mamba env with python3.9. I had to do the following:
brew install tesseract-lang
python -m pip install "huggingface-hub>=0.19.3,<1.0"

then I ran

TESSDATA_PREFIX=/opt/homebrew/share/tessdata/ ./run_trpng8.py

And I the output is

Detected German Text (Cleaned):
— 1 —

„Warum ich gerade nach Heidelberg gegangen
bin, will ich Dir gleich im voraus erzählen, weil die
Veranlassung dazu eben zu mir ins Zimmer gekommen
ist und auf dem Sosa sitzt und gähnt und, da sie
vom Stenographieren ermüdet ist, eben anfängt ein-
zuschlafen und mit geschloffenen Wimpern noch etwas
fühle und blonder aussieht wie gewöhnlich. ch
nenne sie nämlich die kühle Blonde. Sie imponiert
mir maßlo3, mehr als alle Männer. Sie selbst ist
eigentlicd; wie ein Mann, der in eine weibliche Hülle
gejchlüpst if. Und dazu stimmt auch, daß sie von
den Männern so gar keine Notiz nimmt. Sie hast
sie nicht, sie fürchtet sie nicht, sie verachtet sie nicht —
nein, die Männer sind ihr einsach Lust — eine un-
angenehme Naturerscheinung,, der man nun einmal
auf Schritt und Tritt auf der Welt begegnet und
am beiten gar keine Beachtung fehenst. Höchiteng,
daß sie einmal rätfelhast und mitleidig lächelt, wenn
sie die jungen Studenten mit ihren bunten Müten
und den frischen roten Narben auf ihren Kinder:
gesichtern des Weges flanieren sieht.

„Also das ist die kühle Blonde oder richtiger die
cand. phil. Meta Wiggers, die, nebenbei gejagt, schon
fest schläst und, nach ihrem strengen Gesichtsausdrud
zu urteilen, von ihrem Tünstigen Staatsexamen
träumt. Dein Fall wäre sie nicht. Für Dich wäre
sie zu blond und zu überschlant und zu herb und
vor allem viel zu leidenschastslos — sie hat wirklich
ungefähr das füdliche Feuer eines Wafjermolch3 in
ihren Adern — obwohl sie Momente bat, mo sie

Translated English Text:
— 1 — "Why I just went to Heidelberg, I want to tell you in advance, because the reason for this has just come to me in the room and sits on the sosa and yawns and, as she is tired of stenography, just starts to fall asleep and feel something with a sloping eyelash and looks more blond than usual. You call her the cool blonde. She's impressing me, more than all men. She herself is peculiar; like a man who is jhlüpst in a female shell if. And it is also true that she takes no notice of the men at all. She does not have it, she does not fear it, she does not despise it — no, the men are her one-off lust — an un-pleasing natural phenomenon, which one encounters at every step of the world, and which at the behest does not receive any attention at all. Höchiteng, that once she has counseled and compassionately smiles when she sees the young students strolling on her children with their colorful mouths and the fresh red scars: faces of the way. "So that's the cool blonde or right the cand. Phil. Meta Wiggers, who by the way chases, already firmly and, according to her strict facial expression, dreams of her filthy state exam. She wouldn't be your case. For you, she would be too blond and too clumsy and too harsh and, above all, too unscrupulous — she really has about the usual fire of a Wafjermolch3 in her veins — even though she asked for moments,

Digital Humanities @ University of Bern org
edited 29 days ago

Hi Linus,

The following script uses deu_frak.traineddata

curl -L -o /opt/homebrew/share/tessdata/deu_frak.traineddata https://github.com/tesseract-ocr/tessdata/raw/main/deu_frak.traineddata

import os
import warnings
import logging
import re

Suppress warnings

warnings.filterwarnings("ignore", category=FutureWarning)
warnings.filterwarnings("ignore", category=UserWarning)
os.environ["TRANSFORMERS_VERBOSITY"] = "error"
logging.getLogger("transformers").setLevel(logging.ERROR)

import pytesseract
from PIL import Image
from transformers import pipeline

def ocr_and_translate(image_path):
# Setup Paths
pytesseract.pytesseract.tesseract_cmd = r'/opt/homebrew/bin/tesseract'
custom_config = r'--tessdata-dir "/opt/homebrew/share/tessdata"'

# 1. OCR Detection - FORCED Fraktur
# 1. OCR-Erkennung - Zwang auf Fraktur
try:
    # By removing '+deu', we force Tesseract to use ONLY the Fraktur model
    # Indem wir '+deu' entfernen, zwingen wir Tesseract, NUR das Fraktur-Modell zu nutzen
    raw_text = pytesseract.image_to_string(image_path, lang='deu_frak', config=custom_config)
except Exception as e:
    print(f"Detailed Error: {e}")
    return None

if not raw_text.strip():
    return "No text detected."

# 2. Optimized Cleaning for Fraktur
# 2. Optimierte Reinigung für Fraktur

# Safety Regex: Fix the "long s" (f) followed by specific letters if OCR still fails
# Sicherheits-Regex: Korrigiert das „lange s“ (f), falls das OCR noch Fehler macht
text = re.sub(r'f(t|ch|p|k|i|o|u|a|l)', r's\1', raw_text)

# Manual fixes for common Fraktur misreads (numbers vs letters)
# Final minor Fraktur polish for the "last 1%"
clean_text = text.replace('geschlüpst', 'geschlüpft') \
                       .replace('hast sie nicht', 'haßt sie nicht') \
                       .replace('einsach', 'einfach') \
                       .replace('Lust', 'Luft') \
                       .replace('slanieren', 'flanieren') \
                       .replace('rätselhast', 'rätselhaft') \
                       .replace('schläst', 'schläft') \
                       .replace('künstigen', 'künftigen') \
                       .replace('Uooglc', '') # Cleans the Google logo artifact

print(f"Detected German Text (Forced Fraktur):\n{clean_text}")
print("-" * 20)

# 3. Translation logic
translator = pipeline("translation_de_to_en", model="Helsinki-NLP/opus-mt-de-en")

# Split by sentence to ensure completeness
sentences = re.split(r'(?<=[.!?])\s+', clean_text.replace('\n', ' '))
translated_parts = []

for sentence in sentences:
    if sentence.strip():
        translation = translator(sentence, max_length=512, repetition_penalty=2.0)
        translated_parts.append(translation[0]['translation_text'])

return " ".join(translated_parts)

if name == "main":
image_file = "Xhai0seGEt6rmLIOwnZIA.png"
if os.path.exists(image_file):
result = ocr_and_translate(image_file)
print(f"Translated English Text:\n{result}")
else:
print(f"Error: File {image_file} not found.")

And the output is:

Detected German Text (Forced Fraktur):
—11.-

»Warum ich gerade nach Heidelberg gegangen
bin, will ich Dir gleich im voraus erzählen, weil die
Veranlassung dazu eben zu mir ins Zimmer gekommen
ist und auf dem Sosa sitzt und gähnt und, da sie
vom Stenographieren ermüdet ist, eben anfängt ein-
zuschlafen und mit geschlossenen Wimpern noch etwas
kühler und blonder aussieht wie gewöhnlich. Ich
nenne sie nämlich die kühle Blonde. Sie imponiert
mir maßlos, mehr als alle Männer. Sie selbst ist
eigentlich wie ein Mann, der in eine weibliche Hülle
geschlüpft ist. Und dazu stimmt auch, daß sie von
den Männern so gar keine Notiz nimmt. Sie haßt
sie nicht, sie fürchtet sie nicht, sie verachtet sie nicht —-
nein, die Männer sind ihr einfach Luft — eine un-
angenehme Naturerscheinung, der man nun einmal
auf Schritt und Tritt auf der Welt begegnet und
am besten gar keine Beachtung schenkt. Höchstens,
daß sie einmal rätselhaft und mitleidig lächelt, wenn
sie die jungen Studenten mit ihren bunten Mützen
und den frischen roten Narben auf ihren Kinder-
gesichtern des Weges flanieren sieht.

»Also das ist die kühle Blonde oder richtiger die
annä. phil. Meta Wiggers, die, nebenbei gesagt, schon
fest schläft und, nach ihrem strengen Gesichtsausdruck
zu urteilen, von ihrem künftigen Staatsexamen
träumt. Dein Fall wäre sie nicht. Für Dich wäre
sie zu blond und zu überschlank und zu herb und
vor allem viel zu leidenschastslos —- sie hat wirklich
ungefähr das südliche Feuer eines Wassermolchs in
ihren Adern — obwohl sie Momente hat, wo sie

Translated English Text:
—11.- "Why I just went to Heidelberg, I want to tell you in advance, because the reason for this has just come to me in the room and sits on the sosa and yawns and, as she is tired of stenography, just starts to fall asleep and with closed eyelashes looks a little cooler and blonder as usual. Because I call her the cool blonde. She impossibly impossibly, more than all men. She herself is actually like a man who has slipped into a female shell. And it is also true that she takes no notice of the men at all. She doesn't hate her, she doesn't fear her, she doesn't despise her — no, the men are just air to her — an un-pleasing natural phenomenon that is encountered at every step of the world and best does not pay attention at all. At most, she smiles enigmaticly and compassionately once when she sees the young students strolling on her children's faces with their colorful hats and fresh red scars. 'So that's the cool blonde or the real one. Phil. Meta Wiggers, who, by the way, is already sleeping hard and, according to her strict facial expression, dreams of her future state exam. She wouldn't be your case. For you she would be too blond and too clumsy and too harsh and, above all, much too unscrupulous — she really has about the southern fire of a water chute in her veins — even though she has moments where she

Sign up or log in to comment