【OpenCV 例程200篇】225. 特征提取之傅里叶描述子

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


【youcans 的 OpenCV 例程200篇】225. 特征提取之傅里叶描述子


目标特征的基本概念

通过图像分割获得多个区域,得到区域内的像素集合或区域边界像素集合。我们把感兴趣的人或物称为目标,目标所处的区域就是目标区域。
特征通常是针对于图像中的某个目标而言的。图像分割之后,还要对目标区域进行适当的表示和描述,以便下一步处理。


3.4 傅里叶描述子

“描述”是对目标的抽象表达,在区别不同目标的基础上,尽可能对目标的尺度、平移、旋转变化不敏感。

傅里叶描述子(Fourier shape descriptors)的基本思想是用目标边界曲线的傅里叶变换来描述目标区域的形状,将二维描述问题简化为一维描述问题。傅里叶描述子具有旋转、平移和尺度不变性。

目标的边界曲线由一系列边界点组成。将边界点的坐标对 (xk,yk)(x_k, y_k)(xk,yk) 视为复数,记为:
s(k)=x(k)+j∗y(k),k=0,...K−1s(k) = x(k) + j * y(k), \quad k=0,...K-1 s(k)=x(k)+jy(k),k=0,...K1
于是可以将边界点的集合看作一维信号,并具有有限性和周期性,其一维离散傅里叶变换为:
a(u)=∑k=0K−1s(k)e−j2πuk/K,u=0,...K−1a(u) = \sum _{k=0} ^{K-1} s(k) e^{-j 2\pi uk/K}, \quad u=0,...K-1 a(u)=k=0K1s(k)ej2πuk/K,u=0,...K1

式中的复数系数 a(u)a(u)a(u) 称为边界的傅里叶描述子。

显然,通过这些系数 a(u)a(u)a(u) 的傅里叶反变换,就可以恢复原始信号 s(k)s(k)s(k) ,也即恢复目标的边界点集的坐标:
s(k)=1K∑u=0P−1a(u)ej2πuk/K,k=0,...K−1s(k) = \frac{1}{K} \sum _{u=0} ^{P-1} a(u) e^{j 2\pi uk/K}, \quad k=0,...K-1 s(k)=K1u=0P1a(u)ej2πuk/K,k=0,...K1
如果使用全部 K 个系数 a(u),u=0,...K−1a(u),u=0,...K-1a(u),u=0,...K1,则傅里叶反变换等于原输入信号 s(k)s(k)s(k) ;如果仅取前 P 个系数 a(u),u=0,...P−1a(u),u=0,...P-1a(u),u=0,...P1,则傅里叶反变换是原输入信号的近似,

由于傅里叶变换的低频分量决定整体形状,高频分量决定形状的细节。因此,仅取前 P 个系数 a(u)a(u)a(u) 相当于保留低频系数、删除高频系数的理想低通滤波器进行滤波。用少量低频的傅里叶描述子就可以描述目标边界曲线形状的基本特征。

边界曲线数组是一维复数数组,可以将其视为列数为 1 的二维复数图像,借用二维图像傅里叶变换算法(DFT)进行处理。

二维傅里叶变换(DFT)的周期性要求,在对傅里叶变换进行滤波之前,要先将傅里叶变换乘以 (−1)x(-1)^x(1)x 进行中心化,傅里叶逆变换后再乘以 (−1)x(-1)^x(1)x 进行去中心化。

二维傅里叶变换(DFT)的对称性要求,边界曲线及反变换复原曲线的点数必须是偶数。如果边界曲线的点数是奇数,可以在数组的最后添加一个点(如起点),形成首尾相同的偶数点集。另外,在低频滤波,截取低频傅里叶描述子时,保留的项数也要是偶数。

下面的例程表明,使用约 1% 的傅里叶描述子,就可以较好地描述边界曲线的基本形状。


例程 14.4:傅里叶描述子

    #  14.4 特征提取之傅里叶描述子def truncFFT(fftCnt, pLowF=64):  # 截短傅里叶描述子fftShift = np.fft.fftshift(fftCnt)  # 中心化,将低频分量移动到频域中心center = int(len(fftShift)/2)low, high = center - int(pLowF/2), center + int(pLowF/2)fftshiftLow = fftShift[low:high]fftLow = np.fft.ifftshift(fftshiftLow)  # 逆中心化return fftLowdef reconstruct(img, fftCnt, scale, ratio=1.0):  # 由傅里叶描述子重建轮廓图pLowF = int(fftCnt.shape[0] * ratio)  # 截短长度 P<=KfftLow = truncFFT(fftCnt, pLowF)  # 截短傅里叶描述子,删除高频系数ifft = np.fft.ifft(fftLow)  # 傅里叶逆变换 (P,)# cntRebuild = np.array([ifft.real, ifft.imag])  # 复数转为数组 (2, P)# cntRebuild = np.transpose(cntRebuild)  # (P, 2)cntRebuild = np.stack((ifft.real, ifft.imag), axis=-1)  # 复数转为数组 (P, 2)if cntRebuild.min() < 0:cntRebuild -= cntRebuild.min()cntRebuild *= scale / cntRebuild.max()cntRebuild = cntRebuild.astype(np.int32)print("ratio={}, fftCNT:{}, fftLow:{}".format(ratio, fftCnt.shape, fftLow.shape))rebuild = np.ones(img.shape, np.uint8)*255  # 创建空白图像cv2.rectangle(rebuild, (2,3), (568,725), (0,0,0), )  # 绘制边框cv2.polylines(rebuild, [cntRebuild], True, 0, thickness=2)  # 绘制多边形,闭合曲线return rebuild# 特征提取之傅里叶描述子img = cv2.imread("../images/chromosome.tif", flags=1)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 灰度图像_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY)print(gray.shape)  # (727, 570)# 寻找二值化图中的轮廓,method=cv2.CHAIN_APPROX_NONE 输出轮廓的每个像素点contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)  # OpenCV4~cnts = sorted(contours, key=cv2.contourArea, reverse=True)  # 所有轮廓按面积排序cnt = cnts[0]  # 第 0 个轮廓,面积最大的轮廓,(664, 1, 2)cntPoints = np.squeeze(cnt)  # 删除维度为 1 的数组维度,(2867, 1, 2)->(2867,2)lenCnt = cnt.shape[0]  # 轮廓点的数量print("length of max contour:", lenCnt)imgCnts = np.zeros(gray.shape[:2], np.uint8)  # 创建空白图像cv2.drawContours(imgCnts, cnt, -1, (255, 255, 255), 2)  # 绘制轮廓# 离散傅里叶变换,生成傅里叶描述子 fftCntcntComplex = np.empty(cntPoints.shape[0], dtype=complex)  # 声明复数数组 (2867,)cntComplex = cntPoints[:,0] + 1j * cntPoints[:,1]  # (xk,yk)->xk+j*yk# print("cntComplex", cntComplex.shape)fftCnt = np.fft.fft(cntComplex)  # 离散傅里叶变换,生成傅里叶描述子# 由全部傅里叶描述子重建轮廓曲线scale = cntPoints.max()  # 尺度系数rebuild = reconstruct(img, fftCnt, scale)  # 傅里叶逆变换重建轮廓曲线,傅里叶描述子 (2866,)# 由截短傅里叶系数重建轮廓曲线rebuild1 = reconstruct(img, fftCnt, scale, ratio=0.2)  # 截短比例 20%,傅里叶描述子 (572,)rebuild2 = reconstruct(img, fftCnt, scale, ratio=0.05)  # 截短比例 5%,傅里叶描述子 (142,)rebuild3 = reconstruct(img, fftCnt, scale, ratio=0.02)  # 截短比例 2%,傅里叶描述子 (56,)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("Contour")plt.imshow(cv2.cvtColor(imgCnts, cv2.COLOR_BGR2RGB))plt.subplot(233), plt.axis('off'), plt.title("rebuild (100%)")plt.imshow(cv2.cvtColor(rebuild, cv2.COLOR_BGR2RGB))plt.subplot(234), plt.axis('off'), plt.title("rebuild1 (20%)")plt.imshow(cv2.cvtColor(rebuild1, cv2.COLOR_BGR2RGB))plt.subplot(235), plt.axis('off'), plt.title("rebuild2 (5%)")plt.imshow(cv2.cvtColor(rebuild2, cv2.COLOR_BGR2RGB))plt.subplot(236), plt.axis('off'), plt.title("rebuild3 (2%)")plt.imshow(cv2.cvtColor(rebuild3, cv2.COLOR_BGR2RGB))plt.tight_layout()plt.show()

运行结果:

在这里插入图片描述

length of max contour: 2867
ratio=1.0, fftCNT:(2867,), fftLow:(2866,)
ratio=0.2, fftCNT:(2867,), fftLow:(572,)
ratio=0.05, fftCNT:(2867,), fftLow:(142,)
ratio=0.02, fftCNT:(2867,), fftLow:(56,)


【本节完】

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

222. 特征提取之弗里曼链码
225. 特征提取之傅里叶描述子

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

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

相关文章

【OpenCV 例程300篇】238. OpenCV 中的 Harris 角点检测

『youcans 的 OpenCV 例程300篇 - 总目录』 【youcans 的 OpenCV 例程 300篇】238. OpenCV 中的 Harris 角点检测 角是直线方向的快速变化。角点通常被定义为两条边的交点&#xff0c;或者说角点的邻域应该具有两个不同区域的不同方向的边界。 角是高度有效的特征。角点检测&…

基础线性规划实现(matlab,lingo)

目录 一、本次所需解的问题 二、matlab解题 1&#xff09;语法 2&#xff09;数学思维 3&#xff09;matlab解题 运行结果&#xff1a; 三、lingo解题 lingo解题如下&#xff1a; 运行结果&#xff1a; 最后&#xff1a; 一、本次所需解的问题 需解出下面该线性规划问…

cwntos linux kde桌面,Centos如何安装KDE的桌面

其实KDE其实在初次安装系统的时候就可以选择&#xff0c;我下面是进入系统后的安装方法&#xff1a;第一步&#xff1a;检查KDE首先查看自己是否安装了KDE# yum grouplist在grouplist的输出结果中的“Installed Groups:”部分中&#xff0c;如果你能找到“X Window System”和“…

【OpenCV 例程 300篇】239. Harris 角点检测之精确定位(cornerSubPix)

『youcans 的 OpenCV 例程300篇 - 总目录』 【youcans 的 OpenCV 例程 300篇】239. Harris 角点检测之精确定位&#xff08;cornerSubPix&#xff09; 角是直线方向的快速变化。角点通常被定义为两条边的交点&#xff0c;或者说角点的邻域应该具有两个不同区域的不同方向的边界…

基础线性规划实现---python

目录 一、问题 何为线性规划问题&#xff1a; 二、python进行求解 1.通过观察matlab解线性规划步骤进行求解 2.python求解步骤 1&#xff09;求解用到的模块&#xff08;scipy 和 numpy&#xff09;&#xff1a; 2&#xff09;对 max z2x13x2-5x3 该问题确定c如下&…

【OpenCV 例程 300篇】240. OpenCV 中的 Shi-Tomas 角点检测

『youcans 的 OpenCV 例程300篇 - 总目录』 【youcans 的 OpenCV 例程 300篇】240. OpenCV 中的 Shi-Tomas 角点检测 角是直线方向的快速变化。角点通常被定义为两条边的交点&#xff0c;或者说角点的邻域应该具有两个不同区域的不同方向的边界。 角是高度有效的特征。角点检测…

多元统计分析1

第一章 多元正态分布 文章目录 1.1 多元分布的基本概念 1.1.1 随机向量 1.1.2 分布函数与密度函数 联合分布函数&#xff1a; 联合密度函数&#xff1a; 条件密度函数&#xff1a; 分量的独立性&#xff1a; 1.1.3 随机向量的数字特征 1.随机向量的均值 2、随机…

Java并发容器和框架

ConcurrentHashMap 我们为什么要使用 ConcurrentHashMap呢&#xff1f; 原因有三&#xff1a; 并发编程中HashMap会导致死循环&#xff1b;HashTable效率又非常低&#xff1b;ConcurrentHashMap的锁分段技术可有效提升并发访问率。在并发编程使用HashMap会导致死循环。 在多线…

【OpenCV 例程 300篇】241. 尺度不变特征变换(SIFT)

『youcans 的 OpenCV 例程300篇 - 总目录』 【youcans 的 OpenCV 例程 300篇】241. 尺度不变特征变换&#xff08;SIFT&#xff09; 6.4.1 简介 尺度不变特征转换算法&#xff08;Scale-invariant feature transform&#xff0c;SIFT&#xff09;是图像处理中经典的局部特征描…

整数线性规划实现(matlab分枝界定法)

文章目录 一、本次问题 1.利用第一天所学知识求解&#xff1a; 2.本题理解&#xff1a; &#xff08;1&#xff09;分支界定法 背景&#xff1a; 基本理论&#xff08;解题步骤&#xff09;&#xff1a; 求解实现1&#xff1a; 1.第一步 2.第二步 3.第三步 4.第四步…

linux opencv gtk 没窗口,OpenCV GTK+2.x error

可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效&#xff0c;请关闭广告屏蔽插件后再试):问题:I had installed OpenCV following these steps ().After trying to compile one examples,i got this error :OpenCV Error: Unspecified error (The function …

硬盘分区

我们买回一台全新的笔记本的时候&#xff0c;我们会发现里面只有一个硬盘&#xff0c;这个时候为了满足我们的需求我们往往要对硬盘进行分区&#xff0c;那麽如何正确的对硬盘进行分区的呢&#xff1f; 下面教大家如何正确的对电脑硬盘进行分区操作。 操作方法 1、在桌面上找…

python入门:Anaconda和Jupyter notebook的安装与使用

文章目录 一、安装和使用Anaconda 1、anaconda是什么&#xff1f; 2、为什么需要安装anaconda&#xff1f; 3、如何安装anaconda&#xff1f; 通过官网下载页面 开源软件下载 安装步骤&#xff1a; 4、jupyter汉化 5、如何管理包&#xff1f; 1.列出已安装的包 2.安装…

非线性规划(1)

目录 一、非线性规划的定义 二、非线性规划的模型 三、非线性规划函数 四、线性不等式约束 五、线性不等式和等式约束 六、带有非线性约束的求最值 七、非线性约束 总结&#xff1a; 一、非线性规划的定义 前面我们学了线性规划&#xff0c;整数规划&#xff0c;我们可…

响应式布局Demo

顾名思义&#xff0c;响应式布局就是为适应不同终端而形成的一种技术。我总结了一个简单的例子帮助大家了解和学习响应式布局。 实现响应式布局的几种方式&#xff1a;媒体查询、JS、流体布局、弹性布局… 常用的meta标签 <meta content"widthdevice-width,initial-…

整数线性规划实现(lingo,python分枝界定法)

本文章为上篇建模学习打卡第二天的续 文章目录 一、本次问题 二、本题理解 三、问题求解 1.lingo实现 &#xff08;1&#xff09;先抛除整数约束条件对问题求解 &#xff08;2&#xff09;加入整数约束条件求解 2.python实现求解 &#xff08;1&#xff09;先抛除整数约…

Atmel跑Linux的arm芯片,Linux已被移植到Atmel的ATmega微控制器

Ubuntu Linux发行版已经被移植到最便宜、最便携的平台中&#xff1a;一个Atmel的ATmega微控制器。拥有一个20MHz的8位AVR处理器&#xff0c;128KB的闪存和整块16KB的SRAM&#xff0c;ATmega1284P并不是建立微型计算机最合乎逻辑的选择。它是在Arduino原型平台中找到的同样基础的…

Android Studio 详细安装教程

在我们的日常 Android 开发中&#xff0c;一个好的开发工具是必不可少的------Android Studio&#xff0c;是一个最重要的开发工具。 下面我将详细介绍Android Studio的下载安装。 一、安装环境及下载资源 1.1 安装环境 电脑系统 : Windows 10 JDK 版本 : 1.8 Android Stud…

零基础爬虫requests初阶教程,手把手教你爬数据

目录 一、环境与工具 二、学爬虫必备知识 三、简单体验 requests 四、get 请求 3.1 基础讲解一 3.3 基础讲解二 3.2 基础讲解三 3.4 获取cookie 3.5 获取请求头 3.6 添加请求头 3.5 知乎爬取反扒技术 3.6 抓取二进制数据 3.7 美女私房照爬取&#xff08; 准备发车…

vsftpd的主配置文件是什么linux,vsftpd.conf配置文件详解

vsftpd.conf配置文件详解# 是否允许匿名用户登录。默认值为YES。anonymousYES|NO# 是否允许匿名用户上传文件(如果设置为YES&#xff0c;则write_enable也必须设置为YES)。默认值为NO。anon_upload_enableYES|NO# 是否允许匿名用户创建目录(如果设置为YES&#xff0c;则write_e…