2016-08-15 16 views
1

Ich habe ein bearbeitetes Bild mit Text drin und ich möchte die Koordinaten von Linien finden, die die Kanten des Textfelds berühren würden, aber es nicht kreuzen würden und sich strecken würden durch die ganze Seite des Textes. Bild unten zeigt, was ich brauche (die roten Linien zog ich das Beispiel zeigen, was Koordinaten ich auf einem RAW-Bild finden wollen): Finden Sie enter image description hereSo finden Sie die Seitenlinien des Feldes von Text

Es ist nicht so einfach, ich kann nicht nur die Kanten des verarbeiteten Textfeldes (oben links, oben rechts usw.), weil es sein kann, zB ein Anfang eines Absatzes (dies nur ein Beispiel des möglichen Szenarios ist):

enter image description here

Die Seiten des Textes, eine gerade Linie bilden, ist es die obere und untere Kanten gekrümmt sein, so das könnte die Dinge erleichtern.

Was ist der beste Weg, dies zu tun?

Jede Methode, die ich mir vorstellen kann, ist entweder nicht praktikabel, ineffizient oder kann normalerweise zu falschen Ergebnissen führen.

Das Rohbild falls jemand muss für die Verarbeitung:

enter image description here

Antwort

2

Die Idee ist, die konvexe Hülle der gesamten Textes zu finden. Nachdem wir die konvexe Hülle gefunden haben, finden wir ihre Seiten. Wenn die Seite eine große Änderung ihrer y-Koordinate und eine kleine Änderung der x-Koordinate aufweist (d. H. Die Linie hat eine hohe Steigung), betrachten wir sie als eine Seitenlinie.

Das resultierende Bild:

enter image description here

der Code:

import cv2 
import numpy as np 

def getConvexCoord(convexH, ind): 
    yLines = [] 
    xLine = [] 
    for index in range(len(ind[0])): 
     convexIndex = ind[0][index] 

     # Get point 
     if convexIndex == len(convexH) - 1: 
      p0 = convexH[0] 
      p1 = convexH[convexIndex] 
     else: 
      p0 = convexH[convexIndex] 
      p1 = convexH[convexIndex + 1] 

     # Add y corrdinate 
     yLines.append(p0[0, 1]) 
     yLines.append(p1[0, 1]) 
     xLine.append(p0[0, 0]) 
     xLine.append(p1[0, 0]) 
    return yLines,xLine 

def filterLine(line): 
    sortX = sorted(line) 
    # Find the median 
    xMedian = np.median(sortX) 
    while ((sortX[-1] - sortX[0]) > I.shape[0]): 

     # Find out which is farther from the median and discard 
     lastValueDistance = np.abs(xMedian - sortX[-1]) 
     firstValueDistance = np.abs(xMedian - sortX[0]) 
     if lastValueDistance > firstValueDistance: 

      # Discard last 
      del sortX[-1] 
     else: 
      # Discard first 
      del sortX[0] 

    # Now return mixX and maxX 
    return max(sortX),min(sortX) 


# Read image 
Irgb = cv2.imread('text.jpg') 
I = Irgb[:,:,0] 

# Threshold 
ret, Ithresh = cv2.threshold(I,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) 

# Find the convex hull of the text 
textPixels = np.nonzero(Ithresh) 
textPixels = zip(textPixels[1],textPixels[0]) 
convexH = cv2.convexHull(np.asarray(textPixels)) 

# Find the side edges in the convex hull 
m = [] 
for index in range((len(convexH))-1): 

    # Calculate the angle of the line 
    point0 = convexH[index] 
    point1 = convexH[index+1] 
    if(point1[0,0]-point0[0,0]) == 0: 
     m.append(90) 
    else: 
     m.append(float((point1[0,1]-point0[0,1]))/float((point1[0,0]-point0[0,0]))) 

# Final line 
point0 = convexH[index+1] 
point1 = convexH[0] 
if(point1[0,0]-point0[0,0]) == 0: 
    m.append(90) 
else: 
    m.append(np.abs(float((point1[0,1]-point0[0,1]))/float((point1[0,0]-point0[0,0])))) 

# Take all the lines with the big m 
ind1 = np.where(np.asarray(m)>1) 
ind2 = np.where(np.asarray(m)<-1) 

# For both lines find min Y an max Y 
yLines1,xLine1 = getConvexCoord(convexH,ind1) 
yLines2,xLine2 = getConvexCoord(convexH,ind2) 
yLines = yLines1 + yLines2 

# Filter xLines. If we the difference between the min and the max are more than 1/2 the size of the image we filter it out 
minY = np.min(np.asarray(yLines)) 
maxY = np.max(np.asarray(yLines)) 

maxX1,minX1 = filterLine(xLine1) 
maxX2,minX2 = filterLine(xLine2) 

# Change final lines to have minY and maxY 
line1 = ((minX1,minY),(maxX1,maxY)) 
line2 = ((maxX2,minY),(minX2,maxY)) 

# Plot lines 
IrgbWithLines = Irgb 
cv2.line(IrgbWithLines,line1[0],line1[1],(0, 0, 255),2) 
cv2.line(IrgbWithLines,line2[0],line2[1],(0, 0, 255),2) 

Bemerkungen: Der Algorithmus geht davon aus, dass die y Koordinate Änderung größer ist als die x-Koordinate ändern. Dies gilt nicht für sehr hohe perspektivische Verzerrungen (45 Grad). In diesem Fall sollten Sie k-means auf den Pisten benutzen und die Gruppe mit den höheren Steigungen als vertikale Linien nehmen.

0

Die an den Seiten rot markierten Linien konnten mit der Funktion Bild schließen gefunden werden. Nachfolgend finden Sie den Matlab-Ausgang nach der Ausführung mit Strukturierungselement vom Typ Quadrat und Größe 4. ' the result of code segment

Der MATLAB-Code ist wie folgt:

I = rgb2gray (imread ('Bild.jpg ')); im Ausstellung (I); Titel ('Bild');

Ibinär = im2bw (I); Abbildung, imshow (Ibinary);

se = strel ('Quadrat', 4);

Iclose = imclose (Ibinary, se); Abbildung, imshow (Iclose); Titel ("Seitenlinien");

+0

Die Linien hier zeichnete ich, um ein Beispiel zu zeigen, welche Vektor/Koordinaten ich auf einem rohen Bild finden möchte. Ich brauche die Linien, die die Seiten eines Bildes berühren, sich durch die ganze Fläche erstrecken und den Text nicht kreuzen. Sie haben gerade die Linien gefunden, die ich als Beispiel gezeichnet habe. Entschuldigung, wenn meine Erklärung in der Frage nicht klar war. –

Verwandte Themen