wordpress 大型网站吗,免费云服务器推荐,怎样自己做代刷网站,政务公开网站建设重点1#xff0c;Harris角点检测
如果粉色窗口向四周移动#xff0c;窗口内的像素没有变化则认定为平坦区域#xff0c;如果窗口向上移动无明显变化#xff0c;而左右移动有变化则认定为边缘#xff0c;如果窗口向任意方向移动均有明显变化则为角点#xff0c;如下图 dst不是…1Harris角点检测
如果粉色窗口向四周移动窗口内的像素没有变化则认定为平坦区域如果窗口向上移动无明显变化而左右移动有变化则认定为边缘如果窗口向任意方向移动均有明显变化则为角点如下图 dst不是输入参数是输出参数输出检测出来的角点 2Shi-Tomasi角点检测 Shi-Tomasi是Harris角点检测
Harris角点检测算的稳定性和k有关而k是个经验值不是设定最佳值。而Shi-Tomasi好处(区别)在于不需要再对k值进行设定
第一个参数maxCorners是要检测的角点数量无限制就是把能检测到的角点全部输出。qualityLevel是角点质量实际上就是Harris检测时的代码img[dst0.01*dst.max()]将很小的角点去掉使用ShiTimasi方法就不用这一步了直接在参数内填数值即可。第三个参数minDistance指两个交点间最小的距离如果小于所设定的最小距离则角点会舍弃只保留一个。第四个参数mask就是掩码要检测哪个区域就创建一个mask只保留要检测的区域其他区域变为黑色。第五个参数blockSize与Harris相同。第六个参数useHarrisDetector,如果是true则使用Harris角点检测方法如果是False则使用Shi-Tomasi检测方法默认为false。第七个参数k是在第六个参数为true时启用的默认为0.04 import numpy as np
import cv2
img cv2.imread(2.jpg)
gray cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
qualityLevel 0.01#相当于之前的img[dst0.01*dst.max()]
#Shi-Tomasi角点检测。获取的角点存在corners中,输出的corners是一个三维数组且有小数点
corners cv2.goodFeaturesToTrack(gray,1000,qualityLevel,5)
#将corners数组中的浮点型数据转换为整型
corners np.int64(corners)
#Shi-Tomasi绘制角点
for i in corners:x,y i.ravel()#corners中的数组为多维数组这里转换成一维数组cv2.circle(img,(x,y),3,255,-1)#-1画实心圆
cv2.imshow(img,img)
cv2.waitKey(0)
未进行整型转换的corners是一个三维数组且有小数点 进行整型转换后的corners corners[1]输出内容为一个二维数组 进行corners[1].ravel()操作后corners[1]变为一维数组 3SIFT特征检测
具体原理可以查看文章:SIFT算法原理-CSDN博客
Harris角点具有旋转不变性但缩放后原来的角点可能就无法检测如下图 使用步骤
创建SIFT对象进行检测kp sift.detect(img, ....) 绘制关键点drawKeypoints(gray,kp,img)。关键点有信息位置大小和方向计算描述子。kp,dessift.compute(img,kp),des为返回的描述子为一个二维数组每个数组内都有很多数据记录关键点信息。描述子记录了关键点周围对其有贡献的像素点的一组向量值其不受仿射变换光照变换等影响。描述子主要用于特征匹配
opencv为我们提供了一个可以同时计算关键字和描述子的函数kp, des sift.detectAndCompute(img, mask)。mask可以指明对哪个区域进行计算
import numpy as np
import cv2
img cv2.imread(2.jpg)
gray cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#创建SIFT对象
sift cv2.xfeatures2d.SIFT_create()
#进行检测
kp sift.detect(gray, None)#第二个参数可以设置一个掩码对某区域进行检测设为None表示对整 #张图进行检测
#绘制关键点
cv2.drawKeypoints(gray, kp, img)#在img图像上绘制
#计算描述子
kp, des sift.compute(gray, kp)#返回两个结果第一个结果kp还是关键点第二个参数是每个关键 #点对应的特征向量des.shape输出结果为(关键点数量,128)即每个关键点特征向量为128维
cv2.imshow(SIFT, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
import numpy as np
import cv2
img cv2.imread(2.jpg)
gray cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#创建SIFT对象
sift cv2.xfeatures2d.SIFT_create()
#进行检测
kp, des sift.detectAndCompute(gray, None)
#绘制关键点
cv2.drawKeypoints(gray, kp, img)#在img图像上绘制
cv2.imshow(SIFT, img)
cv2.waitKey(0)
cv2.destroyAllWindows() 4SURF特征检测
SIFT最大的问题就是速度慢而SURF速度更快并且保留了SIFT的优点。
创建surf对象。surf cv2.xfeatures2d.SURF_create()检测关键点计算描述子。kp, des surf.detectAndCompute(img, mask)
import numpy as np
import cv2
img cv2.imread(2.jpg)
gray cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#创建SURF对象
surf cv2.xfeatures2d.SURF_create()
#进行检测并计算描述子
kp, des surf.detectAndCompute(gray, None)#第二个参数可以设置一个掩码对某区域进行检测设为None表示对整张图进行检测
#绘制关键点
cv2.drawKeypoints(gray, kp, img)#在img图像上绘制
cv2.imshow(SURF, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
5ORB特征检测
ORB可以做到实时监测也就是它的计算速度很快。ORB是FAST和BRIEF两种技术的结合他的计算速度均高于两者但准确度却不如两者。而且ORB是没有版权的放在Opencv主库
FAST可以做到特征点的实时监测。BRIEF是对已检测到的特征点进行描述它加快了特征描述建立的速度同时也极大降低了特征匹配的时间
使用步骤
创建ORB对象。orb cv2.ORB_create()检测关键点计算描述子。kp, des orb.detectAndCompute(img, mask)
import numpy as np
import cv2
img cv2.imread(2.jpg)
gray cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#创建ORB对象
orb cv2.ORB_create()
#进行检测并计算描述子
kp, des orb.detectAndCompute(gray, None)#第二个参数可以设置一个掩码对某区域进行检测设为None表示对整张图进行检测
#绘制关键点
cv2.drawKeypoints(gray, kp, img)#在img图像上绘制
cv2.imshow(SURF, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
6BF(暴力)特征匹配
通过枚举方式进行特征匹配
原理特征匹配要有两张图首先计算第一张图的关键点和描述子。然后使用第一张图的每个特征的描述子与第二组中的所有特征描述子进行匹配。计算两者之间的差距然后将匹配度最接近的一个匹配返回
特征匹配步骤
创建匹配器。bf BFMatcher(normType, crossCheck)。第一个参数指匹配类型也就是我们要用哪种方法进行相似度的计算包括NORM_L1,NORM_L2,NORM_HAMMING1,NORM_HAMMING2,其中NORM_L1,NORM_L2用于对SIFT和SURF描述子进行计算NORM_HAMMING1是对ORB得到的描述子进行计算默认为NORM_L2。第二个参数是是否进行交叉匹配用第一张图描述子去匹配第二张图得到相似度较高的再用第二张图描述子去匹配第一张图起检查的作用,默认为false开启此功能计算时间会变长进行特征匹配。bf.match(des1, des2)。des1是获取到的第一张图的描述子des2是获取到的第二张图的描述子绘制匹配点(将匹配点通过线连接到一起)。cv2.drawMatches(img1, kp1, img2, kp2.....)img1和kp1是指原图和关键点img2和kp2是指匹配的图和其关键点。最后一个参数就是match()方法返回的匹配结果
import numpy as np
import cv2
img1 cv2.imread(1.jpg)
img2 cv2.imread(2.jpg)
g1 cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
g2 cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
#创建SIFT对象
sift cv2.xfeatures2d.SIFT_create()
#进行检测并计算描述子
kp1, des1 sift.detectAndCompute(g1,None)
kp2, des2 sift.detectAndCompute(g2,None)
bf cv2.BFMatcher(cv2.NORM_L1)
match bf.match(des1,des2)
img3 cv2.drawMatches(img1,kp1,img2,kp2,match,None)
cv2.imshow(SIFT, img3)
cv2.waitKey(0)
cv2.destroyAllWindows()
7FLANN特征匹配
在进行批量特征匹配时FLANN速度更快。但是由于它使用的是邻近近似值所以精度较差
使用步骤
创建FLANN匹配器。FlannBasedMatcher(index_params)。第一个参数是index_params字典主要填入的是匹配算法KDTREE或LSH.如果是SIFT和SURF计算的描述子则使用KDTREE算法如果是ORB计算的描述子则使用LSH算法。如果使用了KDTREE算法则要设置第二个参数search_params字典指定KDTREE算法中遍历树的次数。 由于要填入的参数是字典所以KDTREE通常设置为index_params dict(algorithm FLANN_INDEX_KDTREE, tree 5):FLANN_INDEX_KDTREE实际上代表1填成1即可填成0表示使用的是LSH算法tree是经验值填5。serch_params dict(checks 50)进行特征匹配。flann.match(...)或者是knnMatch(...)。knnMatch():第一二个参数为两张图象计算的描述子第三个参数为k表示取欧式距离最近的前k个关键点即第一张图像中的任何一个描述子与第二张图像中的所有描述子匹配之后最接近的前k个。返回的是DMatch对象DMatch中包括distance(描述子之间的距离值越小说明近似度越高)queryIdx(第一个图像的描述子索引值),trainIdx(第二个图像的描述子索引值),imgIdx(第二幅图索引值)绘制匹配点。cv2.drawMatches(...)或者是drawMatchesKnn(...)【如果特征匹配选择KnnMatch则用此方法】。drawMatchesKnn(...)参数与drawMatches(...)相同
import numpy as np
import cv2
img1 cv2.imread(img1.jpg)
img2 cv2.imread(img2.jpg)
g1 cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
g2 cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
sift cv2.xfeatures2d.SIFT_create()
kp1, des1 sift.detectAndCompute(g1, None)
kp2, des2 sift.detectAndCompute(g2, None)
#创建匹配器
index_params dict(algorithm 1, trees 5)
search_params dict(checks50)
flann cv2.FlannBasedMatcher(index_params, search_params)
matches flann.knnMatch(des1, des2, k2)
#对所有匹配点进行过滤优化
good []
for i,(m,n) in enumerate(matches):if m.distance 0.7*n.distance:good.append(m)
ret cv2.drawMatchesKnn(img1, kp1, img2, kp2, [good], None)
cv2.imshow(ret, ret)
cv2.waitKey(0)
cv2.destroyAllWindows()
8实例练习图像查找
图像查找用到了 特征匹配单应性矩阵。特征匹配得到结果后可以把它当作输入来计算单应性矩阵拿到单应性矩阵再经过透视变换就可以获取到最终的图像了。当我们需要通过一张图去找另一张图时通过以上步骤就可以找到
单应性矩阵通过单应性矩阵可以让图像由一个视角转换到另一个视角 在上述FLANN文件下只需要利用获取的匹配点matches计算单应性矩阵然后利用单应性矩阵通过透视变换最后找到想找的图像
import numpy as np
import cv2
img1 cv2.imread(img1.jpg)
img2 cv2.imread(img2.jpg)
g1 cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
g2 cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
sift cv2.xfeatures2d.SIFT_create()
kp1, des1 sift.detectAndCompute(g1, None)
kp2, des2 sift.detectAndCompute(g2, None)
#创建匹配器
index_params dict(algorithm 1, trees 5)
search_params dict(checks50)
flann cv2.FlannBasedMatcher(index_params, search_params)
matches flann.knnMatch(des1, des2, k2)
#对所有匹配点进行过滤优化
good []
for i,(m,n) in enumerate(matches):if m.distance 0.7*n.distance:good.append(m)
#计算单应性矩阵H时输入特征点必须大于等于4
if len(good) 4:srcPts np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1,1,2)dstPts np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1,1,2)#找到单应性矩阵,cv2.RANSAC是对匹配点的过滤过滤到错误匹配的点。#该函数有两个返回值第一个返回值H是需要的单应性矩阵第二个参数是掩码我们不需要所以用_代替即可H, _ cv2.findHomography(srcPts, dstPts, cv2.RANSAC, 5.0)#透视变换#pts是原图的四个角点h, w img1.shape[:2]pts np.float32([[0,0], [0, h-1], [w-1, h-1], [w-1, 0]]).reshape(-1,1,2)dst cv2.perspectiveTransform(pts, H)#将找到的图像框起来cv2.polylines(img2, [np.int32(dst)], True, (255,0,0))
else:print(there are no matches)exit()
ret cv2.drawMatchesKnn(img1, kp1, img2, kp2, [good], None)
cv2.imshow(ret, ret)
cv2.waitKey(0)
cv2.destroyAllWindows()