日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

sift+图像匹配 算法

發布時間:2024/4/18 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sift+图像匹配 算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

初次使用sift時,有可能會報錯:module ‘cv2.cv2‘ has no attribute ‘xfeatures2d‘
這是因為sift算法申請了專利,在大于某一版本的時候無法調用,解決方案:
先安裝指定版本的opencv,再安裝opencv-contrib-python,兩步都要執行

pip install opencv_python==3.4.2.16 pip install opencv-contrib-python==3.4.2.16

sift算法的原理我們不在這里做過多贅述,有想了解的可以去看我的另一篇博客,這里我們直接分析源碼,在源碼部分會做出注釋。
1.sift? + BFMatxh匹配算法

def sift_image_match(i,img1, img2, img1_, img2_):# siftsift = cv2.xfeatures2d.SIFT_create() # 創建一個sift對象keypoints_1, descriptors_1 = sift.detectAndCompute(img1, None) # 尋找img1關鍵點和描述子keypoints_2, descriptors_2 = sift.detectAndCompute(img2, None) # 尋找img2關鍵點合描述子(這里的描述子其實就每個特征點的128維向量)#print(descriptors_1.shape)print(len(keypoints_1), len(keypoints_2))## feature matchingbf = cv2.BFMatcher(cv2.NORM_L1, crossCheck=True) # 圖像匹配,創建一個匹配器這里選用的是BFMatcher匹配算法matches = bf.match(descriptors_1,descriptors_2) # 輸入特征點描述子來計算匹配點對matches = sorted(matches, key=lambda x: x.distance) # 根據匹配點對之間的相似度來將點對排序img3 = cv2.drawMatches(img1_, keypoints_1, img2_, keypoints_2, matches[:50], img2, flags=2) #使用drawMatcher函數來繪制兩張圖之間匹配點之間的連線name = str(i)+".png"# plt.imshow(img3)# plt.savefig('res.png')# plt.show()cv2.imwrite(name, img3)# cv2.imshow('a', img3)# cv2.waitKey(0)return len(matches)def image_process(img1_path, img2_path):img1_ = cv2.imread(img1_path) # planeimg2_ = cv2.imread(img2_path) # satelliteimg1__shape = img1_.shape# print(img1__shape) # (1080, 1920, 3)img2_ = cv2.resize(img2_, (img1__shape[1], img1__shape[0]))img1 = cv2.cvtColor(img1_, cv2.COLOR_BGR2GRAY) # 圖像匹配算法一般都是基于灰度圖像來計算的,因此通過cvtColor函數將BGR圖像轉換為灰度圖img2 = cv2.cvtColor(img2_, cv2.COLOR_BGR2GRAY)return img1, img2, img1_, img2_

2.sift + FLANN匹配算法

def sift_image_match(i,img1, img2, img1_, img2_):# siftsift = cv2.xfeatures2d.SIFT_create() # 創建一個sift對象keypoints_1, descriptors_1 = sift.detectAndCompute(img1, None) # 尋找img1關鍵點和描述子keypoints_2, descriptors_2 = sift.detectAndCompute(img2, None) # 尋找img2關鍵點合描述子(這里的描述子其實就每個特征點的128維向量)#print(descriptors_1.shape)print(len(keypoints_1), len(keypoints_2))# feature matching# FLANN匹配器參數設置FLANN_INDEX_KDTREE = 0index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)search_params = dict(checks=50)# 聲明FLANN匹配器flann = cv2.FlannBasedMatcher(index_params, search_params)matches = flann.knnMatch(descriptors_1, descriptors_2, k=2) # k表示返回k近鄰個匹配點,這里我們選2,即最近鄰和次近鄰matchesMask = [[0, 0] for i in range(len(matches))]for i, (m, n) in enumerate(matches): # matches是KeyPoint型變量,由關鍵點的k近鄰的集合構成,m,n是與原圖像最相鄰的兩個匹配if m.distance < 0.8 * n.distance: # m表示最近鄰,n表示次近鄰,當m和n的相似性滿足該判別關系的時候,執行matchesMask[i] = [1, 0] #將最近鄰掩碼設1,即可以繪制drawpara = dict(singlePointColor=(0, 255, 0), matchColor=(255, 0, 0), matchesMask=matchesMask, flags=2)img3 = cv.drawMatchesKnn(image1, key1, image2, key2, matches, None, **drawpara)#使用drawMatchesKnn函數來繪制兩張圖之間匹配點之間的連線name = str(i)+".png"# plt.imshow(img3)# plt.savefig('res.png')# plt.show()cv2.imwrite(name, img3)# cv2.imshow('a', img3)# cv2.waitKey(0)return len(matches)def image_process(img1_path, img2_path):img1_ = cv2.imread(img1_path) # planeimg2_ = cv2.imread(img2_path) # satelliteimg1__shape = img1_.shape# print(img1__shape) # (1080, 1920, 3)img2_ = cv2.resize(img2_, (img1__shape[1], img1__shape[0]))img1 = cv2.cvtColor(img1_, cv2.COLOR_BGR2GRAY) # 圖像匹配算法一般都是基于灰度圖像來計算的,因此通過cvtColor函數將BGR圖像轉換為灰度圖img2 = cv2.cvtColor(img2_, cv2.COLOR_BGR2GRAY)return img1, img2, img1_, img2_

這里要注意BF算法和FLANN返回值的差別,雖然二者返回的都是KeyPoint類型,但BF返回的就只最相似的,FLANN返回的則是K近鄰,需要通過添加額外的判斷語句來進行篩選,例如:

if m.distance < cof * n.distance

cof值越大,我們發現,對距離相差不大的K近鄰越不敏感,即不容易篩掉;cof越小,會刪掉較多值相差不大的匹配點,lowe認為相鄰越近的點越容易造成錯配,稱為壞點。因此cof取得稍小一點會比較好,但這個要根據實驗結果來定,不是越小越好

2. sift + FLANN + Ransac
這里的Ransac算法是為了刪除一些錯配的點,通過findFunfamentalMat()函數實現

import cv2 import os import numpy as np import matplotlib.pyplot as plt# read imagesdef sift_image_match(i1,img1, img2, img1_, img2_):# siftsift = cv2.xfeatures2d.SIFT_create() #keypoints_1, descriptors_1 = sift.detectAndCompute(img1, None) # 尋找關鍵點和描述子keypoints_2, descriptors_2 = sift.detectAndCompute(img2, None)#print(descriptors_1.shape)## feature matchingbf = cv2.BFMatcher(cv2.NORM_L1, crossCheck=True) # 圖像匹配bfmatches = bf.match(descriptors_1,descriptors_2)bfmatches_co = bfmatches# FLANN匹配器參數設置FLANN_INDEX_KDTREE = 0index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)search_params = dict(checks=50)# 聲明FLANN匹配器flann = cv2.FlannBasedMatcher(index_params, search_params)matches = flann.knnMatch(descriptors_1, descriptors_2, k=2) # k表示返回k近鄰個匹配點,這里我們選2,即最近鄰和次近鄰pts1 = []pts2 = []for i, (m, n) in enumerate(matches): # matches是KeyPoint型變量,由關鍵點的k近鄰的集合構成if m.distance < 0.8 * n.distance: # m表示最近鄰,n表示次近鄰,當m和n的相似性滿足該判別關系的時候,執行pts1.append(keypoints_1[m.queryIdx].pt) # queryIdx表示當先圖像中的查詢點的索引, .pt方法是從KeyPoint類型中獲取坐標值(這里的kp[]是KeyPoint類型)pts2.append(keypoints_2[m.trainIdx].pt) # trainIdx表示匹配圖中與查詢點匹配的點的索引pts1 = np.int32(pts1)pts2 = np.int32(pts2)# 根據匹配點對計算基礎矩陣,該函數會通過ransac算法篩選錯配點F, mask = cv2.findFundamentalMat(pts1, pts2, cv2.FM_LMEDS)# 尋找內部點,即為篩選后的匹配點pts1 = pts1[mask.ravel() == 1]pts2 = pts2[mask.ravel() == 1]assert len(pts1) == len(pts2)print(len(keypoints_1), len(pts2))bfmatches = sorted(bfmatches, key=lambda x: x.distance) #為匹配點按相似度排序#img3 = cv2.drawMatches(img1_, keypoints_1, img2_, keypoints_2, bfmatches[:5], img2, flags=2)# for i, bfm in enumerate(bfmatches):# print(keypoints_1[bfm.queryIdx].pt)# print(keypoints_2[bfm.trainIdx].pt)# if i == 5:# breakfor bfm, pt1, pt2 in zip(bfmatches,pts1, pts2): #這里bfmatches是KeyPoint類型,bfm是cv2.DMatch類型,包含queryIdx, \#trainIdx,idx, distance四個屬性keypoints_1[bfm.queryIdx].pt = tuple(pt1) #將篩選后的點坐標賦給原來的bfmatches中的點,這樣我們在drawMatches時就僅剩篩選之后的點了keypoints_2[bfm.trainIdx].pt = tuple(pt2)# for i, bfm in enumerate(bfmatches):# print(keypoints_1[bfm.queryIdx].pt)# print(keypoints_2[bfm.trainIdx].pt)# if i == 5:# breakimg3 = cv2.drawMatches(img1_, keypoints_1, img2_, keypoints_2, bfmatches[:5], img2, flags=2)name = str(i1)+"_1.png"cv2.imwrite(name, img3)return len(matches)

相關鏈接:https://blog.csdn.net/qq_36622009/article/details/104919996
? ? ? ? ? ? ? ? ??https://blog.csdn.net/weixin_44072651/article/details/89262277

總結

以上是生活随笔為你收集整理的sift+图像匹配 算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。