网站建设-选猴王网络,小程序制作简单教程,国外的网站模板类网站,网站建设文编一 OpenCV特征场景
①图像搜索#xff0c;如以图搜图#xff1b; ②拼图游戏#xff1b; ③图像拼接#xff0c;将两长有关联得图拼接到一起#xff1b;
1 拼图方法
寻找特征 特征是唯一的 可追踪的 能比较的
二 角点
在特征中最重要的是角点 灰度剃度的最大值对应的…一 OpenCV特征场景
①图像搜索如以图搜图 ②拼图游戏 ③图像拼接将两长有关联得图拼接到一起
1 拼图方法
寻找特征 特征是唯一的 可追踪的 能比较的
二 角点
在特征中最重要的是角点 灰度剃度的最大值对应的像素 两条线的角点 极值点(一阶导数最大值但二阶导数为0
三 Harris角点
哈里斯角点检测 Harris点 ① 光滑地区无论向哪里移动衡量系数不变 ②边缘地址垂直边缘移动时衡量系统变换剧烈 ③在交点处往哪个方向移动衡量系统都变化剧烈
1 Harris角点检测API
cornerHarris(img,dst,blockSize,ksize,k)
blockSize:检测窗口大小
ksize:Sobel的卷积核
k:权重系数经验值一般取0.02~0.04之间。import cv2
import numpy as npblockSize2ksize1k0.04imgcv2.imread(chess.jpg)#灰度化
graycv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#Harris角点检测
dstcv2.cornerHarris(gray,blockSize,ksize,k)#Harris角点的展示
img[dst0.04*dst.max()][0,0,255]
cv2.imshow(img,img)
cv2.waitKey(0)
四 Shi_Tomasi交点检测
Shi-Tomasi是Harris角点检测的改进 Harris角点检测的稳定性和K有关而k是个经验值不好设定最佳值。
1 Shi-Tomasi角点检测API
goodFeaturesToTrack(img,maxCorners,...)
maxCorners:角点的最大数值为0表示无限制
qualityLevel:小于1.0的正数一般在0.01~0.1之间
minDistance:角之间最小欧式距离忽略小于此距离的点。
mask:感兴趣的区域
blockSize:检测窗口
useHarrisDetector:是否使用Harris算法
k:默认是0.04import cv2
import numpy as npmaxCorners100
ql0.01imgcv2.imread(./chess.jpg)
cv2.imshow(img,img)
#灰度化
graycv2.cvtColor(img,cv2.COLOR_BGR2GRAY)# Shi-Tomasi
cornerscv2.goodFeaturesToTrack(gray,maxCorners,ql,10)
print(corners)
cornersnp.int32(corners)
# Shi-Tomasi绘制角点
for i in corners:x,yi.ravel()cv2.circle(img,(x,y),3,(255,0,0),-1)cv2.imshow(img,img)
cv2.waitKey(0)五 SIFTScale-Invariant Feature Transform
SIFT出现的原因 harris 角点具有旋转不变的特性 但缩放后原来的角点有可能就不是角点了
图放大
使用SIFT的步骤
①创建SIFT对象 ②进行检测kpsift.detect(img,…) ③绘制关键点drawKeypoints(gray,kp,img)
from email.mime import imageimport cv2
import numpy as npimgcv2.imread(./chess.jpg)graycv2.cvtColor(img,cv2.COLOR_BGR2GRAY)siftcv2.xfeatures2d.SIFT_create()kpsift.detect(gray,None)cv2.drawKeypoints(gray,kp,img)cv2.imshow(img,img)
cv2.waitKey(0) 六 SIFT计算描述子
关键点和描述子 关键点位置大小和方向 关键点描述子记录了关键点周围对其有贡献的像素点的一组向量值其不受仿射变换、光照变换等影响。
计算描述子
kp,dessift.compute(img,kp)
其作用是进行特征匹配同时计算关键点和描述
kp,dessift.detectAndCompute(img,...)
mask:指明对img中哪个区域进行计算import cv2
import numpy as npimgcv2.imread(./chess.jpg)graycv2.cvtColor(img,cv2.COLOR_BGR2GRAY)siftcv2.xfeatures2d.SIFT_create()kp,dessift.detectAndCompute(gray,None)
print(des)
cv2.drawKeypoints(gray,kp,img)cv2.imshow(img,img)
cv2.waitKey(0)七 SURF特征检测
SURF的优点 SIFT最大的问题是速度慢因此才有SURF
使用SURF的步骤
surfcv2.xfeatures2d.SUFR_create()
kp,dessurf.detectAndCompute(img,mask)import cv2
import numpy as npimgcv2.imread(./chess.jpg)graycv2.cvtColor(img,cv2.COLOR_BGR2GRAY)surfcv2.xfeatures2d.SURF_create()kp,dessurf.detectAndCompute(gray,None)print(des[0])cv2.drawKeypoints(gray,kp,img)cv2.imshow(img,img)
cv2.waitKey(0)
八 ORB(Oriented FAST and Rotated BRIEF)特征检测
1 ORB 优势
①ORB可以做到实时检测 ②ORBOriented FASTRotated BRIEF
2 FAST
可以做到特征点的实时检测
3 BRIEF
BRIEF是对已检测到的特征点进行描述它加快了特征描述符建立的速度。同时也极大的降低了特征匹配的时间。
3 ORB使用步骤
orbcv2.ORB_create()
kp,desorb.detectAndCompute(img,mask)import cv2
import numpy as npimgcv2.imread(./chess.jpg)graycv2.cvtColor(img,cv2.COLOR_BGR2GRAY)orbcv2.ORB_create()kp,desorb.detectAndCompute(gray,None)cv2.drawKeypoints(gray,kp,img)cv2.imshow(img,img)
cv2.waitKey(0) 九 暴力特征匹配
1 特征匹配方法
①BFBrute-Force),暴力特征匹配方法 ②FLANN最快邻近区特征匹配方法 它使用第一组中的每个特征的描述子与第二组中的所有特征描述子进行匹配计算它们之间的差距然后将最接近一个匹配返回。
2 OpenCV特征匹配步骤
创建匹配器BFMatcher(normType,crossCheck)
进行特征匹配bf.match(des1,des2)
绘制匹配点cv2.drawMatches(img1,kp1,img2,k2,...)
BFMatcher
normType:NORM_L1,NORM_L2,HAMMING1....
crossCheck:是否进行交叉匹配默认为false
Match方法
参数为SIFTSURFOBR等计算的描述子
对两幅图的描述子进行计算
drawMatches
搜索img,kp
匹配图img,kp
match()方法返回的匹配结果
import cv2
import numpy as npimgcv2.imread(./opencv_search.png)
img1cv2.imread(./opencv_orig.png)graycv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray1cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)siftcv2.xfeatures2d.SIFT_create()kp1,des1sift.detectAndCompute(gray,None)
kp2,des2sift.detectAndCompute(gray1,None)bfcv2.BFMatcher(cv2.NORM_L1)
matchbf.match(des1,des2)img3cv2.drawMatches(img,kp1,img1,kp2,match,None)cv2.imshow(img3,img3)
cv2.waitKey(0)十 FLANN特征匹配
1 FLANN优缺点
在进行批量特征匹配时FLANN速度更快 由于它使用的是邻近近似值所以精度较差
2 使用FLANN特征匹配的步骤
①创建FLANN匹配器FlannBasedMatcher(...)
②进行特征匹配flann.match/knnMatch(...)
③绘制匹配点cv2.drawMathes/drawMatchesKnn(...)
FlannBasedMathcer
index_params字典匹配算法KDTREE、LSH
search_params字典指定KETREE算法中遍历树的次数
KDTREE
index_paramsdict(algorithmFLANN_INDEX_KETREE,trees5)
search_params
search_paramsdict(checks50)
knnMatch方法
参数为SIFT、SURF、ORB等计算的描述子
k,表示取欧式距离最近的前k个关键点
返回的是匹配的结果DMatch对象
DMatch的内容
distance,描述子之间的距离值越低越好
queryIdx,第一个图像的描述子索引值
trainIdx,第二个图的描述子索引值
imgIdx,第二个图的索引值drawMatchesKnn
搜索img,kp
匹配图img,kp
match()方法返回的匹配结果十一 实战FLANN特征匹配
import cv2
import numpy as npimg1cv2.imread(opencv_search.png)
img2cv2.imread(opencv_orig.png)gray1cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
gray2cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)#创建SIFT特征
siftcv2.xfeatures2d.SIFT_create()#计算描述子与特征
kp1,des1sift.detectAndCompute(img1,None)
kp2,des2sift.detectAndCompute(img2,None)# 创建匹配器
index_paramsdict(algorithm1,trees5)
search_paramsdict(checks50)
flanncv2.FlannBasedMatcher(index_params,search_params)#对描述子进行匹配计算
matchsflann.knnMatch(des1,des2,k2)good[]
for i,(m,n)in enumerate(matchs):if m.distance0.7*n.distance:good.append(m)retcv2.drawMatchesKnn(img1,kp1,img2,kp2,[good],None)cv2.imshow(result,ret)
cv2.waitKey(0) 十二 图像查找
1 图像查找
特征匹配单应性矩阵
什么是单应性矩阵
import cv2
import numpy as npimg1cv2.imread(opencv_search.png)
img2cv2.imread(opencv_orig.png)gray1cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
gray2cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)#创建SIFT特征
siftcv2.xfeatures2d.SIFT_create()#计算描述子与特征
kp1,des1sift.detectAndCompute(img1,None)
kp2,des2sift.detectAndCompute(img2,None)# 创建匹配器
index_paramsdict(algorithm1,trees5)
search_paramsdict(checks50)
flanncv2.FlannBasedMatcher(index_params,search_params)#对描述子进行匹配计算
matchsflann.knnMatch(des1,des2,k2)good[]for i,(m,n) in enumerate(matchs):if m.distance0.7*n.distance:good.append(m)if len(good)4:#print(len(good.trainIdx))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)H, _ cv2.findHomography(srcPts, dstPts, cv2.RANSAC, 5.0)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, (0, 0, 255))
else:print(the number of god is less than 4)exit()retcv2.drawMatchesKnn(img1,kp1,img2,kp2,[good],None)cv2.imshow(resutl,ret)cv2.waitKey(0)
十三 图像拼接
1 图像合并的步骤
读文件并重置尺寸 根据特征点和计算描述子得到单应性矩阵 图像变换 图像拼接并输出图像
import cv2
import numpy as np#第一步 读取文件将图片设置成一样大小640x640
#第二步 找特征点描述子计算单应性矩阵
#第三步 根据单应性矩阵对图像进行变换然后平移
#第四步 拼接并输出最终结果#读取两张图片
img1cv2.imread(map1.png)
img2cv2.imread(map2.png)#将两张同样图片设置成同样大小
img1cv2.resize(img1,(640,480))
img2cv2.resize(img2,(640,480))inputsnp.hstack((img1,img2))
cv2.imshow(input img,inputs)
cv2.waitKey(0)import cv2
import numpy as npdef stitch_image(img1,img2,H):
#获得每张图片的四个角点
#对图片进行变换(单应性矩阵使图进行旋转平移)
#创建一张大图将两张图拼接到一起
#将结果输出#获得原始图的高/宽h1,w1img1.shape[:2]h2,w2img2.shape[:2]img1_dimsnp.float32([[0,0],[0,h1],[w1,h1],[w1,0]]).reshape(-1,1,2)img2_dimsnp.float32([[0,0],[0,h2],[w2,h2],[w2,0]]).reshape(-1,1,2)img1_transformcv2.perspectiveTransform(img1_dims,H)result_dimsnp.concatenate((img2_dims,img1_transform),axis0)[x_min, y_min] np.int32(result_dims.min(axis0).ravel() - 0.5)[x_max, y_max] np.int32(result_dims.max(axis0).ravel() 0.5)#平移的距离transform_dist[-x_min,-y_min]transform_arraynp.array([[1,0,transform_dist[0]],[0,1,transform_dist[1]],[0,0,1]])result_imgcv2.warpPerspective(img1,transform_array.dot(H),(x_max-x_min,y_max-y_min))result_img[transform_dist[1]:transform_dist[1]h2,transform_dist[0]:transform_dist[0]w2]img2return result_img#第一步 读取文件将图片设置成一样大小640x640
#第二步 找特征点描述子计算单应性矩阵
#第三步 根据单应性矩阵对图像进行变换然后平移
#第四步 拼接并输出最终结果def get_homo(img1,img2):
#创建特征转换对象
#通过特征转换对象获得特征点和描述子
#创建特征匹配器
#进行特征匹配
#过滤特征找出有效的特征匹配点siftcv2.xfeatures2d.SIFT_create()k1,d1sift.detectAndCompute(img1,None)k2,d2sift.detectAndCompute(img2,None)#创建特征匹配bfcv2.BFMatcher()matchesbf.knnMatch(d1,d2,k2)
#过滤特征找出有效的特征匹配点verify_ratio0.8verify_matches[]for m1,m2 in matches:if m1.distance0.8*m2.distance:verify_matches.append(m1)min_matches8if len(verify_matches)min_matches:img1_pts[]img2_pts[]for m in verify_matches:img1_pts.append(k1[m.queryIdx].pt)img2_pts.append(k2[m.trainIdx].pt)img1_ptsnp.float32(img1_pts).reshape(-1,1,2)img2_ptsnp.float32(img2_pts).reshape(-1,1,2)H,maskcv2.findHomography(img1_pts,img2_pts,cv2.RANSAC,5.0)return Helse:print(err:Not enough matches!)exit()
#第一步 读取文件将图片设置成一样大小640x480
#第二步 找特征点描述子计算单应性矩阵
#第三步 根据单应性矩阵对图像进行变换然后平移
#第四步 拼接并输出最终结果#读取两张图片
img1cv2.imread(map1.png)
img2cv2.imread(map2.png)#将两张同样图片设置成同样大小
img1cv2.resize(img1,(640,480))
img2cv2.resize(img2,(640,480))inputsnp.hstack((img1,img2))#获得单应性矩阵
Hget_homo(img1,img2)#进行图像拼接
result_imagestitch_image(img1,img2,H)cv2.imshow(input img,inputs)
cv2.waitKey(0)