Bildtext mit GCP Vision und Python automatisch extrahieren
Wandeln Sie eine gescannte Seite oder einen Screenshot mit einem kleinen Python-Kommandozeilenprogramm in Text um. Dieses Beispiel sendet ein lokales JPEG oder PNG an Google Cloud Vision und gibt den erkannten Text oder eine JSON-Zusammenfassung zur Weiterverarbeitung durch ein anderes Programm aus. Ein Cloud-Storage-Bucket ist dafür nicht nötig.
Voraussetzungen
- Python 3.14.7 oder ein neueres Wartungsrelease von Python 3.14, installiert über die Python-Downloads.
- Die Google Cloud CLI und ein Google-Cloud-Projekt, in dem die Abrechnung und die Cloud Vision API aktiviert sind.
- Ein lokales JPEG oder PNG, das Sie an Google Cloud senden dürfen.
Die folgenden Shell-Befehle verwenden Bash unter macOS. Die Anleitung wurde mit Python 3.14.7 und
google-cloud-vision 3.16.0 getestet. Öffnen Sie ein Terminal in einem eigenen
Beispielverzeichnis und legen Sie dort das Programm und Ihr Bild ab. Prüfen Sie vor dem Erstellen der
virtuellen Umgebung, ob die benötigten Programme ausgeführt werden können:
python3.14 --version && gcloud --version
Cloud-Projekt einrichten
Wählen Sie in der Google Cloud Console ein Projekt aus, prüfen Sie, ob die Abrechnung aktiviert ist, und aktivieren Sie die Cloud Vision API. Notieren Sie die Projekt-ID. Wenn jemand anderes das Projekt verwaltet, bitten Sie diese Person, diese Schritte auszuführen und Ihr Konto zu autorisieren. Weitere Informationen finden Sie in Googles Anleitung zur Einrichtung von Vision.
Entwicklungsumgebung einrichten
Verwenden Sie für die lokale Entwicklung Application Default Credentials (ADC). Ersetzen Sie unten
PROJECT_ID durch Ihre Projekt-ID und melden Sie sich dann mit einem Konto an,
das zur Nutzung dieses Projekts berechtigt ist:
gcloud auth application-default login &&
gcloud auth application-default set-quota-project PROJECT_ID
ADC-Zugangsdaten sind von der normalen CLI-Anmeldung getrennt. Der Befehl für das Kontingentprojekt
benötigt serviceusage.services.use, das die Rolle Service Usage Consumer bereitstellt.
Eine vorhandene Einstellung für GOOGLE_APPLICATION_CREDENTIALS hat Vorrang vor der lokalen ADC-Datei.
Prüfen Sie, ob sie auf die vorgesehenen Zugangsdaten verweist, oder entfernen Sie diese Überschreibung
aus diesem Terminal, bevor Sie die lokale Anmeldung verwenden. Googles
Authentifizierungsanleitung erläutert die Anforderungen sowohl für
die Anmeldung als auch für das Kontingentprojekt. Hinterlegen Sie keine Zugangsdaten im Programm.
Authentifizierung im Produktivbetrieb
Bevorzugen Sie für eine spätere Bereitstellung ein zugeordnetes Dienstkonto auf Google Cloud oder Workload Identity Federation auf anderen Plattformen. Beide funktionieren mit ADC, ohne dass Sie einen Dienstkontoschlüssel herunterladen müssen. Diese Anleitung verwendet lokale Benutzerzugangsdaten und richtet keine Produktivbereitstellung ein.
Python-Client installieren
Erstellen Sie eine neue virtuelle Umgebung und installieren Sie den Client in der festgelegten Version. Der direkte Aufruf ihres Interpreters vermeidet die Aktivierung in der Shell und hält die Installation innerhalb dieses Verzeichnisses:
test ! -e .venv && test ! -L .venv &&
python3.14 -m venv .venv &&
./.venv/bin/python -m pip install 'google-cloud-vision==3.16.0'
Die erste Prüfung verhindert die Wiederverwendung einer vorhandenen Umgebung
.venv. Wenn die Installation nach dem Erstellen der Umgebung fehlschlägt,
behalten Sie Ihre Dateien und führen Sie nur den Installationsbefehl erneut aus:
./.venv/bin/python -m pip install 'google-cloud-vision==3.16.0'
Falls bereits das Erstellen der virtuellen Umgebung fehlgeschlagen ist, wählen Sie ein neues
Beispielverzeichnis, bevor Sie die Einrichtung wiederholen. Verwenden Sie für spätere Befehle den
Interpreter .venv, auch wenn in Ihrem Terminal eine andere Umgebung aktiv ist.
OCR-Programm speichern
Speichern Sie den vollständigen Block als extract_text.py. Er verwendet
document_text_detection für dicht gesetzten Seitentext und liest
full_text_annotation.text, wie in Googles
Tutorial zur Texterkennung in Dokumenten beschrieben.
Auch der REST-Transport verwendet den offiziellen Python-Client und ADC.
import argparse
import json
from pathlib import Path
import sys
import time
from google.api_core.exceptions import ServiceUnavailable
from google.cloud import vision
class OcrError(RuntimeError):
"""A safe diagnostic generated by this program."""
def process_ocr_text(raw_text: str) -> dict:
lines = raw_text.splitlines()
return {
'full_text': raw_text,
'lines': lines,
'line_count': len(lines),
'word_count': len(raw_text.split()),
'cleaned_text': ' '.join(raw_text.split()),
}
def safe_ocr_call(client, image):
for attempt in range(3):
try:
response = client.document_text_detection(
image=image, retry=None, timeout=30.0
)
except ServiceUnavailable:
if attempt == 2:
raise
time.sleep(2 ** attempt)
continue
if response.error.code:
raise OcrError(f'Vision OCR failed (code {response.error.code}).')
return response
def extract_text(image_path: str) -> str:
path = Path(image_path)
if path.suffix.lower() not in ('.jpg', '.jpeg', '.png'):
raise OcrError('Use one JPEG or PNG image, not a PDF or TIFF.')
content = path.read_bytes()
if not content.startswith((b'\x89PNG\r\n\x1a\n', b'\xff\xd8\xff')):
raise OcrError('Input does not have a JPEG or PNG signature.')
with vision.ImageAnnotatorClient(transport='rest') as client:
response = safe_ocr_call(client, vision.Image(content=content))
return response.full_text_annotation.text
def main() -> int:
parser = argparse.ArgumentParser(description='Extract text from one JPEG or PNG.')
parser.add_argument('image_path')
parser.add_argument('--json', action='store_true', help='Print a JSON summary.')
args = parser.parse_args()
try:
text = extract_text(args.image_path)
except OcrError as error:
print(error, file=sys.stderr)
return 1
except Exception as error:
print(f'OCR failed ({type(error).__name__}).', file=sys.stderr)
return 1
if args.json:
print(json.dumps(process_ocr_text(text), ensure_ascii=False))
else:
sys.stdout.write(text)
if not text:
print('No text detected.', file=sys.stderr)
return 0
if __name__ == '__main__':
sys.exit(main())
Die Signaturprüfung erkennt leere Dateien und offensichtliche Formatfehler vor einer Anfrage. Sie decodiert oder validiert ein Bild nicht vollständig. Bei Schäden hinter dem Header kann Vision das Bild ablehnen oder wiederherstellen. Prüfen Sie das Quellbild und vergleichen Sie den erkannten Text damit, bevor Sie das Ergebnis verwenden.
Programm für Ihr Bild ausführen
Speichern Sie einen gut lesbaren Scan oder Screenshot als invoice.png neben dem
Programm und führen Sie dann Folgendes aus:
./.venv/bin/python extract_text.py invoice.png
Der erkannte Text wird mit seinen ursprünglichen Zeilenumbrüchen auf der Standardausgabe ausgegeben.
Eine erfolgreiche Anfrage ohne erkannten Text endet mit Status null, lässt die Standardausgabe leer
und gibt No text detected. auf der Standardfehlerausgabe aus. Dies ist ein
Erkennungsergebnis, kein Beleg dafür, dass das Bild keine Schrift enthält. Fehler führen zum
Beenden mit Status eins und ohne extrahierten Text; falsche Kommandozeilenargumente führen zum
Beenden mit Status zwei.
Um das integrierte Normalisierungsbeispiel zu erhalten, führen Sie dasselbe Programm mit
--json aus:
./.venv/bin/python extract_text.py --json invoice.png
full_text bewahrt die OCR-Antwort auf.
lines, line_count und word_count
beschreiben diesen Text; cleaned_text fasst Leerraum für die Suche zusammen.
Diese Felder erkennen keine Rechnungssummen, Tabellen oder Dokumentabsätze. Ein leeres Ergebnis
liefert leere Zeichenfolgen, ein leeres Array für lines und Zählwerte von null.
Fehlgeschlagene Extraktion diagnostizieren
Das Programm deaktiviert die automatischen Retries des Clients und ruft die OCR-Methode höchstens
dreimal auf. Nur bei ServiceUnavailable wird der Aufruf wiederholt, mit Wartezeiten von
einer und zwei Sekunden. Für jeden Aufruf gilt ein Anfrage-Timeout von 30 Sekunden. Das ist keine
Frist für den gesamten Befehl einschließlich Authentifizierung und Wartezeiten zwischen Retries.
Bei Berechtigungsfehlern, ausgeschöpften Kontingenten und eingebetteten Fehlern einzelner Bilder
wird der Aufruf nicht wiederholt.
FileNotFoundError: Prüfen Sie den Bilddateinamen und das aktuelle Verzeichnis Ihres Terminals.DefaultCredentialsError: Schließen Sie die ADC-Anmeldung ab oder korrigieren Sie eine unbeabsichtigte Überschreibung der Zugangsdaten.Forbidden,PermissionDeniedoder eingebetteter Code 7: Prüfen Sie den Projektzugriff, die API-Aktivierung und das ADC-Kontingentprojekt. Die Wiederholung derselben Anfrage kann keine Berechtigung erteilen.TooManyRequests,ResourceExhaustedoder eingebetteter Code 8: Prüfen Sie die Kontingente des Projekts, bevor Sie es manuell erneut versuchen.- Eingebetteter Code 3 oder
InvalidArgument: Prüfen Sie, ob die Eingabe ein lesbares, intaktes JPEG oder PNG ist.
Fehlermeldungen von Drittanbietern werden nicht ausgegeben, da sie Anfragedetails enthalten können. Eingebettete numerische Codes und Ausnahmenamen zeigen, was als Nächstes zu prüfen ist, ohne diese Details offenzulegen.
Grenzen des Bildworkflows beachten
Dieses Programm liest ein vollständiges Bild in den Arbeitsspeicher und sendet es an einen Cloud-Dienst. Verwenden Sie zunächst ein kleines Testbild, prüfen Sie die unterstützten Formate und Größenlimits und sehen Sie sich die Preise für Vision an, bevor Sie größere Datenmengen verarbeiten. Stapelverarbeitung kann den Anfrageaufwand verringern, beseitigt aber nicht die Funktionsgebühren pro Bild.
Verwenden Sie für mehrseitige PDFs oder TIFFs die APIs zur Dateiannotation, statt die Datei umzubenennen oder an diese Bild-CLI zu übergeben. Automatische Spracherkennung und OCR können Text dennoch falsch lesen. Bewerten Sie Ihre eigenen Scans, Schriftsysteme und Layouts. Ein sauberes synthetisches Beispiel belegt keine Genauigkeit bei Belegen, Handschrift oder Dokumenten aus dem Produktivbetrieb.
