2016-08-15 18 views
1

我有一個帶有文本的處理過的圖像,我想要找到會觸摸文本字段邊緣的線條的座標,但不會穿過它並且會拉伸通過文本的整個一面。下面的圖片顯示了什麼,我需要(紅線我畫呈現什麼座標我想找到一個原始圖像的示例): enter image description here如何找到文本字段的邊線

也不是那麼簡單的,我不能只找到邊緣處理文本字段(左上角,右上角等),因爲它可能是,fe一個段落的開始(這僅僅是可能的場景的一個例子):

enter image description here

文本的兩側形成直線,它是頂部和底部邊緣可以是彎曲的,所以這可以讓事情變得更容易。

這樣做的最好方法是什麼?

我能想到的任何方法都不實用,無效或可能通常會給出錯誤的結果。

萬一有人原始圖像進行處理所需:

enter image description here

回答

2

的想法是找到所有文本的凸包。在找到凸包後,我們找到它的兩側。如果邊的y座標變化很大,x座標變化很小(即線的斜率很高),我們會將其視爲邊線。

所得圖像:

enter image description here

的代碼:

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) 

備註: 該算法假定y座標變化比的x座標的變化大。對於非常高的視角扭曲(45度),這不是事實。在這種情況下,也許你應該在斜坡上使用k-means,並將斜坡高的組作爲垂直線。

0

使用圖像關閉操作可以找到側面標記爲紅色的線條。 請在使用square和size 4結構元素進行拼接操作後在matlab輸出中找到下面的代碼。 the result of code segment

的MATLAB代碼是如下:

I = rgb2gray(imread('圖像。JPG')); imshow(I);標題( '圖像');

Ibinary = im2bw(I); figure,imshow(Ibinary);

se = strel('square',4);

Iclose = imclose(Ibinary,se); figure,imshow(Iclose);標題('side lines');

+0

我在這裏畫的線顯示了一個我想在原始圖像上找到的矢量/座標的例子。我需要能夠觸及圖像兩側的線條,貫穿整個圖像而不是穿過文字。你只是找到了我畫的例子。對不起,如果我對問題的解釋不清楚。 –

相關問題