学习OpenCV3
文章目录
官网 中文文档
学习视频感谢
学习视频二感谢
停车场车辆识别
openCV模块介绍
- Core:该模块包含OpenCV库的基础结构以及基本操作
- Improc:图像处理模块包含基本的图像转换,包括过滤以及类似卷积操作
- Highgui:(在OpenCV 3.0中,分割为imcodecs、videoio以及highgui三部分)这个模块包含可以使用来显示图像或者简单的输入的用户交互函数。这可以看作是一个非常轻量的windows UI工具
- Video:该模块包含读取和写视频的函数
- Calib3d:这个模块包括用于检测、描述以及匹配特征点的算法
- Feature2d:这个模块用于检测、描述以及匹配特征点的算法
- objectect:这个模块包含检测特定目标,比如人脸或者行人的算法。也可以训练检测器并用来检测其他物体
- M1:机器学习模块本身是一非常完备的模块,包含大量的机器学习算法实现并且这些算法能和OpenCV的数据类型自然交互
- Flann:Flann的意思是”快速最邻居的库“。这个库包含一些你也许不会直接使用的方法,但是其他的模块中的函数调用它在数据集中进行最邻近搜索
- GPU:(在OpenCV 3.x中被分割为多个cuda*模块)GPU模块主要是函数在CUDA GPU上优化实现,此外,还有一些仅用于GPU的功能。其中一些函数能够返回很好的结果,但是需要足够好的计算资源,如果硬件没有GPU,则不会有什么提升
- Photo:包含计算摄影学的一些函数工具
- Stitching:本模块是一个精巧的图像拼接流程实现。这是库中的新功能
- Nonfree:(在OpenCV 3.0中被移到opencv_contrib|xfeatures2d)OpenCV包含一些受到专利保护或者受到使用限制的(SIFT算法)。这些算法被隔离到他们自己的模块中,以表明你需要做一些特殊工作,才可以在商业产品中使用他们
- Contrib:(OpenCV 3.0中,融合进了opencv_contrib)这个模块包含一些新的、还没被集成到openCV库的东西
- Legacy:(OpenCV 3.0中,被取消)一些老的尚未被完全取消的东西
- 0cl:(OpenCV 3.0中,被取消,取而代之的是T-API)实现了开放并行编程的Khronos OpenCL标准。虽然现在模块的特性比GPU模块少很多,但0cl模块的目标是提供可以运行在任何GPU或者是其他可以搭载Khronos的并行设备。这与GPU模块形成了鲜明的对比,后者使用Nividia CUDA工具包进行开发,因此只能在Nividia GPU设备上工作。
零散内容
机械设备主要使用的色彩空间是 SHV(HBS:亮度混入黑色量)
- Hue:色相,即色彩,如红色、蓝色、用角度度量,取值范围为0°~360°,从红色开始逆时针方向计算,红色为0°,绿色为120°,蓝色为240°
- Saturation:饱和度,表示颜色接近光谱色的程度。一种颜色,可以看成某种光谱色与白色的混合的结果。其中光谱色所占的比例越大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高。饱和度高,颜色则深而艳。光谱色的白光成分为0,饱和度达到最高。通常取值为0%~100%,值越大,颜色越饱和。
- Value:明度,明亮表示颜色的明亮程度,对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射比活反射比有关。通常取值范围为0%(黑)到100%(白)
图片处理
滤波/卷积核
方盒滤波 cv.blur()
均值滤波 cv.boxFilter()
高斯滤波 cv.GaussianBlur(src,ksize,sigmaX[,dst[,sigmaY[,borderType]]])
- kernel 高斯核大小
- sigmaX X轴的标准差
- sigmaY Y轴的标准差,默认0,这是sigmaY=sigmaX
- 如果没有制定sigma值,会分布从ksize的宽度和高度汇总计算sigma。选择权不同的sigma值会得到不同的平滑效果,sigma越大,平滑效果越明显
缺点: 模糊边,物体轮廓
中值滤波 cv.mexdianBlur() 列:cv.medianBlur(img,5)
- 处理胡椒噪音,或椒盐噪音
- 例如:3X3的卷积核中的9个数字排序后取中位数
双边滤波 cv.bilateralFilter(src,d,sigmaColor,sigmaSpace[,dst[,borderType]])
- sigmaColor是计算像素信息使用的sigma
- sigmaSpace是计算空间信息的sigma
- 高斯滤波+灰度距离,降低噪声、轻度模糊物体轮廓
不足: 对椒盐噪声没有效果
高斯滤波
高斯分布:例如3x3的核中,每一个点的分布概率密度
图片中有一些老实电视上的白色雪花点时高时模糊能有效的减少这种模糊的点
算子
算子主要是用来找边界的,图像边缘特征
索贝尔(sobel)算子
边缘像素值发生越阡的位置,是图像的显著特征之一,在图像特征提取,对象检测,模式识别等方面都有重要的作用。人眼识别图像的边缘,是像素的灰度值快速变化的地方。
sobel:算子对图像求一阶导数。一阶导数越大,说明像素在该方向的变化越大,边缘信号越强。因为图像的灰度值都是离散的数组,sobel算子采用的离散分差算子计算图像像素点点亮度值的近似梯度。
沙尔(Scharr)算子
Scharr(src,ddepth,dx,dy[,dst,[,scale[,delta,[,borderType]]]])
当内核大小为3时以上Sobel内核可能产生比较明显的误差(毕竟,Sobel算子只是求取了倒数的近似值)为了解决这一问题,OpenCV提供了Scharr函数,但该函数仅作用于大小为3的内涵。该内核的运算与Sobel函数块一样,但结果更加精准。Scharr算子和Sobel很类似,只不过使用不同的kernel值没放大了像素变换的情况
- Scharr算子只支持3X3的kernel所以没有kernel参数
- 只能求x方向和y方向的边缘
- ksize是遏制为-1就是Scharr算子
- 擅长寻找细小的边缘,一般用的较少
拉普拉斯算子
索贝尔算子时模拟一阶求导,导数越大说明变换越剧烈,越有可能是边缘
Laplacian(src,ddepth[,[,ksize[,scale[,delta[,borderType]]]]])
- 需要先去除噪声在使用拉普拉斯算子
Canny边缘检测 实际使用
边缘检测的主要标准
- 低错误率:标识出尽可能多的实际边缘,同时尽可能的减少噪声产生的误报
- 高定位性:标识出的边缘要与图像中的边缘尽可能接近
- 最小响应:图像中的边缘只能表示一次
Canny边缘检测需要
Canny(img,minVal,maxVal…r)
- 去除噪声:边缘容易受到噪声的影响,一般使用高斯滤波去去除噪声
- 计算梯度:对平滑后的图像采用sobel算子计算梯度方向
形态学
- 一系列处理图像形状特征的图像处理技术
- 形态学的基本思想是利用一种特殊的结构元(只有0和1的卷积核)来测量或提取输入的图像中相应的形状或特征,以便进一步进行图像分析和目标识别
- 这些处理方法基本是对二进制图像处理,即黑白图像
- 形态学基本操作有
- 膨胀和腐蚀
- 开运算
- 闭运算
- 顶帽
- 黑帽
获取形态学卷积核
getStructuringElement(shape,ksize[,anchor])
- shape 卷积核的形状,这里是不是指长宽,是指卷积核中1形成的形状
- MORPH_RECT 卷积核中1是矩形常用
- MORPH_ELLIPSSE 圆锥
- MORPH_CROSS 十字
全局二值化
二值化:将图像的每一个像素变成两种值0,255
threshold(src,thresh,maxval,type[,dst])
- src 最好是灰度图
- thresh 阈值
- maxval 最大值,最大值不一定是255
- type 操作类型
- cv.THRESH_BINARY
- cv.THRESH_BINARY_INV
- cv.THRESH_TRUNC 超过阈值截断
- cv.THRESH_TOZERO
- cv.THRESH_TOZERO_INV
自适应阈值二值化
二值化是对灰度图的操作
前面的方式都是使用的全局阈值,整幅图片采用同一个数字作为阈值,但是这种方式并不适用所有情况一张图片上有不同的亮度时,需要采用自适应阈值。自适应阈值根据每一个小的区域计算与其对应的阈值。因此在同一幅图像上的不同区域采用不同的阈值,从而使我们能亮度不同的情况下得到更好的效果。
adaptiveThreshold(src,maxValue,adaptiveMethod,thresholdType,blockSize,C,dst=None)
- Adaptive Method 指定计算阈值的方法
- cv2.ADPTIVE_THRESH_MEAN_C 阈值取自相邻区域的平均值
- cv2.ADPTIVE_THRESH_GAUSSIAN_C 阈值取值相邻区域的加权和,权重为一个高斯窗口
- Block Size 领域大小
- C 一个常数,阈值等于平均值活着甲醛平均值减去这个常数
腐蚀操作
黑色覆盖白色
腐蚀操作也是用卷积核扫描图像,腐蚀操作的卷积核一般都是1,如果卷积核内所有的像素点都是白色那么锚点即为白色
erode(src,kernel[,dst[,anchor[,iterations[,borderTypel[,borderValue]]]]])
- iterations 腐蚀操作的迭代次数,次数越多,腐蚀效果越明显
膨胀操作
腐蚀的反操作,卷积核锚点非0值周边都变成0(白色覆盖黑色)
dilate(img,kernel,iterations=1)
开运算、闭运算
开运算 = 腐蚀+膨胀
morphologyEx(img,MORPH_OPEN,lernel,iterations)
- MORPH_OPEN 形态学的开运算
- kernel 如果噪点比较多,会选择大一点的kernel,如果噪点比较小选择小一点的kernel
闭运算 = 膨胀+腐蚀
cv.morphologyEx(img,cv.MORPH_CLOSE,kernel,iterations=1)
形态学梯度
梯度 = 原图 - 腐蚀 , 可以得到腐蚀掉部分图形,图形边缘
cv.morphologyEx(img,cv.MORPH_GRADIENT,kernel,iterations=1)
顶帽操作
顶帽 = 原图 - 开运 ,获得去除掉的噪点
cv.morphologyEx(img,cv.MORPH_TOPHAT,kernel,iterations=1)
黑帽操作
黑帽子 = 闭运算 - 原图 , 去除图片内部的噪点
cv.morphologyEx(img,cv.MORPH_BLACKHAT,kernel,iterations=2)
图像轮廓
图像轮廓是具有相同颜色或灰度的连续点的曲线,轮廓在形状分析和物体的检测和识别中很有用。一般检测之前需要做二值化或Canny操作画轮廓时会修改输入的图像,如果自后想继续使用原始图,应该将原始图存储到其他变量中
查找轮廓
findContour(image,mode,method[,contours[,hierarchy[,offset]]])
- mode 查找轮廓的模式
- RETR_EXTERNAL = 0 只检测外围轮廓
- RETR_LIST = 1 检测的轮廓不建立等级关系,即检查所有轮廓,较为常用
- RETR_CCOMP = 2 每次最多两级,从小到大,从里到外
- RETR_TREE = 3 按照树型存储轮廓,从大到小,从右到左
- method 轮廓近似方法ApproximationMode
- CHAIN_APPROX_NONE 保存所有轮廓上的点
- CHAIN_APPROX_SIMPLE 只保存角点,只保留四边行的4个角,存储信息少,比较常用
- 返回 contours和hirarchy即轮廓和层级
# 查找轮廓
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# 二值化
ret,binary = cv.threshold(gray,150,255,cv.THRESH_BINARY)
# 查找轮廓,新版本返回2个结果,轮廓和层,老版本返回3个参数 图像、轮廓、层级
contours,hierarchy = cv.findContours(binary,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
查找出来的 contours时所有的点坐标,在绘制轮廓
drawContours(image,contours,contourldx,color[,thickness[,lineType[,hierarchy[,maxlevel[,offset]]]]])
- image 绘制轮廓的图像
- contours 轮廓点
- contourldx 要绘制的编号,-1表示绘制所有轮廓
- color 轮廓的颜色(0,0,0)
- thickness 线宽 -1 表示全部填充
# 绘制轮廓,绘制会直接修改原图,最好拷贝一份
img_copy = img.copy()
cv.drawContours(img_copy,contours,-1,(0,0,255),1)
cv.imshow('绘制边',np.hstack((img,img_copy)))
计算轮廓面积、周长
轮廓面积是所有像素点围成的区域面积,单位为像素,轮廓面积是重要的统计特征之一,通过轮廓面积的大小进一步分析每个轮廓隐含的信息,例如通过轮廓面积区分物体大小识别不同物体。同时查找轮廓过程中,可能出现很多细小的轮如上图头发哪里,可以通过轮廓面积过滤。
- contourArea(contour) 面积
- arcLength(cuve,closes) 周长
- curve 轮廓
- closed 是否闭合轮廓
多边形逼近
findContours后的轮廓信息contours比较详细,边不平滑。可以使用approxPolyDP函数对该多边形曲线做适当近似,这就是轮廓的多边形逼近。approxPolyDP采用的是Douglas-Peucker算法简称DP(DP算法就是不断找多边形远的点加入形成新的多边形,知道最短距离小于指定的精度)
approxPolyDP(curve,epsilon,closed[,approxCurve])
- curve 要近似毕竟的轮廓
- epsilon 即DP算法使用的阈值
- closes 轮廓是否闭合
# 近似轮廓 approx npArray 转换列表
approx = cv.approxPolyDP(contours[10],10,closed=True)
cv.drawContours(img_copy,[approx],0,(0,0,255),2)
cv.imshow('近似轮廓',np.hstack((img,img_copy)))
凸包
逼近多边形是轮廓的高度近似,但是有时候,我们希望使用一个多边形的凸包来简化它。凸包跟逼近多边形很想,只不过他是物体最外层的凸多边形。凸包指的是完全包含原有轮廓,并且金柚轮廓上的点所构成的多边形。凸包的每一处都是凸的,即在凸包内链接任意两点的直线都在凸包内部。凸包内,任意联系的三个点内角小于180度
convexHull(points[,hull[,clockwise[,returnPoints]]])
- points 即轮廓
- colckwise 顺时针绘制
绿色是凸包边
外接矩形
红色框:最小外接矩形,绿色框:最大外接矩形
minAreaRect(points) 最小
- points 即为轮廓
- 返回元组,内容是一个选择矩形(RotatedRect)参数矩形的起始坐标x,y举行的宽度和高度,矩形的旋转角度
boundingRect(points) 最大外接矩阵
- points 轮廓
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,binary = cv.threshold(gray,150,255,cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(binary, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
# 最小外接矩形 获得一个旋转矩形数据 矩形启始坐标(x,y),矩形长宽,矩形旋转角度
rect = cv.minAreaRect(contours[10])
# 计算出矩形的4个坐标
box = cv.boxPoints(rect)
# box = np.int0(box) # 截取小数
box = np.round(box).astype('int64') # 四舍五入后转int
# 绘制出来 contours里面必须是整数 box中通过计算得到的是浮点数会报错
img_min = img.copy()
cv.drawContours(img_min,[box],0,(255,0,0),1)
# 最大外接矩形 返回 x,y,w,h
x,y,w,h =cv.boundingRect(contours[10])
img_max = img.copy()
cv.rectangle(img_max,(x,y),(x+w,y+h),(0,0,255),1)
cv.imshow('最小矩形',np.hstack((img,img_min,img_max)))
斜着的图能看到效果
图像金字塔
图像金字塔: 是图像中多尺度表达。主要是用于图像的分割,是以多种分辨率来解释图像的有效单概念简单的结构。简单来说,图像金字塔是同一图像的不同分辨率的子图集合。图像金字塔最初用于机器视觉和图像压缩,一幅图像的金字塔形状排列的分辨率逐步降低,且来源于同一张原始图像的集合。其通过梯次向下采样获得,直到达到某个终止条件菜停止采样。金字塔的地图是带处理图像的高分辨率表示,顶部是低分辨率的近似。我们将一层一层的图像比喻成金字塔,层级越高,则图像越小,分辨率越低。
高斯金字塔:用来向下/降采样,主要的图像金字塔
拉普拉斯金字塔:用来从金字塔底层图像重建上层未采样图像,在数字图像处理中也即是预测残差,可以对图像进行最大程度的还原,配合高斯金字塔一起使用。
高斯金字塔
通过高斯平滑和亚采样获得一系列下采样图像。抽取偶数行和列去掉,每次图片缩小至四分之一
# 图片缩小到四分之一向下采样
dst = cv.pyrDown(img)
# 向上采样图片扩大四倍
dst = cv.pyrUp(img)
拉普拉斯金字塔
拉普拉斯金字塔是高斯金字塔丢失的图像细节。可以用于图像的压缩
直方图
图像直方图:表示图像中亮度分布的直方图,标绘了图像中每个亮度的像素数。横坐标图像中各个像素点的灰度级,纵坐标具有该会度极的像素个数。直方图术语,dims:需要统计的特征数目(dims=1;统计会度图),bins:每个特征空间子区段的数目,range:统计会度值的范围[0,255]
calcHist(images,channels,mask,hisSize,ranges[,hist[,accumulate]])
- images:原属图
- channels:指定通道[0],[1],[2],对应BGR
- mask:掩码图像
- 统计整幅图像的直方图,设置为None
- 统计图像某一部分的直方图,需要掩码图像
- histSize:Bins的数量
- 需要使用中括号例如[255]
- accumulate:累计标识
- 默认值fasle
- 如果被设置为true泽直方图在开始分配时不会清零
- 该参数允许从多个对象中计算单个直方图,活着用于实时更新直方图
- 多个直方图的累积结果,用于对一组图像计算直方图
绘制直方图
openCV没有绘制直方图的方法,需要使用的matplotlib工具
import matplotlib.pyplot as plt
def m_calcHist(img):
# 直方图,返回值是二维的
hist = cv.calcHist([img],[0],None,[255],[0,255])
# mac不显示绘图
plt.plot(hist,color = 'r')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# mac这里好像不兼容图像
plt.hist(gray.ravel(),bins=255)
掩膜直方图
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# 生成掩膜图像
mask = np.zeros(gray.shape,np.uint8)
# 设置想要统计直方图到区域
mask[100:200,100:200]=255;
cv.imshow('直方图掩膜',cv.bitwise_and(gray,gray,mask=mask))
直方图均衡化
- 计算累积直方图
- 将累积直方图进行区间转换
- 在累积直方图中,概率相近的原始值,会被处理为相同的值
识别视频
背景:静态图像、前景:动态图像。背景减除BackgroundSubtractorMOG(cv.bgsegm.createBackgroundSubtractorMOG())。通过backgroundsubtractor.apply()就可以得到前景的掩膜,移动物体会标记为白色,背景会标记为黑色。
# 加载视频
cap = cv.VideoCapture(0)
# 创建mog对象
mog = cv.bgsegm.createBackgroundSubtractorMOG()
kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
while True:
ret, frame = cap.read()
if ret == True:
gray = cv.cvtColor(frame,cv.COLOR_BGR2GRAY)
# 去除噪声
blur = cv.GaussianBlur(gray,(3,3),5)
fgmask = mog.apply(blur)
# 腐蚀、膨胀
erode = cv.erode(fgmask,kernel)
dialte = cv.dilate(erode,kernel)
# 闭运算消除内部空洞
close = cv.morphologyEx(dialte,cv.MORPH_CLOSE,kernel)
cv.imshow('前景获取', close)
key = cv.waitKey(10)
# esc 退出
if key == 27:
break
cap.release()
cv.destroyAllWindows()
会度加去噪声(高斯滤波)
特征检测
使用计算机提取图像信息,决定每个图像的点是否属于一个图像特征。特征检测点结果是吧图像上的点分为不同的子集,这些子集往往属于孤立的点、连续的曲线活着联系的区域。特征检测包括边缘检测,角检测,区域检测和脊检测。主要应用于图像搜索、拼图游戏、图像拼接。特征唯一的、特征是可追踪的、特征是能比较的。
图像特征就是值有意义的图像区域,具有独特性,易于识别,比较角点,斑点以及高密度区在图像特征中最重要的就是角点
- 灰度梯度的最大值对应的像素
- 两条线的交点
- 极值点(一阶导数最大,二阶导数为0)
Harris角点检测
旋转不变特性,缩放后角点可能就不被检测到
cornerHarris(src,blockSize,ksize,k[,dst[,borderType]])
- blockSize: 检测窗口大小
- ksize:sobel的卷积核
- K:权重系数,是一个经验值,一般取0.04-0.06之间
img = cv.imread('../Picture/1.png')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# 角点检测,计算出图片中每一个点的角点响应
dst = cv.cornerHarris(gray,blockSize=2,ksize=3,k=0.04)
# 显示角点 设置满足条件的角点位置为红色
img[dst>(0.01*dst.max())] = [0,0,255]
cv.imshow('角点检测',img)
cv.waitKey(27)
cv.destroyAllWindows()
shi-Tomasi角点检测
Harris角点检测和计算的稳定性和K有关,而K是一个经验值,不太好设定最佳的K值。
goodFeaturesToTrack(imgage,maxComers,qualityLevel,minDistance[,corners[,mask[,blockSize[,useHarrisDetector[,k]]]]]))
- maxCorners:角点最大数设置为0表示无限制
- qualityLevel:角点质量,小于1.0的整数,一般0.01-0.1之间
- minDistance:角之间最小欧式距离,忽略小雨此距离的点
- mask:感兴趣的区域
- blockSize:检测窗口大小
- useHarrisDetector:是否使用Harris算法
- K:默认0.04
img = cv.imread('../Picture/1.png')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# 角点检测,返回一组角点坐标
corners = cv.goodFeaturesToTrack(gray,maxCorners=0,qualityLevel=0.01,minDistance=10)
# 类型转换
corners = np.int0(corners)
# 画出角点 corners= [[[x,y][x,y]...]]
for i in corners:
x,y = i.ravel()
cv.circle(img,(x,y),3,[0,0,255],-1)
cv.imshow('角点检测',img)
cv.waitKey(27)
cv.destroyAllWindows()
SIFT关键点检测
SIFT即尺度不变特征变换(Scale-invariant feature transform,SIFT)用于图像处理领域的一种描述,这种描述具有尺度不变性,可在图像中检测出关键点,是一种局部特征描述。Harris角点具有旋转不变的特性但是缩放后,原来的角点可能就不是角点。
- DoG空间极值检测:为了寻找尺度空间的极值点,每个像素点药和其图像域(同一尺度空间)和尺度域(相邻的尺度空间)的所有相邻点进行比较,当其大于(或者小于)所有相邻点时,该点就是极值点。如下图所示,中间的检测点药和其所在的图像的3x3领域8个像素点,以及其相邻的上下两层3x3领域18个像素点,共26个像素点进行比较。
- 关键点的精确定位:这些关键点是DoG空间的局部极值点均为离散的点,精确定位极值点的一种方法是,对尺度空间DoG函数进行曲线拟合,计算其极值点,从而实现关键点点精确定位。
- 消除边界响应:Hessian矩阵
- 特征点主方向:特征的点的位置,尺度,方向。具有多个方向的关键点可以被复制成多份,然后将方向值分别赋给复制后的特征点,一个特征点就产生了多个坐标、尺度相等、但是方向不同的特征点。
- 生成特征表述:为了保特征矢量的选择不变性,要以特征点为中心,在附近领域内将坐标轴旋转角度,即将坐标轴旋转为特征点的主方向。旋转之后的主方向为中心取8x8点窗口,求每个像素的梯度幅值和方向,箭头方向代表梯度方向,长度代表梯度幅值,然后利用高斯窗口对其进行加权运算,最后每个4x4的小块上绘制8个方向梯度直方图,计算每个梯度方向的累加值,即可形成一个种子点,即每个特点由4个种子点组成,每个种子点有8个方向的向量信息。
aip使用
- 创建SIFT对象sift=cv.xfeatures2d.SIFT_create()
- 进行检测kp,kp=sift.delete(img…)
- 绘制关键点,drawKeypoints(gray,kp,img)
关键点: 只包含了:位置、大小、方向
img = cv.imread("../Picture/1.png")
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# 创建sift对象
sift = cv.SIFT_create()
# 进行检测 kp=特征点
kp = sift.detect(gray)
# 绘制关键点
cv.drawKeypoints(gray,kp,img)
cv.imshow('SIFT特征检测',img)
cv.waitKey(27)
cv.destroyAllWindows()
描述子: 记录了关键点周围对其有共享的像素点点一组向量值,其不受放射转变,光照变换等影响,描述子的作用就是进行特征匹配。
kp,des = sift.compute(gray,kp)
特征点匹配
Brute-Force蛮力匹配、RNSAC算法
img = cv.imread("../Picture/1.png",0)
img1 = cv.imread("../Picture/1_p.png",0)
sift = cv.SIFT_create()
kp1,des1 = sift.detectAndCompute(img,None)
kp2,des2 = sift.detectAndCompute(img1,None)
# crossCheck表示两个特征点要相互匹配,例如A中第i个特征点与B中的第j个特征点最近的,并且B中的第j个特点到A的第i个特征点
# NORM_L2:归一化数组(欧几里德距离),如果其他特征计算方法需要考虑不同的匹配计算方式
# 蛮力匹配1对1
# bf = cv.BFMatcher(crossCheck=True)
# RNSAC 1对多 k=2 一个点匹配相邻的2个点
bf = cv.BFMatcher()
matches = bf.knnMatch(des1,des2,k=2)
good = []
for m,n in matches:
if m.distance < 0.75 * n.distance:
good.append(m)
matches = bf.match(des1,des2)
# 关键点排序
matches = sorted(matches,key=lambda x: x.distance)
# 关键点链接到一起
img3 = cv.drawMatches(img,kp1,img1,kp2,matches[:30],None,flags=2)
cv.imshow('关键点对应图像',img3)
cv.waitKey(27)
cv.destroyAllWindows()
随机抽样一致算法RandomSampleConsensus简称RANSAC
图片拼接 TODO
视频处理
在Fedora中:DIVX,XVID,MJPG,X264,WMV1,WMV2。(最好使用XVID。MJPG会生成大尺寸的视频。X264会生成非常小的尺寸的视频)
在Windows中:DIVX(尚待测试和添加)
在OSX中:MJPG(.mp4),DIVX(.avi),X264(.mkv)。
mac 不兼容
# 轨迹栏
cv.createTrackbar('trackbar','tt',0,4,callback)
cv.imshow('名称无效',img)
最后一个窗口关不掉
cv.destroyAllWindows()