Open geimist opened 1 year ago
Also das was in dem ersten link vorgeschlagen wird, könnte ja ein Weg sein. Aber das scheint sehr zeitintensiv zu sein. Also das pdf in einzelne Seiten aufteilen, alle abspeichern, und die Größe ermitteln. Als Stufe dahinter könnte man noch ermitteln ob auf den einzelnen Seiten noch Text vorhanden ist. Aber wie gesagt das ist sehr zeitintensiv.
Das mit dem Imagemavick muss ich mir mal genauer ansehen.
Mir scheint die Variante aus den Kommentaren des 2. Links auch sehr vielversprechend. Dort wird auf Pillow verwiesen. Leider wurden dort keine Details gezeigt.
Das mit dem Imagemavick muss ich mir mal genauer ansehen.
Irgendwo hatte ich gelesen, dass auch ImageMagick für diesen Job teilweise auf Ghostsrkipt zurückgreift. Wenn das wirklich benötigt würde, wäre das glaube eine nicht sehr einfach aufzulösende Abhängigkeit.
Mal ein dummer Gedanke eines Laien. Wäre es nicht am einfachsten erst OCR laufen zu lassen, und dann Seite mit dem leeren Layer zu löschen?
Das. Problem ist die leere Seite richtig zu erkennen. Da gibt es wie von Stephan erwähnt unterschiedliche Hürden. Also wann ist eine Seite leer. Was mit Bildern im der Seite......
02.04.2023 08:18:47 Struppix @.***>:
Mal ein dummer Gedanke eines Laien. Wäre es nicht am einfachsten erst OCR laufen zu lassen, und dann Seite mit dem leeren Layer zu löschen?
— Reply to this email directly, view it on GitHub[https://github.com/geimist/synOCR/issues/9#issuecomment-1493236647], or unsubscribe[https://github.com/notifications/unsubscribe-auth/A24BCYIMEILD6RBZRKYEEUTW7EK4NANCNFSM6AAAAAAWPDO62A]. You are receiving this because you commented.[Verfolgungsbild][https://github.com/notifications/beacon/A24BCYKDS632H4VSI5SN7VLW7EK4NA5CNFSM6AAAAAAWPDO62CWGG33NNVSW45C7OR4XAZNMJFZXG5LFINXW23LFNZ2KUY3PNVWWK3TUL5UWJTSZAD52O.gif]
OK anderer Gedanke. Was wäre wenn wir die Datengröße der Seiten abfragen und dann alles unter Xbyte löschen ?
https://write.tchncs.de/~/Paperless/tools-3-leerseiten-entfernen/
Ah sehe gerade Stephan hatte ja den gleichen Gedanken. Finde aber den letzten link nicht schlecht als Ansatz. Hätte man alles bereits an Board.
Das wäre auch eine Möglichkeit. Aber wie groß ist zb eine Seite wo nur eine Seitenzahl oder ein Wort drauf steht. Ist die auch leer?
02.04.2023 09:08:57 Struppix @.***>:
OK anderer Gedanke. Was wäre wenn wir die Datengröße der Seiten abfragen und dann alles unter Xbyte löschen ?
https://write.tchncs.de/~/Paperless/tools-3-leerseiten-entfernen/[url]
— Reply to this email directly, view it on GitHub[https://github.com/geimist/synOCR/issues/9#issuecomment-1493250761], or unsubscribe[https://github.com/notifications/unsubscribe-auth/A24BCYPNJ6FC47GL4O27B23W7EQYRANCNFSM6AAAAAAWPDO62A]. You are receiving this because you commented.[Verfolgungsbild][https://github.com/notifications/beacon/A24BCYOOWRVSCI2KWJLV67DW7EQYRA5CNFSM6AAAAAAWPDO62CWGG33NNVSW45C7OR4XAZNMJFZXG5LFINXW23LFNZ2KUY3PNVWWK3TUL5UWJTSZAEZMS.gif]
Na das ist es doch dann. Erst prüfen ob Textlayer belegt. Dann kleiner als xbyte und löschen., oder umgekehrt.
Muss man mal probieren ob das zuverlässig klappt. Ich könnte mir vorstellen das die Grenzwert nicht so einfach sind. Also. Dieses kleiner xbyte zb. Aber ich schaue mir das als nächstes mal an. Kämpfe gerade noch mit dem neuen Schreiben der.metadaten
02.04.2023 09:15:12 Struppix @.***>:
Na das ist es doch dann. Erst prüfen ob Textlayer belegt. Dann kleiner als xbyte und löschen., oder umgekehrt.
— Reply to this email directly, view it on GitHub[https://github.com/geimist/synOCR/issues/9#issuecomment-1493251724], or unsubscribe[https://github.com/notifications/unsubscribe-auth/A24BCYPXE5EO6F6H2X4CU43W7ERP7ANCNFSM6AAAAAAWPDO62A]. You are receiving this because you commented.[Verfolgungsbild][https://github.com/notifications/beacon/A24BCYIPPU6OMD7477XNKZTW7ERP7A5CNFSM6AAAAAAWPDO62CWGG33NNVSW45C7OR4XAZNMJFZXG5LFINXW23LFNZ2KUY3PNVWWK3TUL5UWJTSZAE3IY.gif]
Den Gedanken, die Anzahl der erkannten Wörter gegen einen Wert abgleichen, der in der GUI von synOCR konfigurierbar ist, hatte ich auch schon ins Auge gefasst: https://www.synology-forum.de/threads/synocr-gui-fuer-ocrmypdf.99647/page-178#post-1068432
Vielleicht ist das ja ein gangbarer Weg? Ich könnte mir schon vorstellen, dass wenn keinerlei Wörter auf einer Seite erkannt wurden, die Seite als leer gilt. Allerdings ist die Frage wie dann mit anderen Objekten umgegangen wird, denn Grafiken spielen ja auch eine Rolle, die ja per Definition nicht als Text ins finalen PDF einfliessen werden.
Ich denke, wir dürften uns nicht nur auf eine Variante verlassen, sondern es müsste eine Kombination aus mehreren sein. Aus Performancegründen würde ich eigentlich auf eine vorherige Texterkennung verzichten, aber ich sehe die auch als eines der wichtigsten Kriterien (ob Zeichen erkannt wurden). Vielleicht ist es auch von Vorteil, wenn wir nur die Seiten genauer ansehen, auf denen kein Text gefunden wurde. Im zweiten Schritt fände ich die Ermittlung der Deckung sympathischer als die Dateigröße. Um die Realisierbarkeit abzuwägen, muss man das mal simulieren und eine Testumgebung erstellen.
Aber wie @Gthorsten65 schon schrieb: zu Zeit arbeiten wir noch anderen Features und Problemchen.
chatGPT sagt folgendes und kommt letztendlich zu der gleichen Schlussfolgerung (und kennt die Problematik 😉):
Wenn Sie eine gescannte PDF-Seite verarbeiten, kann es schwierig sein, zwischen relevanten Inhalten und unnötigem Rauschen (wie z.B. Pixeln vom Scannen) zu unterscheiden. Ein Ansatz besteht darin, ein Schwellenwertverfahren anzuwenden, um Pixel mit niedriger Helligkeit zu entfernen. Hier ist ein Beispielcode, der zeigt, wie Sie das Schwellenwertverfahren in Python mit der Bibliothek Pillow anwenden können:
from PIL import Image
with Image.open('input.pdf') as img:
threshold_value = 150 # Setzen Sie den Schwellenwert auf einen passenden Wert
threshold_img = img.convert('L').point(lambda x: 255 * (x > threshold_value), mode='1')
# Ermitteln der Anzahl der nicht-weißen Pixel
pixel_count = threshold_img.size[0] * threshold_img.size[1]
white_pixel_count = threshold_img.histogram()[255]
black_pixel_count = pixel_count - white_pixel_count
# Überprüfen, ob die Seite leer ist
if black_pixel_count == 0:
print('Die Seite ist leer.')
else:
print('Die Seite ist nicht leer.')
> In diesem Beispiel wird die gescannte PDF-Seite mit Pillow als Bild geladen und dann das Schwellenwertverfahren angewendet. Das Verfahren wandelt das Bild in Graustufen um, wendet dann den Schwellenwert an und konvertiert das Ergebnis in ein binäres Schwarzweißbild. Anschließend wird die Anzahl der nicht-weißen Pixel ermittelt, um festzustellen, ob die Seite leer ist.
> Beachten Sie, dass Sie den Schwellenwert anpassen müssen, um ihn an Ihre spezifischen Anforderungen anzupassen. Wenn der Schwellenwert zu hoch ist, können relevante Informationen verloren gehen, und wenn er zu niedrig ist, können unnötige Pixel beibehalten werden.
Mir scheint das ein guter Ansatz, den wir mal testen sollten, sofern dafür mal Kapazität vorhanden ist.
Diese Prüfung würde ich nur auf Seiten anwenden, auf denen zuvor kein Text gefunden wurde.
Ggf. sollte es vielleicht notwendig sein, dem User in der GUI einen Schwellwert definieren zu lassen.
Die lib hatten wir ja eh schon im Auge. Die Frage ist dann ob es so einstufig reicht.
Wie soll das eigentlich von Ablauf her laufen? Also nach dem OCR das Dokument durchsuchen und alle leerseiten entfernen?
Das würde ja eigentlich in das Modul passen was auch den Split oder die Metadaten macht...
Soll ich das als test da mal mit einbauen?
08.04.2023 00:11:29 Stephan Geisler @.***>:
chatGPT sagt folgendes und kommt letztendlich zu der gleichen Schlussfolgerung (und kennt die Problematik 😉 ):
Wenn Sie eine gescannte PDF-Seite verarbeiten, kann es schwierig sein, zwischen relevanten Inhalten und unnötigem Rauschen (wie z.B. Pixeln vom Scannen) zu unterscheiden. Ein Ansatz besteht darin, ein Schwellenwertverfahren anzuwenden, um Pixel mit niedriger Helligkeit zu entfernen. Hier ist ein Beispielcode, der zeigt, wie Sie das Schwellenwertverfahren in Python mit der Bibliothek Pillow anwenden können:
*from PIL import Image
Laden der gescannten PDF-Seite als Bild
with Image.open('input.pdf') as img:
Anwenden des Schwellenwerts
threshold_value = 150 # Setzen Sie den Schwellenwert auf einen passenden Wert threshold_img = img.convert('L').point(lambda x: 255 * (x > threshold_value), mode='1') # Ermitteln der Anzahl der nicht-weißen Pixel pixel_count = threshold_img.size[0] * threshold_img.size[1] white_pixel_count = threshold_img.histogram()[255] black_pixel_count = pixel_count - white_pixel_count # Überprüfen, ob die Seite leer ist if black_pixel_count == 0: print('Die Seite ist leer.') else: print('Die Seite ist nicht leer.')
* In diesem Beispiel wird die gescannte PDF-Seite mit Pillow als Bild geladen und dann das Schwellenwertverfahren angewendet. Das Verfahren wandelt das Bild in Graustufen um, wendet dann den Schwellenwert an und konvertiert das Ergebnis in ein binäres Schwarzweißbild. Anschließend wird die Anzahl der nicht-weißen Pixel ermittelt, um festzustellen, ob die Seite leer ist. Beachten Sie, dass Sie den Schwellenwert anpassen müssen, um ihn an Ihre spezifischen Anforderungen anzupassen. Wenn der Schwellenwert zu hoch ist, können relevante Informationen verloren gehen, und wenn er zu niedrig ist, können unnötige Pixel beibehalten werden.
Mir scheint das ein guter Ansatz, den wir mal testen sollten. Ggf. sollte es vielleicht notwendig sein, dem User in der GUI einen Schwellwert definieren zu lassen.
— Reply to this email directly, view it on GitHub[https://github.com/geimist/synOCR/issues/9#issuecomment-1500688843], or unsubscribe[https://github.com/notifications/unsubscribe-auth/A24BCYJ7XLS7BNOVSS56BX3XACGJBANCNFSM6AAAAAAWPDO62A]. You are receiving this because you were mentioned.[Verfolgungsbild][https://github.com/notifications/beacon/A24BCYJX44XLGY5N5D7AXA3XACGJBA5CNFSM6AAAAAAWPDO62CWGG33NNVSW45C7OR4XAZNMJFZXG5LFINXW23LFNZ2KUY3PNVWWK3TUL5UWJTSZOKY4W.gif]
Die Frage ist dann ob es so einstufig reicht.
Auf jeden Fall zweistufig. Ich würde das vor der Trennseitenverarbeitung angehen. synOCR sucht im 1. Schritt alle Seiten, die keinen Text enthalten und übergibt alle Parameter dem Pythonskript.
Wie soll das eigentlich von Ablauf her laufen?
In der GUI würde ich den User folgende Parameter setzen lassen:
0-255
(default 150)n
(Defaultwert müssen wir testen - die Anzahl der weißen und schwarzen Pixel würde ich im Loglevel 2 (oder besser generell 🤔) mit ausgeben, damit der User das gut justieren kannSoll ich das als test da mal mit einbauen?
Gerne. Wir können die Umstellung von pypdf zu pikepdf aber auch erst abschließen. Ganz wie du möchtest.
Ok, das halte ich auch für eine gute Lösung. Aber mit synOCR sucht meinst du das Python script oder? Also das Script würde die leeren Seiten suchen und zurück geben? Aber wenn ich die leeren Seiten suche, könnte ich sie doch auch direkt entfernen? Mit einstufig meinte ich ob nur die Suche mit der. Pil lib reicht, oder ob es macher sinnvoller ist nochmal nach Text in den Seiten zu suchen, oder Seitengrösse bewerten.
08.04.2023 11:53:50 Stephan Geisler @.***>:
Die Frage ist dann ob es so einstufig reicht.
Auf jeden Fall zweistufig. Ich würde das vor der Trennseitenverarbeitung angehen. synOCR sucht im 1. Schritt alle Seiten, die keinen Text enthalten und übergibt alle Parameter dem Pythonskript.
In der GUI würde ich den User folgende Parameter setzen lassen:
- Leerseitenerkennung: an/aus
- Schwellwert, für die 1Bit-Konvertierung (ab welchem Helligkeitswert zählt ein Pixel als weiß oder schwarz): 0-255 (default 150)
- Schwellwert Anzahl schwarzer Pixel: n (Defaultwert müssen wir testen - die Anzahl der weißen und schwarzen Pixel würde ich im Loglevel 2 mit ausgeben, damit der User das gut justieren kann
— Reply to this email directly, view it on GitHub[https://github.com/geimist/synOCR/issues/9#issuecomment-1500849664], or unsubscribe[https://github.com/notifications/unsubscribe-auth/A24BCYP3PUUZOFBW4BTMS73XAEYSZANCNFSM6AAAAAAWPDO62A]. You are receiving this because you were mentioned.[Verfolgungsbild][https://github.com/notifications/beacon/A24BCYLIZ3Y7D5IDE43XYQ3XAEYSZA5CNFSM6AAAAAAWPDO62CWGG33NNVSW45C7OR4XAZNMJFZXG5LFINXW23LFNZ2KUY3PNVWWK3TUL5UWJTSZOUTAA.gif]
Aber mit synOCR sucht meinst du das Python script oder?
Ich dachte an synOCR.sh in der gleichen Weise, wie es dem Pythonskript die Seitenzahlen für die Trennseiten übergibt - lediglich mit dem Unterschied, dass in dem Fall die übergebenen Seiten auf Bildinhalt geprüft und ggf. entfernt werden. Von mir aus kannst du die Seiten auch direkt im Pythonskript auf Text prüfen.
Also das Script würde die leeren Seiten suchen und zurück geben?
synOCR.sh übergibt dir den Pfad der Quelldatei und einen temporären Zielpfad und das Pythonskript entfernt alle Seiten. War die Aktion erfolgreich, so ersetzt die temporäre Datei die Quelldatei.
Ich bin noch am Überlegen, ob wie die entfernten Seiten sichern sollten?
Ich dachte an synOCR.sh in der gleichen Weise, wie es dem Pythonskript die Seitenzahlen für die Trennseiten übergibt - lediglich mit dem Unterschied, dass in dem Fall die übergebenen Seiten auf Bildinhalt geprüft und ggf. entfernt werden
Aber die Funktion zum erkennen der leeren Seiten wäre doch auch eine Python Funktion.
Ich dachte du rufst das HandlePdf.py Script auf, mit einem anderen task Parameter, Input und Output file, sowie dem schwellwert.
Dann macht HandlePdf.py die Arbeit und scannt nach leeren Seiten.
Und entfernt diese dann. Ggf kann so eine leere Seite auch noch mach Text untersucht werden.
.
Servus Jungs!
Bevor ihr an die Umsetzung im GUI geht, würde ich persönlich zunächst das Ganze über das Skript testen, also die Parameter zunächst statisch direkt im Skript, zu Testzwecken, hinterlegen und bei Bedarf immer wieder abändern.
Nicht dass die Umsetzung der Erkennung scheitert, und die Arbeit am GUI dann auch umsonst war...
Und...wenn das GUI dann an der Reihe ist, vielleicht auch berücksichtigen, dass der ein oder andere die leeren Seiten gar nicht erkennen und damit Zeit einsparen will. Also vielleicht im GUI eine Option vorsehen, die das Leere-Seiten-Erkennen, nur bei Bedarf einschaltet.
Ich persönlich bin da ja eher wieder ein Freund, diese Erkennung (zusätzlich) in der Yaml-Datei, je Regel einzuschalten, aber ich weiß nicht wie kompliziert dies wiederum ist. Die von euch oben genannten Parameter müssten dann auch je Regel ermöglicht werden?
Aber die Funktion zum erkennen der leeren Seiten wäre doch auch eine Python Funktion.
Ich bin jetzt von einer analogen Umsetzung zu den Trennseiten ausgegangen. Mir ist es egal. Wenn du die Texterkennung mit in Python machen möchtest, kannst du das gerne tun. Meistens wird es so sein, dass es keine Seiten ohne Text gibt. Ich weiß nicht, ob es für die Laufzeit von Vorteil ist, wenn man nicht jedes PDF prinzipiell über das Pythonskript schickt.
Ich dachte du rufst das HandlePdf.py Script auf, mit einem anderen task Parameter, Input und Output file, sowie dem schwellwert.
Und zusätzlich die Seitenzahlen ohne Text. So war mein Gedanke. Aber wie gesagt: mir ist's eigentlich egal (bis auf meine Bedenken mit der Laufzeit).
Becor ihr an die Umsetzung im GUI geht, würde ich persönlich zunächst das Ganze über das Skript testen, also die Parameter zunächst statisch direkt im Skript, zu Testzwecken, hinterlegen und bei Bedarf immer wieder abändern.
Genauso würde ich das machen. Ein GUI-Update erfordert u.a. neben den GUI-Anpassungen auch ein DB-Upgrade, Übersetzungsstrings ect. Das mache ich gerne am Schluss, wenn alles in Sack und Tüten ist.
Und...wenn das GUI dann an der Reihe ist, vielleicht auch berücksichtigen, dass der ein oder andere die leeren Seiten gar nicht erkennen und damit Zeit einsparen will. Also vielleicht im GUI eine Option vorsehen, die das Leere-Seiten-Erkennen, nur bei Bedarf einschaltet.
Das schrieb ich ja schon HIER.
Ich persönlich bin da ja eher wieder ein Freund, diese Erkennung (zusätzlich) in der Yaml-Datei, je Regel einzuschalten, aber ich weiß nicht wie kompliziert dies wiederum ist. Die von euch oben genannten Parameter müssten dann auch je Regel ermöglicht werden?
Ich weiß nicht, ob mir das so spät im Arbeitsablauf gefällt. Und bringt es wirklich einen nutzbaren Mehrwert, diese Parameter in YAML-Regeln zu legen, also das die Leerseitenerkennung wirklich so granular gesteuert werden muss? Ich würde mal vermuten, dass dieses Feature auch in der elementaren Form von den meisten nicht benötigt wird (weil viele Scanner es von Haus aus machen). Und dann gibt es ja User, die gar keine YAML-Regeldatei nutzen. Man bräuchte also dennoch ein Fallback für die GUI.
Ich bin jetzt von einer analogen Umsetzung zu den Trennseiten ausgegangen. Mir ist es egal. Wenn du die Texterkennung mit in Python machen möchtest, kannst du das gerne tun. Meistens wird es so sein, dass es keine Seiten ohne Text gibt. Ich weiß nicht, ob es für die Laufzeit von Vorteil ist, wenn man nicht jedes PDF prinzipiell über das Pythonskript schickt.
Hm. Jetzt bin ich verwirrt. Also ich dachte wir probieren den Weg mit dem PIL Modul. So wie Du das gefunden hattest. Also Umwandlung in ein Image und dann ermitteln der Anzahl der Pixel und Vergleich mit dem Grenzwert. Das mit der Texterkennung hatte ich dann als zusätzliche Sicherheit gesehen. So und das ( also das mit dem Image) wäre ja doch eh ein python modul? Wenn das zu langsam ist, ist es ja auch zu langsam wenn es von der shell aus aufgerufen wird?
Also ich dachte so:
Oder @geimist wie hast Du den Ablauf gedacht?
Natrülich gebe ich Dir recht, das das umwandlen in ein Image evtl viel Zeit kostet. Aber das würde ja über das Shell Skript auch nicht schneller gehen, und der User wählt es ja bewusst aus....
Und @MichiFr, natürlich testen wir das vorher alle per Skript und prüfen ob es so klappt.
Ich stelle mir den Ablauf so vor:
pdftotext
wie bei den Trennseiten)Ich hoffe, das war verständlich 🙈
Ja ok so geht es....jetzt habe ich Dummerchen es auch verstanden. Aber lass uns erst die andere Baustelle fertig machen. Bis Montag Nachmittag bin ich jetzt wieder nur am Handy ( das echte Leben ruft). Montag kann ich Dir dann hoffentlich die Version mit den Metadaten geben. Dann können wir das hier angehen.
Genau so. Alles der Reihe nach 👍
Ich weiß nicht, ob mir das so spät im Arbeitsablauf gefällt. Und bringt es wirklich einen nutzbaren Mehrwert, diese Parameter in YAML-Regeln zu legen, also das die Leerseitenerkennung wirklich so granular gesteuert werden muss? Ich würde mal vermuten, dass dieses Feature auch in der elementaren Form von den meisten nicht benötigt wird (weil viele Scanner es von Haus aus machen). Und dann gibt es ja User, die gar keine YAML-Regeldatei nutzen. Man bräuchte also dennoch ein Fallback für die GUI.
Grundsätzlich habe ich Dokumente von denen ich weiß, dass sie immer eine Voder- und Rückseite haben und andere wiederum nur eine Frontseite. Um Performance zu sparen, ich gehe jetzt von einer mehrstufigen Erkennung aus, die ihr iben kns Auge gefasst habt, könnte man eben nur bei bestimmten Regeln, eine Erkennung leerer Seiten durchführen lassen...
Mein Plan ist, dass das Feature erst mal als Grundfunktion über die GUI steuerbar sein wird (wenn alles wie gewünscht funktioniert). Dann kann ich die Schalter und Parameter immer noch über die YAML-Regeln abfragen. Das sollte dann kein großer Aufwand sein.
Mich würde interessieren, ob es hier schon etwas neues gibt. Außerdem habe ich auch noch einen Vorschlag. Wenn ich das ganze richtig verstehe, wäre die Erkennung vor allem dann aufwändig, wenn die Seiten ohne erkannten Text im zweiten Schritt auf Bilder untersucht werden. Macht es da nicht vielleicht Sinn dem Anwender auch die Möglichkeit zu geben diese aufwändigere Berechnungsform auszuschalten? Mein Vorschlag wäre anstatt eines EIN-AUS-Schalters ein Dropdown mit drei Zuständen zu definieren z.B. mit den Werten [Aus], [Ohne Text (schnell)] und [Vollständig (langsam)].
Ziel:
Es gibt Scanner, welche nicht selbstständig Leerseiten erkennen können. Es wird also eine Funktion benötigt, die das (im Idealfall vor dem OCR) durchführt und Leerseiten verwirft. Der schnellste und unsauberste Weg bestünde darin, nach dem OCR auf vorhandenen Text zu prüfen. Damit würden aber auch Seiten, welche lediglich Bilder enthalten, gelöscht werden. Wichtig ist, dass die Lösung möglichst Architektur neutral (x84_64 / aarch64) und ressourcenschonend arbeitet.
Herausforderungen:
Es gibt verschiedene Ansätze, um das Ziel zu erreichen:
Inspiration: