OpenCV_10 傅里叶变换:频域滤波+CV的应用

1 傅里叶变换的理解

傅里叶变换是由法国的一位数学家Joseph Fourier在18世纪提出来的,他认为:任何连续周期的信号都可以由一组适当的正弦曲线组合而成

傅里叶变换是描述信号的需要,它能够反映信号的特征,并可以使用特征值进行量化,比如正弦波可以使用幅值和频率进行描述。下面这幅图是变压器空载电流的输入波形:

它看起来和正弦波很相近,但很难定量的描述其特征,采用傅里叶变换后,得到下述的频谱图(幅值):

从该频谱图中可以清楚的看到,主要包括3,5,7,9次谐波,我们就可以对原信号进行描述。

傅里叶变换是一种信号分析方法,它使我们能够对信号的构成和特点进行深入和定量的研究,把信号通过频谱的方式进行准确的、定量的描述。

那我们为什么要把信号分解为正弦波的组合,而不是其他波形呢?

傅里叶变换是信号的分析方法,目的就是要简化问题,而不是将其变复杂,傅里叶选择了正弦波,而没有选择其他波形,是因为正弦波有任何其他波形不具有的特点:正弦波输入至任何线性系统中,不会产生新的频率成分,输出的仍是正弦波,改变的仅仅是幅值和相位。用单位幅值的不同频率的正弦波输入至某线性系统,记录其输出正弦波的幅值和频率的关系,就得到该系统的幅频特性,记录输出正弦波的相位和频率的关系,就得到该系统的相频特性。线性系统是自动控制研究的主要对象,我们只要研究系统对正弦波的输入输出关系,就可以知道该系统对任意输入信号的响应。这是傅里叶变换的最主要的意义。

2 傅里叶变换中相关概念

2.1 时域和频域

傅里叶变换是将难以处理的时域信号转换成易于分析的频域信号,那频域和时域到底是什么呢?

时域:时域是真实的世界,是唯一存在的域。从我们出生开始,所接触的这个世界就是随着时间在变化的,如花开花落,四季变换,生老病死等。以时间作为参照来分析动态世界的方法我们称其为时域分析。

比如说一段音乐,就是一个随时间变化的震动,这就是时域的表示,如下图:

频域频域它不是真实的,而是一个数学构造。频域是一个遵循特定规则的数学范畴,也被一些学者称为上帝视角。结合上面对时域的理解,如果时域是运动永不停止的,那么频域就是静止的。 正弦波是频域中唯一存在的波形,这是频域中最重要的规则,即正弦波是对频域的描述,因为频域中的任何波形都可用正弦波合成

在看上面那段音乐,我们可以将其表示成频域形式,就是一个永恒的音符。

而对于信号来说,信号强度随时间的变化规律就是时域特性,信号是由哪些单一频率的信号合成的就是频域特性,傅里叶变换实质就是是频域函数和时域函数的转换。

那频域与时域之间的关系是什么样的呢?利用正弦函数的叠加成一个矩形,不仅仅是矩形,你能想到的任何波形都是可以如此方法用正余弦波叠加起来的。如下图所示,时域是永远随着时间的变化而变化的,而频域就是装着装着正余弦波的空间。

从时域来看,我们会看到一个近似为矩形的波,而我们知道这个矩形的波可以拆分为一些正弦波的叠加。而从频域方向来看,我们就看到了每一个正余弦波的幅值,每两个正弦波之间都还有一条直线,那并不是分割线,而是振幅为 0 的正弦波!也就是说,为了组成特殊的曲线,有些正弦波成分是不需要的。随着叠加的递增,所有正弦波中上升的部分逐渐让原本缓慢增加的曲线不断变陡,而所有正弦波中下降的部分又抵消了上升到最高处时继续上升的部分使其变为水平线。一个矩形就这么叠加而成了。

我们看下面的动图理解,如下所示:

2.2 频谱和相位谱

在傅里叶变换中怎么描述变换后的结果呢?有两个概念:频谱和相位谱。

频谱:将信号分解为若干不同频率的正弦波,那么每一个正弦波的幅度,就叫做频谱,也叫做幅度谱。

相位谱:频谱只代表了一个正弦函数的幅值,而要准确描述一个正弦函数,我们不仅需要幅值,还需要相位,不同相位决定了波的位置,所以对于频域分析,仅仅有频谱(振幅谱)是不够的,我们还需要一个相位谱。

如上图所示:投影点我们用粉色点来表示,红色的点表示离正弦函数频率轴最近的一个峰值,而相位差就是粉色点和红色点水平距离。将相位差画到一个坐标轴上就形成了相位谱

3 傅里叶变换

根据原信号的属性,我们可以将傅里叶变换分为以下几种:

在实际应用较多的是傅里叶变换、傅里叶级数离散傅里叶变换,我们对其进行分别介绍。

任意波形都可以通过正弦波的叠加来表示,正弦波可以通过欧拉公式写成指数的形式,欧拉公式如下:

所以以下内容都是以指数形式进行展示。

3.1 傅里叶级数

任意的周期连续信号都可以使用正弦波叠加而成,这叫做傅里叶级数,写成指数形式如下所示:

其中cn​​表示傅里叶级数:

公式中的T表示时域信号的周期。从上式中可以看出周期信号的频谱是离散的非周期信号。

3.2 傅里叶变换

对于非周期的连续信号,也可以使用正弦信号来逼近,这时我们将非周期信号看做周期无限大的周期信号,则有

其中,ω表示频率,t表示时间。我们叫做傅里叶变换。从中可以看出非周期信号的频谱是连续的非周期信号。

 

逆变换为:

利用上述公式就可将频域信号转换为时域信号。

3.3 离散傅里叶变换(DFT)

 由于数字信号处理是希望在计算机上实现各种运算和变换,其所涉及的变量和运算都是离散的,因此对于数字信号处理,应该找到在时域和频域都是离散的傅里叶变换,即离散傅里叶变换。

对于非周期的离散信号进行傅里叶变换就是离散傅里叶变换,其计算方法如下所示:

其中N表示傅里叶变换的点数,k表示傅里叶变换的频谱。

逆变换为:

4 傅里叶变换在图像中的应用

4.1 图像中的傅里叶变换

图像是二维的离散信号,所以我们在对图像进行二维傅里叶变换。对于M*N的一幅图像的离散二维傅里叶变换,公式如下:

其中u和v确定频率,f(x,y)是灰度值,该式的意义是两个求和号对图像进行遍历,f(x,y)取出原像素的数值,当固定x时,横轴不动,对y进行遍历时,表示变换前像素的位置比例与变换后的位置相乘,映射到新的位置,且能够反映像素沿y方向距离的差异,越靠后的像素(y越大)​​值越大,即​​能够反映出不同位置(纵轴)像素之间的差异;前一项含义为保留像素相对位置(横轴)的信息(遍历y时为常数),2π为修正参数。

逆变换由下式给出:

4.2 图像傅里叶变换的物理意义

图像的频率是表征图像中灰度变化剧烈程度的指标,是灰度在平面空间上的梯度。如:大面积的沙漠在图像中是一片灰度变化缓慢的区域,对应的频率值很低;而对于地表属性变换剧烈的边缘区域在图像中是一片灰度变化剧烈的区域,对应的频率值较高。傅里叶变换在实际中有非常明显的物理意义,从物理效果看,傅里叶变换是将图像从空间域转换到频率域,其逆变换是将图像从频率域转换到空间域。换句话说,傅里叶变换的物理意义是将图像的灰度分布函数变换为图像的频率分布函数。

傅里叶逆变换是将图像的频率分布函数变换为灰度分布函数。

我们在做DFT时是将图像的空域和频域沿x和y方向进行无限周期拓展的,如下图所示:

如果只取其中一个周期,会得到:

 为了便于频域的滤波和频谱的分析,常在变换后进行频谱的中心化,即对掉频谱的四个象限,如下图所示:

 经中心化后的频谱为:

在经过频谱居中后的频谱中,中间最亮的点是最低频率,属于直流分量,越往外,频率越高,如下所示: 

4.3 在opencv中实现图像的傅里叶变换

在OPenCV中实现图像的傅里叶变换,使用的是:

正变换:

dft = cv2.dft(src, dst=None)

参数:

  • src: 输入图像,要转换成np.float32格式
  • dst:参数是可选的, 决定输出数组的大小。默认输出数组的大小和输入图像大小一样。如果输出结果比输入图像大,输入图像就需要在进行变换前补0。如果输出结果比输入图像小的话,输入图像就会被切割。

返回:

  • dft: 傅里叶变换后的结果,有两个通道,第一个通道是结果的实数部分,第二个通道是结果的虚数部分。我们需要在此基础上计算傅里叶变换的频谱和相位。

逆变换:

img = cv.idft(dft)

参数:

  • dft: 图像的频域表示

返回:

  • img: 图像的空域表示

实现:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt# 1 读取图像
img = cv.imread('./img/2.jpg', 0)
# 2 傅里叶变换
# 2.1 正变换
dft = cv.dft(np.float32(img), flags=cv.DFT_COMPLEX_OUTPUT)
# 2.2 频谱中心化
dft_shift = np.fft.fftshift(dft)
# 2.3 计算频谱和相位谱
mag, angle = cv.cartToPolar(dft_shift[:, :, 0], dft_shift[:, :, 1], angleInDegrees=True)
mag = 20 * np.log(mag)
# 3 傅里叶逆变换
# 3.1 逆变换
img_back = cv.idft(dft)
# 3.2 计算灰度值
img_back = cv.magnitude(img_back[:, :, 0], img_back[:, :, 1])# 4 图像显示
plt.figure(figsize=(10, 8))
plt.subplot(221), plt.imshow(img, cmap='gray')
plt.title('输入图像'), plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(mag, cmap='gray')
plt.title('频谱'), plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(angle, cmap='gray')
plt.title('相位谱'), plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(img_back, cmap='gray')
plt.title('逆变换结果'), plt.xticks([]), plt.yticks([])
plt.show()

结果展示:
 

4.4 频域滤波

图像变换到频域后,就可以进行频域滤波,主要包括:高通滤波,低通滤波,带通滤波和带阻滤波。

1 高通和低通滤波器

我们知道,图像在经过傅里叶变换后,经频谱中心化后,从中间到外面,频率上依次是从低频到高频的。那么我们假设把中间规定一小部分去掉,是不是相对于把低频信号去掉了呢?这也就是相当于进行了高通滤波。

这个滤波模板如下图所示:

 其中黑色部分为0,白色部分为1,我们将这个模板与图像的傅里叶变换相与就实现了高通滤波。如下所示:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt# 1 读取图像
img = cv.imread('./img/2.jpg', 0)
# 2 设计高通滤波器(傅里叶变换结果中有两个通道,所以高通滤波中也有两个通道)
rows, cols = img.shape
mask = np.ones((rows, cols, 2), np.uint8)
mask[int(rows / 2) - 30:int(rows / 2) + 30, int(cols / 2) - 30:int(cols / 2) + 30, :] = 0# 3 傅里叶变换
# 3.1 正变换
dft = cv.dft(np.float32(img), flags=cv.DFT_COMPLEX_OUTPUT)
# 3.2 频谱中心化
dft_shift = np.fft.fftshift(dft)
# 3.3 滤波
dft_shift = dft_shift * mask
# 3.4 频谱去中心化
dft_shift = np.fft.fftshift(dft_shift)# 3 傅里叶逆变换
# 3.1 反变换
img_back = cv.idft(dft_shift)
# 3.2 计算灰度值
img_back = cv.magnitude(img_back[:, :, 0], img_back[:, :, 1])plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Original drawing'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img_back, cmap='gray')
plt.title('High pass filtering results'), plt.xticks([]), plt.yticks([])
plt.show()


从结果中可以看出,高通滤波器有利于提取图像的轮廓,图像的轮廓或者边缘或者一些噪声处,灰度变化剧烈,那么在把它们经过傅里叶变换后。就会变成高频信号(高频是捕捉细节的),所以在把图像低频信号滤掉以后剩下的自然就是轮廓了。
 

现在我们看下低通滤波的效果,构造一个低通滤波器很简单,只要把上述模板中的1改为0,0改为1即可。把设计高通滤波器部分的代码改成如下所示:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt# 1 读取图像
img = cv.imread('./img/2.jpg', 0)
# 2 设计低通滤波器(傅里叶变换结果中有两个通道,所以高通滤波中也有两个通道)
rows, cols = img.shape
mask = np.ones((rows, cols, 2), np.uint8)
mask[int(rows / 2) - 30:int(rows / 2) + 30, int(cols / 2) - 30:int(cols / 2) + 30, :] = 1# 3 傅里叶变换
# 3.1 正变换
dft = cv.dft(np.float32(img), flags=cv.DFT_COMPLEX_OUTPUT)
# 3.2 频谱中心化
dft_shift = np.fft.fftshift(dft)
# 3.3 滤波
dft_shift = dft_shift * mask
# 3.4 频谱去中心化
dft_shift = np.fft.fftshift(dft_shift)# 3 傅里叶逆变换
# 3.1 反变换
img_back = cv.idft(dft_shift)
# 3.2 计算灰度值
img_back = cv.magnitude(img_back[:, :, 0], img_back[:, :, 1])plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Original drawing'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img_back, cmap='gray')
plt.title('Effect of low-pass filtering'), plt.xticks([]), plt.yticks([])
plt.show()

低通滤波的效果如下图所示:

  从结果中可看到低通滤波后图像轮廓变模糊了,图像的大部分信息基本上都保持了。图像的主要信息都集中在低频上,所以低通滤波器的效果是这样也是能够理解的。
上述的高通、低通滤波器的构造有0,1构成的理想滤波器,也是最简单的滤波器,另一些其它的滤波器。比方说高斯滤波器,butterworth滤波器等等,如下图所示:

2 带通滤波器

我们把高通和低通的一部分结合在模板中就形成了带通滤波器,它容许一定频率范围信号通过, 但减弱(或减少)频率低于於下限截止频率和高于上限截止频率的信号的通过,如下图所示:

 还是以理想的带通滤波器演示如下,将构建的滤波的代码修改如下:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt# 1 读取图像
img = cv.imread('./img/2.jpg', 0)
# 2 设计带通滤波器(傅里叶变换结果中有两个通道,所以高通滤波中也有两个通道)
rows,cols = img.shape
mask1 = np.ones((rows,cols,2),np.uint8)
mask1[int(rows/2)-8:int(rows/2)+8,int(cols/2)-8:int(cols/2)+8] = 0
mask2 = np.zeros((rows,cols,2),np.uint8)
mask2[int(rows/2)-80:int(rows/2)+80,int(cols/2)-80:int(cols/2)+80] = 1
mask = mask1*mask2# 3 傅里叶变换
# 3.1 正变换
dft = cv.dft(np.float32(img), flags=cv.DFT_COMPLEX_OUTPUT)
# 3.2 频谱中心化
dft_shift = np.fft.fftshift(dft)
# 3.3 滤波
dft_shift = dft_shift * mask
# 3.4 频谱去中心化
dft_shift = np.fft.fftshift(dft_shift)# 3 傅里叶逆变换
# 3.1 反变换
img_back = cv.idft(dft_shift)
# 3.2 计算灰度值
img_back = cv.magnitude(img_back[:, :, 0], img_back[:, :, 1])plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Original drawing'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img_back, cmap='gray')
plt.title('Effect of bandpass filter'), plt.xticks([]), plt.yticks([])
plt.show()

结果如下所示:

 这就是带通的效果,它既能保留一部分低频,也能保留一部分高频。至于保留多少,根据需求选择就可以了。


3 带阻滤波器

带阻滤波器减弱(或减少)一定频率范围信号, 但容许频率低于於下限截止频率和高于上限截止频率的信号的通过,如下示:
 

 在代码中将设计滤波器部分改为如下所示:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt# 1 读取图像
img = cv.imread('./img/2.jpg', 0)
# 2 设计带阻滤波器(傅里叶变换结果中有两个通道,所以高通滤波中也有两个通道)
rows,cols = img.shape
mask = np.ones((rows,cols,2),np.uint8)
mask[int(rows/2)+80:int(rows/2)+150,int(cols/2)-150:int(cols/2)+150] = 0
mask[int(rows/2)-150:int(rows/2)-80,int(cols/2)-150:int(cols/2)+150] = 0
mask[int(rows/2)-150:int(rows/2)+150,int(cols/2)+80:int(cols/2)+150] = 0
mask[int(rows/2)-150:int(rows/2)+150,int(cols/2)-150:int(cols/2)-80] = 0
plt.imshow(mask[:,:,1],cmap=plt.cm.gray)# 3 傅里叶变换
# 3.1 正变换
dft = cv.dft(np.float32(img), flags=cv.DFT_COMPLEX_OUTPUT)
# 3.2 频谱中心化
dft_shift = np.fft.fftshift(dft)
# 3.3 滤波
dft_shift = dft_shift * mask
# 3.4 频谱去中心化
dft_shift = np.fft.fftshift(dft_shift)# 3 傅里叶逆变换
# 3.1 反变换
img_back = cv.idft(dft_shift)
# 3.2 计算灰度值
img_back = cv.magnitude(img_back[:, :, 0], img_back[:, :, 1])plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Original drawing'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img_back, cmap='gray')
plt.title('Effect of band stop filter'), plt.xticks([]), plt.yticks([])
plt.show()

结果如下所示:

 从结果中可看到带阻滤波器保持了原图像的大部分信息,图像的主要信息都集中在低频上,而边缘轮廓信息都在高频位置。带阻滤波器滤除了中频信息,保留了低频和高频信息,所以对图像的信息破坏是比较小的。:


总结:

  1. 傅里叶变换的理解

    任何连续周期的信号都可以由一组适当的正弦曲线组合而成

  2. 相关概念:

    时域:以时间作为参照来分析动态世界的方法

    频域:频域它不是真实的,而是一个数学构造

    幅度谱:将信号分解为若干不同频率的正弦波,那么每一个正弦波的幅度,就叫做频谱,也叫做幅度谱

    相位谱:每一个正弦波的相位,就叫做相位谱

  3. 傅里叶变换分类

    傅里叶级数:任意的周期连续信号的傅里叶变换

    傅里叶变换:非周期连续信号

    离散傅里叶变换:非周期离散信号

  4. 图像中的应用

    • 二维傅里叶变换

    • 意义:将图像的灰度分布函数变换为图像的频率分布函数。

    • API:

      cv.dft()

      cv.idft()

    • 滤波:高通,低通,带通,带阻

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

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

相关文章

OpenCV_11 轮廓检测:图像的轮廓+绘制轮廓+轮廓近似+边界矩形+椭圆拟合+直线拟合

1 图像的轮廓 轮廓可以简单认为成将连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度。轮廓是图像目标的外部特征,这种特征对于我们进行图像分析,目标识别和理解等更深层次的处理都有很重要的意义。 轮廓提…

数据结构之平衡树:2-3查找树的介绍——16

平衡树(AVL tree) 引入 之前学习的树,都不是平衡的,查找时需要一个一个往内比较,一个结点只储存一个值,数据量存储较大,树的深度会非常的深,导致数据查询时效率会十分的低&#xf…

OpenCV_12 图像分割:全阈值分割+自适应阈值分割+Otsu 阈值(大津法)+分水岭算法+GraphCut+GrabCut

1 图像分割 所谓图像分割指的是根据灰度、颜色、纹理和形状等特征把图像划分成若干互不交迭的区域,并使这些特征在同一区域内呈现出相似性,而在不同区域间呈现出明显的差异性。我们先对目前主要的图像分割方法做个概述,后面再对个别方法做详…

Android中的IPC机制

Android IPC简介 IPC是Inter-Process Communication的缩写,含义就是进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程。那么什么是进程,什么是线程,进程和线程是两个截然不同的概念。在操作系统中,线程是…

数据结构之平衡树:红黑树的介绍与Python代码实现——17

红黑树的介绍与Python代码实现 红黑树的介绍 红黑树(Red-Black Tree)是一种平衡二叉查找树,它是一种以比较简单的方式实现的2-3查找树 红黑树基于2-3查找树的表现 红链接:将两个2-结点连接起来构成一个3-结点 ;黑链接:则是2-3树中的普通链接。 红黑树的定义&a…

数据结构之并查集:并查集的介绍与Python代码实现——18

并查集的介绍 并查集(Union-find)数据结构也称作合并查找集(Merge-find set)或者不相交集数据结构(disjoint-set data structure),它是一种记录了由一个或多个元素组成的不连续的分组的集合。并…

图像特征提取与描述_角点特征01:Harris算法+Shi-Tomas算法

1 Harris角点检测 1.1 原理 Harris角点检测的思想是通过图像的局部的小窗口观察图像,角点的特征是窗口沿任意方向移动都会导致图像灰度的明显变化,如下图所示: 将上述思想转换为数学形式,即将局部窗口向各个方向移动(u,v)并计算…

canvas小程序-快跑程序员

canvas不用说html5带来的好东西,游戏什么的,么么哒 记得有一天玩手机游戏,就是一个跳跃过柱子那种,其实元素很简单啊,app能开发,借助html5 canvas也可以啊,于是就开始了。 --------------------…

数据结构之并查集:UF-Tree优化并查集——19

并查集的优化 在上一节了解到并查集的快速查询,合并,判断归属组等操作,虽然这些操作都非常方便,但是在数据量较大的情况下,并查集的效率并不算高: 上一节中实现代码中使用的合并方法(merge,AP…

图像特征提取与描述_角点特征02:SIFT算法+SURF算法

SIFT/SURF算法 1.1 SIFT原理 前面两节我们介绍了Harris和Shi-Tomasi角点检测算法,这两种算法具有旋转不变性,但不具有尺度不变性,以下图为例,在左侧小图中可以检测到角点,但是图像被放大后,在使用同样的窗…

图像特征提取与描述_角点特征03:Fast算法+ORB算法

1 Fast算法 1.1 原理 我们前面已经介绍过几个特征检测器,它们的效果都很好,特别是SIFT和SURF算法,但是从实时处理的角度来看,效率还是太低了。为了解决这个问题,Edward Rosten和Tom Drummond在2006年提出了FAST算法&…

数据结构之并查集:路径压缩继续优化并查集——20

路径压缩继续优化并查集 在实现的并查集中,在合并操作merge(item1, item2)时,会不管两个元素所在的分组大小,总是将item 1的分组合并到item2的分组,这样可能会导致树的深度无必要地增加: 如果是大树合并到小树上&…

数据结构之并查集:并查集解决案例, Python——21

并查集解决案例畅通工程 案例问题介绍: 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府"畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还…

图像特征提取与描述_角点特征04:LBP算法+HOG特征算子

1.LBP算法 LBP(Local Binary Pattern)指局部二值模式,是一种用来描述图像局部特征的算子,LBP特征具有灰度不变性和旋转不变性等显著优点。它是由T. Ojala, M.Pietikinen, 和 D. Harwood在1994年提出,由于LBP特征计算简单、效果较好&#xff…

视频操作_01视频读写:视频读写+读取视频+保存视频

1 从文件中读取视频并播放 在OpenCV中我们要获取一个视频,需要创建一个VideoCapture对象,指定你要读取的视频文件: 1.创建读取视频的对象 cap cv.VideoCapture(filepath) 参数: filepath: 视频文件路径 2.视频的属性信息 2.1…

数据结构之图:无向图的介绍与功能实现,Python——22

无向图(Undigraph)的介绍 引入 生活中的图,有地图,集成电路板的图,可以看类似的看做是数据结构中的图数据有"一对一",“一对多”和“多对多”的关系,前两种分别表示线性表和树的存储…

视频操作_02视频追踪:meanshift算法+Camshift算法

1.meanshift 1.1原理 meanshift算法的原理很简单。假设你有一堆点集,还有一个小的窗口,这个窗口可能是圆形的,现在你可能要移动这个窗口到点集密度最大的区域当中。 如下图: 最开始的窗口是蓝色圆环的区域,命名为C1…

数据结构之图:图的搜索,Python代码实现——23

图的搜索 深度优先搜索(Depth First Search) 定义 从例子出发理解 DFS是一种用于遍历或搜寻树类或图类数据结构的算法,这种算法从根结点出发(如果是图,则任意选择一个顶点作为根结点),在回溯之前会尽可能地遍历每一…

人脸识别案例:【实战】opencv人脸检测+Haar特征分类器

1 基础 我们使用机器学习的方法完成人脸检测,首先需要大量的正样本图像(面部图像)和负样本图像(不含面部的图像)来训练分类器。我们需要从其中提取特征。下图中的 Haar 特征会被使用,就像我们的卷积核&…

数据结构之图:用图解决案例,Python代码实现——24

用图解决畅通工程案例与途径查找 代码中需要引入的类方法代码链接: 无向图Undigraph深度优先搜索DFS与广度优先搜索BFS 畅通工程-续 介绍 案例和之前并查集中实现的一样,但问题略有改动,需要判断9-10城市是否相通,9-8城市是否…