Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Python和OpenCV从左到右排序轮廓,同时从上到下排序_Python_Sorting_Opencv_Contour - Fatal编程技术网

如何使用Python和OpenCV从左到右排序轮廓,同时从上到下排序

如何使用Python和OpenCV从左到右排序轮廓,同时从上到下排序,python,sorting,opencv,contour,Python,Sorting,Opencv,Contour,我正在寻找一个带有数字和字符的图像轮廓,用于OCR。所以,我需要将轮廓从左到右排序,同时逐行排序,即从上到下。现在,轮廓不是这样排序的 例如,上面图像的轮廓是随机排序的 我需要的是排序为D,O,Y,O,U,K,N,O,W,S,O,M,E,O,N,E,R,(点),I(无点),C,H等。我尝试了两种方法,首先观察y坐标,然后使用一些键和x坐标。就像现在一样,我有下面的排序代码。它适用于前两行。然后在第三行,排序不知何故没有发生。主要问题似乎出现在字母中,如i、j、、(点),(逗号)等,其中(点)的

我正在寻找一个带有数字和字符的图像轮廓,用于OCR。所以,我需要将轮廓从左到右排序,同时逐行排序,即从上到下。现在,轮廓不是这样排序的

例如,上面图像的轮廓是随机排序的

我需要的是排序为D,O,Y,O,U,K,N,O,W,S,O,M,E,O,N,E,R,(点),I(无点),C,H等。我尝试了两种方法,首先观察y坐标,然后使用一些键和x坐标。就像现在一样,我有下面的排序代码。它适用于前两行。然后在第三行,排序不知何故没有发生。主要问题似乎出现在字母中,如i、j、、(点),(逗号)等,其中(点)的y轴变化,尽管属于同一行。那么,有什么好的解决办法呢

for ctr in contours:    
    if cv2.contourArea(ctr) > maxArea * areaRatio: 
        rect.append(cv2.boundingRect(cv2.approxPolyDP(ctr,1,True)))

#rect contains the contours
for i in rect:
    x = i[0]
    y = i[1]
    w = i[2]
    h = i[3]

    if(h>max_line_height):
        max_line_height = h

mlh = max_line_height*2
max_line_width = raw_image.shape[1] #width of the input image
mlw = max_line_width
rect = np.asarray(rect)
s = rect.astype( np.uint32 ) #prevent overflows
order= mlw*(s[:,1]/mlh)+s[:,0]
sort_order= np.argsort( order )
rect = rect[ sort_order ]

我喜欢你用一次排序来解决这个问题。但正如您所说,每行中y的变化可能会破坏您的算法,另外,
max\u line\u height
可能需要根据不同的输入进行调整

因此,我会提出一个稍微不同的算法,但计算复杂度相当高。其思想是,如果您仅水平查看所有框,则第
N+1
行中的所有框将永远不会与第
1
行到
N
行中的框相交,但它们在一行内彼此相交。因此,您可以先按它们的
y
对所有框进行排序,逐个遍历并尝试找到“断点”(将它们分组为一行),然后在每行中,按它们的
x
对它们进行排序

下面是一个不太像Python的解决方案:

# sort all rect by their y
rect.sort(key=lambda b: b[1])
# initially the line bottom is set to be the bottom of the first rect
line_bottom = rect[0][1]+rect[0][3]-1
line_begin_idx = 0
for i in xrange(len(rect)):
    # when a new box's top is below current line's bottom
    # it's a new line
    if rect[i][1] > line_bottom:
        # sort the previous line by their x
        rect[line_begin_idx:i] = sorted(rect[line_begin_idx:i], key=lambda b: b[0])
        line_begin_idx = i
    # regardless if it's a new line or not
    # always update the line bottom
    line_bottom = max(rect[i][1]+rect[i][3]-1, line_bottom)
# sort the last line
rect[line_begin_idx:] = sorted(rect[line_begin_idx:], key=lambda b: b[0])

现在,
rect
应该按照您想要的方式进行排序。

我使用了这个方法,它对我很有效。 在我的例子中,每行有5个等高线

def x_cord_contour(contours):
    #Returns the X cordinate for the contour centroid
    M = cv2.moments(contours)
    return (int(M['m10']/M['m00']))
    
def y_cord_contour(contours):
    #Returns the Y cordinate for the contour centroid
    M = cv2.moments(contours)
    return (int(M['m01']/M['m00']))
    

# Sort by top to bottom using our y_cord_contour function
contours_top_to_bottom = sorted(questionCnts, key = y_cord_contour, reverse = False)





for (q, i) in enumerate(np.arange(0, len(contours_top_to_bottom), 5)):
    # sort the contours for the current question from left to right
    
    # As in my example every row contain 5 coutours so now i sorted them in row wise
    cnts = sorted(contours_top_to_bottom[i:i + 5], key = x_cord_contour, reverse = False)
    
    # loop over the sorted contours
    for (j, c) in enumerate(cnts):
        # construct a mask that reveals only the current contour
        #and do what ever you want to do
        #....#

如果我错了,请纠正我

请提供一个清晰的例子,说明第三行中什么不起作用。图像第三行的轮廓被排序为应力。ed,hav..i,n,g。等等这些点随机出现在其他字母的位置上,导致其他字母在正确的排序位置上散落。