我正在使用
CV_TM_CCORR_NORMED
匹配模板的方法来比较两个图像...我想让这个旋转和缩放不变..有什么想法吗?
我尝试使用相同的方法对图像和模板进行傅里叶变换,但旋转后的结果仍然不同
当您的对象在场景中旋转或缩放时,与
matchTemplate
的模板匹配效果不佳。
您应该尝试
Features2D
框架中的openCV功能。例如 SIFT
或 SURF
描述符,以及 FLANN
匹配器。另外,您还需要findHomography
方法。
这里是在场景中查找旋转对象的一个很好的例子。
更新:
简单来说,算法是这样的:
找到物体图像的关键点 1.1.从这些关键点中提取描述符
找到场景图像的关键点 2.1 从关键点提取描述符
通过匹配器匹配描述符
分析您的比赛
FeatureDetectors、DescriptorExtractors 和 DescriptorMatches 有不同的类别,您可以阅读它们并选择适合您任务的类别。
有比通过特征检测和单应性来匹配模板比例和旋转不变性更简单的方法(如果你知道它实际上只是旋转和缩放,但其他一切都是不变的)。 对于真实的对象检测,上述建议的基于关键点的方法效果更好。
如果您知道它是相同的模板并且不涉及透视变化,则可以使用图像金字塔进行尺度空间检测,并在该金字塔的不同级别上匹配您的模板(通过一些简单的方法,例如 SSD 或 NCC)。在金字塔的较高(=较低分辨率)级别上找到粗略匹配将很便宜。事实上,它是如此便宜,以至于您还可以在低分辨率级别上粗略地旋转模板,当您将模板追溯到更高分辨率级别时,您可以使用更细粒度的旋转步进。这是一种非常标准的模板匹配技术,并且在实践中效果很好。
尝试 OpenFDCM,它在旋转、平移和缩放模板匹配方面比 OpenCV 更快。请查看这里。
您可以在 Google Colab 此处尝试。
pip install openfdcm
import openfdcm
templates = # A list of 4xN array where each array is a template represented as N lines [x1, y1, x2, y2]^T
scene = # A 4xM array representing the M scene lines
# Perform template matching
max_tmpl_lines, max_scene_lines = 4, 4 # Combinatory search parameters.
depth = 30 # The [0, pi] discretization.
coeff = 5.0 # A weighting factor to enhance the angular cost vs distance cost in FDCM algorithm.
scene_padding = 1.5 # A ratio to pad the scene images used in the FDCM algorithm, use if best match may appear on image boundaries.
distance_type = openfdcm.distance.L2 # or openfdcm.distance.L2_SQUARED or openfdcm.distance.L1
#num_threads = 4
threadpool = openfdcm.ThreadPool() # could pass num_threads here, but default is optimal
featuremap_params = openfdcm.Dt3CpuParameters(depth, coeff, scene_padding, distance_type)
search_strategy = openfdcm.DefaultSearch(max_tmpl_lines, max_scene_lines)
optimizer_strategy = openfdcm.BatchOptimize(10, threadpool)
matcher = openfdcm.DefaultMatch()
penalizer = openfdcm.ExponentialPenalty(tau=1.5)
# Build FDCm feature map and search
start_time = time.time()
featuremap = openfdcm.build_cpu_featuremap(scene, featuremap_params, threadpool)
raw_matches = openfdcm.search(matcher, search_strategy, optimizer_strategy, featuremap, templates, scene)
penalized_matches = openfdcm.penalize(penalizer, raw_matches, openfdcm.get_template_lengths(templates))
sorted_matches = openfdcm.sort_matches(penalized_matches)
search_time = time.time() - start_time
print(f"Template matching search completed in {search_time:.4f} seconds.")
best_match = sorted_matches[0] # Best match (lower score) is first
best_match_id = best_match.tmpl_idx
best_matched_tmpl = templates[best_match_id]
result_rotation = best_match.transform[0:2, 0:2]
result_translation = best_match.transform[0:2, 2]