Lesson4-3:OpenCV图像特征提取与描述---SIFT/SURF算法

学习目标

  • 理解 S I F T / S U R F SIFT/SURF SIFT/SURF算法的原理,
  • 能够使用 S I F T / S U R F SIFT/SURF SIFT/SURF进行关键点的检测

SIFT/SURF算法

1.1 SIFT原理

前面两节我们介绍了 H a r r i s Harris Harris S h i − T o m a s i Shi-Tomasi ShiTomasi角点检测算法,这两种算法具有旋转不变性,但不具有尺度不变性,以下图为例,在左侧小图中可以检测到角点,但是图像被放大后,在使用同样的窗口,就检测不到角点了。
在这里插入图片描述
所以,下面我们来介绍一种计算机视觉的算法,尺度不变特征转换即 S I F T ( S c a l e − i n v a r i a n t f e a t u r e t r a n s f o r m ) SIFT (Scale-invariant feature transform) SIFT(Scaleinvariantfeaturetransform)。它用来侦测与描述影像中的局部性特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量,此算法由 David Lowe在1999年所发表,2004年完善总结。应用范围包含物体辨识、机器人地图感知与导航、影像缝合、3D模型建立、手势辨识、影像追踪和动作比对等领域。

SIFT算法的实质是在不同的尺度空间上查找关键点(特征点),并计算出关键点的方向。SIFT所查找到的关键点是一些十分突出,不会因光照,仿射变换和噪音等因素而变化的点,如角点、边缘点、暗区的亮点及亮区的暗点等。

1.1.1 基本流程

L o w e Lowe Lowe S I F T SIFT SIFT算法分解为如下四步:

  1. 尺度空间极值检测:搜索所有尺度上的图像位置。通过高斯差分函数来识别潜在的对于尺度和旋转不变的关键点。
  2. 关键点定位:在每个候选的位置上,通过一个拟合精细的模型来确定位置和尺度。关键点的选择依据于它们的稳定程度。
  3. 关键点方向确定:基于图像局部的梯度方向,分配给每个关键点位置一个或多个方向。所有后面的对图像数据的操作都相对于关键点的方向、尺度和位置进行变换,从而保证了对于这些变换的不变性。
  4. 关键点描述:在每个关键点周围的邻域内,在选定的尺度上测量图像局部的梯度。这些梯度作为关键点的描述符,它允许比较大的局部形状的变形或光照变化。

我们就沿着 L o w e Lowe Lowe的步骤,对 S I F T SIFT SIFT算法的实现过程进行介绍:

1.1.2 尺度空间极值检测

在不同的尺度空间是不能使用相同的窗口检测极值点,对小的关键点使用小的窗口,对大的关键点使用大的窗口,为了达到上述目的,我们使用尺度空间滤波器。

高斯核是唯一可以产生多尺度空间的核函数。-《Scale-space theory: A basic tool for analysing structures at different scales》。

一个图像的尺度空间 L ( x , y , σ ) L(x,y,σ) L(x,y,σ),定义为原始图像 I ( x , y ) I(x,y) I(x,y)与一个可变尺度的 2 2 2维高斯函数 G ( x , y , σ ) G(x,y,σ) G(x,y,σ)卷积运算 ,即:

L ( x , y , σ ) = G ( x , y , σ ) ∗ I ( x , y ) L(x,y,σ)=G(x,y,σ)∗I(x,y) L(x,y,σ)=G(x,y,σ)I(x,y)

其中:

G ( x , y , σ ) = 1 2 π σ 2 e x 2 + y 2 2 σ 2 G(x,y,σ)= \frac{1}{2πσ^{2}}e^{\frac{x^{2}+y^{2}}{2σ^{2}}} G(x,y,σ)=2πσ21e2σ2x2+y2

σ σ σ是尺度空间因子,它决定了图像的模糊的程度。在大尺度下( σ σ σ值大)表现的是图像的概貌信息,在小尺度下( σ σ σ值小)表现的是图像的细节信息。

在计算高斯函数的离散近似时,在大概 3 σ 3σ 3σ距离之外的像素都可以看作不起作用,这些像素的计算也就可以忽略。所以,在实际应用中,只计算 ( 6 σ + 1 ) ∗ ( 6 σ + 1 ) (6σ+1)*(6σ+1) (6σ+1)(6σ+1)的高斯卷积核就可以保证相关像素影响。

下面我们构建图像的高斯金字塔,它采用高斯函数对图像进行模糊以及降采样处理得到的,高斯金字塔构建过程中,首先将图像扩大一倍,在扩大的图像的基础之上构建高斯金字塔,然后对该尺寸下图像进行高斯模糊,几幅模糊之后的图像集合构成了一个 O c t a v e Octave Octave,然后对该 O c t a v e Octave Octave下选择一幅图像进行下采样,长和宽分别缩短一倍,图像面积变为原来四分之一。这幅图像就是下一个 O c t a v e Octave Octave的初始图像,在初始图像的基础上完成属于这个 O c t a v e Octave Octave的高斯模糊处理,以此类推完成整个算法所需要的所有八度构建,这样这个高斯金字塔就构建出来了,整个流程如下图所示:

在这里插入图片描述
利用 L o G LoG LoG(高斯拉普拉斯方法),即图像的二阶导数,可以在不同的尺度下检测图像的关键点信息,从而确定图像的特征点。但 L o G LoG LoG的计算量大,效率低。所以我们通过两个相邻高斯尺度空间的图像的相减,得到 D o G DoG DoG(高斯差分)来近似 L o G LoG LoG

为了计算 D o G DoG DoG我们构建高斯差分金字塔,该金字塔是在上述的高斯金字塔的基础上构建而成的,建立过程是:在高斯金字塔中每个 O c t a v e Octave Octave中相邻两层相减就构成了高斯差分金字塔。如下图所示:在这里插入图片描述

高斯差分金字塔的第 1 1 1组第 1 1 1层是由高斯金字塔的第1组第2层减第1组第1层得到的。以此类推,逐组逐层生成每一个差分图像,所有差分图像构成差分金字塔。概括为 D O G DOG DOG金字塔的第 o o o组第 l l l层图像是有高斯金字塔的第 o o o组第 l + 1 l+1 l+1层减第 o o o组第 l l l层得到的。后续 S i f t Sift Sift特征点的提取都是在 D O G DOG DOG金字塔上进行的

D o G DoG DoG 搞定之后,就可以在不同的尺度空间中搜索局部最大值了。对于图像中的一个像素点而言,它需要与自己周围的 8 8 8 邻域,以及尺度空间中上下两层中的相邻的 18 ( 2 x 9 ) 18(2x9) 182x9个点相比。如果是局部最大值,它就可能是一个关键点。基本上来说关键点是图像在相应尺度空间中的最好代表。如下图所示:
在这里插入图片描述
搜索过程从每组的第二层开始,以第二层为当前层,对第二层的 D o G DoG DoG图像中的每个点取一个 3 × 3 3×3 3×3的立方体,立方体上下层为第一层与第三层。这样,搜索得到的极值点既有位置坐标( D o G DoG DoG的图像坐标),又有空间尺度坐标(层坐标)。当第二层搜索完成后,再以第三层作为当前层,其过程与第二层的搜索类似。当 S = 3 S=3 S=3时,每组里面要搜索 3 3 3层,所以在 D O G DOG DOG中就有 S + 2 S+2 S+2层,在初使构建的金字塔中每组有 S + 3 S+3 S+3层。

1.1.3 关键点定位

由于 D o G DoG DoG对噪声和边缘比较敏感,因此在上面高斯差分金字塔中检测到的局部极值点需经过进一步的检验才能精确定位为特征点。

使用尺度空间的泰勒级数展开来获得极值的准确位置, 如果极值点的 灰度值小于阈值(一般为 0.03 0.03 0.03 0.04 0.04 0.04)就会被忽略掉。 在 OpenCV 中这种阈值被称为 contrastThreshold

D o G DoG DoG 算法对边界非常敏感, 所以我们必须要把边界去除。 H a r r i s Harris Harris 算法除了可以用于角点检测之外还可以用于检测边界。从 H a r r i s Harris Harris 角点检测的算法中,当一个特征值远远大于另外一个特征值时检测到的是边界。那在 D o G DoG DoG算法中欠佳的关键点在平行边缘的方向有较大的主曲率,而在垂直于边缘的方向有较小的曲率,两者的比值如果高于某个阈值(在OpenCV中叫做边界阈值),就认为该关键点为边界,将被忽略,一般将该阈值设置为 10 10 10

将低对比度和边界的关键点去除,得到的就是我们感兴趣的关键点。

1.1.4 关键点方向确定

经过上述两个步骤,图像的关键点就完全找到了,这些关键点具有尺度不变性。为了实现旋转不变性,还需要为每个关键点分配一个方向角度,也就是根据检测到的关键点所在高斯尺度图像的邻域结构中求得一个方向基准。

对于任一关键点,我们采集其所在高斯金字塔图像以r为半径的区域内所有像素的梯度特征(幅值和幅角),半径 r r r为:
r = 3 × 1.5 σ r=3×1.5σ r=3×1.5σ

其中σ是关键点所在 o c t a v e octave octave的图像的尺度,可以得到对应的尺度图像。

梯度的幅值和方向的计算公式为:

m ( x , y ) = ( L ( x + 1 , y ) − L ( x − 1 , y ) 2 + ( L ( x , y + 1 ) − L ( x , y − 1 ) ) 2 m(x,y)=\sqrt{(L(x+1,y)-L(x-1,y)^{2}+(L(x,y+1)-L(x,y-1))^{2}} m(x,y)=(L(x+1,y)L(x1,y)2+(L(x,y+1)L(x,y1))2

θ ( x , y ) = a r c t a n ( L ( x , y + 1 ) − L ( x , y − 1 ) L ( x + 1 , y ) − L ( x − 1 , y ) ) θ(x,y)=arctan(\frac{L(x,y+1)-L(x,y-1)}{L(x+1,y)-L(x-1,y)}) θ(x,y)=arctan(L(x+1,y)L(x1,y)L(x,y+1)L(x,y1))

邻域像素梯度的计算结果如下图所示:
在这里插入图片描述

完成关键点梯度计算后,使用直方图统计关键点邻域内像素的梯度幅值和方向。具体做法是,将 360 ° 360° 360°分为 36 36 36柱,每 10 ° 10° 10°为一柱,然后在以r为半径的区域内,将梯度方向在某一个柱内的像素找出来,然后将他们的幅值相加在一起作为柱的高度。因为在r为半径的区域内像素的梯度幅值对中心像素的贡献是不同的,因此还需要对幅值进行加权处理,采用高斯加权,方差为 1.5 σ 1.5σ 1.5σ。如下图所示,为简化图中只画了 8 8 8个方向的直方图。
在这里插入图片描述
每个特征点必须分配一个主方向,还需要一个或多个辅方向,增加辅方向的目的是为了增强图像匹配的鲁棒性。辅方向的定义是,当一个柱体的高度大于主方向柱体高度的80%时,则该柱体所代表的的方向就是给特征点的辅方向。

直方图的峰值,即最高的柱代表的方向是特征点邻域范围内图像梯度的主方向,但该柱体代表的角度是一个范围,所以我们还要对离散的直方图进行插值拟合,以得到更精确的方向角度值。利用抛物线对离散的直方图进行拟合,如下图所示:

在这里插入图片描述
获得图像关键点主方向后,每个关键点有三个信息 ( x , y , σ , θ ) (x,y,σ,θ) (x,y,σ,θ):位置、尺度、方向。由此我们可以确定一个 S I F T SIFT SIFT特征区域。通常使用一个带箭头的圆或直接使用箭头表示 S I F T SIFT SIFT区域的三个值:中心表示特征点位置,半径表示关键点尺度,箭头表示方向。如下图所示:
在这里插入图片描述

1.1.5 关键点描述

通过以上步骤,每个关键点就被分配了位置,尺度和方向信息。接下来我们为每个关键点建立一个描述符,该描述符既具有可区分性,又具有对某些变量的不变性,如光照,视角等。而且描述符不仅仅包含关键点,也包括关键点周围对其有贡献的的像素点。主要思路就是通过将关键点周围图像区域分块,计算块内的梯度直方图,生成具有特征向量,对图像信息进行抽象。

描述符与特征点所在的尺度有关,所以我们在关键点所在的高斯尺度图像上生成对应的描述符。以特征点为中心,将其附近邻域划分为 d ∗ d d∗d dd个子区域(一般取 d = 4 d=4 d=4),每个子区域都是一个正方形,边长为 3 σ 3σ 3σ,考虑到实际计算时,需进行三次线性插值,所以特征点邻域的为 3 σ ( d + 1 ) ∗ 3 σ ( d + 1 ) 3σ(d+1)∗3σ(d+1) 3σ(d+1)3σ(d+1)的范围,如下图所示:
在这里插入图片描述
为了保证特征点的旋转不变性,以特征点为中心,将坐标轴旋转为关键点的主方向,如下图所示:
在这里插入图片描述
计算子区域内的像素的梯度,并按照 σ = 0.5 d σ=0.5d σ=0.5d进行高斯加权,然后插值计算得到每个种子点的八个方向的梯度,插值方法如下图所示:
在这里插入图片描述

每个种子点的梯度都是由覆盖其的 4 4 4个子区域插值而得的。如图中的红色点,落在第 0 0 0行和第 1 1 1行之间,对这两行都有贡献。对第 0 0 0行第 3 3 3列种子点的贡献因子为 d r dr dr,对第 1 1 1行第3列的贡献因子为 1 − d r 1-dr 1dr,同理,对邻近两列的贡献因子为 d c dc dc 1 − d c 1-dc 1dc,对邻近两个方向的贡献因子为 d o do do 1 − d o 1-do 1do。则最终累加在每个方向上的梯度大小为:

w e i g h t = w ∗ d r k ( 1 − d r ) 1 − k d c m ( 1 − d c ) 1 − m d o n ( 1 − d o ) 1 − n weight=w*dr^{k}(1-dr)^{1-k}dc^{m}(1-dc)^{1-m}do^{n}(1-do)^{1-n} weight=wdrk(1dr)1kdcm(1dc)1mdon(1do)1n

其中 k , m , n k,m,n kmn 0 0 0或为 1 1 1。 如上统计4∗4∗8=128个梯度信息即为该关键点的特征向量,按照特征点的对每个关键点的特征向量进行排序,就得到了SIFT特征描述向量。

1.1.6 总结

S I F T SIFT SIFT在图像的不变特征提取方面拥有无与伦比的优势,但并不完美,仍然存在实时性不高,有时特征点较少,对边缘光滑的目标无法准确提取特征点等缺陷,自 S I F T SIFT SIFT算法问世以来,人们就一直对其进行优化和改进,其中最著名的就是 S U R F SURF SURF算法。

1.2 SURF原理

使用 S I F T SIFT SIFT 算法进行关键点检测和描述的执行速度比较慢, 需要速度更快的算法。 2006 年 Bay提出了 S U R F SURF SURF 算法,是 S I F T SIFT SIFT算法的增强版,它的计算量小,运算速度快,提取的特征与 S I F T SIFT SIFT几乎相同,将其与 S I F T SIFT SIFT算法对比如下:

在这里插入图片描述

1.3 实现

在OpenCV中利用SIFT检测关键点的流程如下所示:

1.实例化sift

sift = cv.xfeatures2d.SIFT_create()

2.利用sift.detectAndCompute()检测关键点并计算

kp,des = sift.detectAndCompute(gray,None)

参数:

  • gray: 进行关键点检测的图像,注意是灰度图像

返回:

  • kp: 关键点信息,包括位置,尺度,方向信息
  • des: 关键点描述符,每个关键点对应128个梯度信息的特征向量

3.将关键点检测结果绘制在图像上

cv.drawKeypoints(image, keypoints, outputimage, color, flags)

参数:

  • image: 原始图像
  • keypoints:关键点信息,将其绘制在图像上
  • outputimage:输出图片,可以是原始图像
  • color:颜色设置,通过修改(b,g,r)的值,更改画笔的颜色,b=蓝色,g=绿色,r=红色。
  • flags:绘图功能的标识设置
    1. cv2.DRAW_MATCHES_FLAGS_DEFAULT:创建输出图像矩阵,使用现存的输出图像绘制匹配对和特征点,对每一个关键点只绘制中间点
    2. cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG:不创建输出图像矩阵,而是在输出图像上绘制匹配对
    3. cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS:对每一个特征点绘制带大小和方向的关键点图形
    4. cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS:单点的特征点不被绘制

S U R F SURF SURF算法的应用与上述流程是一致,这里就不在赘述。

示例:

利用 S I F T SIFT SIFT算法在中央电视台的图片上检测关键点,并将其绘制出来:

import cv2 as cv 
import numpy as np
import matplotlib.pyplot as plt
# 1 读取图像
img = cv.imread('./image/tv.jpg')
gray= cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# 2 sift关键点检测
# 2.1 实例化sift对象
sift = cv.xfeatures2d.SIFT_create()# 2.2 关键点检测:kp关键点信息包括方向,尺度,位置信息,des是关键点的描述符
kp,des=sift.detectAndCompute(gray,None)
# 2.3 在图像上绘制关键点的检测结果
cv.drawKeypoints(img,kp,img,flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# 3 图像显示
plt.figure(figsize=(8,6),dpi=100)
plt.imshow(img[:,:,::-1]),plt.title('sift检测')
plt.xticks([]), plt.yticks([])
plt.show()

结果:

在这里插入图片描述


总结

SIFT原理:

  • 尺度空间极值检测:构建高斯金字塔,高斯差分金字塔,检测极值点。

  • 关键点定位:去除对比度较小和边缘对极值点的影响。

  • 关键点方向确定:利用梯度直方图确定关键点的方向。

  • 关键点描述:对关键点周围图像区域分块,计算块内的梯度直方图,生成具有特征向量,对关键点信息进行描述。

API:cv.xfeatures2d.SIFT_create()

SURF算法:

对SIFT算法的改进,在尺度空间极值检测,关键点方向确定,关键点描述方面都有改进,提高效率

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

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

相关文章

Mac下使用Homebrew安装MySQL5.7

Mac下使用Homebrew安装MySQL5.7 1. 安装Homebrew & Oh-My-Zsh2. 查询软件信息3. 执行安装命令4. 开机启动5. 服务状态查询6. 初始化配置7. 登录测试7.1 终端登录7.2 客户端登录 参考 1. 安装Homebrew & Oh-My-Zsh mac下如何安装homebrew MacOS安装Homebrew与Oh-My-Zsh…

港陆证券:服装家纺公司上半年投资并购力度加大

9月1日,嘉曼服饰发布公告,为完善多品牌差异化开展战略,将以自有资金收买暇步士(Hush Puppies)品牌我国内地及香港、澳门区域IP财物。 面对服饰市场的激烈竞争,本年以来一些服饰类A股公司开启了“买买买”形…

SSRF服务端请求伪造

服务端请求伪造,其实就是攻击者构造恶意请求,服务端发起恶意请求,如果服务端不对用户传递的参数进行严格的过滤和限制,就可能导致服务端请求伪造 上面是百度识图,我们可以传递图片地址,百度识图向图片发起…

哈夫曼编码实现文件的压缩和解压

程序示例精选 哈夫曼编码实现文件的压缩和解压 如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助! 前言 这篇博客针对《哈夫曼编码实现文件的压缩和解压》编写代码,代码整洁,规则&#xff0…

C语言:字符函数和字符串函数(一篇拿捏字符串函数!)

目录 求字符串长度: 1. strlen(字符串长度) 长度不受限制函数: 2. strcpy(字符串拷贝) 3. strcat(字符串追加) 4. strcmp(字符串比较) 长度受限制函数: 5. strncpy(字符串拷贝) 6. strncat(字符串追加) 7. strncmp(字符串比较) 字…

【GAMES202】Real-Time Global Illumination(in 3D)—实时全局光照(3D空间)

一、SH for Glossy transport 1.Diffuse PRT回顾 上篇我们介绍了PRT,并以Diffuse的BRDF作为例子分析了预计算的部分,包括Lighting和Light transport,如上图所示。 包括我们还提到了SH,可以用SH的有限阶近似拟合球面函数&#xff…

购物商场项目实践

1.项目开始 1)此项目为在线电商项目 2)包含首页,搜索列表,商品详情,购物车,订单,支付,用户登录/注册等多个子模块 3)使用Vue全家桶ES6webpackAxios等前端技术 4&…

Pandas数据分析基础—pandas自带函数map()/apply()/applymap()

文章目录 前言一、Series数据处理1、map()方法2、apply()方法3、applymap()方法总结 二、DataFrame数据处理1、map()方法2、apply()方法3、applymap()方法总结 三、map、apply、applymap三个函数区别 前言 在进行数据处理时,经常会对一个DataFrame展开逐行、逐列、…

【AI】机器学习——绪论

文章目录 1.1 机器学习概念1.1.1 定义统计机器学习与数据挖掘区别机器学习前提 1.1.2 术语1.1.3 特点以数据为研究对象目标方法——基于数据构建模型SML三要素SML步骤 1.2 分类1.2.1 参数化/非参数化方法1.2.2 按算法分类1.2.3 按模型分类概率模型非概率模型逻辑斯蒂回归 1.2.4…

redis 数据结构(二)

整数集合 整数集合是 Set 对象的底层实现之一。当一个 Set 对象只包含整数值元素,并且元素数量不时,就会使用整数集这个数据结构作为底层实现。 整数集合结构设计 整数集合本质上是一块连续内存空间,它的结构定义如下: typed…

避雷,软件测试常见的误区之一

随着软件规模的不断扩大,软件设计的复杂程度不断提高,软件开发中出现错误或缺陷的机会越来越多。同时,市场对软件质量重要性的认识逐渐增强。所以,软件测试在软件项目实施过程中的重要性日益突出。但是,现实情况是&…

喜讯 | 数智经营新典范,体验家XMPlus荣获「年度数智经营服务商」

7月27日,“助力运营知识与创新传播”的内容服务平台——运营研究社举行了「2023数字化运营生态大会」,会上正式揭晓了「2023数字化运营生态大奖」的四大榜单,体验家XMPlus荣获「年度数智经营服务商」!现场有800运营伙伴齐聚&#…

python 笔记(3)——request、爬虫、socket、多线程

目录 1、使用requests发送http请求 1-1)发送get请求 1-2)发送 post 请求 1-3)发送 get 请求下载网络图片 1-4)使用 post 上传文件 1-5)自动维护 session 的方式 2、使用 os.popen 执行cmd命令 3、基于 beautif…

【微服务部署】五、Jenkins+Docker一键打包部署NodeJS(Vue)项目的Docker镜像步骤详解

NodeJS(Vue)项目也可以通过打包成Docker镜像的方式进行部署,原理是先将项目打包成静态页面,然后再将静态页面直接copy到Nginx镜像中运行。 一、服务器环境配置 前面说明了服务器Nginx的安装和配置,这里稍微有些不同&a…

mysql Index

创建索引 方法1 create table 表( col1 int, col2 int, … index | key index_name (列名) 方法2 alter table 表名 ADD index alter table student_table add index index_name(stu_id); 方法3 create index index_name on 表名(列) 删除索引 方式1 alter table xx drop prima…

革命性的电子元件:RAD继电器 | 百能云芯

在现代电子和通信系统中,RAD继电器是一种关键的电子元件,它在各种应用中发挥着重要作用。RAD继电器(Reed-relay Actuated Device)是一种基于磁性原理的电子开关,其特点是极其高速、可靠、低功耗和长寿命。下面云芯将为…

案例分享:西河水库安全监测信息化系统实施方案

一、项目概述1.1项目背景西河水库信息化工作已开展多年,但是由于西河水库监测设备都已经老化或者损坏,现有设备已渐渐不能满足新时期西河水库信息化和现代化发展需求。因此,灌区管理局拟在运用现代信息和通信技术手段感测、分析、整合水库运行…

el-date-picker自定义只能选中当前月份和半年内月份等

需求:el-date-picker只能选中当前月期和当前月期往前半年,其他时间就禁用了不让选择了,因为没数据哈哈。当然也可以选择往前一年等。 一、效果 二、写个日期选择器 :picker-options:日期选项 value-format:选择后的格…

设计模式-工厂模式Factory

工厂模式 b.工厂方法模式 (Factory Method) (重点)1) 简单工厂 Simple Factory1.a) 简单工厂的好处 2) 工厂方法 Factory Method2.a) 对工厂进行抽象化 (版本一)2.b) 对工厂进行缓存 (版本二)2.c) 加载配置文件到缓存中 (版本三)c.1) 产品线 c.抽象工厂模式 (Abstract Factory)…

SQL-DQL

-----分组查询----- 1.语法: SELECT 字段列表 FROM 表名 [WHERE 条件 ] GROUP BY 分组字段名 [HAVING 分组后过滤条件]; 2.where与having区别 》执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组&…