如何跟着OpenCV飞起来?——kaggle水果数据库图片识别案例

一、项目简介

  • OpenCV是一个用于图像处理、分析、机器视觉方面的开源工具包。无论科学研究,还是商业应用,OpenCV都是进行图像识别的不二之选。熟练掌握OpenCV的图片识别能力,在图片识别领域里飞起来不是梦!
  • 本文利用kaggle数据库上的水果图片数据集(fruit-images-for-object-detection)展示如何训练机器学习模型识别水果图片的类别。
  • 数据地址(kaggle数据库地址需要插件支持才能正常访问,请自行百度):
    https://www.kaggle.com/mbkinaci/fruit-images-for-object-detection

二、图片数据分析

  • 数据库分为训练集(train)和测试集(test)两部分
  • 训练集包含四类apple,orange,banana,mixed(多种水果混合)四类237张图片;测试集包含每类图片各两张。图片集如下图所示。
  • 图片类别可由图片名称中提取。
    训练集图片预览
    训练集图片列表
    测试集预览
    测试集图片列表

三、模型构建和实现

  • 建模思路:将rgb图片转化为gray灰度图,进而提取关键点信息,训练hmm模型进行图片预测。
  • 核心工具包:cv2,hmmlearn
1、导入工具包
import os
import warnings
import numpy as np
import cv2 as cv
import hmmlearn.hmm as hl
warnings.filterwarnings(
    'ignore', category=DeprecationWarning)
np.seterr(all='ignore')
2、收集文件路径
  • 将图片文件(jpg,png等…)收集在字典中备用
def search_objects(directory):
    # 将文件路径格式化,以便适应于各种操作系统
    directory = os.path.normpath(directory)
    # 如果输入路径不是文件件则抛出异常
    if not os.path.isdir(directory):
        raise IOError(directory + '不是文件夹')
    objects = {}
    # 遍历文件夹收集jpg文件,放入字典
    for curdir, _, files in os.walk(directory):
        for jpeg in [file for file in files
                     if file.endswith('.jpg')]:
            path = os.path.join(curdir, jpeg)
            # 从文件名中提取图片所属类别
            label = jpeg.split('_')[0]
            # label = path.split(os.path.sep)[-2]
            if label not in objects:
                objects[label] = []
            objects[label].append(path)
    return objects
3、图片特征值提取
  • 定义flags主要是来区分训练集合测试集,测试集需要保存图片并呈现,训练集不需要。
# 收集图片数据集的标签和灰度值
def label_desc02(objects, flags=None):
    data_x, data_y, data_z = [], [], []
    # 遍历类别标签及对应的文件名
    for label, files in objects.items():
        descs = np.array([])
        for file in files:
            image = cv.imread(file)
            # 训练阶段可不收集图片,不用给定flags值
            if flags:
                # 保存(测试集)中的图片
                data_z.append([])
                data_z[-1].append(image)
            # 将图片转化为灰度图
            gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
            h, w = gray.shape[:2]
            f = 600 / min(h, w)
            gray = cv.resize(gray, None, fx=f, fy=f)
            # 提取灰度图的关键点特征值
            star = cv.xfeatures2d.StarDetector_create()
            keypoints = star.detect(gray)
            sift = cv.xfeatures2d.SIFT_create()
            _, desc = sift.compute(gray, keypoints)
            if len(descs) == 0:
                descs = desc
                # print(descs)
            else:
                descs = np.append(descs, desc, axis=0)
                # print(descs)
            if flags:
                # 测试集按图片进行特征值收集
                data_x.append(descs)
                data_y.append(label)
        if not flags:
            # 训练集按类别进行特征值收集
            data_x.append(descs)
            data_y.append(label)
    return data_x, data_y, data_z
4、模型的创建和预测
# 训练模型函数,hmm模型
def model_train(data_x, data_y):
    models = {}
    for descs, label in zip(data_x, data_y):
        model = hl.GaussianHMM(
            n_components=4, covariance_type='diag',
            n_iter=1000) # 提取4个主要特征,训练上限为1000轮
        models[label] = model.fit(descs)
    return models

# 定义利用图像识别进行模型预测的函数
def model_pred(test_x, models):
    pred_test_y = []
    for descs in test_x:
        # for desc in descs:
        # 定义最优得分和预测标签
        best_score, best_label = None, None
        for label, model in models.items():
            score = model.score(descs)
            # 选择则有得分的预测标签保存,作为预测值
            if not best_score or (
                    best_score < score):
                best_score, best_label = score, label
        pred_test_y.append(best_label)
    return pred_test_y
4、图片可视化
  • 将测试集和预测结果进行可视化,观察预测效果
# 可视化识别的图片
def show_pics(test_y, pred_test_y, test_z):
    i = 0
    for label, pred_label, images in zip(
            test_y, pred_test_y, test_z):
        for image in images:
            i += 1
            cv.imshow('{} - {} {} {}'.format(
                i, label,
                '==' if label == pred_label
                else '!=', pred_label), image)
5、模型执行
# 给定训练集、测试集路径地址
train_path = 'train'
test_path = 'test'
# 收集训练集、测试集的jpg文件
train_files = search_objects(train_path)
test_files = search_objects(test_path)
# 提取训练集、测试集图片文件关键点特征值
# 通过flags赋值区分测试集和训练集
train_x, train_y, _ = label_desc02(train_files)
test_x, test_y, test_z = label_desc02(test_files, flags=1)
# 观察测试集真实类别和预测类别列表
print(test_y)
print(pred_test_y)

测试集真实与预测类别列表
真实与预测值

models = model_train(train_x, train_y)
# 利用模型进行测试集预测
pred_test_y = model_pred(test_x, models)
# 将预测结果与真实结果进行图片可视化
show_pics(test_y, pred_test_y, test_z)
# 设置键盘阻塞,保留图片
cv.waitKey()

测试集预测结果如下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

四、模型评估

  • 由预测结果可知,8张图片类型均预测正确。即使进行多次实验,模型仍具有较好的预测精度。
  • 该模型可以作为四类水果的简单预测模型。
  • 更加复杂准确的预测模型与上述模型具有相同的原理,可根据实际应用需求进行更新。

github地址
https://github.com/Willsgao/Personal-projects/tree/master/跟着OpenCV飞起来_kaggle水果图片识别

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值