『youcans 的 OpenCV 例程200篇 - 总目录』

【youcans 的 OpenCV 例程 300篇】237. 基于主成分提取的方向校正(OpenCV)

主成分分析(Principal Components Analysis,PCA)是一种基于统计的数据降维方法,又称主元素分析、主分量分析。主成分分析只需要特征值分解,就可以对数据进行压缩、去噪,应用非常广泛。

主成分分析方法得到的主成分变量具有几个特点:(1)每个主成分变量都是原始变量的线性组合;(2)主成分的数目大大少于原始变量的数目;(3)主成分保留了原始变量的绝大多数信息;(4)各主成分变量之间彼此相互独立。

5.4 OpenCV 的主成分分析方法

OpenCV 中提供了主成分分析(Principal Components Analysis,PCA)方法的实现,即 cv::PCA 类。类的声明在 include/opencv2/core.hpp 文件中,类的实现在 modules/core/src/pca.cpp 文件中。

  • 成员函数:

    • PCA::PCA:默认构造并初始化一个空的 PCA 结构
    • PCA::backproject:将数据从 PCA 空间投影回原始空间,重建原始数据
    • PCA::operator():对提供的数据执行主成分分析操作
    • PCA::project:将输入数据投影到 PCA 特征空间;
    • PCA::read:从指定文件读入特征值、特征向量和均值;
    • PCA::write:向指定文件写入特征值、特征向量和均值;
  • 属性:
    • PCA::eigenvalues:协方差矩阵的特征值
    • PCA::eigenvectors:协方差矩阵的特征向量
    • PCA::mean:均值,投影前减去均值,投影后加上均值

PCA 类使用 Karhunen-Loeve 变换,由协方差矩阵的特征向量计算得到一组向量的正交基。

在 Python 语言中,OpenCV 提供了 PCA 类的接口函数 cv.PCACompute()cv.PCAProject()cv.PCABackProject()

函数说明:

cv.PCACompute(data, mean[, eigenvectors=None, maxComponents=0]) → mean, eigenvectors
cv.PCACompute(data, mean, retainedVariance[, eigenvectors=None]) → mean, eigenvectors
cv.PCACompute2(data, mean[, eigenvectors=None, eigenvalues=None, maxComponents=0]) → mean, eigenvectors, eigenvalues
cv.PCACompute2(data, mean, retainedVariance[, eigenvectors=None, eigenvalues=None]) → mean, eigenvectors, eigenvaluescv.PCAProject(data, mean, eigenvectors[, result=None]) → result
cv.PCABackProject(data, mean, eigenvectors[, result=None]) → result

函数 cv.PCACompute 是 PCA::operator 的接口,用于对提供的数据执行主成分分析操作,返回均值、特征向量和特征值。

函数 **cv.PCAProject ** 是 PCA::project 的接口,用于将输入数据按选择的特征向量投影到 PCA 特征空间。

函数 cv.PCABackProject 是 PCA::backproject 的接口,用于将输入数据按选择的特征向量投影从 PCA 空间投影回原始空间,重建原始数据。

参数说明:

  • data:输入数据矩阵,对于 cv.PCACompute 和 PCAProject 是 m×P 原始数据矩阵,对于 PCABackProject 是 m×K 降维数据矩阵 (K≤P)(K \le P)(K≤P)

  • mean:均值,形状为 (1,P),如果该参数的输入为空,则通过输入数据计算均值

  • maxComponents:保留主成分的个数,默认为保留全部主成份

  • retainedVariance:保留的累计方差的百分比,据此确定保留主成分的个数(至少保留 2个主成分)

  • eigenvectors:特征向量,全部特征向量的形状为 (P,P),前 K 个特征向量的形状为 (K,P)

  • eigenvalues:特征值,全部特征向量的形状为 (P,1),前 K 个特征向量的形状为 (K,1)

例程 14.18:特征描述之PCA 方向校正

特征描述应尽可能独立于大小、平移和旋转的变化。使用主成分分析方法,可以对目标进行归一化边界/区域,获得目标的主要方向。

本例对于二维图像,通过 PCA 方法对目标进行方向校正。

(1)通过主成分分析(PCA)获得目标的主方向,将数据投影到主方向及其垂直方向上。

(2)计算目标的均值,第一主方向的角度。

(3) 以目标的均值作为质心(旋转中心),按主方向角度旋转原始图像,得到归一化的目标图像。

    # 14.18 基于 PCA 的方向矫正 (OpenCV)img = cv2.imread("../images/airplane01.png", flags=1)height, width = img.shape[:2]  # 512 512print(height, width)# src = cv2.resize(img, (300, 300))gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)_, binary = cv2.threshold(gray, 205, 255, cv2.THRESH_BINARY_INV)# 寻找二值化图中的轮廓,检索所有轮廓,输出轮廓的每个像素点contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)  # OpenCV4~fullCnts = np.zeros(img.shape[:2], np.uint8)  # 绘制轮廓函数会修改原始图像fullCnts = cv2.drawContours(fullCnts, contours, -1, (255, 255, 255), thickness=3)  # 绘制全部轮廓# 按轮廓的面积排序,绘制面积最大的轮廓cnts = sorted(contours, key=cv2.contourArea, reverse=True)  # 所有轮廓按面积排序cnt = cnts[0]  # 第 0 个轮廓,面积最大的轮廓,(1445, 1, 2)maxCnt = np.zeros(img.shape[:2], np.uint8)  # 初始化最大轮廓图像cv2.drawContours(maxCnt, cnts[0], -1, (255, 255, 255), thickness=3)  # 仅绘制最大轮廓 cntprint("len(contours) =", len(contours))  # contours 所有轮廓的数量print("area of max contour: ", cv2.contourArea(cnt))  # 轮廓面积print("perimeter of max contour: {:.1f}".format(cv2.arcLength(cnt, True)))  # 轮廓周长# 主成分分析方法提取目标的方向markedCnt = maxCnt.copy()ptsXY = np.squeeze(cnt).astype(np.float64)  # 删除维度为1的数组维度,(1445, 1, 2)->(1445, 2)mean, eigenvectors, eigenvalues = cv2.PCACompute2(ptsXY, np.array([]))  # (1, 2) (2, 2) (2, 1)print("mean:{}, eigenvalues:{}".format(mean.round(1), eigenvalues[:,0].round(2)))# 绘制第一、第二主成分方向轴center = mean[0, :].astype(int)  # 近似作为目标的中心 [266 281]e1xy = eigenvectors[0,:] * eigenvalues[0,0]  # 第一主方向轴e2xy = eigenvectors[1,:] * eigenvalues[1,0]  # 第二主方向轴p1 = (center + 0.01*e1xy).astype(np.int)  # P1:[149 403]p2 = (center + 0.01*e2xy).astype(np.int)  # P2:[320 332]theta = np.arctan2(eigenvectors[0,1], eigenvectors[0,0]) * 180/np.pi  # 第一主方向角度 133.6cv2.circle(markedCnt, center, 6, 255, -1)  # 在PCA中心位置画一个圆圈  RGBcv2.arrowedLine(markedCnt, center, p1, (255, 0, 0), thickness=3, tipLength=0.1)  # 从 center 指向 pt1cv2.arrowedLine(markedCnt, center, p2, (255, 0, 0), thickness=3, tipLength=0.2)  # 从 center 指向 pt2print("center:{}, P1:{}, P2:{}".format(center, p1, p2))# 根据主方向角度和中心旋转原始图像alignCnt = img.copy()cv2.circle(alignCnt, center, 8, (255,255,255), 2)  # 在PCA中心位置画一个圆圈  BGRcv2.arrowedLine(alignCnt, center, p1, (0,0,255), thickness=3, tipLength=0.1)  # 从 center 指向 pt1cv2.arrowedLine(alignCnt, center, p2, (0,255,0), thickness=3, tipLength=0.2)  # 从 center 指向 pt2x0, y0 = int(center[0]), int(center[1])print("x0={}, y0={}, theta={:.1f}(deg)".format(x0, y0, theta))MAR1 = cv2.getRotationMatrix2D((x0,y0), theta, 1)alignCnt = cv2.warpAffine(alignCnt, MAR1, alignCnt.shape[:2], borderValue=(255,255,255))  # 白色填充# 显示图像plt.figure(figsize=(9, 6))plt.subplot(231), plt.axis('off'), plt.title("Origin")plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))plt.subplot(232), plt.axis('off'), plt.title("Binary")plt.imshow(binary, 'gray')plt.subplot(233), plt.axis('off'), plt.title("Contour")plt.imshow(fullCnts, 'gray')plt.subplot(234), plt.axis('off'), plt.title("Max contour")plt.imshow(maxCnt, 'gray')plt.subplot(235), plt.axis('off'), plt.title("Marked contour")plt.imshow(markedCnt, 'gray')plt.subplot(236), plt.axis('off'), plt.title("Alignment image")plt.imshow(cv2.cvtColor(alignCnt, cv2.COLOR_BGR2RGB))plt.tight_layout()

运行结果:

512 512
len(contours) = 42
area of max contour: 63499.5
perimeter of max contour: 1725.4
mean:[[266.2 281.6]], eigenvalues:[16866.21 7533.31]
center:[266 281], P1:[149 403], P2:[320 332]
x0=266, y0=281, theta=133.6(deg)

【本节完】

版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/125782405)
Copyright 2022 youcans, XUPT
Crated:2022-7-15

234. 特征提取之主成分分析(PCA)
235. 特征提取之主成分分析(sklearn)
236. 特征提取之主成分分析(OpenCV)
237. 基于主成分提取的方向校正(OpenCV.PCA)

【OpenCV 例程 300篇】237. 基于主成分提取的方向校正(OpenCV)相关推荐

  1. 【OpenCV 例程 300篇】224. 特征提取之提取骨架

    OpenCV 例程200篇 总目录 [youcans 的 OpenCV 例程 300篇]224. 特征提取之提取骨架 目标特征的基本概念 通过图像分割获得多个区域,得到区域内的像素集合或区域边界像素集 ...

  2. 【youcans的OpenCV例程300篇】总目录

    版权声明: 转载本系列作品时必须标注以下版权内容: [youcans@qq.com, youcans的OpenCV 例程300篇, https://blog.csdn.net/youcans/cate ...

  3. 【OpenCV 例程300篇】214. 绘制椭圆的参数详解

    OpenCV 例程200篇 总目录 [youcans 的 OpenCV 例程300篇]214. 绘制椭圆的参数详解 OpenCV提供了绘图功能,可以在图像上绘制直线.矩形.圆.椭圆等各种几何图形. 7 ...

  4. 【OpenCV 例程 300篇】235. 特征提取之主成分分析(sklearn)

    『youcans 的 OpenCV 例程300篇 - 总目录』 [youcans 的 OpenCV 例程 300篇]235. 特征提取之主成分分析(sklearn) 特征提取是指从原始特征中通过数学变 ...

  5. 【OpenCV 例程 300篇】221.加密马赛克图像处理与解密复原

    『youcans 的 OpenCV 例程200篇 - 总目录』 [youcans 的 OpenCV 例程 300篇]221.加密马赛克图像处理与解密复原 9. 图像的马赛克处理 马赛克效果是广泛使用的 ...

  6. 【OpenCV 例程 300篇】249. 特征描述之视网膜算法(FREAK)

    『youcans 的 OpenCV 例程300篇 - 总目录』 [youcans 的 OpenCV 例程 300篇]249. 特征检测之视网膜算法(FREAK) 1. FREAK 算法简介 快速视网膜 ...

  7. 【OpenCV 例程300篇】208. Photoshop 对比度自动调整算法

    OpenCV 例程200篇 总目录 [youcans 的 OpenCV 例程300篇]208. Photoshop 对比度自动调整算法 对比度是指图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量 ...

  8. 【OpenCV 例程 300篇】222. 特征提取之弗里曼链码(Freeman chain code)

    OpenCV 例程200篇 总目录 [youcans 的 OpenCV 例程 300篇]222. 特征提取之弗里曼链码(Freeman chain code) 目标特征的基本概念 通过图像分割获得多个 ...

  9. 【OpenCV 例程 300 篇】105. 湍流模糊退化模型

    专栏地址:『youcans 的 OpenCV 例程 300篇 - 总目录』 [第 7 章:图像复原与重建] 104. 运动模糊退化模型 105. 湍流模糊退化模型 [youcans 的 OpenCV ...

最新文章

  1. Beta 冲刺 (1/7)
  2. 《深入理解mybatis原理》 MyBatis缓存机制的设计与实现
  3. 【手写系列】理解数据库连接池底层原理之手写实现
  4. 打响进军元宇宙第一枪!网易云信发布两大元宇宙解决方案
  5. 如何在PowerPoint中制作打字机或命令行动画
  6. 用内核对象进行线程同步
  7. 在WPF TreeView中使用复选框
  8. 设计模式(3)——装饰者模式
  9. Hadoop YARN配置参数剖析(5)—Capacity Scheduler相关参数
  10. Elasticsearch多种方案数据迁移
  11. 微软bi报表服务器,升级 Power BI 报表服务器
  12. mysql 夏令时_MySQL日期时间字段和夏时制-如何引用“额外”小时?
  13. 为什么认真自学了NLP,面试还是回答不出问题
  14. 痞子衡嵌入式:飞思卡尔Kinetis系列MCU启动那些事(1)- KBOOT架构
  15. 背景图片大小兼容ie
  16. diy nas配置推荐2019_5款NAS 系统横向测评,看看哪款最适合你!
  17. 怎么调计算机运行内存大小,运行内存太小怎么办?如何扩大电脑的运行内存?...
  18. Prometheus和Grafana告警服务创建与对接腾讯云短信告警平台(prometheus_alert)
  19. bmzctf-crypto writeup(一) (持续更新)
  20. VS 2008 Express

热门文章

  1. Windows 2008 Windows7 针对某一个应用程序 取消用户账户控制
  2. 七种寻址方式(相对基址加变址寻址方式)
  3. (原创)vue-cli3引入google地图 —— 自己坑自己填
  4. 家用投影仪有哪些优缺点?帮你避雷!
  5. Vue2_人力资源管理系统项目笔记
  6. 计算机数控机床编程,数控车床手工编程实例
  7. 使用TeeChart Pro ActiveX轻松捕获放射性核素数据!
  8. Cesium加载天地图
  9. SQL server Error Number
  10. VS2017下DILL动态库的生成和使用