小项目:手写数字识别,可识别小数点(一)(2020.7.3)

小项目:手写数字识别,可识别小数点(一)

完整代码已经上传 GitHub(https://github.com/wwwwkd/Digit-Recognition)有帮助的话给个小星星!!!

代码是自己写的,有些不严谨,有更好的方法或者思路,希望大家之间相互指点相互进步。首先提供思路,然后在提供部分代码,然后在展示效果图。

功能要求:可以根据自己手工书写一个数字得带小数,拍照后,程序能将该手写数字转换成对应的数字。
经过查阅资料,将其大致分为一下三个部分:

数字的定位、分割、保存.
小数点的识别.
网络的训练、测试和最佳模型参数保存加载.

数字的定位、分割、保存

本次项目使用的第三方库包含了cv2、matplotlib、numpy和torch下面将对涉及的相关算法进行介绍。
(1)cv2
在计算机视觉项目的开发中,OpenCV作为较大众的开源库,拥有了丰富的常用图像处理函数库。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
在本次手写数字识别项目中,有三个难点,一个是基于深度学习的网络模型得选择、训练及最佳模型参数的保存,第二个就是对于手写数字的定位、分割和保存。最后一个是对于小数点是否存在的一个判断。
针对第二点:我首先对输入的图像进行高斯滤波(cv2.GaussianBlur())进行预处理,然后在对其进行中值滤波(cv2.medianBlur())去除图像得椒盐噪声。将处理好的图像进行二值化操作(cv2.threshold()),然后针对二值化后的图像进行外轮廓的检测其函数为(cv2.findContours())、获取外轮廓的面积(cv2.contourArea())并获取轮廓外接矩形的四点坐标(cv2.boundingRect())绘制外接最小矩形(cv2.rectangle()),这时我发现数字5的一横因为书写习惯没有与其余部分连成一个整体,因此被两个矩形外框截取,这并不是我们想要的结果,因此我这部分设置卷积核采用膨胀(cv2.dilate())的方法在x方向的力度比较强,使其连接成为一个整体。膨胀前后变化如图一所示。
在这里插入图片描述
如果这些没问题了,我们就可以进入下一个环节,对于其进行字符分割,这部分要考虑的问题就是,分割的数字,而不能是输入一张原始图片输出的数字是乱序的。我使用的方法是将上述的外接矩形的四点坐标存入一个列表内,然后根据x轴坐标储存位置的索引,按大小顺序排列,这样存入的坐标就是手写数字的实际顺序保存。然后根据矩形四点坐标在经过预处理候得二值化图像进行切片,这样我们要的数字。
在这里插入图片描述
下面仅展示部分代码只含有数字定位并不包含小数点识别,小数点的识别见下一篇,完整代码见 GitHub
https://github.com/wwwwkd/Digit-Recognition

def digital_segmentation(image):

    image = cv.GaussianBlur(image, (3, 3), 0) #高斯去噪

    gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY) #转灰度图像

    gray = cv.medianBlur(gray, 5) #中值滤波去除椒盐噪声

    ret, binary = cv.threshold(gray,0,255,cv.THRESH_OTSU|cv.THRESH_BINARY_INV)  #获取二值化图像

    kernelX = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))  # 17在x方向膨胀力度更大 返回指定形状和尺寸的结构元素。cv2.MORPH_RECT返回得是个矩形
    #print(kernelX)
    binary1 = cv.morphologyEx(binary, cv.MORPH_CLOSE, kernelX, iterations=3)

    # 下面的膨胀、腐蚀或者腐蚀、膨胀根据个人需求自行设定即可
    kerne2X = cv.getStructuringElement(cv.MORPH_RECT, (5, 5)) #设置卷积核
    # kernelY = cv.getStructuringElement(cv.MORPH_RECT, (1, 5))

    # 膨胀,腐蚀
    binary1 = cv.dilate(binary1, kerne2X)
    #binary = cv.erode(binary, kernelX)

    contours,hireachy = cv.findContours(binary1,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE) #只检测外轮廓即可

    numbers = []
    number_image = []

    i = 0
    for item in contours:
        i = i+1
        x,y,w,h = cv.boundingRect(item)     #获取轮廓的外接矩形
        rate = min(w,h)/max(w,h)    #获取外接矩形宽高比,可以起到一定的筛选作用
        cv.rectangle(image, (x, y), (x + w, y + h), (255, 0, 255), 3)  # 根据轮廓外接矩形返回数据,画出外接矩形

        number = []
        number.append(x) # 将矩形轮廓得四点坐标添加到number
        number.append(y)
        number.append(w)
        number.append(h)
        numbers.append(number) #再将所有number添加到numbers

    numbers = sorted(numbers, key=lambda s: s[0], reverse=False) # 按照x方向顺序来进行保存分割数字

    i = 0
    for number in numbers:
        i = i + 1
        splite_image = binary[(number[1]-2):(number[1]-2) + (number[3]+2), (number[0]-2):(number[0]-2) + (number[2]+2)]
        number_image.append(splite_image)
        #plt_show0(number_image)
        cv.imwrite('./get_nums_img/' + str(i-1) + '.png', splite_image)
    print('手写数字得定位、分割、保存,已完成')
    return number_image  # 返回分割图像列表
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值