机器学习:opencv
2025-06-24 12:12:53
来源:新华网
目录。
前言。
一、两个函数。
1.显示图像。
2.计算图片特征和描述符。
二、代码实例。
1.准备图像。
2.特征检测。
3.特征匹配。
4.图像变换。
5.图像融合。
前言。
图像拼接是一种将多个图像合成大图的技术,常用于全景图生成、图像拼接、图像合成等应用场景。
。
一、两个函数。
1.显示图像。
def cv_show(name, img): cv2.imshow(name, img) cv2.waitKey(0)。
。
2.计算图片特征和描述符。
- 将输入图像转换为灰度图。
- 创建sift对象。
- 对灰度图进行特征检测,并计算描述符。
- 在数组中安装每个关键点的坐标。
- 返回关键点关键点坐标数组和描述符。
def detectAndDescribe(image): gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) sift = cv2.SIFT_create() # 检测SIFT特征点,计算描述符,第二个参数为掩膜 (kps, des) = sift.detectAndCompute(gray, None) # 将结果转化为NumPy数组 kps_float = np.float32([kp.pt for kp in kps]) # kp.pt 图像中包含两个值,即关键点 x 和 y 坐标。这些坐标通常是浮点数,可以准确描述图像中关键点的位置。 return (kps, kps_float, des)。
。
二、代码实例。
1.准备图像。
- 选择需要拼接的图像,确保它们之间有一定的重叠区域。
import cv2import numpy as npimport sys"""阅读拼接图片"""imageA = cv2.imread('1.jpg')cv_show('imageA', imageA)imageB = cv2.imread('2.jpg')cv_show('imageB', imageB)。
输出:
。
2.。特征检测。
- 使用特征检测算法(如 SIFT、ORB 或 AKAZE)在每个图像中找到关键特征点。
"""图像特征的计算和描述符"""(kpsA, kps_floatA, desA) = detectAndDescribe(imageA)(kpsB, kps_floatB, desB) = detectAndDescribe(imageB)。
。
3.特征匹配。
- 通过描述子匹配算法(如 BFMatcher 或 FLANN)匹配不同图像中的特征点。
"""使用FlannBasedMatcher来匹配大型训练集合,使用FlannBasedMatcher更快"""matcher = cv2.BFMatcher()# knnMatch(queryDescriptors,trainDescriptors,k,mask=None, compactResult=None)# 使用KNN检测来自AANN检测、B图SIFT特征匹配对,参数说明:# queryDescriptors:查询图像A的描述符# trainDescriptors:目标图像B的描述符# k:最佳匹配的描述符数。一般K=2.# 返回的数据结构描述:# distance:匹配的特征点描述符的欧式距离,值越小,特征点越相似。# queryIdx:查询图像特征点描述符的下标(第几个特征点描述符),也是描述符对应特征点的下标。# trainIdx:目标图像的特征描述符下标,也是描述符合相应特征的下标。# 选择查询图像中的一个关键点 在两个点中选择目标图像 判断rawmatches = matcher.knnMatch(desB, desA, 2)good = [] # 例如,[[m1, m2], [m3, m4], ...] 格式,其中 m1, m2 两个匹配对应同一关键点。matches = []for m in rawMatches: # 当最近距离与次近距离的比值小于0.65时,保留此匹配对 if len(m) == 2 and m[0].distance < 0.65 * m[1].distance: good.append(m) # 在featuresa和featuresB中存储两个点的索引值 matches.append((m[0].trainIdx, m[0].queryIdx))print(len(good))print(matches)# 绘制k近邻匹配结果# kp2 取两个关键点的图像vis = cv2.drawMatchesKnn(imageB, kpsB, imageA, kpsA, good, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)cv_show('Keypoint Matches', vis)。
输出:
。
输出:
- 。
4.图像变换。
根据计算的变换矩阵,将图像转换为同一平面。
"""透视变换"""if len(matches) > 4: # 当筛选匹配大于4时,计算视角变换矩阵。 # 获得匹配的点坐标 ptsA = np.float32([kps_floatA[i] for (i, _) in matches]) # matches是通过阈值筛选的特征点对象 ptsB = np.float32([kps_floatB[i] for (_, i) in matches]) # kps_floata是图片a中的所有特征点坐标 # 计格透视变换矩阵 # findHomography(srcPoints, dstPoints, method=None, ransacReprojThreshold=None) # 计算视角变换矩阵,透视变换雨数,cv2.getPerspectiveTransform()与可多个数据点变换的区别在于 # srcPointsrc参数:选择关键点的图片 # 参数dstPointst:选择两个关键点的图片 # 参数method:计算变换矩降的方法 # 0 - 使用所有点,最小二乘法 # RANSAC - 基于随机样本的一致性,https://zhuanlan.zhihu.com/p/402727549 # LMEDS - 最小中值 # RHO - 转向浙近样本的一致性 # ransacReprojThreshold:最大允许货币投影错误的阀值。该参数仅在method参数为RANSAC和RHO时使用,默认为3 # 返回值:h为变换矩阵,mask为掩模标志,指示内点对,外点对。该参数仅在method参数为RANSAC和RHO时使用,默认为3 # 返回值:h为变换矩阵,mask为掩模标志,指示内点对,外点对。 内点;指与估计模型非常接近的数据点,通常是正确匹魔或真实数据。 (H, mask) = cv2.findHomography(ptsB, ptsA, cv2.RANSAC, 10)else: print('图片找不到4个以上的匹配点') sys.exit()。
输出:
- 。
5.图像融合。
合成转换后的图像,缝隙可以通过加权平均、渐变等方式平滑拼接。