使用orb进行关键点匹配的,图像处理一开始都没有问题,处理到一半出现
import cv2
import numpy
import os
from math import sqrt, pow, acos
def cv_show(name, img):
cv2.imshow(name, img)
cv2.waitKey(10000)
cv2.destroyAllWindows()
def orb_features(img):
orb = cv2.ORB_create(
5000, # 特征点数目
1.2, # 金字塔层级之间的缩放比例
8, # 金字塔图像层级系数
31, # 边缘阈值
0, # 原图在金字塔中的层数
2, # 生成描述子时需要用的像素点数目
cv2.ORB_HARRIS_SCORE, # 使用Harris方法评价特征点
31, # 生成描述子时关键点周围邻域的尺寸
20 # 计算FAST角点时像素值差值的阈值
)
kp = orb.detect(img, None)
kp, des = orb.compute(img, kp)
return kp, des
if __name__ == '__main__':
# f = open("output.txt")
img_path = "D://python//txsc"
for img in range(647):
# print(f"{i}.jpg".rjust(10, "0"))
img_name1 = f"{img}.jpg".rjust(10, "0")
img_name2 = f"{img + 1}.jpg".rjust(10, "0")
img_name1 = os.path.join(img_path, img_name1)
img_name2 = os.path.join(img_path, img_name2)
img1 = cv2.imread(img_name1)[350:750, 450:1450]
img2 = cv2.imread(img_name2)[350:750, 450:1450]
kp1, des1 = orb_features(img1)
kp2, des2 = orb_features(img2)
outimg1 = cv2.drawKeypoints(img1, keypoints=kp1, outImage=None)
outimg2 = cv2.drawKeypoints(img2, keypoints=kp2, outImage=None)
matcher = cv2.BFMatcher(cv2.NORM_HAMMING) # 定义特征点匹配的类
matches = matcher.match(des1, des2) # 进行特征点匹配
min_dist = 10000
max_dist = 0
# 提取最大距离和最小距离
for i in range(len(matches)):
dist = matches[i].distance
if dist < min_dist:
min_dist = dist
if dist > max_dist:
max_dist = dist
"""
//将汉明距离较大的匹配点对剔除,并缩小特征点选取范围
vector<DMatch> good_matches;//用于储存剔除完的结果
int matchidx1, matchidx2;//用于储存匹配点在查询子和描述子中的序号
float matchx1, matchy1;//用于储存匹配点在查询子中的坐标
float matchx2, matchy2;//用于储存匹配点在描述子中的坐标
"""
good_matches = []
for i in range(len(matches)):
matchidx1 = matches[i].queryIdx
matchidx2 = matches[i].trainIdx
matchx1, matchy1 = kp1[matchidx1].pt
matchx2, matchy2 = kp2[matchidx2].pt
if (matches[i].distance <= max(3 * min_dist, 40.0) and
(sqrt(pow((matchx1 - 278), 2) + pow((matchy1 - 269), 2)) > 158) and
(sqrt(pow((matchx1 - 278), 2) + pow((matchy1 - 269), 2)) < 250) and
(sqrt(pow((matchx2 - 278), 2) + pow((matchy2 - 269), 2)) > 158) and
(sqrt(pow((matchx2 - 278), 2) + pow((matchy2 - 269), 2)) < 250) and
(matchy1 < 0.66 * matchx1 + 83.5) and
(matchy1 < -1.64 * matchx1 + 725) and
(matchy2 < 0.66 * matchx2 + 83.5) and
(matchy2 < -1.64 * matchx2 + 725)):
good_matches.append(matches[i])
nums1 = []
# 计算所有匹配点转过的角度
for i in range(len(good_matches)):
index1 = good_matches[i].queryIdx
index2 = good_matches[i].trainIdx
ax, ay = kp1[index1].pt
bx, by = kp2[index2].pt
OA = sqrt(pow(ax - 278, 2) + pow(ay - 269, 2))
OB = sqrt(pow(bx - 278, 2) + pow(by - 269, 2))
AB = sqrt(pow(ax - bx, 2) + pow(ay - by, 2))
costheta = (pow(OA, 2) + pow(OB, 2) - pow(AB, 2)) / (2 * OA * OB)
# print(costheta)
theta = acos(round(costheta, 2)) / 3.1415926 * 180
nums1.append(theta)
# 创建用于归类角度的矩阵numinrange和计数的矩阵count
"""
vector<vector<float>> numinrange(31, vector<float>(1, 0)); //创建30行,1列,值为0的二维数组
vector<float> count(31, 0);//计数用的数组,长度与划分的范围数量相等
"""
HANG = 30
numinrange = [[0]] * 30
count = []
for i in range(len(nums1)):
if nums1[i] == 0:
numinrange.append(nums1[i])
count.append(i + 1)
# 将num1中的角度theta归到二维数组中相应范围内,每归入一个相应计数加一
for i in range(31):
for j in range(len(nums1)):
if (nums1[j] > 3 * i - 3) and (nums1[j] <= 3 * i):
numinrange[i].append(nums1[j])
count[i] += 1
# //查找0以外计数最大的行数
max1 = 0
maxnum = 0
for i in range(2, len(count)):
if count[i] >= max1:
max1 = count[i]
maxnum = i
# 不动的点需多于其余点三倍以上才能被计算
if count[0] > 30 * (len(good_matches) - count[0] - count[1]) + 6:
max1 = count[0]
maxnum = 0
elif count[1] > 30 * (len(good_matches) - count[0] - count[1]) + 10:
max1 = count[1]
maxnum = 1
"""
//取平均值计算转角
float sum, ave, rec;
"""
sum = 0
ave = 0
for i in range(1, len(numinrange[maxnum])):
rec = numinrange[maxnum][i]
sum += rec
ave = sum / count[maxnum]
print(f"图片{img}, 转过角度 {ave}")
with open(f"ave/{img}.txt", "w", encoding="utf-8") as f:
f.write(f"{ave}")
运行结果及报错内容
报错内容:
关键点匹配存在问题,能够匹配上的点太少:
我的解答思路和尝试过的方法
现阶段orb关键点大部分匹配不上,有可能是主要原因,想问问应该要怎么调整比较好
我想要达到的结果
提高关键点的匹配数量