[PYTHON] Der Hintergrund der Zeichen im Textbild ist überbelichtet, um das Lesen zu erleichtern.

Ich mache oft Fotos von Dokumenten mit meinem Smartphone und benutze sie. Es ist einfach, aber weniger klar als das vom Scanner erfasste. Um das Lesen von Bildern mit mattem Kontrast zu erleichtern, z. B. mit einem Smartphone, sollten Sie die Helligkeit des Hintergrunds erhöhen, während die Zeichen schwarz bleiben. Zur Vereinfachung des Aufhellens des Hintergrunds wurde es notwendig, zwischen dem Zeichenteil des Bildes und dem einfachen weißen Hintergrundteil zu unterscheiden, aber es funktioniert gut, wenn die Statistik der Pixel für jeden lokalen Teil des Bildes anhand der Größe der Standardabweichung der Pixelwerte erstellt und beurteilt wird. Es war.

Lassen Sie uns als Beispiel das folgende Bild verarbeiten. Sie sollten in der Lage sein, jedes Bild zu vergrößern, indem Sie darauf klicken. tarama36p.jpg Naoki Hatano, "Tara Majima Visionary Line" S.36

Graphitabflachung

Beim Schärfen eines Bildes wird häufig ein Abflachungsprozess des Histogramms durchgeführt. Wenn die Helligkeit der Pixel des Bildes in einem engen Bereich liegt, wenn Sie sie auf den gesamten Bereich des Bildformats oder 0 bis 255 für Graustufenbilder erweitern, vergrößert sich der Unterschied zwischen den Pixeln und das Bild wird klarer. OpenCV hat eine eigene Funktion, die unter dem folgenden Link ausführlich erläutert wird. [Hysterogramm in OpenCV> Histogramm Teil 2: Abflachen des Histogramms](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_histograms/py_histogram_equalization/py_histogram_e .html) Auf diese Weise wird das Originalbild grau skaliert und das Histogramm im folgenden Bild abgeflacht. Wird mit dem Programm angezeigt.

 bookimg = cv2.imread('tarama36p.jpg')
 img_gray = cv2.cvtColor(bookimg, cv2.COLOR_BGR2GRAY)
 
 equ = cv2.equalizeHist(img_gray)
 cv2.imwrite('tarama36pcv2.jpg', equ )

tarama36pcv2.jpg Das Ergebnis ist nicht besonders klar. Ich wusste es nicht vom Originalbild, aber es scheint, dass die rechte Seite heller ist als die linke. Die Reflexion des oberen Metallstücks wird betont. Tatsächlich ist das Histogramm dieses Bildes wie folgt und die rote Linie zeigt die Maximal- und Minimalwerte der Helligkeit der Pixel, aber da die Maximal- und Minimalwerte bereits auf den vollen Bildbereich erweitert wurden, wird ein einfaches Histogramm abgeflacht Die Wirkung von ist gering. tarama36p_hist_maxmin.png OpenCV hat auch eine Funktion namens anwendbare Histogrammabflachung, die das Bild in kleine Blöcke unterteilt und das Histogramm für jeden Block abflacht. Das Verarbeitungsergebnis ist das folgende Bild.

 bookimg = cv2.imread('tarama36p.jpg')
 img_gray = cv2.cvtColor(bookimg, cv2.COLOR_BGR2GRAY)
 
 equ = cv2.equalizeHist(img_gray)
 cv2.imwrite('tarama36pcv2.jpg', equ )

tarama36pcv2cl1.jpg Es ist einfacher zu sehen als cv2.equalizeHist (), aber nicht so viel wie ein Scanner.

Machen Sie alle weißen Pixel rein weiß

Der allgemeine Kontrastverbesserungsprozess versucht, einen gewissen Unterschied im Pixelwert des weißen Teils zu hinterlassen. Im Fall eines Textbildes sind keine detaillierten Informationen auf einem weißen Hintergrund erforderlich, sodass alle Pixel über einem bestimmten Schwellenwert vollständig weiß sein können und alle Pixelwerte möglicherweise auf 255 umgeschrieben werden. Da die schwarze Seite Informationen zur Zeichenform enthält, wird der ursprüngliche Pixelwert mit einem Wert kleiner als 1 multipliziert, und der Wert wird zur schwarzen Seite verschoben, die ursprüngliche Tendenz bleibt jedoch erhalten. Es wird angenommen, dass der Schwellenwert 140 aus dem Wert pro Medianwert des Histogramms beträgt. Das Programm und die Verarbeitungsergebnisse sind wie folgt.

    for y in range(img_gray.shape[0]):
         for x in range(img_gray.shape[1]):
             if img_gray[y][x] > 140:
                 img_gray[y][x] = 255
             else:
                 img_gray[y][x] = img_gray[y][x] * 0.5

    cv2.imwrite('tarama36p140.jpg', img_gray )

tarama36p140.jpg Auf der rechten Seite war der Hintergrund weiß und die Zeichen waren wie beabsichtigt klar. Die zusätzliche Reflexion der Metallteile ist ebenfalls verschwunden. Da jedoch die untere linke Ecke insgesamt dunkel war, wurde der Hintergrundteil als schwarz erkannt und hervorgehoben. Wenn Sie jedoch den Schwellenwert unten links einstellen, wird der Charakterteil diesmal auf der rechten Seite weiß geflogen. Das heißt, der geeignete Schwellenwert hängt von der Position des Bildes ab.

Verarbeiten Sie das Bild in Blöcken

Ähnlich wie bei der anwendbaren Histogrammabflachung wird das Originalbild vertikal und horizontal in Blöcke mit 64 Punkten unterteilt, und für jeden werden geeignete Schwellenwerte erhalten und verarbeitet. Es ist wichtig, wie der Schwellenwert bestimmt wird, aber hier wird der Wert des Schwellenwerts so eingestellt, dass die untere Hälfte des Medianwerts jedes Blockpixels, dh 1/4 des gesamten Blockpixels, als schwarz angesehen wird. Eine Funktion, die einen Schwellenwert mit dem Blockbild img als Argument zurückgibt, wird in Python wie folgt geschrieben. Es ist eine grobe Idee, aber es scheint einen vernünftigen Wert zu liefern. Schwarzweißtext funktioniert jedoch nicht.

 import numpy as np
 def getBWThrsh(img):
     med = np.median(img)
     fild = img[img < med]
     return np.median(fild) 

Das verarbeitete Ergebnis ist das folgende Bild. Zusätzlich wird der Histogramm-Mittelungsprozess auch für jeden Block durchgeführt, und anstatt einfach die weißen Bereiche durch 255 zu ersetzen, ersetzen Sie das ursprüngliche Pixel durch einen Koeffizienten, so dass der Großteil des Hintergrunds 256 überschreitet. Es gibt. Die meisten von ihnen sind weiß, aber die dunkleren Teile bleiben übrig. tarama36p_s0.00b64.jpg Der Hintergrund der Zeichen ist schön weiß, aber die Zeichen auf der Rückseite sind im weißen Hintergrund, wo keine Zeichen vorhanden sind, schwach transparent. Das folgende Bild ist vergrößert. a3bcf44c70f2e1a919809ebccd290c54-png.png In dem Teil, in dem die Rückseite transparent ist, gibt es nur einen sehr geringen Unterschied in den Schattierungen. Durch Ausführen des Histogramm-Mittelungsprozesses sind die Rückbuchstaben jedoch hervorragend entstanden.

Unterscheiden Sie zwischen Buchstaben und weißem Hintergrund

Da die Rückseite transparent ist, möchte ich den Histogramm-Mittelungsprozess auf dem weißen Hintergrund vermeiden. Wie kann ich zwischen dem Textteil und dem weißen Hintergrundteil unterscheiden? Bisher haben wir für jeden Block eine statistische Verarbeitung mit numpy durchgeführt, um den Medianwert der Pixel zu ermitteln. Ich kam jedoch auf die Idee, dass die Standardabweichung der Pixelwerte zur Unterscheidung zwischen Zeichen und weißem Hintergrund verwendet werden kann. Der weiße Hintergrund weist weniger Abweichungen bei den Pixelwerten auf und die Standardabweichung ist gering, und der Zeichenteil hat einen größeren Wert. Wie auch immer, ich fand die Standardabweichung der Pixel jedes Blocks, erstellte ein Histogramm, um festzustellen, welche Art von Wert groß ist, und untersuchte die Tendenz. tarama36p_stdhist.png Auf dem kleinen Wert auf der linken Seite befindet sich eine Spitze, aber dies ist wahrscheinlich ein Block auf weißem Hintergrund. Ein weißer Hintergrund kann bestimmt werden, indem ein Schwellenwert der Standardabweichung auf einen Wert eingestellt wird, der diesen Peak enthält. Wenn Sie den Schwellenwert zu klein machen, bleibt Staub auf einem weißen Hintergrund zurück, und wenn Sie ihn groß machen, wird er, selbst wenn einige kleine Zeichen im weißen Hintergrund enthalten sind, als weißer Hintergrund betrachtet und abgebrochen, sodass es tatsächlich schwierig ist, einen geeigneten Schwellenwert festzulegen. Wie auch immer, das Bild unten zeigt den Prozess der Unterscheidung zwischen Zeichen und weißem Hintergrund und macht den weißen Hintergrund vollständig weiß. tarama36p_s6.00b64.jpg Es gab viel Müll an anderen Stellen als dem umgebenden Text, aber ich denke, der Textteil wurde ordentlich verarbeitet. Da es jetzt möglich ist, blockweise zwischen weißen und nicht weißen Hintergründen zu unterscheiden, sind die weißen Hintergrundblöcke, wenn sie durchgehend sind, die umgebenden Ränder, wenn sich lose Zeichen in den Rändern befinden, sind sie nicht bleibbar usw. Ich bin der Meinung, dass es auf verschiedene Urteile angewendet werden kann.

Die obigen Quellen sind wie folgt. Wenn Sie den zu konvertierenden Dateinamen in das Argument sharpenImg () in der unteren Zeile schreiben, wird eine Datei mit weißem Hintergrund erstellt. Im Moment dauert die Konvertierung einige zehn Sekunden, aber ich denke, es wird eine praktische Verarbeitungsgeschwindigkeit sein, wenn es mit C oder ähnlichem neu geschrieben wird.

import cv2
from matplotlib import pyplot as plt
import numpy as np

def getStdThrsh(img, Blocksize):
    stds = []
    for y in range( 0, img.shape[0], Blocksize ):
        for x in range( 0, img.shape[0], Blocksize ):
            pimg = img[y:y+Blocksize, x:x+Blocksize]
            std = np.std( pimg )
            minv = np.min( pimg )
            maxv = np.max( pimg )
            stds.append(std)

    hist = np.histogram( stds, bins=64 )
    peaki = np.argmax(hist[0])   

    #plt.hist( stds, bins=64 )
    #plt.show()

    slim = 6.0
    for n in range(peaki,len(hist[0])-1):
        if hist[0][n] < hist[0][n+1]:
            slim = hist[1][n+1]
            break

    if slim > 6.0:
        slim = 6.0
    
    return slim

def getBWThrsh(img):
    med = np.median(img)
    fild = img[img < med]
    return np.median(fild)

def getWbias( img, bwthr ):
    wimg = img[ img > bwthr ]
    hist = np.histogram( wimg, bins=16 )
    agm = np.argmax(hist[0])
    return hist[1][agm]

def getOutputName( title, slim ):
    return title + "_s{:04.2f}.jpg ".format( slim )

def sharpenImg(imgfile):
    Testimagefile = imgfile
    TestimageTitle = Testimagefile.split('.')[0]
    Blocksize = 64
    Bbias = 0.2

    bookimg = cv2.imread( Testimagefile )
    img_gray = cv2.cvtColor(bookimg, cv2.COLOR_BGR2GRAY)
    outimage = img_gray.copy()

    slim = getStdThrsh(img_gray, Blocksize)
    for y in range( 0, img_gray.shape[0], Blocksize ):
        s = ""
        for x in range( 0, img_gray.shape[1], Blocksize ):
            pimg = img_gray[y:y+Blocksize, x:x+Blocksize]
            std = np.std( pimg )
            minv = np.min( pimg )
            maxv = np.max( pimg )
            pimg -= minv

            cimg = pimg.copy()
            if maxv != minv:
                for sy in range (cimg.shape[0]):
                    for sx in range( cimg.shape[1] ):
                        cimg[sy][sx] = (cimg[sy][sx]*255.0)/(maxv - minv)

            bwthrsh = getBWThrsh( pimg )
            wb = getWbias( cimg, bwthrsh )
            if wb == 0:
                wbias = 1.5
            else:
                wbias = 256 / wb
            
            if std < slim:
                s = s + "B"
                for sy in range (pimg.shape[0]):
                    for sx in range( pimg.shape[1] ):
                        outimage[y+sy][x+sx] = 255
            else:
                s = s + "_"
                for sy in range (cimg.shape[0]):
                    for sx in range( cimg.shape[1] ):
                        if cimg[sy][sx] > bwthrsh:
                            v = cimg[sy][sx]
                            v = v * wbias
                            if v > 255:
                                v = 255
                            outimage[y+sy][x+sx] = v
                        else:
                            outimage[y+sy][x+sx] = cimg[sy][sx] * Bbias
        print( "{:4d} {:s}".format( y, s ) )

    cv2.imwrite(getOutputName(TestimageTitle, slim), outimage )

if __name__ =='__main__':
    sharpenImg('tarama36p.jpg')

https://github.com/pie-xx/TextImageViewer

Recommended Posts

Der Hintergrund der Zeichen im Textbild ist überbelichtet, um das Lesen zu erleichtern.
Verwenden Sie Pillow, um das Bild transparent zu machen und nur einen Teil davon zu überlagern
Erweitern Sie devicetree source include, um das Lesen zu vereinfachen
Python Open CV hat versucht, das Bild im Text anzuzeigen.
Ich habe versucht, den Text in der Bilddatei mit Tesseract der OCR-Engine zu extrahieren
Erleichtern Sie die Anzeige von Python-Modulausnahmen
Sie, die das Protokoll ausmalen, um es besser sehen zu können
Zählen Sie die Anzahl der Zeichen im Text in der Zwischenablage auf dem Mac
So überprüfen Sie, ob sich der angegebene Schlüssel im angegebenen Bucket in Boto 3 befindet
So implementieren Sie Java-Code im Hintergrund von Red Hat (Linux ONE)
Was tun, wenn ein Teil des Hintergrundbilds transparent wird, wenn Sie transparente Bilder mit Pillow kombinieren?
[Bilderkennung] Lesen des Ergebnisses der automatischen Annotation mit VoTT
[TensorFlow 2] Es wird empfohlen, die Funktionsmenge von TFRecord in Batch-Einheiten zu lesen.
Tipps, um das Lesen von Python-Hördokumenten zu vereinfachen
So speichern Sie die Feature-Point-Informationen des Bildes in einer Datei und verwenden sie zum Abgleichen
Eine Geschichte über einen Ingenieur, der das Emo der Kryptographie bemerkt hat und versucht, es in Python zu implementieren
Verschiedene Möglichkeiten, die letzte Zeile einer CSV-Datei in Python zu lesen
Ändern Sie in Python das Verhalten der Methode je nach Aufruf
So zeigen Sie im gesamten Fenster an, wenn Sie das Hintergrundbild mit tkinter einstellen
Hackasons Erfahrung, dass es am wichtigsten ist, die Gefühle des Veranstalters zu verstehen
So stellen Sie die Schriftbreite des in pyenv eingegebenen Jupyter-Notizbuchs gleich
Deep Learning macht es dramatisch einfacher, den Zeitraffer körperlicher Veränderungen zu erkennen
Machen Sie es sich einfach, die Zeit von AWS CloudWatch-Ereignissen mit CDK anzugeben.
Was ist im Docker Python-Image pfeifend?
Kopieren Sie die Liste in Python
Ich habe versucht, die Trapezform des Bildes zu korrigieren
Lesen Sie die Ausgabe von subprocess.Popen in Echtzeit
Ich kann keine Zeichen in den Textbereich eingeben! ?? !! ?? !! !! ??
Machen Sie den Fortschritt von dd in der Fortschrittsanzeige sichtbar
Ich möchte die LED-Beleuchtung von ErgoDox EZ zum Leuchten bringen, aber sagen Sie mir, was die LED überhaupt ist
[Lösung] Wenn "0001" in die Zeichenfolgenspalte in sqlite3 eingefügt wird, wird es als "1" eingegeben.
Wie identifiziere ich das Element mit der geringsten Anzahl von Zeichen in einer Python-Liste?
[Python] Ändern Sie die Textfarbe und Hintergrundfarbe eines bestimmten Schlüsselworts in der Druckausgabe
Was tun, wenn der Fortschrittsbalken in tqdm von Python nicht angezeigt wird?
Ermitteln Sie die maximale Anzahl von Zeichen in mehrzeiligem Text, die in einem Datenrahmen gespeichert sind
So überprüfen Sie in Python, ob sich eines der Elemente einer Liste in einer anderen Liste befindet
Ich habe versucht, es einfach zu machen, die Einstellung des authentifizierten Proxys auf Jupyter zu ändern
Es ist einfach, SQL mit Python auszuführen und das Ergebnis in Excel auszugeben
Es ist schwierig, einen grünen Bildschirm zu installieren, daher habe ich nur das Gesicht ausgeschnitten und es dem Hintergrundbild überlagert
Eine einfache Möglichkeit, den Wert im Eigenschaftsdekorator zwischenzuspeichern. Schreibgeschützt. Beachten Sie, dass er so lange zwischengespeichert wird, bis das Objekt gelöscht wird.
Ein Tool zum Erstellen von Maskenbildern für ETC in Python
Vorlage des Python-Skripts zum Lesen des Inhalts der Datei
So ermitteln Sie die Anzahl der Stellen in Python
Lesen Sie die CSV-Datei und zeigen Sie sie im Browser an
Konvertieren Sie das Bild in .zip mit Python in PDF
Überprüfen Sie, ob es sich um Unix in der Skriptsprache handelt
So entfernen Sie verstümmelte Zeichen im Matplotlib-Ausgabebild
Wie man Decorator in Django benutzt und wie man es macht
Um das Äquivalent von Rubys ObjectSpace._id2ref in Python zu tun
Stellen Sie die Verwaltungsseite für die Produktion bereit, um die Wartung zu vereinfachen.
Ist es ein Problem, den Bedarf an analogen Humanressourcen in der KI-Ära zu beseitigen?
Das Geräusch von Mr. Tick am Arbeitsplatz ist ... Ich habe es mit dem Code geschafft
Notieren Sie sich, was Sie in Zukunft mit Razpai machen möchten
[Dance Dance Revolution] Ist es möglich, den Schwierigkeitsgrad (Fuß) aus dem Wert des Groove-Radars vorherzusagen?
Belüftung ist wichtig. Was ich getan habe, um die CO2-Konzentration im Raum aufzuzeichnen
Was tun, wenn das Bild nicht mit matplotlib usw. im Docker-Container angezeigt wird?
Wie kann man schnell die Häufigkeit des Auftretens von Zeichen aus einer Zeichenfolge in Python zählen?
Geben Sie die Bilddaten mit Flask of Python zurück und zeichnen Sie sie in das Canvas-Element von HTML
Das Bild wird in der lokalen Entwicklungsumgebung angezeigt, aber das Bild wird nicht auf dem Remote-Server von VPS angezeigt.