当前位置: 首页 > news >正文

OpenCV计算机视觉实战(26)——OpenCV与机器学习

OpenCV计算机视觉实战(26)——OpenCV与机器学习

    • 0. 前言
    • 1. K-Means 色彩量化
      • 1.1 实现过程
      • 1.2 优化思路
    • 2. SVM 图像分类
      • 2.1 实现过程
      • 2.2 优化思路
    • 3. 决策树数字识别
      • 3.1 实现过程
      • 3.2 优化思路
    • 小结
    • 系列链接

0. 前言

在计算机视觉领域中,传统机器学习算法依然扮演着不可替代的角色,尤其在中小型图像任务、资源受限设备或解释性分析场景中。与深度学习相比,这些方法具备更强的可控性和更低的计算开销。本文从三个经典应用切入,介绍图像处理中的机器学习技术:利用 K-Means 实现色彩量化压缩图像冗余,借助 SVM 完成图像分类并借助混淆矩阵进行误差分析,最后通过决策树实现手写数字识别并可视化模型决策依据。

1. K-Means 色彩量化

使用 K-Means 聚类,将一幅彩色图像中相似颜色合并为少量“代表色”,既可用于图像压缩,也能作为后续分割与风格化的预处理。

1.1 实现过程

  • 图像读取与预处理
    • cv2.imread 加载彩色图像,得到 h × w × 3 的数组
    • 将其重塑为 (h x w) × 3 的二维数据,为聚类准备
  • K-Means 聚类
    • 创建 KMeans(n_clusters=8) 对象,fit_predict 同时训练与分配每个像素的簇标签
    • 聚类中心 cluster_centers_ 即为 8 种“代表色”
  • 重建量化图像
    • 用每个像素的标签索引 palette,重构回原始分辨率
    • 使用 astype(np.uint8) 确保颜色格式正确
  • 可视化对比
    • 原图与量化图并排显示,直观体会颜色压缩效果
import cv2
import numpy as np
from sklearn.cluster import KMeans# 1. 读取图像并准备数据
img = cv2.imread('1.jpeg')
h, w = img.shape[:2]
pixels = img.reshape(-1, 3)  # N×3 的像素矩阵# 2. 用 K-Means 聚为 8 类颜色
n_colors = 8
kmeans = KMeans(n_clusters=n_colors)
labels = kmeans.fit_predict(pixels)
palette = kmeans.cluster_centers_.astype(np.uint8)# 3. 重建量化图像
quantized = palette[labels].reshape(h, w, 3)# 4. 显示
cv2.imshow('Original', img)
cv2.imshow('Quantized', quantized)
cv2.waitKey(0)
cv2.destroyAllWindows()

色彩量化

关键函数解析:

  • KMeans(n_clusters):创建聚类器,n_clusters 控制量化色数
  • fit_predict(X):在 X (样本 × 特征)上执行 K-Means,返回每个样本的簇索引
  • cluster_centers_:训练完成后每个簇的中心坐标,对应量化后的颜色
  • reshape:在聚类前后做数组形状变换,以适应 OpenCVscikit-learn 接口

1.2 优化思路

  • Elbow 方法自动选 K
    先计算不同 K 下的 簇内平方和 (inertia_),绘制折线图寻找“肘点”自动决定最优 K
  • 颜色调色板可视化
    将聚类中心绘制成条形色块,直观呈现量化后调色效果
  • 加速聚类
    对大分辨率图像可先随机抽样 10% 像素做聚类,再将中心应用于所有像素以加快速度
# Elbow 方法找最优 K
inertias = []
Ks = list(range(2,11))
for k in Ks:km = KMeans(n_clusters=k).fit(pixels[np.random.choice(len(pixels), len(pixels)//10)])inertias.append(km.inertia_)
plt.plot(Ks, inertias, '-o')
plt.title('Elbow Method')
plt.xlabel('K')
plt.ylabel('Inertia')
plt.show()# 色板可视化
swatch = np.zeros((50, 50*n_colors, 3), dtype=np.uint8)
for i, color in enumerate(palette):swatch[:, i*50:(i+1)*50] = color
plt.imshow(cv2.cvtColor(swatch, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.show()

关键函数解析:

  • km.inertia_KMeans 聚类后的簇内平方和,用于评估聚类质量
  • np.random.choice(..., size):随机抽样,加速大规模数据聚类

2. SVM 图像分类

使用支持向量机 (Support Vector Machine, SVM) 对手写数字图像进行分类,以 scikit-learn 自带的 digits 数据集为例,演示如何加载数据、训练线性 SVM 并评估分类效果。

2.1 实现过程

  • 加载与理解数据
    • load_digits() 提供 17978×8 灰度手写数字图像
    • data(1797,64),每行是展开后的像素向量
  • 训练/测试集划分
    • train_test_split70 / 30 划分,保证评估的泛化性
  • SVM 模型训练
    • SVC(kernel='linear', C=1.0) 表示线性核,C 控制软间隔大小
    • fit 方法完成训练
  • 评估与可视化
    • classification_report 输出精度、召回率与 F1-score
    • 随机挑选几张测试图,用 Matplotlib 显示预测与真值对比
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm, metrics
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split# 1. 加载数据集
digits = load_digits()
X = digits.data            # 样本×64(8×8)
y = digits.target# 2. 划分训练/测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)# 3. 创建并训练线性 SVM
clf = svm.SVC(kernel='linear', C=1.0)
clf.fit(X_train, y_train)# 4. 在测试集上预测并评估
y_pred = clf.predict(X_test)
print(metrics.classification_report(y_test, y_pred))# 5. 显示部分预测结果
fig, axes = plt.subplots(2, 5, figsize=(8,4))
for ax, img, true, pred in zip(axes.ravel(),X_test.reshape(-1,8,8),y_test, y_pred):ax.imshow(img, cmap=plt.cm.gray_r)ax.set_title(f'T:{true} P:{pred}')ax.axis('off')
plt.show()

手写数字识别

关键函数解析:

  • svm.SVC(kernel, C):创建支持向量机分类器
  • fit(X, y) / predict(X):分别执行训练和预测
  • metrics.classification_report():输出详细分类性能指标

2.2 优化思路

  • Grid Search 交叉验证
    GridSearchCVCkernelgamma 上网格搜索,自动选出最优参数组合
  • 混淆矩阵热力图
    评估分类器在各类上的表现,用 seaborn 绘制混淆矩阵热力图
  • 标准化预处理
    对像素特征先做 StandardScaler 标准化,再输入 SVM,能加速收敛并提升性能
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import svm, metrics
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler# 1. 加载并标准化
digits = load_digits()
X, y = digits.data, digits.target
sc = StandardScaler().fit(X)
X = sc.transform(X)X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)# 2. Grid Search
param_grid = {'C': [0.1,1,10],'kernel': ['linear','rbf'],'gamma': ['scale','auto']
}
grid = GridSearchCV(svm.SVC(), param_grid, cv=5)
grid.fit(X_train, y_train)
print("Best params:", grid.best_params_)# 3. 评估
y_pred = grid.predict(X_test)
cm = metrics.confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.title('Confusion Matrix'); plt.xlabel('Pred'); plt.ylabel('True'); plt.show()
print(metrics.classification_report(y_test, y_pred))

混淆矩阵

关键函数解析:

  • StandardScaler():将特征归一到零均值单位方差
  • GridSearchCV(estimator, param_grid, cv):网格搜索 + 交叉验证,自动寻找最优超参数
  • metrics.confusion_matrix() + seaborn.heatmap():生成并可视化混淆矩阵

3. 决策树数字识别

使用决策树 (Decision Tree) 对 digits 数据集进行分类,并对比 SVM 性能;展示如何设置最大深度、防止过拟合,并可视化树结构。

3.1 实现过程

  • 模型参数设定
    • max_depth=10 限制树深,防止过拟合
    • min_samples_split=5 保证每个内部节点至少有 5 个样本
  • 训练与评估
    • fit 对训练集建树
    • predict 在测试集上预测并用 classification_report 打分
  • 树结构可视化
    • plot_tree 绘制前两层,标注特征与类别,直观理解决策边界
import numpy as np
import matplotlib.pyplot as plt
from sklearn import tree, metrics
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split# 1. 加载数据
digits = load_digits()
X, y = digits.data, digits.target# 2. 划分数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)# 3. 创建并训练决策树
clf = tree.DecisionTreeClassifier(max_depth=10, min_samples_split=5)
clf.fit(X_train, y_train)# 4. 预测与评估
y_pred = clf.predict(X_test)
print(metrics.classification_report(y_test, y_pred))# 5. 可视化决策树
plt.figure(figsize=(12,8))
tree.plot_tree(clf, max_depth=2, feature_names=[f'p{i}' for i in range(64)],class_names=[str(i) for i in digits.target_names],filled=True, fontsize=6)
plt.show()

决策树

关键函数解析:

  • DecisionTreeClassifier(max_depth, min_samples_split):创建决策树分类器
  • tree.plot_tree():可视化树结构,参数 filled=True 用颜色区分节点类别
  • metrics.classification_report():对比 SVM 与决策树的性能差异

3.2 优化思路

  • 后剪枝 (Cost Complexity Pruning)
    ccp_alpha 参数找到最优剪枝系数,防止过拟合
  • 特征重要度可视化
    绘制决策树对 64 个像素特征的重要度排名,帮助理解模型决策依据
  • 与随机森林对比
    训练 RandomForestClassifier 并对比准确度与特征重要度分布
import numpy as np
import matplotlib.pyplot as plt
from sklearn import tree, metrics
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifierdigits = load_digits()
X, y = digits.data, digits.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)# 1. 决策树 + 剪枝
dt = tree.DecisionTreeClassifier(random_state=0)
path = dt.cost_complexity_pruning_path(X_train, y_train)
ccp_alphas = path.ccp_alphas
# 交叉验证找最优 alpha
clfs = []
for alpha in ccp_alphas:clf = tree.DecisionTreeClassifier(random_state=0, ccp_alpha=alpha)clf.fit(X_train, y_train)clfs.append(clf)
# 选最高测试准确度模型
scores = [clf.score(X_test, y_test) for clf in clfs]
best = clfs[np.argmax(scores)]
print("Best alpha:", best.ccp_alpha, "Accuracy:", max(scores))# 2. 特征重要度
importances = best.feature_importances_
indices = np.argsort(importances)[::-1][:10]
plt.bar(range(10), importances[indices])
plt.xticks(range(10), [f'p{idx}' for idx in indices], rotation=45)
plt.title('Top 10 Feature Importances'); plt.show()# 3. 随机森林对比
rf = RandomForestClassifier(n_estimators=100, random_state=0)
rf.fit(X_train, y_train)
print("RF Accuracy:", rf.score(X_test, y_test))

重要度可视化

关键函数解析:

  • cost_complexity_pruning_path():计算一系列 ccp_alpha 值以供剪枝
  • ccp_alpha:控制剪枝强度,越大树越小
  • feature_importances_:各特征对模型决策贡献度

小结

通过本节的学习,我们完成了从图像数据提取到机器学习模型训练与评估的完整闭环。K-Means 帮助我们理解聚类在图像色彩空间的应用;SVM 通过强大的分类边界与调参机制展示了其在图像识别中的潜力;而决策树不仅可解释性强,还通过剪枝与特征重要度揭示了模型如何“看待”图像。

系列链接

OpenCV计算机视觉实战(1)——计算机视觉简介
OpenCV计算机视觉实战(2)——环境搭建与OpenCV简介
OpenCV计算机视觉实战(3)——计算机图像处理基础
OpenCV计算机视觉实战(4)——计算机视觉核心技术全解析
OpenCV计算机视觉实战(5)——图像基础操作全解析
OpenCV计算机视觉实战(6)——经典计算机视觉算法
OpenCV计算机视觉实战(7)——色彩空间详解
OpenCV计算机视觉实战(8)——图像滤波详解
OpenCV计算机视觉实战(9)——阈值化技术详解
OpenCV计算机视觉实战(10)——形态学操作详解
OpenCV计算机视觉实战(11)——边缘检测详解
OpenCV计算机视觉实战(12)——图像金字塔与特征缩放
OpenCV计算机视觉实战(13)——轮廓检测详解
OpenCV计算机视觉实战(14)——直方图均衡化
OpenCV计算机视觉实战(15)——霍夫变换详解
OpenCV计算机视觉实战(16)——图像分割技术
OpenCV计算机视觉实战(17)——特征点检测详解
OpenCV计算机视觉实战(18)——视频处理详解
OpenCV计算机视觉实战(19)——特征描述符详解
OpenCV计算机视觉实战(20)——光流法运动分析
OpenCV计算机视觉实战(21)——模板匹配详解
OpenCV计算机视觉实战(22)——图像拼接详解
OpenCV计算机视觉实战(23)——目标检测详解
OpenCV计算机视觉实战(24)——目标追踪算法
OpenCV计算机视觉实战(25)——立体视觉详解

http://www.dtcms.com/a/478210.html

相关文章:

  • ACE会成为下一代上下文工程技术吗?
  • GitHub 热榜项目 - 日榜(2025-10-13)
  • 网站首页关键如何优化网络促销的方法有哪些
  • CTFSHOW WEB 2
  • 学术研究者的AI记录工具对比评测
  • mianf网站换友网站
  • 旧电脑变废为宝:Puter+cpolar打造你的专属云盘
  • springboot考试管理系统-计算机毕业设计源码84001
  • 手写MyBatis第106弹:#{}预编译安全机制 vs ${}字符串替换风险 - 源码级深度解析
  • 【Pytorch】数学运算
  • 金泉网站建设开发手机网站开发注意
  • 当Excel遇上大语言模型:ExcelAgentTemplate架构深度剖析与实战指南
  • 新农村建设在哪个网站申请vi设计包含的内容
  • 达梦数据库相关术语及管理操作
  • 百度网站推广公司济南网络优化推广
  • 【SpringBoot从初学者到专家的成长14】SpringBoot项目结构介绍
  • mongodb一个服务器部署多个节点
  • 基金网站制作工程承包公司
  • 成都企业网站建设价格搜索引擎收录
  • 第9章:两条道路的风景:技术与管理的真实世界(4)
  • 基于frenet坐标系的规划与避障
  • 从本地到云端:Fiora+cpolar打造真正的私密社交通讯站
  • Vue Router 导航守卫
  • 技术评测丨RPA主流平台稳定性、安全与信创适配能力对比
  • 简约淘宝网站模板免费下载建立 wiki 网站
  • 【Unity】uNet游戏服务端框架(三)心跳机制
  • 二叉树的深搜
  • C++设计模式之行为型模式:模板方法模式(Template Method)
  • 做3dh春丽网站叫什么重庆十大软件公司
  • 长沙电商网站开发php开发网站后台