pythonimport cv2import numpy as np# 1. 读取双视角图像img1 = cv2.imread("view1.jpg")img2 = cv2.imread("view2.jpg")gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)# 2. ORB特征提取与匹配orb = cv2.ORB_create(nfeatures=2000)kp1, des1 = orb.detectAndCompute(gray1, None)kp2, des2 = orb.detectAndCompute(gray2, None)# 暴力匹配+优质筛选bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)matches = bf.match(des1, des2)# 提取匹配点坐标pts1 = np.float32([kp1[m.queryIdx].pt for m in matches])pts2 = np.float32([kp2[m.trainIdx].pt for m in matches])# 3. RANSAC求解基础矩阵F(去噪抗误匹配)F, mask = cv2.findFundamentalMat(pts1, pts2, cv2.FM_RANSAC, 1.0, 0.99)# 筛选有效内点匹配对pts1_in = pts1[mask.ravel() == 1]pts2_in = pts2[mask.ravel() == 1]# 4. 定义极线绘制函数def draw_epilines(img_src, img_dst, lines, pts_src, pts_dst):r, c = img_src.shape[:2]img_src = cv2.cvtColor(img_src, cv2.COLOR_GRAY2BGR)img_dst = cv2.cvtColor(img_dst, cv2.COLOR_GRAY2BGR)for line, pt1, pt2 in zip(lines, pts_src, pts_dst):# 随机配色绘制极线color = tuple(np.random.randint(0,255,3).tolist())x0, y0 = map(int, [0, -line[2]/line[1]])x1, y1 = map(int, [c, -(line[2]+line[0]*c)/line[1]])img_src = cv2.line(img_src, (x0,y0), (x1,y1), color, 1)img_src = cv2.circle(img_src, tuple(np.int32(pt1)), 5, color, -1)img_dst = cv2.circle(img_dst, tuple(np.int32(pt2)), 5, color, -1)return img_src, img_dst# 5. 计算左右视图极线lines1 = cv2.computeCorrespondEpilines(pts2_in.reshape(-1,1,2), 2, F)lines1 = lines1.reshape(-1,3)lines2 = cv2.computeCorrespondEpilines(pts1_in.reshape(-1,1,2), 1, F)lines2 = lines2.reshape(-1,3)# 绘制极线可视化结果img1_line, img2_line = draw_epilines(gray1, gray2, lines1, pts1_in, pts2_in)img2_line2, img1_line2 = draw_epilines(gray2, gray1, lines2, pts2_in, pts1_in)# 拼接展示结果res = np.hstack((img1_line, img2_line))cv2.imshow("Epipolar Geometry - Epiline Constraint", res)cv2.waitKey(0)cv2.destroyAllWindows()print("基础矩阵F:")print(F)print(f"有效匹配对数:{len(pts1_in)}") |