用于表示和量化图像的数字列表,简单理解成将图片转化为一个数字列表表示。特征向量中用来描述图片的各种属性的向量称为特征矢量。
参考
是一种算法和方法,输入1个图像,返回多个特征向量(主要用来处理图像的局部,往往会把多个特征向量组成一个一维的向量)。主要用于图像匹配(视觉检测),匹配图像中的物品。
SIFT论文
原理
opencv官网解释
实质是在不同的尺度空间上查找关键点(特征点),并计算出关键点的方向。SIFT所查找到的关键点是一些十分突出,不会因光照,仿射变换和噪音等因素而变化的点,如角点、边缘点、暗区的亮点及亮区的暗点等。
尺度不变特征转换(Scale-invariant feature transform或SIFT)是一种电脑视觉的算法用来侦测与描述影像中的局部性特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量。
其应用范围包含物体辨识、机器人地图感知与导航、影像缝合、3D模型建立、手势辨识、影像追踪和动作比对。
对现实中物体的描述一定要在一个十分重要的前提下进行,这个前提就是对自然界建模时的尺度。当用一个机器视觉系统分析未知场景时,计算机没有办法预先知道图像中物体的尺度,因此我们需要同时考虑图像在多尺度下的描述,获知感兴趣物体的最佳尺度。图像的尺度空间表达指的是图像的所有尺度下的描述。
KeyPoint数据结构解析
SURF论文
原理
opencv官网解释
SURF是SIFT的加速版,它善于处理具有模糊和旋转的图像,但是不善于处理视角变化和光照变化。在SIFT中使用DoG对LoG进行近似,而在SURF中使用盒子滤波器对LoG进行近似,这样就可以使用积分图像了(计算图像中某个窗口内所有像素和时,计算量的大小与窗口大小无关)。总之,SURF最大的特点在于采用了Haar特征以及积分图像的概念,大大加快了程序的运行效率。
因为专利原因,OpenCV3.3开始不再免费开放SIFT\SURF,需要免费的请使用ORB算法
ORB算法综合了FAST角点检测算法和BRIEFF描述符。
算法原理
opencv官方文档
FAST只是一种特征点检测算法,并不涉及特征点的特征描述。
论文
opencv官方文档
中文版
Brief是Binary Robust Independent Elementary Features的缩写。这个特征描述子是由EPFL的Calonder在ECCV2010上提出的。主要思路就是在特征点附近随机选取若干点对,将这些点对的灰度值的大小,组合成一个二进制串,并将这个二进制串作为该特征点的特征描述子。文章同样提到,在此之前,需要选取合适的gaussian kernel对图像做平滑处理。
1:不具备旋转不变性。
2:对噪声敏感
3:不具备尺度不变性。
ORB论文
OpenCV官方文档
ORB采用了FAST作为特征点检测算子,特征点的主方向是通过矩(moment)计算而来解决了BRIEF不具备旋转不变性的问题。
ORB还做了这样的改进,不再使用pixel-pair,而是使用9×9的patch-pair,也就是说,对比patch的像素值之和,解决了BRIEF对噪声敏感的问题。
关于计算速度:
ORB是sift的100倍,是surf的10倍。
对图片数据、特征分布的一种统计
对数据空间(bin)进行量化
Kmeans
边缘:尺度问题->不同的标准差 捕捉到不同尺度的边缘
斑点 Blob:二阶高斯导数滤波LoG
关键点(keypoint):不同视角图片之间的映射,图片配准、拼接、运动跟踪、物体识别、机器人导航、3D重建
SIFT\SURF
这个用不着SURF。只需要聚色彩就可以了。芬达主要由橙色与黑色组成。只需要按橙色与黑色设计两个向量指标,立刻就可以看出来,只有芬达同时符合这两个峰值。你显然没有做过数据处理的经验。这个东西。甚至用不着opencv的核心功能。只需要用它的图像采集然后处理一下图像就可以了。
当然芬达是一个对象。你还需要将对象与背景分享出来。这个时候,可以使用一些类似人脸识别的算法。
但是换作是我自己。显然不会这样做。我只需要计算颜色距离相似度。把相似的颜色自动分成区域。然后计算区域的重心与离散度。就可以轻松分离出哪些区域是背景,哪些是对象。
import os
print(os.name) # 操作系统名称 Windows nt 非Windows posix
print(os.sep) # 路径分隔符 Windows \ 其他 /
import os
# 使用 os.path 方法获取文件的路径
# 001.获取文件的绝对路径 使用abspath方法
print(os.path.abspath("04_模块导入.py"))
# 运行结果:D:\mypycharm\pythonProject\千峰培训\day11module1\04_模块导入.py
# 002判断是否是文件 False
print(os.path.isdir(""))
# 运行结果: False
# 003.判断文件是否存在如果存在返回True 否则返回False
print(os.path.exists("mydir"))
# True
import os
files = "2020.12.22.test.py"
print(files.rpartition(".")[-1])
print(os.path.splitext(files)[-1])
# 运行结果:
# 获取文件的后缀名 py
# 获取文件的后缀名 .py
import os
print(os.getcwd())
# 运行结果:
# D:\mypycharm\pythonProject\培训\day11module1
import os
os.chdir("mydir")
print(os.getcwd())
# D:\mypycharm\pythonProject\培训\day11module1\mydir
import os
os.rename("66.py","../99.py")
import os
# 001.删除文件
os.remove("../99.py")
# 002.删除空文件夹
os.rmdir("../mydir")
os.removedirs("mydir")
import os
os.mkdir("mydir")
import os
# 001.列出指定目录里所有的子目录和文件
print(os.listdir("D:\mypycharm\pythonProject"))
# 002.默认当前目录里的 子目录和文件
print(os.listdir())
# 运行结果:
# ['.idea', '千峰培训', '学校实习']
# ['03_module.py', '04_模块导入.py', '05_os.py', '2020.12.22.tests.py', 'a01_module1.py', 'a02_module2.py', '__pycache__']
import os
print(os.environ)
print(os.environ["PATH"])
import os
import string # 字符串模块
import random
files = "test.jpg"
# 01.获取文件的后缀
surffix = os.path.splitext(files)[-1]
# print(surffix) # .jpg
# 02.生成所有大小写字母的列表
res = list(string.ascii_letters)
# print(string.ascii_letters)
# 运行结果;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
# 03.将0-9添加到res中
for i in range(0, 10):
res.append(str(i))
# 04.随机生成文件名:
mystr = "".join(random.sample(res, 10)) # sample随机生成10个字符
# print(mystr)
# bJpED6dj2Y
# 05.将文件名和后缀拼接
print(mystr+surffix)
import sys
print(sys.path)
res = sys.stdin
print(res)
import math
# print(math.pi) # 3.141592653589793
print(math.factorial(5)) # 120
# 幂运算 第一个参数是底数 第二个参数是幂
print(math.pow(2, 3)) # 8.0
# 向上取整和向下取整
print(math.floor(15.999)) # 15
print(math.ceil(15.001)) # 16
# 四舍五入
print(round(123.51, 1)) # 123.5
# 三角函数
print(math.sin(math.pi / 6)) # sin(pi/6) 0.49999999999999994
print(math.cos(math.pi / 3)) # sin(pi/3) 0.5000000000000001
print(math.tan(math.pi / 4)) # sin(pi/6) 0.9999999999999999
# 开方
a = 9
b = 16
print(math.sqrt(a+b)) # 5.0
# 以e为底的指数函数
print(math.exp(a))
# 8103.083927575384
import random
# 01.random() 随机生成[0,1)之间的数 前闭后开
print(random.random()) # 生成[0,1)之间的小数
# 02.randint() 生成范围内的随机整数 全闭
print(random.randint(10, 20)) # 生成[10,20]之间的整数
# 03.randrange() 生成范围内的随机整数 前闭后开
print(random.randrange(10, 20)) # 生成[10,20)之间的整数
# 04.choice 参数是列表 随机从列表中取一个 取一次
print(random.choice([1, 2, 3, 4, 5, 6, 77, 8, 9]))
# 05.sample 的第一个参数 必须是一个可迭代对象
# 第二个参数代表着从可迭代对象从随机选取几个,选取的对象不能重复
print("".join(random.sample(["a", "b", "c", "d"], 3)))
import datetime as dt # 引入datetime 模块并将其命别名为dt
import time
import calendar # 引入日历模块
# 01.datetime模块
# 001.获取当前时间的具体信息
print(dt.datetime.now())
# 运行结果:
# 2020-12-26 15:36:36.408129
# 年 月 日 时 分 秒 毫秒
# 002.创建日期
print(dt.date(2020,1,1))
# 年月日 2020-01-01
# 003.创建时间
print(dt.time(16,30,30))
# 时 分 秒: 16:30:30
# 004.timedelta() 括号中的默认参数是天
print(dt.datetime.now()+dt.timedelta(3)) # 2020-12-25 15:50:15.811738
print(dt.datetime.now()+dt.timedelta(hours=3)) # 2020-12-22 18:51:41.723093
print(dt.datetime.now()+dt.timedelta(minutes=10)) # 2020-12-22 16:01:41.723093
# 02.time
# 001.当前时间的时间戳
# 时间戳是指从1970—01-01 0:0:0到现在的秒数 utc时间 也叫格林尼治时间
print(time.time())
# 002.按照指定格式输出时间
# print(time.strftime("%Y-%m-%d %H:%M:%S")) # 2020-12-22 15:57:49
# 时间格式:
# %Y Year with century as a decimal number.
# %m Month as a decimal number [01,12].
# %d Day of the month as a decimal number [01,31].
# %H Hour (24-hour clock) as a decimal number [00,23].
# %M Minute as a decimal number [00,59].
# %S Second as a decimal number [00,61].
# %z Time zone offset from UTC.
# %a Locale's abbreviated weekday name.
# %A Locale's full weekday name.
# %b Locale's abbreviated month name.
# %B Locale's full month name.
# %c Locale's appropriate date and time representation.
# %I Hour (12-hour clock) as a decimal number [01,12].
# %p Locale's equivalent of either AM or PM.
# 003.ctime 和 asctime 时间格式 输出的时间格式一样,
# print(time.asctime()) # Tue Dec 22 15:57:49 2020
# print(time.ctime()) # Tue Dec 22 15:58:35 2020
# 004.sleep() 时间休眠
print("我负责浪")
print(time.sleep(3))
print("你负责漫")
# 005.calender 生成日历
res = calendar.calendar(2021) # 生成2021年的日历
print(res)
# 006.判断是否为闰年
print(calendar.isleap(2020)) # True
# 007.从1988年 到 2020年有多少个闰年
print(calendar.leapdays(1988, 2020)) # 8