Python图像数据处理
功能概述
这段代码是一个完整的图像数据处理流程,主要用于准备猫狗分类任务的训练数据。主要功能包括:
- 加载猫和狗的图片数据集
- 展示样本图片
- 将图片统一调整为标准尺寸
- 创建训练数据集
- 保存处理后的数据以便后续使用
详细代码解析
1. 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
import os
import cv2
from tqdm import tqdm
numpy
: 用于数值计算和数组操作matplotlib.pyplot
: 用于图像显示os
: 用于文件和目录操作cv2
(OpenCV): 用于图像处理tqdm
: 用于显示进度条
2. 数据集路径和类别定义
DATADIR = "../doc/PetImages"
CATEGORIES = ["Dog", "Cat"]
- 定义数据集路径和类别名称(狗和猫)
3. 展示样本图片
for category in CATEGORIES:path = os.path.join(DATADIR,category)for img in os.listdir(path):img_array = cv2.imread(os.path.join(path,img), cv2.IMREAD_GRAYSCALE)plt.imshow(img_array, cmap='gray')plt.show()breakbreak
- 遍历每个类别目录
- 读取并显示每个类别的第一张图片(灰度图)
- 使用
break
只显示一张图片作为示例
4. 图片尺寸调整演示
IMG_SIZE = 50
new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
plt.imshow(new_array, cmap='gray')
plt.show()IMG_SIZE = 100
new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
plt.imshow(new_array, cmap='gray')
plt.show()
- 展示将图片调整为50x50和100x100两种尺寸的效果
5. 创建训练数据集
training_data = []def create_training_data():for category in CATEGORIES:path = os.path.join(DATADIR,category)class_num = CATEGORIES.index(category) # 0=dog, 1=catfor img in tqdm(os.listdir(path)):try:img_array = cv2.imread(os.path.join(path,img), cv2.IMREAD_GRAYSCALE)new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))training_data.append([new_array, class_num])except Exception as e:passcreate_training_data()
- 初始化空列表
training_data
存储所有训练数据 create_training_data()
函数:
-
- 遍历每个类别目录
- 为每张图片:
-
-
- 读取为灰度图
- 调整大小为
IMG_SIZE
(最后设置为100x100) - 将图片数组和对应标签(0或1)添加到
training_data
-
-
- 使用
tqdm
显示进度条 - 使用try-except跳过处理错误的图片
- 使用
6. 数据预处理
print(len(training_data))import random
random.shuffle(training_data)for sample in training_data[:10]:print(sample[1])
- 打印训练数据总数
- 随机打乱训练数据顺序(重要步骤,避免模型学习到顺序信息)
- 打印前10个样本的标签,验证数据已打乱
7. 分离特征和标签
X = []
y = []for features,label in training_data:X.append(features)y.append(label)
- 将
training_data
分离为特征(X)和标签(y)
8. 数据reshape
print(X[0].reshape(-1, IMG_SIZE, IMG_SIZE, 1))
X = np.array(X).reshape(-1, IMG_SIZE, IMG_SIZE, 1)
- 将特征数据转换为numpy数组
- reshape为适合卷积神经网络输入的4D张量:(样本数, 高度, 宽度, 通道数)
- 因为是灰度图,所以通道数为1
9. 数据保存与加载
import pickle# 保存特征数据
pickle_out = open("../doc/X.pickle","wb")
pickle.dump(X, pickle_out)
pickle_out.close()# 保存标签数据
pickle_out = open("../doc/y.pickle","wb")
pickle.dump(y, pickle_out)
pickle_out.close()# 加载特征数据
pickle_in = open("../doc/X.pickle","rb")
X = pickle.load(pickle_in)# 加载标签数据
pickle_in = open("../doc/y.pickle","rb")
y = pickle.load(pickle_in)
- 使用pickle模块将处理好的数据保存到文件
- 演示如何从文件加载数据
改进建议
- 路径处理:使用
os.path
处理路径更安全,特别是在不同操作系统上 - 错误处理:当前代码忽略了所有错误,建议至少记录错误信息
- 数据验证:在处理前检查图片文件是否有效
- 参数化:将
IMG_SIZE
等参数放在文件开头,便于修改 - 数据划分:可以考虑直接划分训练集和测试集
总结
这段代码完成了从原始图像到可用于机器学习模型训练的数据预处理全流程,包括:
- 图像加载和显示
- 尺寸标准化
- 数据打乱
- 特征标签分离
- 数据序列化保存
处理后的数据可以直接用于构建和训练图像分类模型,特别是卷积神经网络(CNN)。
数据集下载:
https://www.microsoft.com/en-us/download/details.aspx?id=54765
📎Day 40.ipynb
# 导入numpy库,用于后续的数值运算
import numpy as np
# 导入matplotlib.pyplot库,用于绘图
import matplotlib.pyplot as plt
# 导入os库,用于操作系统相关功能,比如读取文件路径
import os
# 导入cv2库,即OpenCV,用于图像处理任务
import cv2
# 导入tqdm库,用于显示循环的进度条,提升程序执行的可视化效果
from tqdm import tqdm# 定义数据集目录
DATADIR = "../doc/PetImages" # 数据集的路径,请根据需要修改# 定义类别
CATEGORIES = ["Dog", "Cat"]# 遍历类别,展示每个类别中的第一张图片
for category in CATEGORIES:path = os.path.join(DATADIR,category) # 创建路径for img in os.listdir(path): # 迭代遍历每个图片img_array = cv2.imread(os.path.join(path,img) ,cv2.IMREAD_GRAYSCALE) # 转化成arrayplt.imshow(img_array, cmap='gray') # 转换成图像展示plt.show() # display!break # 我们作为演示只展示一张,所以直接break了break #同上# 打印出展示的图片数组
print(img_array)# 打印图片数组的形状
print(img_array.shape)# 定义图片大小,用于后续的图片大小标准化
IMG_SIZE = 50# 将图片调整为50x50大小
new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
plt.imshow(new_array, cmap='gray')
plt.show()# 再次定义图片大小,用于展示不同大小的图片
IMG_SIZE = 100
new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
plt.imshow(new_array, cmap='gray')
plt.show()# 初始化训练数据列表
training_data = []# 定义创建训练数据的函数
def create_training_data():for category in CATEGORIES:path = os.path.join(DATADIR,category)class_num = CATEGORIES.index(category) # 得到分类,其中 0=dog 1=catfor img in tqdm(os.listdir(path)):try:img_array = cv2.imread(os.path.join(path,img) ,cv2.IMREAD_GRAYSCALE)new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE)) # 大小转换training_data.append([new_array, class_num]) # 加入训练数据中except Exception as e: # 为了保证输出是整洁的pass#except OSError as e:# print("OSErrroBad img most likely", e, os.path.join(path,img))#except Exception as e:# print("general exception", e, os.path.join(path,img))# 调用函数创建训练数据
create_training_data()# 打印训练数据的数量
print(len(training_data))# 使用random库打乱训练数据
import random
random.shuffle(training_data)# 打印前10个训练数据的标签
for sample in training_data[:10]:print(sample[1])# 初始化特征和标签列表
X = []
y = []# 将训练数据分离为特征和标签
for features,label in training_data:X.append(features)y.append(label)# 打印第一个特征的形状
print(X[0].reshape(-1, IMG_SIZE, IMG_SIZE, 1))# 将特征列表转换为numpy数组
X = np.array(X).reshape(-1, IMG_SIZE, IMG_SIZE, 1)# 使用pickle库保存特征数据
import pickle
pickle_out = open("../datasets/X.pickle","wb")
pickle.dump(X, pickle_out)
pickle_out.close()# 使用pickle库保存标签数据
pickle_out = open("../datasets/y.pickle","wb")
pickle.dump(y, pickle_out)
pickle_out.close()# 从pickle文件中加载特征数据
pickle_in = open("../datasets/X.pickle","rb")
X = pickle.load(pickle_in)# 从pickle文件中加载标签数据
pickle_in = open("../datasets/y.pickle","rb")
y = pickle.load(pickle_in)