如何使用Python和OpenCV在从上到下的同时从左到右对轮廓进行排序 [英] How to sort contours left to right, while going top to bottom, using Python and OpenCV

查看:185
本文介绍了如何使用Python和OpenCV在从上到下的同时从左到右对轮廓进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为OCR找到带有数字和字符的图像的轮廓.因此,我需要等高线在逐行(即从上到下)的同时从左到右排序.现在,轮廓并不是按照这种方式排序的.

I'm finding the contours for an image with digits and characters, for OCR. So, I need the contours to be sorted left to right, while going line to line, i.e. top to bottom. Right now, the contours aren't sorted that way.

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

For example, the contours for the above image is sorted randomly.

我需要按D,o,y,o,u,k,n,o,w,s,o,m,e,o,n,e,r,.(点),i进行排序(不带点),c,h ...等等.我尝试了几种方法,首先观察y坐标,然后使用一些键和x坐标.像现在一样,我有以下排序代码.它适用于前2行.然后在第三行中,排序不会发生.主要问题似乎出在诸如i,j,?,(点),(逗号)之类的字母中,尽管它们属于同一行,但(点)的y轴却有所不同.那么什么可能是一个好的解决方案?

What I need is the sorting as D,o,y,o,u,k,n,o,w,s,o,m,e,o,n,e,r,.(dot),i(without dot),c,h...and so on. I've tried couple of methods where we first observe the y-coordinate and then use some keys and the x-coordinate. Like right now, I have the following sorting code. It works for the first 2 lines. Then in the 3rd line, the sorting somehow doesn't happen. The main problem seem to be in the letters such as i, j, ?, (dot), (comma), etc where the y axis of the (dot) varies, despite belonging to the same line. So what might be a good solution for this?

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 ]

推荐答案

我使用了此方法,并且对我有用.就我而言,每行有5个轮廓

I used this method and it worked for me. In my case, there was 5 contours in each row

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
        #....#

如果我错了,请纠正我

这篇关于如何使用Python和OpenCV在从上到下的同时从左到右对轮廓进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆