HyperLPR源码分析10

本文深入分析了HyperLPR中用于车牌文字裁剪优化的refineCrop函数。该函数首先找到图片中心,进行二值化处理,分离文字与背景。接着利用findContours识别边缘,通过boundingRect确定最小包围矩形,从而精确裁剪出文字区域。最终,计算出最优的裁剪框new_box,以备后续文字识别使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2021SC@SDUSC

在上一次分析中,提到了refineCrop函数,对裁剪下来含有车牌文字的图片区域进行了修剪,这次我们就分析一下具体是如何实现的。

这是refineCrop函数的全部代码:

def refineCrop(sections,width=16):
    new_sections = []
    for section in sections:
        # cv2.imshow("section¡",section)

        # cv2.blur(section,(3,3),3)

        sec_center = np.array([section.shape[1]/2,section.shape[0]/2])
        binary_niblack = nt.niBlackThreshold(section,17,-0.255)
        imagex, contours, hierarchy  = cv2.findContours(binary_niblack,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
        boxs = []
        for contour in contours:
            x,y,w,h = cv2.boundingRect(contour)

            ratio = w/float(h)
            if ratio<1 and h>36*0.4 and y<16\
                    :
                box = [x,y,w,h]

                boxs.append([box,np.array([x+w/2,y+h/2])])
                # cv2.rectangle(section,(x,y),(x+w,y+h),255,1)




        # print boxs

        dis_ = np.array([ ((one[1]-sec_center)**2).sum() for one in boxs])
        if len(dis_)==0:
            kernal = [0, 0, section.shape[1], section.shape[0]]
        else:
            kernal = boxs[dis_.argmin()][0]

        center_c  = (kernal[0]+kernal[2]/2,kernal[1]+kernal[3]/2)
        w_2 = int(width/2)
        h_2 = kernal[3]/2

        if center_c[0] - w_2< 0:
            w_2 = center_c[0]
        new_box = [center_c[0] - w_2,kernal[1],width,kernal[3]]
        # print new_box[2]/float(new_box[3])
        if new_box[2]/float(new_box[3])>0.5:
            # print "异常"
            h = int((new_box[2]/0.35 )/2)
            if h>35:
                h = 35
            new_box[1] = center_c[1]- h
            if new_box[1]<0:
                new_box[1] = 1
            new_box[3] = h*2
        
        section  = section[int(new_box[1]):int(new_box[1]+new_box[3]), int(new_box[0]):int(new_box[0]+new_box[2])]
        # cv2.imshow("section",section)
        # cv2.waitKey(0)
        new_sections.append(section)
        # print new_box
    return new_sections

传递的参数,就是之前剪裁出来的图片的部分。

        sec_center = np.array([section.shape[1]/2,section.shape[0]/2])
        binary_niblack = nt.niBlackThreshold(section,17,-0.255)
        imagex, contours, hierarchy  = cv2.findContours(binary_niblack,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
        boxs = []

这里找出图片部分的中心,然后用niBlackThreshold进行了图像二值化,把前景(也就是文字)和背景分离开来,然后用findContours识别出边缘,边缘保存在contours中

        for contour in contours:
            x,y,w,h = cv2.boundingRect(contour)

            ratio = w/float(h)
            if ratio<1 and h>36*0.4 and y<16\
                    :
                box = [x,y,w,h]

                boxs.append([box,np.array([x+w/2,y+h/2])])

对于每个边缘,也就是文字的边缘,使用boundingRect函数,这个函数的作用就是画出能够包含目标图形的最小矩形,也就是能包含识别出的文字的最小矩形,这样就能裁剪出尽可能小的包含文字的区域,便于识别文字。将最小矩形的坐标信息和长宽信息存储在boxs列表里。

        dis_ = np.array([ ((one[1]-sec_center)**2).sum() for one in boxs])
        if len(dis_)==0:
            kernal = [0, 0, section.shape[1], section.shape[0]]
        else:
            kernal = boxs[dis_.argmin()][0]

        center_c  = (kernal[0]+kernal[2]/2,kernal[1]+kernal[3]/2)
        w_2 = int(width/2)
        h_2 = kernal[3]/2

        if center_c[0] - w_2< 0:
            w_2 = center_c[0]
        new_box = [center_c[0] - w_2,kernal[1],width,kernal[3]]

然后计算dis,这是识别出的最小矩形距离图形中心的距离,接下来算出kernel,kernel的值是距离中心最小的那个矩形,也就是最靠近中心的那个文字所在的最小矩形的长宽信息和位置信息。特别地,如果根本没有识别出任何边缘,也就没有任何最小矩形,kernel就被直接设定为图形中心点位置和图形的长宽。center_c是用kernel的信息计算出来的,最小矩形的中心坐标。 

最后,根据以上计算得出的信息,最小矩形的位置坐标和长宽数值被保存在new_box中,这样接下来识别文字的时候,就可以根据new_box重新生成这个最小矩形。new_box也就是返回值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值