手写数字识别之数据集生成


目录

      • 一. 要求:
      • 二. 主要代码:
          • (1)将图片填充为正方形
          • (2)切分图片,两重循环,生成100张图片基于原图的位置
          • (3)按命名要求保存图片并进行要求的灰度处理与大小设置
          • (4)调用
      • 三. 样例图片:
      • 四. 参考博客:

一. 要求:

在纸上适当做出10X10格子,手写数字0-9各10遍,

,拍照,进行图像数据的预处理,转为灰度图像,进行适当的亮度、对比度调整,像素为28*28,生成100个灰度图片文件:标签-序号-学号.png,如下:

0-a-46660001.png

0-b-46660001.png

0-j-46660001.png

1-a-46660001.png

1-b-46660001.png

9-j-46660001.png

其中0-9表示数字符号“0”到“9”,a~j表示手写的第1个到第10个数字。46660001是学号。

二. 主要代码:

(1)将图片填充为正方形
1
2
3
4
5
6
7
8
9
10
11
12
13
def fill_image(image):
    width, height = image.size
    #选取长和宽中较大值作为新图片的边长
    new_image_length = width if width > height else height
    #生成新图片[白底]
    new_image = Image.new(image.mode, (new_image_length, new_image_length), color='white')
    #将之前的图粘贴在新图上,居中
    if width > height:#原图宽大于高,则填充图片的竖直维度
        #(x,y)二元组表示粘贴上图相对下图的起始位置
        new_image.paste(image, (0, int((new_image_length - height) / 2)))
    else:
        new_image.paste(image,(int((new_image_length - width) / 2),0))
    return new_image

由于采用长和宽中较大值作为新图片的边长,以白底填充,故希望导入图片时为近似正方形图片。

(2)切分图片,两重循环,生成100张图片基于原图的位置
1
2
3
4
5
6
7
8
9
10
def cut_image(image,n):
    width, height = image.size
    item_width = int(width / n)
    box_list = []
    for i in range(0,n):
        for j in range(0,n):
            box = (j*item_width,i*item_width,(j+1)*item_width,(i+1)*item_width)
            box_list.append(box)
    image_list = [image.crop(box) for box in box_list]
    return image_list

本次是生成10*10数量的图片,调用函数时传入n为10,如有不同需求,可以传参时更换其他数字满足需求。

(3)按命名要求保存图片并进行要求的灰度处理与大小设置
1
2
3
4
5
6
7
8
9
10
11
def save_images(image_list):
    first_id = 0
    second_id = 'a'
    for image in image_list:
        img = image.convert('L')  #保存前进行灰度处理
        img = img.resize((28,28)) #保存前设置大小
        img.save('./img/'+str(first_id)+'-'+str(second_id)+'-'+str('41824334') + '.png', 'PNG')
        second_id = chr(ord(second_id)+1)
        if second_id == 'k':
            first_id += 1
            second_id = 'a'

本次进行的灰度处理使用的是PIL库,灰度处理方式有很多,具体可参考文末参考博文;
保存时大小设置为28*28,可根据实际需要进行更改

(4)调用
1
2
3
4
5
6
if __name__ == '__main__':
    file_path = "./1.jpg"
    image = Image.open(file_path)
    image = fill_image(image)
    image_list = cut_image(image,10)
    save_images(image_list)

三. 样例图片:

下图为notability上手写的数字截图

在这里插入图片描述

四. 参考博客:

python将1张图片分割成9张
python3读取图片并灰度化图片的四种方法(OpenCV、PIL.Image、TensorFlow方法)总结
cv2.imread与Image.open打开图片格式的不同与调整
python 读取、保存、二值化、灰度化图片+opencv处理图片的方法
python-关于改变图片的大小-resize