个人笔记:OpenCV(一)图像分类——猫狗分类为例

目录

前言:

数据集准备

模型训练

模型调用

附录一:代码运行结果参考

附录二:代码详解(个人简介仅供参考)


前言:

        使用的编译环境和工具:Anaconda、Jupyter Notebook

        需要安装的库:OpenCV(打开 Anaconda Prompt 终端,输入命令:conda install opencv)

数据集准备

文件结构
CATandDOG(总文件夹)
data(数据集文件夹)

XXX.ipynb(代码文件)

train(训练集文件夹)test(测试集文件夹)
cat(猫的图片)dog(狗的图片)

模型训练

以下是模型训练代码:

#导入必要的库
import cv2
import numpy as np
import os
##加载训练数据
def load_data():
    train_data = []
    train_labels = []
    for label, folder_name in enumerate(['cat', 'dog']):
        folder_path = os.path.join('data', 'train', folder_name)
        for filename in os.listdir(folder_path):
            img_path = os.path.join(folder_path, filename)
            img = cv2.imread(img_path)
            img = cv2.resize(img, (128, 128))
            train_data.append(img)
            train_labels.append(label)
    train_data = np.array(train_data)
    train_labels = np.array(train_labels)
    train_data = train_data.astype(np.float32)
    return train_data, train_labels
##训练模型
train_data, train_labels = load_data()
# 将数据转换为一维数组
train_data = train_data.reshape((train_data.shape[0], -1))
# 训练模型
model = cv2.ml.SVM_create()
model.setType(cv2.ml.SVM_C_SVC)
model.setKernel(cv2.ml.SVM_LINEAR)
model.setTermCriteria((cv2.TERM_CRITERIA_MAX_ITER, 100, 1e-6))
model.train(train_data, cv2.ml.ROW_SAMPLE, train_labels)
model.save('catdog_model.xml')

等待运行结束即可在CATandDOG文件夹中找到生成的catdog_model.xml模型文件。

模型调用

模型调用有两种方式。

① 第一种是训练之后直接调用,直接在模型训练代码后加上以下代码:

#加载测试数据并进行预测
test_data = []
folder_path = os.path.join('data', 'test')
for filename in os.listdir(folder_path):
    img_path = os.path.join(folder_path, filename)
    img = cv2.imread(img_path)
    img = cv2.resize(img, (128, 128))
    test_data.append(img)
test_data = np.array(test_data)
test_data = test_data.astype(np.float32)
test_data = test_data.reshape((test_data.shape[0], -1))
# 进行预测
_, test_labels = model.predict(test_data)

##输出预测结果
for filename, label in zip(os.listdir(folder_path), test_labels):
    if label == 0:
        print(filename, 'is a cat')
    elif label == 1:
        print(filename, 'is a dog')

② 另一种方式是python程序调用.xml模型文件,代码如下:

import cv2
import numpy as np
import os
import time

#开始计时
start_time = time.time()

# 加载模型文件
model = cv2.ml.SVM_load('catdog_model.xml')

##加载测试数据并进行预测
test_data = []
folder_path = os.path.join('data', 'test')
for filename in os.listdir(folder_path):
    img_path = os.path.join(folder_path, filename)
    img = cv2.imread(img_path)
    img = cv2.resize(img, (128, 128))
    test_data.append(img)
test_data = np.array(test_data)
test_data = test_data.astype(np.float32)
test_data = test_data.reshape((test_data.shape[0], -1))

# 进行预测
_, test_labels = model.predict(test_data)

##输出预测结果
for filename, label in zip(os.listdir(folder_path), test_labels):
    if label == 0:
        print(filename, 'is a cat')
    elif label == 1:
        print(filename, 'is a dog')
        
#结束计时
end_time = time.time()
print('Time elapsed:', end_time - start_time, 'seconds')

附录一:代码运行结果参考

方法一运行结果

方法二运行结果

我的测试集(可以看到测试结果基本正确)

附录二:代码详解(个人见解仅供参考)

train_data = []

train_labels = []

#定义一个空列表train_data和train_labels用于存储训练数据和标签

for label, folder_name in enumerate(['cat', 'dog']):

#对于列表中的每个元素,使用enumerate()函数生成一个元素和其索引组成的序列,其中label表示索引,folder_name表示元素,用于遍历猫和狗两个文件夹。

folder_path = os.path.join('data', 'train', folder_name)

使用os.path.join()函数将'data', 'train', folder_name三个字符串合并为一个路径字符串,用于指定训练数据所在的文件夹路径。

for filename in os.listdir(folder_path):

遍历文件夹下的每个文件名

img_path = os.path.join(folder_path, filename)

img = cv2.imread(img_path)

img = cv2.resize(img, (128, 128))

使用os.path.join()函数将folder_path和filename组合为完整的图片路径img_path,然后使用cv2.imread()函数读取图片,cv2.resize()函数将图片大小调整为128x128像素。

train_data.append(img)

train_labels.append(label)

将处理过的图片存储在train_data列表中,将对应的标签存储在train_labels列表中。

train_data = np.array(train_data)

train_labels = np.array(train_labels)

将train_data和train_labels转换为numpy数组。

train_data = train_data.astype(np.float32)

将train_data的数据类型转换为np.float32,以便后续处理。

return train_data, train_labels

返回处理好的训练数据train_data和对应的标签train_labels。

train_data, train_labels = load_data()

调用load_data()函数加载训练数据,将训练数据和标签分别存储在train_data和train_labels变量中。

train_data = train_data.reshape((train_data.shape[0], -1))

将train_data变量的形状从(n, w, h, c)转换为(n, w * h * c),即将每个图片数据压缩成一维数组。

model = cv2.ml.SVM_create()

创建一个SVM分类器对象model。

model.setType(cv2.ml.SVM_C_SVC)

设置SVM分类器的类型为C_SVC,即支持向量分类器。

model.setKernel(cv2.ml.SVM_LINEAR)

设置SVM分类器的核函数为线性核。

model.setTermCriteria((cv2.TERM_CRITERIA_MAX_ITER, 100, 1e-6))

设置SVM分类器的终止准则,当迭代次数达到100次或误差小于1e-6时停止训练。

model.train(train_data, cv2.ml.ROW_SAMPLE, train_labels)

使用训练数据和标签train_data、train_labels训练SVM分类器。

model.save('catdog_model.xml')

将训练好的模型保存到catdog_model.xml文件中。

test_data = []

定义一个空列表test_data用于存储测试数据。

folder_path = os.path.join('data', 'test')

使用os.path.join()函数将'data'和'test'两个字符串合并为一个路径字符串,用于指定测试数据所在的文件夹路径。

for filename in os.listdir(folder_path):

遍历文件夹下的每个文件名。

img_path = os.path.join(folder_path, filename)

img = cv2.imread(img_path)

img = cv2.resize(img, (128, 128))

使用os.path.join()函数将folder_path和filename组合为完整的图片路径img_path,然后使用cv2.imread()函数读取图片,cv2.resize()函数将图片大小调整为128x128像素。

test_data.append(img)

将处理过的图片存储在test_data列表中。

test_data = np.array(test_data)

将test_data转换为numpy数组。

test_data = test_data.astype(np.float32)

将test_data的数据类型转换为np.float32,以便后续处理。

test_data = test_data.reshape((test_data.shape[0], -1))

将test_data变量的形状从(n, w, h, c)转换为(n, w * h * c),即将每个图片数据压缩成一维数组。

model = cv2.ml.SVM_load('catdog_model.xml')

在本例中,该行代码加载了文件名为 'catdog_model.xml' 的 SVM 模型,并将其赋值给变量 model。这个 SVM 模型是在之前的训练过程中训练好的,用于对猫狗图像进行分类。加载已经训练好的 SVM 模型,可以避免重新训练模型的时间和计算成本,同时可以快速地对新的数据进行分类预测。

_, test_labels = model.predict(test_data)

使用训练好的SVM分类器model对测试数据test_data进行预测,结果存储在test_labels中。_表示不关心预测结果的置信度。

for filename, label in zip(os.listdir(folder_path), test_labels):

循环语句用于遍历测试数据集中的所有样本。os.listdir(folder_path) 用于获取指定文件夹 folder_path 中的所有文件名,test_labels 是测试数据集中每个样本的标签,将它们通过 zip 函数打包在一起,得到一个可迭代的对象,每次迭代返回一个文件名和对应的标签。

if label == 0:

print(filename, 'is a cat')

用于输出当前样本的文件名和标签。如果标签为0,即当前样本为猫。

elif label == 1:

print(filename, 'is a dog')

用于输出当前样本的文件名和标签。如果标签为1,即当前样本为狗

  • 3
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值