基于OpenCV的ORB特征匹配实现重复图案样本扩展
基于ORB/SIFT特征匹配生成重复壁纸图案的问题
我希望利用ORB或SIFT特征匹配技术,将带有重复特征的壁纸样本在更大画布上生成完整重复图案,核心原理类似全景图像拼接,不过是将图案与自身拼接,补全边缘处被截断的特征。
示例说明
- 测试用简单图案:图案顶部存在截断的飞船,底部有完整的飞船,目标是将顶部截断部分与底部完整飞船匹配,使图案能延伸至原壁纸边缘之外
- 更复杂的图案示例:包含更多重复元素的壁纸样本
当前进展与问题
我已成功用ORB和OpenCV完成简单的壁纸局部拼接以生成更大样本,但无法利用完整样本生成大尺寸重复图案。我尝试通过对比图像中心区域与各边缘区域进行ORB特征匹配(代码如下),但无法实现将中心图像映射到外部边缘以生成完整扩展图像。
import cv2 import numpy as np from PIL import Image import matplotlib.pyplot as plt # 裁剪图像中心90%区域的函数 def crop_center(image, crop_percentage=0.9): # 获取原始图像尺寸 width, height = image.size # 计算裁剪后图像的尺寸 new_width = int(width * crop_percentage) new_height = int(height * crop_percentage) # 计算居中裁剪的坐标 left = (width - new_width) // 2 top = (height - new_height) // 2 right = (width + new_width) // 2 bottom = (height + new_height) // 2 # 执行裁剪 return image.crop((left, top, right, bottom)) # 提取图像外围10%边缘区域的函数 def extract_edges(image, edge_percentage=0.1): width, height = image.size # 计算边缘区域的尺寸 edge_width = int(width * edge_percentage) edge_height = int(height * edge_percentage) # 提取四个边缘区域 edges = { "top": image.crop((0, 0, width, edge_height)), "bottom": image.crop((0, height - edge_height, width, height)), "left": image.crop((0, 0, edge_width, height)), "right": image.crop((width - edge_width, 0, width, height)), } return edges # 执行ORB特征匹配的函数 def feature_match(cropped_img, edge_img): # 将图像转为灰度图 cropped_img_gray = cv2.cvtColor(np.array(cropped_img), cv2.COLOR_RGB2GRAY) edge_img_gray = cv2.cvtColor(np.array(edge_img), cv2.COLOR_RGB2GRAY) # 初始化ORB检测器 orb = cv2.ORB_create() # 检测关键点并计算描述符 kp1, des1 = orb.detectAndCompute(cropped_img_gray, None) kp2, des2 = orb.detectAndCompute(edge_img_gray, None) # 创建暴力匹配器 bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) # 匹配描述符 matches = bf.match(des1, des2) # 根据匹配距离排序(距离越小匹配度越高) matches = sorted(matches, key=lambda x: x.distance) # 绘制前10个匹配结果 matched_image = cv2.drawMatches(np.array(cropped_img), kp1, np.array(edge_img), kp2, matches[:10], None, flags=2) # 返回匹配后的图像 return matched_image # 在Colab笔记本中显示图像的函数 def show_image(img, title="Image"): plt.figure(figsize=(10, 10)) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.title(title) plt.axis("off") plt.show() # 主函数 def find_and_show_matches(image_path): # 打开原始图像 img = Image.open(image_path) # 裁剪图像中心90%区域 cropped_img = crop_center(img) # 提取外围10%的边缘区域(上、下、左、右) edges = extract_edges(img) # 对每个边缘区域执行特征匹配并可视化结果 for edge_name, edge_img in edges.items(): matched_img = feature_match(cropped_img, edge_img) # 使用matplotlib显示匹配结果 show_image(matched_img, title=f"与{edge_name}边缘的匹配结果")
内容的提问来源于stack exchange,提问作者redmaple
相关产品推荐
相关产品推荐

