树莓派OPENCV数字识别——上
这里给2000是第一次尝试时候用的2000,对于部分数字已经够用,但是对于6,8,9等比较模糊的数字还是不太够,需要根据实际需要修改数量。生成数字的代码如下,这里对图片进行了很多修改,如让其旋转一定角度,或者是更改其对比度,可以让训练的结果更好。第三,字体路径,点开C:/Windows/Fonts/后,你就可以看到电脑的各种字体,我选的是黑体。第二,他这里生成的数字是64x64的,后续SVM时候,
本文目前使用的方法是基于SVM的,后续可能会改进成别的,不够不管是哪一种,都需要创造训练集。
先说第一种,mnist,不推荐,毕竟是手写训练集,打印出来的还是能好一些。
所以,这里采用生成数字的方式

首先在python里面导入必须要的库,我用的是pycharm,设置里能直接加。
生成数字的代码如下,这里对图片进行了很多修改,如让其旋转一定角度,或者是更改其对比度,可以让训练的结果更好
不过又两个地方需要注意,一个是图片数量那里,他这个数量是图片总数,也就是一共生成多少图片。这里给2000是第一次尝试时候用的2000,对于部分数字已经够用,但是对于6,8,9等比较模糊的数字还是不太够,需要根据实际需要修改数量
第二,他这里生成的数字是64x64的,后续SVM时候,以及数字识别的时候,大小都要写64x64.
第三,字体路径,点开C:/Windows/Fonts/后,你就可以看到电脑的各种字体,我选的是黑体。
import os
import random
from PIL import Image, ImageDraw, ImageFont, ImageEnhance
import numpy as np
# 设置文件保存路径
output_dir = 'generated_images'
os.makedirs(output_dir, exist_ok=True)
# 设置字体路径
font_path = "C:/Windows/Fonts/simhei.ttf"
# 设置生成图片的数量
num_images = 2000
# 图像数据增强:旋转、平移、亮度调整
def augment_image(image):
# 随机旋转
angle = random.randint(-15, 15)
image = image.rotate(angle, resample=Image.BICUBIC, expand=False)
# 随机平移
max_translation = 5
translation = (random.randint(-max_translation, max_translation),
random.randint(-max_translation, max_translation))
image = image.transform(
image.size, Image.AFFINE,
(1, 0, translation[0], 0, 1, translation[1]),
resample=Image.BICUBIC
)
# 随机缩放 + 裁剪或填充回原始尺寸
scale_factor = random.uniform(0.8, 1.2)
new_size = (int(image.size[0] * scale_factor), int(image.size[1] * scale_factor))
image = image.resize(new_size, resample=Image.BICUBIC)
# 保持输出尺寸为 64x64
if scale_factor < 1.0:
# 缩小后,放到中央,填充白色背景
background = Image.new('RGB', (64, 64), 'white')
offset = ((64 - new_size[0]) // 2, (64 - new_size[1]) // 2)
background.paste(image, offset)
image = background
else:
# 放大后,居中裁剪
left = (new_size[0] - 64) // 2
top = (new_size[1] - 64) // 2
image = image.crop((left, top, left + 64, top + 64))
# 随机亮度调整
enhancer = ImageEnhance.Brightness(image)
image = enhancer.enhance(random.uniform(0.8, 1.2))
return image
# 生成并保存图像
def generate_images():
for i in range(num_images):
# 随机选择数字
digit = str(random.randint(0, 9))
# 创建白色背景
img = Image.new('RGB', (64, 64), color='white')
draw = ImageDraw.Draw(img)
# 随机字体大小
font_size = random.randint(30, 50)
font = ImageFont.truetype(font_path, font_size)
# 获取文本边界框(替代 textsize)
bbox = draw.textbbox((0, 0), digit, font=font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]
# 计算文本位置(居中)
x = (img.width - text_width) // 2
y = (img.height - text_height) // 2
# 绘制文本
draw.text((x, y), digit, font=font, fill='black')
# 增强图像
img = augment_image(img)
# 保存图片
img.save(os.path.join(output_dir, f"{i}_{digit}.png"))
if __name__ == '__main__':
generate_images()
生成完之后就可以在python的文件夹找到图片集了。
下面还有一个没有黑边纯数字的数字生成集,而且数字放大了一些:
import os
import random
from PIL import Image, ImageDraw, ImageFont, ImageEnhance
output_dir = 'generated_images'
os.makedirs(output_dir, exist_ok=True)
font_path = "C:/Windows/Fonts/simhei.ttf"
image_size = (64, 64)
digit_counts = {
'0': 500,
'1': 500,
'2': 500,
'3': 500,
'4': 500,
'5': 500,
'6': 500,
'7': 500,
'8': 500,
'9': 500,
}
def augment_image(image):
# 增加图像背景,使旋转时不产生黑边
angle = random.randint(-15, 15)
new_size = (image.size[0] * 2, image.size[1] * 2) # 扩大背景
expanded_image = Image.new('RGB', new_size, color='white')
# 计算中心位置
x_offset = (new_size[0] - image.size[0]) // 2
y_offset = (new_size[1] - image.size[1]) // 2
expanded_image.paste(image, (x_offset, y_offset))
# 旋转图像
rotated_image = expanded_image.rotate(angle, expand=True, fillcolor='white') # 保证旋转时无黑边
# 缩放时确保最小比例为 0.9,避免数字太小
scale = random.uniform(0.9, 1.2) # 防止缩放过小
new_size = (int(rotated_image.size[0] * scale), int(rotated_image.size[1] * scale))
rotated_image = rotated_image.resize(new_size, Image.Resampling.LANCZOS)
# 裁剪并调整至 64x64,确保数字居中
left = (rotated_image.size[0] - 64) // 2
top = (rotated_image.size[1] - 64) // 2
right = (rotated_image.size[0] + 64) // 2
bottom = (rotated_image.size[1] + 64) // 2
rotated_image = rotated_image.crop((left, top, right, bottom))
rotated_image = rotated_image.resize((64, 64), Image.Resampling.LANCZOS) # 确保图像大小为64x64
# 提高对比度,确保数字更清晰
enhancer = ImageEnhance.Contrast(rotated_image)
rotated_image = enhancer.enhance(random.uniform(1.2, 2.0))
return rotated_image
def generate_images():
count = 0
for digit, num in digit_counts.items():
for _ in range(num):
img = Image.new('RGB', image_size, color='white') # 白色背景
draw = ImageDraw.Draw(img)
font_size = random.randint(30, 50)
font = ImageFont.truetype(font_path, font_size)
# 获取文本边界框,计算宽度和高度
bbox = draw.textbbox((0, 0), digit, font=font)
w, h = bbox[2] - bbox[0], bbox[3] - bbox[1] # 计算宽度和高度
x = (image_size[0] - w) // 2
y = (image_size[1] - h) // 2
draw.text((x, y), digit, font=font, fill='black') # 黑色字体
img = augment_image(img) # 增强图像(旋转、缩放等)
img.save(os.path.join(output_dir, f"{count}_{digit}.png"))
count += 1
generate_images()
剩下的见中篇和下篇。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)