【OpenCV-Python】教程:7-7 PCA

news2024/12/28 6:25:34

OpenCV Python PCA

【目标】

  • 利用 pca 来计算目标的方向

【理论】

Introduction to Principal Component Analysis (PCA)

PCA(主成分分析)是提取最重要特征的统计过程。

在这里插入图片描述

假设你有一组2D点,如上图所示。每个维度都对应于您感兴趣的特性。有些人可能会说,这些点是按随机顺序设置的。然而,如果你仔细观察,你会发现有一个很难忽视的线性模式(由蓝线表示)。主成分分析的关键是降维。降维是减少给定数据集的维数的过程。例如,在上述情况下,可以将点集近似为一条线,因此,将给定点的维数从2D降至1D。

此外,您还可以看到,这些点沿蓝线变化最大,超过它们沿特征1或特征2轴的变化。这意味着,如果你知道一个点沿蓝线的位置,你就比只知道它在特征1轴或特征2轴上的位置有更多关于这个点的信息。

因此,PCA允许我们找到数据变化最大的方向。事实上,在图中的点集上运行主成分分析的结果由两个被称为特征向量的向量组成,它们是数据集的主成分。

在这里插入图片描述

每个特征向量的大小被编码在相应的特征值中,并表示数据沿主成分的变化程度。特征向量的起点是数据集中所有点的中心。将PCA应用于N维数据集,得到N个N维特征向量、N个特征值和1个N维中心点。

特征向量和特征值的计算

目标是将一个给定的维度 p的数据集 X转换为一个维度更小的 l的备选数据集 Y,等价地,我们正在寻找矩阵 Y,其中 Y是矩阵 XKarhunen-Loève变换(KLT):

Y = K L T { X } Y=\mathbb{KLT}\{X\} Y=KLT{X}

组织数据

假设你有一组包含 p个变量的观察数据,你想要缩减数据,以便每个观察结果都可以用 L 个变量来描述,L < p。进一步假设,一组 n 个数据向量 x 1 … x n x_1…x_n x1xn, 其中每个 x i x_i xi 表示的就是一个单独的 p 个变量的一个数据。

  • x 1 . . . x n x_1...x_n x1...xn 为行向量,每个有 p p p
  • 将所有行向量放到矩阵 X X X里,构建一个矩阵 X X X, 维度为 n × p n×p n×p

计算经验平均值

  • 沿着维度 j = 1 , . . . , p j=1,...,p j=1,...,p,计算经验均值
  • 将计算出的平均值放入维度为 p × 1 p×1 p×1的经验平均向量 u u u中。

u [ j ] = 1 n ∑ i = 1 n X [ i , j ] u[j] = \frac{1}{n}\sum_{i=1}^n X[i,j] u[j]=n1i=1nX[i,j]

计算均值的偏差

均值减法是寻找主成分基的解决方案的一个组成部分,使接近数据的均方误差最小化。因此,我们将数据居中,如下所示:

  • 从数据矩阵 X X X的每一行中减去经验平均向量 u u u
  • 将偏差数据存入矩阵 B B B 中,

B = X − h u T B = X-hu^T B=XhuT

其中 h h h为 全 1 n × 1 n×1 n×1 向量,即

h [ i ] = 1 , i = 1 , . . . , n h[i]=1, i=1,...,n h[i]=1,i=1,...,n

求协方差矩阵

  • 找到 p × p p×p p×p 经验协方差矩阵 C C C

C = 1 n − 1 B ∗ ⋅ B C=\frac{1}{n-1}B^* \cdot B C=n11BB

其中 ∗ * 是共轭转置算子。请注意,如果B完全由实数组成,这是在许多应用中的情况,“共轭转置”与常规转置相同。

找出协方差矩阵的特征向量和特征值

  • 计算特征向量的矩阵V,它对角化协方差矩阵C:

V − 1 C V = D V^{-1}CV = D V1CV=D

其中 D D D C C C 特征值的对角化矩阵。

  • 矩阵 D D D将采用 p × p p×p p×p对角矩阵的形式:

D [ k , l ] = { λ k ,   k = l 0 , k ≠ l D[k,l]=\begin{cases} \lambda_k,&\, k=l \\ 0,&k\not =l \end{cases} D[k,l]={λk,0,k=lk=l

其中, λ j \lambda_j λj 是 协方差矩阵 C C C j j j 个特征值

  • 矩阵 V V V,同样是 p × p p × p p×p的,包含 p p p个列向量,每个列向量的长度都是 p p p,它们表示协方差矩阵 C C C p p p个特征向量。
  • 特征值和特征向量是有序配对的。第 j j j个特征值对应于第 j j j个特征向量。

【代码】

在这里插入图片描述

在这里插入图片描述

import cv2
import numpy as np
import argparse
from math import atan2, cos, sin, sqrt, pi


def drawAxis(img, p_, q_, colour, scale):
    p = list(p_)
    q = list(q_)

    angle = atan2(p[1] - q[1], p[0] - q[0])  # angle in radians
    hypotenuse = sqrt((p[1] - q[1]) * (p[1] - q[1]) +
                      (p[0] - q[0]) * (p[0] - q[0]))
  
    # 
    q[0] = p[0] - scale * hypotenuse * cos(angle)
    q[1] = p[1] - scale * hypotenuse * sin(angle)
    cv2.line(img, (int(p[0]), int(p[1])),
            (int(q[0]), int(q[1])), colour, 1, cv2.LINE_AA)
  
    # 创建箭头钩
    p[0] = q[0] + 9 * cos(angle + pi / 4)
    p[1] = q[1] + 9 * sin(angle + pi / 4)
    cv2.line(img, (int(p[0]), int(p[1])),
            (int(q[0]), int(q[1])), colour, 1, cv2.LINE_AA)
    p[0] = q[0] + 9 * cos(angle - pi / 4)
    p[1] = q[1] + 9 * sin(angle - pi / 4)
    cv2.line(img, (int(p[0]), int(p[1])),
            (int(q[0]), int(q[1])), colour, 1, cv2.LINE_AA)


def getOrientation(pts, img):
    sz = len(pts)
    data_pts = np.empty((sz, 2), dtype=np.float64)
    for i in range(data_pts.shape[0]):
        data_pts[i, 0] = pts[i, 0, 0]
        data_pts[i, 1] = pts[i, 0, 1]
  
    # 执行 PCA 分析
    mean = np.empty((0))
    mean, eigenvectors, eigenvalues = cv2.PCACompute2(data_pts, mean)
  
    # 存储物体的中心
    cntr = (int(mean[0, 0]), int(mean[0, 1]))

    cv2.circle(img, cntr, 3, (255, 0, 255), 2)
    p1 = (cntr[0] + 0.02 * eigenvectors[0, 0] * eigenvalues[0, 0],
          cntr[1] + 0.02 * eigenvectors[0, 1] * eigenvalues[0, 0])
    p2 = (cntr[0] - 0.02 * eigenvectors[1, 0] * eigenvalues[1, 0],
          cntr[1] - 0.02 * eigenvectors[1, 1] * eigenvalues[1, 0])
    drawAxis(img, cntr, p1, (0, 255, 0), 1)
    drawAxis(img, cntr, p2, (255, 255, 0), 5)
    # orientation in radians
    angle = atan2(eigenvectors[0, 1], eigenvectors[0, 0])

    return angle


imname = "assets/pca_test2.jpg"
src = cv2.imread(imname)
# Check if image is loaded successfully
if src is None:
    print('Could not open or find the image: ', imname)
    exit(0)
# cv2.imshow('src', src)

# 图像预处理和找轮廓
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
_, bw = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
contours, _ = cv2.findContours(bw, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)

for i, c in enumerate(contours):
    # 计算每个轮廓的面积
    area = cv2.contourArea(c)
  
    # 忽略太小和太大的轮廓
    if area < 1e2 or 1e5 < area:
        continue
  
    # 画每一个轮廓
    cv2.drawContours(src, contours, i, (0, 0, 255), 2)
  
    # 找到每一个形状的方向
    getOrientation(c, src)

cv2.imshow('output', src)
cv2.waitKey()
cv2.destroyAllWindows()

【接口】

  • PCACompute
cv2.PCACompute(	data, mean[, eigenvectors[, maxComponents]]	) ->	mean, eigenvectors
cv2.PCACompute(	data, mean, retainedVariance[, eigenvectors]	) ->	mean, eigenvectors
cv2.PCACompute2(	data, mean[, eigenvectors[, eigenvalues[, maxComponents]]]	) ->	mean, eigenvectors, eigenvalues
cv2.PCACompute2(	data, mean, retainedVariance[, eigenvectors[, eigenvalues]]	) ->	mean, eigenvectors, eigenvalues

wrap PCA::operator() , performs PCA

  • data: 输入的数据
  • mean: 均值,
  • eigenvectors: 特征向量
  • eigenvalues: 特征值
  • maxComponents: 最多主成分数量, 默认就是所有的主成分
  • retainedVariance: 主成分分析应保留的方差百分比。使用此参数将让PCA决定保留多少个组件,但它总是至少保留2个

【参考】

  1. Introduction to Principal Component Analysis (PCA)
  2. https://robospace.wordpress.com/2013/10/09/object-orientation-principal-component-analysis-opencv/
  3. sources [1], [2] and special thanks to Svetlin Penkov for the original tutorial.
  4. cv::PCA Class Reference
  5. OpenCV: Operations on arrays

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/114821.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Blender——苹果的材质绘制

效果图 前言 在进行纹材质的绘制之前&#xff0c;首先要具有苹果的三维模型和进行苹果纹理绘制。 关于苹果的建模请参考&#xff1a;Blender——“苹果”建模_行秋的博客 关于苹果的纹理绘制请参考&#xff1a;Blender——苹果纹理绘制_行秋的博客 书接上回&#xff0c;由Te…

FMOC-PEG-acid,FMOC-PEG-COOH,芴甲氧羰基PEG羧基用于探究新型材料

用于探究新型材料的化学试剂芴甲氧羰基-聚乙二醇-羧基&#xff0c; 其英文名为FMOC-PEG-acid&#xff08;FMOC-PEG-COOH&#xff09;&#xff0c;它所属分类为Boc/Fmoc protected amine PEG Carboxylic acid PEG。 芴甲氧羰基peg羧基试剂的分子量均可定制&#xff0c;有&#…

使用nginx实现自定义大小预览缩略图,http_image_filter模块的安装使用

使用nginx实现自定义大小预览缩略图&#xff0c;http_image_filter模块的安装使用注意事项服务器配置方法安装模块备份http_image_filter模块用以调用配置文件调整引入模块修改配置文件设置访问入口随后重启nginx服务访问请求测试注意事项 本预览图功能使用的是nginx的http_im…

哦,原来事务传播是这样

引言 ​ 在介绍正文之前&#xff0c;让我们先一起来看下这段代码&#xff1a; Transactionalpublic void createProduct(Long skuId, Integer number, Long operatorUcid) {// 插入商品信息recordProduct(skuId, number);// 插入商品操作记录日志recordProductOperateLogClass…

关于操作数组元素的实际应用

sort()升序、降序排序方法应用 sort()排序方式原理&#xff1a;当sort()传入函数中的第一个参数a位于第二个参数b之前&#xff0c;则返回一个负数&#xff0c;相等则返回0&#xff0c;a位于b之后则返回正数。 比如&#xff0c;当要做升序排序时&#xff0c;我们需要想到前面的…

【SpringMVC】常用注解

1.RequestParam 1.1 使用说明 作用: 把请求中指定名称的参数给控制器中的形参赋值 属性&#xff1a; ​ **value&#xff1a;**请求参数中的名称 ​ **required&#xff1a;**请求参数是否必须提供此参数。默认值&#xff1a;true&#xff0c;表示必须提供&#xff0c;如果…

Linux下tree命令C/C++实现(以树状格式列出目录的内容)

在UNIX/LINUX系统中&#xff0c;tree是一个递归目录列表程序&#xff0c;它生成文件的深度缩进列表。在没有参数的情况下&#xff0c;树将列出当前目录中的文件。当给定目录参数时&#xff0c;树依次列出在给定目录中找到的所有文件或目录。列出找到的所有文件和目录后&#xf…

机器学习从零到入门 逻辑回归详解

逻辑回归详解 从零开始 从理论到实践一、逻辑回归的理解1.1、字面含义1.2、引申1.2.1、阶跃函数的引入1.2.2、可导的阶跃函数 - Logistic函数1.2.3、Logistic回归1.2.4、回归系数的求解 - 极大似然估计二、sklearn的使用参考一、逻辑回归的理解 前面介绍了线性回归及其衍生回归…

目标检测之YOLOv4算法分析

基本原理 网络结构 CSPDarknet53 最后三个箭头指向输出即三种特征图 SPP 解决多尺度问题 对于同一个特征输出图&#xff0c;进行三种maxpool2d操作&#xff0c;然后将三种操作的输出进行叠加 PANet 融合上采样、下采样等特征&#xff0c;深度方向拼接 PANet由五个核心模…

Unity 3D工具栏与常用工具||Unity 3D 菜单栏与快捷键

Unity 3D 的工具栏&#xff08; Toolbar &#xff09;中&#xff0c;一共包含 13 种常用工具&#xff0c;如下所列。 一. 平移窗口工具&#xff1a;平移场景视图画面。 快捷键&#xff1a;鼠标中键 二. 位移工具&#xff1a;针对单个或两个轴向做位移。 快捷键&#xff1a;W…

stm32f407VET6 系统学习 day04 DHT11 温湿度传感器

1.温湿度的一次完整的数据包括&#xff1a; 一次完整的数据传输为40bit,高位先出。 数据格式: 8bit湿度整数数据 8bit湿度小数数据 8bi温度整数数据 8bit温度小数数据 8bit校验&#xff08;校验和的值是前四个字节数据的和) 用户MCU发送一次开始信号后,DHT11从低功耗模式转…

灰色关联分析(系统分析+综合评价)

系统分析&#xff1a;探究系统中哪个自变量对系统的影响最大 灰色关联分析的基本思想是根据序列曲线几何形状的相似程度来判断其联系是否紧密。曲线越接近&#xff0c;相应序列之间的关联度就越大&#xff0c;反之就越小 应用一、进行系统分析&#xff08;国内比赛合适&#xf…

idea创建spring项目

文章目录一、Maven 项目的创建1.1 创建一个空项目2.2 新建一个模块2.3 创建Maven模块2.4 添加resources目录2.5 选定maven版本二、添加spring2.1 添加依赖2.2 创建applicationContext文件2.3 添加bean一、Maven 项目的创建 1.1 创建一个空项目 新建一个空项目&#xff1b;随便…

十、Express 路由

路由是Express框架中最重要的功能之一&#xff0c;在Express中&#xff0c;路由指的是客户端的请求与服务器处理函数之间的映射关系&#xff0c;Express中的路由分别由请求的类型&#xff08;GET/POST等&#xff09;、请求的URL地址和处理函数三个部分组成的&#xff1b; APP级…

【C++】侯捷C++面向对象高级编程(下)

转换函数(conversion function) 可以把"这种"东西&#xff0c;转化为"别种"东西。 即Fraction ——> double class Fraction { public:Fraction(int num, int den 1) :m_numerator(num), m_denominator(den) {}operator double()const {return ((dou…

hashmap哈希map是什么?什么时候需要使用hashmap?C实现hashmap示例

背景 对于C程序员&#xff0c;尤其是嵌入式C程序员&#xff0c;hashmap使用的相对较少&#xff0c;所以会略显陌生&#xff0c;hashmap其实涉及到2个概念&#xff0c;分别是哈希(hash)、map。 哈希hash&#xff1a;是把任意长度输入通过蓝列算法变换成固定长度的输出&#xff…

CSS Flex 布局的 flex-direction 属性讲解

flex-direction 设置了主轴&#xff0c;从而定义了弹性项目放置在弹性容器中的方向。 Flexbox 是一种单向布局概念&#xff0c;可将弹性项目视为主要以水平行或垂直列布局。 .container {flex-direction: row | row-reverse | column | column-reverse; }几种支持的属性&#x…

devServer和VueCli | Webpack

文章目录devServer和VueCliwebpack-dev-servercontentBase模块热替换开启HMRhotOnly host配置port open compressproxyresolveextensions和alias配置如何区分开发环境devServer和VueCli webpack-dev-server contentBase 模块热替换 开启HMR hotOnly host配置 port open compres…

IMX6ULL学习笔记(15)——GPIO接口使用【官方SDK方式】

一、GPIO简介 i.MX6ULL 芯片的 GPIO 被分成 5 组,并且每组 GPIO 的数量不尽相同&#xff0c;例如 GPIO1 拥有 32 个引脚&#xff0c; GPIO2 拥有 22 个引脚&#xff0c; 其他 GPIO 分组的数量以及每个 GPIO 的功能请参考 《i.MX 6UltraLite Applications Processor Reference M…

有没有股票实时行情的同花顺l2接口?

对于个人投资者而言&#xff0c;一般看盘平台软件系统中&#xff0c;通过自定义公式接口&#xff0c;可以获取到股票实时行情的。例如同花顺l2接口系统会通过一些输入的公式就能查找指定的股票行情了&#xff0c;那么这个就相当于股票实时行情的API接口一样的道理&#xff0c;输…