Leere Seite (blank page) filtern bei DelphiTwain
Hallo,
ich habe ein sehr kleines Scan-Programm für unser Büro geschrieben - nichts weltbewegendes. Der Scanner scannt duplex. Das wiederum kann man per Voreinstellung in der Software vom Scanner steuern. Wenn es Seiten gibt, die eine leere Rückseite haben, will man die nicht mit abspeichern. Aktuell "löse" ich das so, dass ich jede zweite Seite einfach nicht abspeichere. Das muss aber der Benutzer im Vorfeld einstellen. Ich würde das gern so gestalten, dass ich die ankommenden Seiten "untersuche". Wenn sie leer sind, dann sollen sie automatisch verworfen werden. Es gibt Twain-Software, die so etwas anbietet. Bei unserem Scanner gibt es das leider nicht. Kann mir jemand auf die Sprünge helfen, wie man das am besten angeht? Nach welchen Suchworten (notfalls auch Englisch) muss ich suchen? Gruß, Alex |
AW: Leere Seite (blank page) filtern bei DelphiTwain
Ganz brutal geht das mit einer Überprüfung der Pixelfarben. Wenn jeder Pixel im Bild den gleichen Farbwert hat, dann haben wir keine wirkliche Information (Eisbär im Schneesturm, Schwarzer Adler auf schwarzem Grund).
|
AW: Leere Seite (blank page) filtern bei DelphiTwain
Zitat:
|
AW: Leere Seite (blank page) filtern bei DelphiTwain
Mitunter werde auch die Ränder der Löcher des Lochers eingescannt und eine nicht ganz sauber eingelegte Vorlage kann auch am Seitenrand spuren aufweisen. Du könntest aber vielleicht den "inneren" Teil der Seite auswerten du die Farbwerte der Pixel innerhalb einer minimalen Toleranz vergleichen, so dass kleine Unreinheiten dadurch ausgefiltert werden. Bei großen Kratzern wird das aber wohl nicht funktionieren.
Danach würde ich dem Benutzer die gescannten Seiten in einer Miniaturansicht präsentieren und die als leer erkannten Seiten mit einem Tag "Löschen" versehen. Der Benutzer kann jetzt noch in der Miniaturansicht weitere nicht leer erkannte Seiten entfernen, oder als leer erkannte Seiten eben doch als gültig zulassen (ggf. sogar auch noch die Reihenfolge verändern). Erst wenn er dann bestätigt wird das Dokument übernommen. |
AW: Leere Seite (blank page) filtern bei DelphiTwain
Hallo,
Ich habe es nicht gelesen. Der Titel sieht aber erfolgsversprechend aus. :P http://stackoverflow.com/questions/5...nned-documents |
AW: Leere Seite (blank page) filtern bei DelphiTwain
Danke für Eure Antworten!
Zitat:
Zunächst habe ich das Bild nach schwarz/weiß umgewandelt. Mein nächster Ansatz war es dann, die schwarzen Pixel zu zählen. Anschließend habe ich diese mit den weißen ins Verhältnis gesetzt und ab einem Wert von 3 ‰ (Promille) das Bild als Bild mit Inhalt deklariert. Allerdings war das sehr fehlerbehaftet. Denn es gibt nicht nur Staub, Falten etc., sondern dann auch schwarze Ränder und - überholter Beitrag - schwarze Löscher. Also schneide ich jetzt die Ränder innerhalb bestimmter Grenzen ab. Anschließend zähle ich die Anzahl der schwarzen Pixel. Wenn diese einen absoluten Wert überschreiten, ist es kein leeres Bild mehr. Das beschleunigt sogar die Suche, weil ich dann die Procedure verlassen kann. Hier mein Code fürs Protokoll:
Delphi-Quellcode:
// Leeres Bild erkennen --------------------------------------------------------
// MaxBlack ist die Anzahl maximal zulässiger schwarzer Pixel. // Beim Scannen können schwarze Ränder, Staubkörner etc. auftreten. Um ein // möglichst genaues Ergebnis zu erzielen werden zuerst die Ränder abge- // schnitten und dann die Anzahl der dunkeln/schwarzen Pixel ermittelt. // Der Wert selbst dürfte hardwareabhängig sein und kann deshalb als Variable // übergeben werden. Function TScanForm.PictureIsEmpty(Const BitMap: TBitmap; Const MaxBlack: Integer = 75): Boolean; Const lMargin = 12; // linker Rand rMargin = 8; // rechter Rand bMargin = 4; // unterer Rand tMargin = 8; // oberer Rand Tolerance = 118; // guter Schwarz-Wert Var lWidth : Integer; lHeight : Integer; lBlack : Int64; I, J : Integer; lLine :^TRGBTriple; Begin Result:=True; // ausgehen von leerem Bild lWidth:= BitMap.Width - lMargin - rMargin; // maximale Breite lHeight:=BitMap.Height - tMargin - bMargin; // maximale Höhe BitBlt(Bitmap.Canvas.Handle, 0, 0, lWidth, lHeight, Bitmap.Canvas.Handle, lMargin, tMargin, SRCCOPY); BitMap.Width :=lWidth; BitMap.Height:=lHeight; If (Bitmap.PixelFormat <> pf24bit) Then Bitmap.PixelFormat := pf24bit; // wegen Scanline lBlack:=0; // schwarze Pixel For I:=0 To Pred(Bitmap.Height) Do // alle Zeilen durchgehen Begin lLine:=Bitmap.Scanline[I]; // Zeile zuweisen For J:=0 To Pred(Bitmap.Width) Do // Zeile abarbeiten Begin If (lLine^.rgbtred + lLine^.rgbtBlue + lLine^.rgbtgreen) Div 3 < Tolerance Then Inc(lBlack); // = dunkler Wert -> schwarz If (lBlack >= MaxBlack) Then // viele schwarze Pixel Begin Result:=False; // = Bild mit Inhalt // Exit; // Zeit sparen!!! End; Inc(lLine); // nächste Zeile durchsuchen End; End; // TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TE fList.Append(IntToStr(fCount) + ';' + IntToStr(BitMap.Height * BitMap.Width) + ';' + IntToStr(lBlack)); // TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TE End; |
AW: Leere Seite (blank page) filtern bei DelphiTwain
Delphi-Quellcode:
Noch schneller...If (lLine^.rgbtred + lLine^.rgbtBlue + lLine^.rgbtgreen) Div 3 < Tolerance Then begin Inc(lBlack); // = dunkler Wert -> schwarz If (lBlack >= MaxBlack) Then // viele schwarze Pixel Begin Result:=False; // = Bild mit Inhalt // Exit; // Zeit sparen!!! End; End; |
AW: Leere Seite (blank page) filtern bei DelphiTwain
Zitat:
Bei dem Ganzen sehe ich aber noch ein Problem: Es kann durchaus vorkommen, daß auf einem Din-A-4-Blatt nur ganz ganz wenig Text steht oder nur ein klitzekleines Logo eingescannt werden soll. In diesem Fall könnte es sein, daß ein daraus resultierendes Bitmap ebenfalls als leer interpretiert würde. Daher sollte man vielleicht noch überprüfen, ob soundsoviele Pixel nebeneinander schwarz sind und bei einer – wiederum durch den Anwender einstellbaren – Größe das Bild durchgehen lassen. Sicher kennst du dieses Prinzip aus Tracing-Programmen, die Pixelbilder in Vektorgrafiken umwandeln wie z.B. Corel Trace. |
AW: Leere Seite (blank page) filtern bei DelphiTwain
Liste der Anhänge anzeigen (Anzahl: 2)
Danke für die weiteren Anmerkungen!
@Jens01 Ich bin natürlich immer an noch schnellerem Code interessiert; auch weil Büro-PC in der Regel keine Höllenmaschinen sind und die Bildbearbeitung die Dinger nicht aufhalten sollte. Ich muss aber gestehen, dass ich die Beschleunigung am Code selbst nicht auf den ersten Blick erkennen kann. Ich interpretiere das so, dass die Abfrage immer nur dann durchgeführt wird, wenn er einen schwarzen Pixel findet und sonst nicht. Wenn das Bild aber weiß ist, "scannt" er sowieso das gesamte Bild. Und wenn er schwarz ist, fliegt er spätestens einen Zyklus später raus? Kann man die Beschleunigung messen? @Perlsau Das habe ich schon gebastelt. Meine Leute haben jetzt die Möglichkeit, über das Menü genau diese Werte zu manipulieren. Ich habe etliche Tests gemacht. Im Rahmen dessen habe ich festgestellt, dass ich immer von Farbbildern ausgegangen bin. Bei Grau- oder Schwarzweiß-Bildern passen diese Wert nur sehr bedingt. Ich habe daher mal ein Screenshot angehängt, was aus meiner sich sinnvolle Einstellungen sind. Ich habe bei meinen Tests auch mit den extremen gespielt :lol:. Ich habe also "leere" Seiten mit eingeschmuggelt, auf denen mit immer dünner werdenden Bleistiftstrichen Smileys gemalt sind, die man kaum mit dem bloßen Auge erkennen kann. Diese wurden gefunden und als "nicht leer" identifiziert. Es kann aber wirklich am guten Seitenscanner liegen - obwohl dieser nach 5 Jahren auch schon einen Rotstich hat... :dp: Aber dass ich so schnell zum Ziel gekommen bin, hatte ich auch selten. Danke für Eure qualifizierte Hilfe! |
AW: Leere Seite (blank page) filtern bei DelphiTwain
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:23 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz