keypoints.append(kp)
descriptors.append(desc)
# 特征匹配
matches = []
for i in range(len(descriptors) - 1):
matches.append(matcher.match(descriptors[i], descriptors[i+1]))
# 计算图像配准的单应性矩阵
homographies = []
for match in matches:
src_pts = np.float32([keypoints[i][m.queryIdx].pt for i, m in enumerate(match)]).reshape(-1, 1, 2)
dst_pts = np.float32([keypoints[i+1][m.trainIdx].pt for i, m in enumerate(match)]).reshape(-1, 1, 2)
H, _ = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
homographies.append(H)
# 图像拼接
result = images[0]
for i in range(len(images) - 1):
result = cv2.warpPerspective(result, homographies[i], (result.shape[1] + images[i+1].shape[1], result.shape[0]))
result[0:images[i+1].shape[0], 0:images[i+1].shape[1]] = images[i+1]
return result
读取图像
image1 = cv2.imread(“image1.jpg”)
image2 = cv2.imread(“image2.jpg”)
image3 = cv2.imread(“image3.jpg”)
图像拼接
result_image = stitch_images([image1, image2, image3])
显示结果
cv2.imshow(“Panorama”, result_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
在上述示例代码中,首先通过`cv2.SIFT_create()`创建了一个SIFT特征提取器,并使用`detectAndCompute()`方法检测关键点和计算特征描述符。
然后,通过`cv2.BFMatcher()`创建了一个基于暴力匹配的匹配器。对于每两个相邻的图像,使用匹配器的`match()`方法进行特征匹配。
接下来,使用`cv2.findHomography()`计算了相邻图像之间的单应性矩阵,将它们配准到同一个坐标空间。
最后,使用`cv2.warpPerspective()`进行透视变换,将配准后的图像进行拼接。
您需要将示例代码中的`image1.jpg`、`image2.jpg`和`image3.jpg`替换为您自己的图像路径。运行代码后,会显示生成的全景图像。
请注意,这只是一个简单的示例代码,实际的图像拼接任务可能需要更多的处理和优化。对于复杂的场景,您可能需要调整算法参数或使用其他图像拼接算法来获得更好的结果。
![在这里插入图片描述](https://img-blog.csdnimg.cn/c10994c7593f4940ac10349c8cb330bc.jpg)以下是对上述示例代码的扩展,包括图像预处理和结果优化:
import cv2
import numpy as np
def stitch_images(images):
# 图像预处理
gray_images = []
for image in images:
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray_images.append(gray)
# 初始化特征提取器和匹配器
sift = cv2.SIFT_create()
matcher = cv2.BFMatcher()
# 检测关键点和计算特征描述符
keypoints = []
descriptors = []
for gray_image in gray_images:
kp, desc = sift.detectAndCompute(gray_image, None)
keypoints.append(kp)
descriptors.append(desc)
# 特征匹配
matches = []
for i in range(len(descriptors) - 1):
matches.append(matcher.match(descriptors[i], descriptors[i+1]))
# 计算图像配准的单应性矩阵
homographies = []
for match in matches:
src_pts = np.float32([keypoints[i][m.queryIdx].pt for i, m in enumerate(match)]).reshape(-1, 1, 2)
dst_pts = np.float32([keypoints[i+1][m.trainIdx].pt for i, m in enumerate(match)]).reshape(-1, 1, 2)
H, _ = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
homographies.append(H)
# 图像拼接
result = gray_images[0]
for i in range(len(gray_images) - 1):
result = cv2.warpPerspective(result, homographies[i], (result.shape[1] + gray_images[i+1].shape[1], result.shape[0]))
result[0:gray_images[i+1].shape[0], 0:gray_images[i+1].shape[1]] = gray_images[i+1]
# 结果优化
result = cv2.medianBlur(result, 5)
return result
读取图像
image1 = cv2.imread(“image1.jpg”)
image2 = cv2.imread(“image2.jpg”)
image3 = cv2.imread(“image3.jpg”)
图像拼接
result_image = stitch_images([image1, image2, image3])
显示结果
cv2.imshow(“Panorama”, result_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
在扩展的代码中,我们进行了以下改进:
1. 图像预处理:将输入图像转换为灰度图像,以减少特征提取和匹配的计算量。
2. 结果优化:使用`cv2.medianBlur()`对拼接结果进行中值滤波,以去除可能的噪声和不连续性。
这些改进可以提高拼接结果的质量和鲁棒性。您还可以根据具体需求添加其他的预处理步骤和优化方法,以获得更好的全景图像拼接效果。
### 四、图像融合示例代码和扩展
![在这里插入图片描述](https://img-blog.csdnimg.cn/60e2e8fbb3ec4d1fb6893a1c265889df.jpg)以下是一个使用OpenCV实现图像融合的示例代码:
import cv2
def blend_images(image1, image2, alpha):
blended_image = cv2.addWeighted(image1, alpha, image2, 1 - alpha, 0)
return blended_image
读取图像
image1 = cv2.imread(“image1.jpg”)
image2 = cv2.imread(“image2.jpg”)
图像融合
alpha = 0.5 # 调整融合比例,范围为[0, 1]
result_image = blend_images(image1, image2, alpha)
显示结果
cv2.imshow(“Blended Image”, result_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
在上述示例代码中,我们定义了一个`blend_images()`函数,该函数接受两个输入图像`image1`和`image2`,以及一个融合比例`alpha`。通过使用`cv2.addWeighted()`函数,将两个图像按照给定的融合比例进行加权平均,得到融合后的图像。
您需要将示例代码中的`image1.jpg`和`image2.jpg`替换为您自己的图像路径。运行代码后,会显示生成的融合图像。
请注意,融合比例`alpha`决定了两个图像在融合中的权重,如果`alpha`为0,则完全使用`image2`;如果`alpha`为1,则完全使用`image1`;如果`alpha`为0.5,则两个图像的权重相等。
根据具体需求,您可以调整融合比例和选择其他的图像融合方法,例如使用不同的混合模式或应用其他图像处理技术来实现更复杂的融合效果。
![在这里插入图片描述](https://img-blog.csdnimg.cn/44f21879197749ecba129005bf9640e8.jpg)以下是对上述示例代码的扩展,包括多图像融合和融合掩码的应用:
import cv2
import numpy as np
def blend_images(images, alpha_values):
# 确保输入图像数量和融合比例数量一致
assert len(images) == len(alpha_values)
# 获取图像尺寸
height, width, channels = images[0].shape
# 创建融合结果的初始画布
blended_image = np.zeros((height, width, channels), dtype=np.float32)
# 图像融合
for i in range(len(images)):
alpha = alpha_values[i]
blended_image += alpha \* images[i]
# 归一化并转换为8位图像
blended_image = np.clip(blended_image, 0, 255).astype(np.uint8)
return blended_image
读取图像
image1 = cv2.imread(“image1.jpg”)
image2 = cv2.imread(“image2.jpg”)
image3 = cv2.imread(“image3.jpg”)
设置融合比例
alpha_values = [0.4, 0.3, 0.3] # 调整融合比例,总和应为1
图像融合
result_image = blend_images([image1, image2, image3], alpha_values)
显示结果
cv2.imshow(“Blended Image”, result_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
在扩展的代码中,我们对图像融合进行了改进:
### 最后
> **🍅 硬核资料**:关注即可领取PPT模板、简历模板、行业经典书籍PDF。
> **🍅 技术互助**:技术群大佬指点迷津,你的问题可能不是问题,求资源在群里喊一声。
> **🍅 面试题库**:由技术群里的小伙伴们共同投稿,热乎的大厂面试真题,持续更新中。
> **🍅 知识体系**:含编程语言、算法、大数据生态圈组件(Mysql、Hive、Spark、Flink)、数据仓库、Python、前端等等。
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化学习资料的朋友,可以戳这里无偿获取](https://bbs.csdn.net/topics/618317507)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**