Open CV 中的二维子图像检测

问题描述 投票:0回答:3

对于以下问题,使用 OpenCV 的最明智的算法或算法组合是什么:

  • 我有一组小型 2D 图像。我想检测这些子图像在较大图像中的位置。
  • 子图像通常约为 32x32 像素,较大图像约为 400x400。
  • 子图像并不总是正方形,其中包含 Alpha 通道。
  • 可选 - 较大的图像可能有颗粒感、压缩、3D 旋转或其他轻微扭曲

我尝试过cvMatchTemplate,结果很差(很难正确匹配,并且误报大量,所有匹配方法都如此)。一些问题来自于 OpenCV 似乎无法处理 alpha 通道模板匹配。

我尝试过手动搜索,似乎效果更好,并且可以包含 Alpha 通道,但速度很慢。

感谢您的帮助。

opencv image-processing template-matching
3个回答
7
投票
  1. cvMatchTemplate 使用 MSE (SQDIFF/SQDIFF_NORMED) 类型的度量进行匹配。这种度量将严重惩罚不同的 alpha 值(由于方程中的平方)。您尝试过标准化互相关吗?众所周知,可以更好地模拟像素强度的线性变化。
  2. 如果 NCC 不能完成这项工作,您将需要将图像转换到强度差异不会产生太大影响的空间。例如计算边缘强度图像(canny、sobel 等)并在这些图像上运行 cvMatchTemplate。
  3. 考虑到图像比例的巨大差异(~10x)。必须采用图像金字塔来找出匹配的正确比例。建议您从一个比例开始(2^1/x:x 是正确的比例)并将估计值传播到金字塔。

2
投票

您需要的是 SIFT 或 SURF 之类的东西。


0
投票

我建议使用 OpenFDCM。它比 OpenCV 更快,并且具有旋转和平移不变性。它的速度非常快,您还可以通过添加一堆缩放模板来实现缩放不变。看看这里,它叫OpenFDCM。

您可以在 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]
© www.soinside.com 2019 - 2024. All rights reserved.