


OpenCV: Spalten in arabischen Zeitschriften finden (Python)
Ich bin neu bei opencv und neu bei Python. Ich habe versucht, Code, den ich online gefunden habe, zusammenzusetzen, um mein Forschungsproblem zu lösen. Ich habe ein arabisches Tagebuch aus dem Jahr 1870, das Hunderte von Seiten hat, jede Seite enthält zwei Spalten und hat einen dicken schwarzen Rand. Ich möchte zwei Spalten als Bilddateien extrahieren, damit ich sie einzeln mit OCR bearbeiten und dabei die Kopf- und Fußzeile ignorieren kann. Hier ist eine Beispielseite:
Seite 3
Ich habe zehn Seiten des Originaldrucks als separate PNG-Dateien. Ich habe das folgende Skript geschrieben, um jeden einzelnen zu behandeln. Auf zwei der zehn Seiten funktioniert es wie erwartet, auf den anderen acht Seiten gelingt es jedoch nicht, die Spalten zu generieren. Ich verstehe nicht alle Funktionen gut genug, um zu wissen, wo ich diese Werte verwenden könnte, oder wenn mein gesamter Ansatz falsch ist, denke ich, dass der beste Weg, dies zu lernen, darin besteht, die Community zu fragen, wie Sie dieses Problem lösen würden.
import cv2 def cutpage(fname, pnum): image = cv2.imread(fname) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (7,7), 0) thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 13)) dilate = cv2.dilate(thresh, kernel, iterations=1) dilatename = "temp/dilate" + str(pnum) + ".png" cv2.imwrite(dilatename, dilate) cnts = cv2.findContours(dilate, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if len(cnts) == 2 else cnts[1] cnts = sorted(cnts, key=lambda x: cv2.boundingRect(x)[0]) fullpage=1 column=1 for c in cnts: x, y, w, h = cv2.boundingRect(c) if h > 300 and w > 20: if (h/w)<2.5: print("Found full page: ", x, y, w, h) filename = "temp/p" + str(pnum) + "-full" + str(fullpage) + ".png" fullpage+=1 else: print("Found column: ", x, y, w, h) filename = "temp/p" + str(pnum) + "-col" + str(column) + ".png" column+=1 roi = image[y:y+h, x:x+w] cv2.imwrite(filename, roi) return (column-1) for nr in range(10): filename = "p"+str(nr)+".png" print("Checking page", nr) diditwork = cutpage(filename, nr) print("Found", diditwork, "columns")
Im Anschluss an das Tutorial habe ich eine unscharfe und erweiterte binäre Umkehrung erstellt, damit die verschiedenen rechteckigen Bereiche anhand der großen weißen Fläche identifiziert werden können. Ich habe auch eine Kopie jeder erweiterten Version gespeichert, damit ich sehen kann, wie sie aussieht. Hier ist die Seite oben nach der Verarbeitung:
Seite 3 wurde vergrößert
Die „for c in cnts“-Schleife sollte große rechteckige Bereiche im Bild finden. Wenn das Seitenverhältnis kleiner als 2,5 ist, erhalte ich eine ganze Seite (ohne Kopf- und Fußzeile, was gut funktioniert). Wenn das Seitenverhältnis größer ist, weiß ich, dass es sich um eine Spalte handelt, und es speichert diese z. B. temp/p2-col2.png
Ich habe ein paar schöne ganze Seiten ohne Kopf- und Fußzeilen bekommen, also nur mit großen schwarzen Rändern, aber nicht in Spalten zerstückelt. Auf 2 von 10 Seiten habe ich bekommen, was ich wollte, nämlich:
Erfolgskolumne auf Seite 2
Da ich manchmal die gewünschten Ergebnisse erhalte, muss irgendetwas funktionieren, aber ich weiß nicht, wie ich es weiter verbessern kann.
Herausgeber:
Hier sind weitere Seitenbeispiele:
p0
p1
p5
Richtige Antwort
Ich habe etwas ohne Erweiterung ausprobiert, weil ich sehen wollte, ob ich die Mittellinie einfach als „Trennzeichen“ verwenden kann. Hier ist der Code:
im = cv2.cvtcolor(cv2.imread("arabic.png"), cv2.color_bgr2rgb) # read im as rgb for better plots gray = cv2.cvtcolor(im, cv2.color_rgb2gray) # convert to gray _, threshold = cv2.threshold(gray, 250, 255, cv2.thresh_binary_inv) # inverse thresholding contours, _ = cv2.findcontours(threshold, cv2.retr_external, cv2.chain_approx_none) # find contours sortedcontours = sorted(contours, key = cv2.contourarea, reverse=true) # sort according to area, descending bigbox = sortedcontours[0] # get the contour of the big box middleline = sortedcontours[1] # get the contour of the vertical line xmiddleline, _, _, _ = cv2.boundingrect(middleline) # get x coordinate of middleline leftboxcontour = np.array([point for point in bigbox if point[0, 0] < xmiddleline]) # assign left of line as points from the big contour rightboxcontour = np.array([point for point in bigbox if point[0, 0] >= xmiddleline]) # assigh right of line as points from the big contour leftboxx, leftboxy, leftboxw, leftboxh = cv2.boundingrect(leftboxcontour) # get properties of box on left rightboxx, rightboxy, rightboxw, rightboxh = cv2.boundingrect(rightboxcontour) # get properties of box on right leftboxcrop = im[leftboxy:leftboxy + leftboxh, leftboxx:leftboxx + leftboxw] # crop left rightboxcrop = im[rightboxy:rightboxy + rightboxh, rightboxx:rightboxx + rightboxw] # crop right # maybe do you assertations about aspect ratio?? cv2.imwrite("right.png", rightboxcrop) # save image cv2.imwrite("left.png", leftboxcrop) # save image
Ich mache keine Aussagen zum Seitenverhältnis, also ist das vielleicht noch etwas, was Sie tun müssen..
Grundsätzlich sind die wichtigsten Linien bei dieser Methode die Erzeugung linker und rechter Konturen basierend auf x-Koordinaten. Dies ist das Endergebnis, das ich erhalten habe:
Es gibt immer noch einige schwarze Stellen an den Rändern, aber das sollte für OCR kein Problem darstellen.
Zu Ihrer Information: Ich verwende die folgenden Pakete in Jupyter:
import cv2 import numpy as np %matplotlib notebook import matplotlib.pyplot as plt
v2.0: Implementiert nur mit der Erkennung großer Kästchen:
Also habe ich etwas geweitet und die große Box war leicht zu erkennen. Ich verwende einen horizontalen Kernel, um sicherzustellen, dass die vertikalen Linien der großen Box immer dick genug sind, um erkannt zu werden. Allerdings kann ich das Problem mit der Mittellinie nicht lösen, da diese sehr dünn ist... Nichtsdestotrotz ist hier der Code für die obige Methode:
im = cv2.cvtcolor(cv2.imread("1.png"), cv2.color_bgr2rgb) # read im as rgb for better plots gray = cv2.cvtcolor(im, cv2.color_rgb2gray) # convert to gray gray[gray<255] = 0 # added some contrast to make it either completly black or white _, threshold = cv2.threshold(gray, 250, 255, cv2.thresh_binary_inv) # inverse thresholding thresholddilated = cv2.dilate(threshold, np.ones((1,10)), iterations = 1) # dilate horizontally contours, _ = cv2.findcontours(thresholddilated, cv2.retr_external, cv2.chain_approx_none) # find contours sortedcontours = sorted(contours, key = cv2.contourarea, reverse=true) # sort according to area, descending x, y, w, h = cv2.boundingrect(sortedcontours[0]) # get the bounding rect properties of the contour left = im[y:y+h, x:x+int(w/2)+10].copy() # generate left, i included 10 pix from the right just in case right = im[y:y+h, int(w/2)-10:w].copy() # and right, i included 10 pix from the left just in case fig, ax = plt.subplots(nrows = 2, ncols = 3) # plotting... ax[0,0].axis("off") ax[0,1].imshow(im) ax[0,1].axis("off") ax[0,2].axis("off") ax[1,0].imshow(left) ax[1,0].axis("off") ax[1,1].axis("off") ax[1,2].imshow(right) ax[1,2].axis("off")
Das sind die Ergebnisse. Sie können feststellen, dass es nicht perfekt ist, aber da Ihr Ziel OCR ist, sollte dies kein Problem sein.
Bitte sagen Sie mir, ob das funktioniert. Wenn nicht, werde ich mir den Kopf zerbrechen, um eine bessere Lösung zu finden...
v3.0: Eine bessere Möglichkeit, geradere Bilder zu erhalten, was die Qualität der OCR verbessert.
Inspiriert von meiner anderen Antwort hier: Antwort. Es ist sinnvoll, das Bild zu begradigen, damit die OCR bessere Ergebnisse liefert. Daher habe ich eine Vierpunkttransformation für den erkannten Außenrahmen verwendet. Dadurch wird das Bild etwas begradigt und der Text horizontaler. Hier ist der Code:
im = cv2.cvtcolor(cv2.imread("2.png"), cv2.color_bgr2rgb) # read im as rgb for better plots gray = cv2.cvtcolor(im, cv2.color_rgb2gray) # convert to gray gray[gray<255] = 0 # added some contrast to make it either completly black or white _, threshold = cv2.threshold(gray, 250, 255, cv2.thresh_binary_inv) # inverse thresholding thresholddilated = cv2.dilate(threshold, np.ones((1,10)), iterations = 1) # dilate horizontally contours, _ = cv2.findcontours(thresholddilated, cv2.retr_external, cv2.chain_approx_none) # find contours largest_contour = max(contours, key = cv2.contourarea) # get largest contour hull = cv2.convexhull(largest_contour) # get the hull epsilon = 0.02 * cv2.arclength(largest_contour, true) # epsilon pts1 = np.float32(cv2.approxpolydp(hull, epsilon, true).reshape(-1, 2)) # get the points result = four_point_transform(im, pts1) # using imutils height, width = result.shape[:2] # get the dimensions of the transformed image left = result[:, 0:int(width/2)].copy() # from the beginning to half the width right = result[:, int(width/2): width].copy() # from half the width till the end fig, ax = plt.subplots(nrows = 2, ncols = 3) # plotting... ax[0,0].axis("off") ax[0,1].imshow(result) ax[0,1].axvline(width/2) ax[0,1].axis("off") ax[0,2].axis("off") ax[1,0].imshow(left) ax[1,0].axis("off") ax[1,1].axis("off") ax[1,2].imshow(right) ax[1,2].axis("off")
Hat die folgenden Pakete:
import cv2 import numpy as np %matplotlib notebook import matplotlib.pyplot as plt from imutils.perspective import four_point_transform
Wie Sie dem Code entnehmen können, ist dies ein besserer Ansatz. Dank der Vierpunkttransformation können Sie erzwingen, dass das Bild zentriert und horizontal ist. Darüber hinaus besteht keine Notwendigkeit für Überlappungen, da die Bilder gut voneinander getrennt sind. Hier ist ein Beispiel als Referenz:
Das obige ist der detaillierte Inhalt vonOpenCV: Spalten in arabischen Zeitschriften finden (Python). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Seit seiner Einführung im Jahr 2009 hat sich Bitcoin zu einem führenden Unternehmen in der Welt der Kryptowährungen entwickelt und sein Preis hat enorme Schwankungen erfahren. Um einen umfassenden historischen Überblick zu bieten, stellt dieser Artikel Bitcoin-Preisdaten von 2009 bis 2025 zusammen und deckt wichtige Marktereignisse, Änderungen der Marktstimmung und wichtige Faktoren ab, die die Preisbewegungen beeinflussen.

Bitcoin hat als Kryptowährung seit seiner Einführung erhebliche Marktvolatilität erlebt. Dieser Artikel bietet einen Überblick über den historischen Preis von Bitcoin seit seiner Geburt, um den Lesern zu helfen, seine Preistrends und Schlüsselmomente zu verstehen. Durch die Analyse der historischen Preisdaten von Bitcoin können wir die Einschätzung des Marktes über seinen Wert und die Faktoren, die seine Schwankungen beeinflussen, verstehen und eine Grundlage für zukünftige Investitionsentscheidungen schaffen.

Seit seiner Gründung im Jahr 2009 hat der Preis von Bitcoin im November 2021 auf 69.044,77 USD auf 69.044,77 USD gestiegen und im Dezember 2018 auf 3.191,22 USD gesunken. Ab Dezember 2024 hat der jüngste Preis 100.204 USD überschritten.

Echtzeit-Bitcoin-USD-Preis Faktoren, die den Bitcoin -Preis beeinflussen Indikatoren für die Vorhersage zukünftiger Bitcoin -Preise Hier finden Sie einige wichtige Informationen zum Preis von Bitcoin in den Jahren 2018-2024:

Die Methode zur Anpassung der Größe der Größe der Größe der Größe in CSS ist mit Hintergrundfarben einheitlich. In der täglichen Entwicklung begegnen wir häufig Situationen, in denen wir die Details der Benutzeroberfläche wie Anpassung anpassen müssen ...

Wie kann man den 45-Grad-Kurveneffekt des Segmenters erreichen? Bei der Implementierung des Segmenters verwandeln Sie den rechten Rand in eine 45-Grad-Kurve, wenn Sie auf die linke Schaltfläche klicken, und der Punkt ...

Ja, die H5-Seitenproduktion ist eine wichtige Implementierungsmethode für die Front-End-Entwicklung, die Kerntechnologien wie HTML, CSS und JavaScript umfasst. Entwickler bauen dynamische und leistungsstarke H5 -Seiten auf, indem sie diese Technologien geschickt kombinieren, z. B. die Verwendung der & lt; canvas & gt; Tag, um Grafiken zu zeichnen oder JavaScript zu verwenden, um das Interaktionsverhalten zu steuern.

Das Problem der Containeröffnung aufgrund einer übermäßigen Auslassung von Text unter Flex -Layout und Lösungen werden verwendet ...
