使用 FFT 进行 Matlab 模板匹配

2024-03-26

我正在努力解决 Matlab 中傅立叶域中的模板匹配问题。这是我的图片(艺术家是 DeviantArt 上的 RamalamaCreatures):

我的目标是在负鼠的耳朵周围放置一个边界框,就像这个例子(我使用normxcorr2执行模板匹配):

这是我正在使用的 Matlab 代码:

clear all; close all;

template = rgb2gray(imread('possum_ear.jpg'));
background = rgb2gray(imread('possum.jpg'));

%% calculate padding
bx = size(background, 2); 
by = size(background, 1);
tx = size(template, 2); % used for bbox placement
ty = size(template, 1);

%% fft
c = real(ifft2(fft2(background) .* fft2(template, by, bx)));

%% find peak correlation
[max_c, imax]   = max(abs(c(:)));
[ypeak, xpeak] = find(c == max(c(:)));
figure; surf(c), shading flat; % plot correlation 

%% display best match
hFig = figure;
hAx  = axes;
position = [xpeak(1)-tx, ypeak(1)-ty, tx, ty];
imshow(background, 'Parent', hAx);
imrect(hAx, position);

The code is not functioning as intended - it is not identifying the correct region. This is the failed result - the wrong area is boxed: failed template matching

This is the surface plot of the correlations for the failed match: surf plot for failed template matching

希望您能帮忙!谢谢。


您在代码中所做的实际上根本不相关。您正在使用模板并且执行卷积与输入图像。如果您还记得傅里叶变换,两个信号的频谱相乘相当于两个信号在时间/空间域中的卷积。

基本上,您所做的就是使用模板作为内核并使用它来过滤图像。然后,您将找到此输出的最大响应,这就是模板所在的位置。响应被装箱的地方是有意义的,因为该区域是完全白色的,并且使用模板作为具有完全白色区域的内核会给您一个非常大的响应,这就是为什么它最有可能确定该区域是最大的回复。具体来说,该区域将具有很多高值(~255 左右),并且自然地与模板补丁执行卷积,并且由于操作是加权和,该区域将为您提供非常大的输出。因此,如果您在图像的暗区域使用模板,则输出会很小 - 这是错误的,因为模板也由暗像素组成。


但是,您当然可以使用傅立叶变换来定位模板的位置,但我建议您使用相位相关性 https://en.wikipedia.org/wiki/Phase_correlation反而。基本上,您不是计算两个谱的乘积,而是计算互功率谱。互功率谱R频域中两个信号之间的关系定义为:

Source: Wikipedia https://en.wikipedia.org/wiki/Phase_correlation

Ga and Gb是频域中的原始图像和模板,并且*是共轭。这o就是所谓的哈达玛积或元素积。我还想指出,该分数的分子和分母的除法也是逐元素的。使用互功率谱,如果您发现(x,y)产生绝对最大响应的位置,这是模板应位于背景图像中的位置。

因此,您只需更改计算“相关性”的代码行,以便它计算互功率谱。不过,我想指出一些非常重要的事情。当你表演时normxcorr2,相关性从图像的左上角开始。模板匹配从该位置开始,并与以模板大小为原点的窗口进行比较。当查找模板匹配的位置时,该位置相对于匹配窗口的左上角。一旦你计算normxcorr2,传统上将最大响应的一半行和一半列相加来找到中心位置.

因为我们或多或少在 FFT/频域中对模板匹配(滑动窗口、相关性等)进行相同的操作,所以当您完成在该相关数组中找到峰值时,您还必须考虑到这一点。但是,您致电imrect无论如何,要在模板匹配的位置周围绘制一个矩形,都会在边界框的左上角进行绘制,因此无需在此处进行偏移。因此,我们将稍微修改该代码,但在使用此代码时要记住偏移逻辑,以便稍后找到匹配的中心位置。


我还修改了您的代码,以直接从 StackOverflow 读取图像,以便其可重现:

clear all; close all;

template = rgb2gray(imread('https://i.stack.imgur.com/6bTzT.jpg'));
background = rgb2gray(imread('https://i.stack.imgur.com/FXEy7.jpg'));

%% calculate padding
bx = size(background, 2); 
by = size(background, 1);
tx = size(template, 2); % used for bbox placement
ty = size(template, 1);

%% fft
%c = real(ifft2(fft2(background) .* fft2(template, by, bx)));

%// Change - Compute the cross power spectrum
Ga = fft2(background);
Gb = fft2(template, by, bx);
c = real(ifft2((Ga.*conj(Gb))./abs(Ga.*conj(Gb))));

%% find peak correlation
[max_c, imax]   = max(abs(c(:)));
[ypeak, xpeak] = find(c == max(c(:)));
figure; surf(c), shading flat; % plot correlation    

%% display best match
hFig = figure;
hAx  = axes;

%// New - no need to offset the coordinates anymore
%// xpeak and ypeak are already the top left corner of the matched window
position = [xpeak(1), ypeak(1), tx, ty];
imshow(background, 'Parent', hAx);
imrect(hAx, position);

这样,我得到了以下图像:

在显示交叉功率谱的曲面图时,我还得到以下结果:

有一个明确定义的峰值,其余输出的响应非常小。这实际上是相位相关性的一个属性,很明显,最大值的位置是明确定义的,这就是模板所在的位置。


希望这可以帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 FFT 进行 Matlab 模板匹配 的相关文章

  • Matlab多核

    我正在运行一种占用大量资源并最大化 CPU 的算法 问题是它只使用一个CPU 我怎样才能使MATLAB多线程计算并使用超过1个CPU 除非您专门使用并行结构 即使用显式并行性 或使用已经为您并行化的内置函数 否则 Matlab 将不会在多核
  • 洪水填充算法是否考虑了 alpha 且不会在抗锯齿线周围留下边缘?

    我已经实现了一个典型的洪水填充算法 当使用纯色时 它按预期工作 其中我使用 ARGB 分量之间的欧几里德距离来比较颜色 我的问题是 如果您在透明背景上绘制类似抗锯齿红线的内容 我的洪水填充算法将不会填充大多数半透明像素 从而在对象周围留下条
  • 与 Matlab 相比,Numpy 加载 csv 太慢

    我发布这个问题是因为我想知道我是否做了一些非常错误的事情才能得到这个结果 我有一个中等大小的 csv 文件 我尝试使用 numpy 来加载它 为了便于说明 我使用 python 创建了该文件 import timeit import num
  • 在 Swift ios 中使用 vImageBuffer_initWithCGImage 时出现“致命错误:在展开可选值时意外发现 nil”

    我正在 Swift iOS8 中工作 并尝试将 UIImage 转换为 vImage Buffer 以使用 Accelerate framework 执行操作 我正在尝试使用 vImageBuffer initWithCGImage 进行转
  • iOS:使用覆盖裁剪从 UIImagePickerController 相机抓取的静态图像

    我是 iOS 新手 过去一周我一直在网上寻找教程 例如 处理 Exif 图像 http niftybean com main blog 16 selecting regions from rotated exif images on iph
  • 将数据库导入 MATLAB 错误

    我正在尝试将表导入到我的 MATLAB 工作区 但它一直向我抛出错误 Undefined function or method fetch for input arguments of type struct 这是我尝试执行的代码 dyn
  • MatLab 中的输出有小数点的上限 [重复]

    这个问题在这里已经有答案了 我修改了 MatLab 中的一些代码 以便它可以给出函数 cos x 3 x 的根 当我运行代码并要求它返回 xnew 的值 因为 xnew 应该等于函数的根 时 它仅将 xnew 返回到小数点后 4 位 我希望
  • 如何从opencv中的轮廓中提取简单的几何形状

    我有一个Mat contours我已经近似了每个contour with approxPolyDP 我现在想做的是检测矩形 三角形 圆形等形状 以及例如用不同的颜色或使用画布等重新绘制它们 有没有办法利用轮廓 我如何访问点Mat conto
  • Matlab:通过扩展向量来扩展矩阵

    我有一个dxmxn matrix A 解释 对于每个n 有m维度向量d 我想将每个 d 维向量扩展如下 考虑一个向量v维度 d 1 2 d 它是 x 1 x 2 x d 但为了简单起见 我删除了 x 目标是延长v获得一个d d向量形式 1
  • ND 输入的 im2col 算法

    我正在尝试为输入维度 gt 2D 编写自己的 im2col 算法 目前我正在研究 Matlab im2col 的实现 但是 我找不到任何有关二维以上输入的情况的文档 如果我将 3D 张量输入到函数中 我确实会得到输出 不过我不太明白你是如何
  • 如何在不使用 MATLAB 的情况下打开 .mat 文件?

    我在Matlab中做了一个项目 现在我已经卸载了Matlab 现在 我需要一些我的项目的参考 我留下了所有 mat 文件 我正在尝试在记事本中打开它们 并且我在那里得到了 unicode 字符 我的问题很简单 如何在记事本或某些文字处理器中
  • Python 中的归一化互相关

    最近几天我一直在努力计算两对向量 x和y 的自由度 参考Chelton 1983 它是 根据 Chelton 1983 的自由度 https i stack imgur com O0DqE png 我找不到使用 np correlate 计
  • 使用 Polyfit 进行垂直线拟合

    这只是一个基本问题 我正在使用拟合线来分散点polyfit 在某些情况下 我的散点具有相同的 X 值并且polyfit无法在其上放置一条线 必须有某种东西可以处理这种情况 毕竟 它只是一个线配合 我可以尝试交换 X 和 Y 然后再画一条线
  • 从图像中识别数字

    我正在尝试编写一个应用程序来查找图像内的数字并将它们相加 如何识别图像中的书写数字 图像中有很多框 我需要获取左侧的数字并将它们相加得出总数 我怎样才能实现这个目标 编辑 我对图像进行了 java tesseract ocr 但没有得到任何
  • 使用 sprintf 打印元素数量可变的向量

    在下面的代码中 我可以打印向量中的所有元素item用空格分隔为 item 123 456 789 sprintf d d d item ans 123 456 789 我怎样才能做到这一点而不必输入那么多 d作为元素的数量item 最简单的
  • Python 中 FFT 的循环加速(使用“np.einsum”)

    Problem 我想加速包含大量乘积和求和的 python 循环np einsum 但我也愿意接受任何其他解决方案 我的函数采用形状为 n n 3 的向量配置 S 我的情况 n 72 并对 N N 点的相关函数进行傅里叶变换 相关函数定义为
  • 使用二进制遮罩遮罩 RGB 图像

    我在 MATLAB 中读入了一个 RGB 图像 M x N x 3 矩阵 我还有一个图像的二进制掩码 M x N 矩阵 对于某些感兴趣的区域来说它只是 0 而其他地方都是 1 我正在尝试找出如何使用该二进制掩码来掩蔽 RGB 图像 我尝试过
  • 如何将 Simulink 编码器编译器版本设置为支持 C++11 的版本?

    我正在尝试将代码合并到 Simulink 及其嵌入式编码器中 该代码使用 C 11 扩展 跑步mex setup c 给出这个输出 mex setup c MEX configured to use Xcode Clang for C la
  • Matlab,如何获取imagesc生成的结果?

    我读过一些类似的文章 但它们不是我想要的 得到imagesc之后的矩阵 https stackoverflow com questions 14364239 get the matrix after imagesc 14364434 143
  • 这段代码可以优化吗?

    我有一些图像处理代码 循环遍历 2 个多维字节数组 大小相同 它从源数组中获取一个值 对其执行计算 然后将结果存储在另一个数组中 int xSize ResultImageData GetLength 0 int ySize ResultI

随机推荐

  • 带有 JSON 的范围对象

    我正在编写一个 Chrome 扩展程序 我需要将用户在网站上选择的值传递到我的服务器 我正在使用返回范围对象的代码 window getSelection 我正在使用 JSON 将范围对象传递回我的服务器 但它不起作用 我对此很陌生 但我认
  • C# 无法获取某些客户端计算机名称

    我使用下面的代码来获取客户端计算机名称 但是它适用于某些客户端 而某些客户端会出现错误 string IPAdd Request UserHostName IPHostEntry hostEntry Dns GetHostEntry IPA
  • IIS 上的 django,进程意外退出

    我已经阅读了关于该主题的所有文章 但我仍然无法在 IIS 上运行 django 项目 错误消息为 500 Internal Server Error c program files x86 python 3 5 python exe Fas
  • 如何更改 WPF 中绑定选项的默认值?

    在我当前的项目中 我使用了几个文本框控件 其内容由来自数据库的对象填充 该对象使用验证来验证文本的正确插入 当我想显示验证错误 即文本有很多字符 时 我必须向文本属性添加一些绑定选项 如下行所示
  • 删除 json_encode() 中的双引号

    我想删除 json encode 中的双引号 这是我的代码
  • 如何使用 Python 多线程处理 MySQL 连接

    我有一个主要的 Python 脚本 它连接到 MySQL 数据库并从中提取一些记录 根据返回的结果 它会启动与抓取的记录一样多的线程 类实例 每个线程都应该返回数据库并通过将一个状态标志设置为不同的状态 进程已启动 来更新另一个表 为了实现
  • Laravel 将数据透视表附加到具有多个值的表

    背景 我正在创建一个围绕食物过敏的数据库 并且食物和过敏之间存在多对多的关系 还有一个枢轴值称为severity其中有一个数字代表对该食品过敏的严重程度 这个链接表看起来像这样 food id allergy id severity 1 1
  • 指定与 Chef Solo 一起运行哪些食谱

    我正在使用 Chef solo 在本地测试我的食谱 但我希望能够只运行我正在测试的食谱 目前 chef solo 似乎将运行在solo rb 中指定的cookbooks 目录中的所有cookbook 我已经在 json 属性文件中指定了运行
  • 通过 jQuery ajax 调用将值列表传递给 django 视图

    我正在尝试使用 jQuery ajax 调用将数值 ids 列表从一个网页传递到另一个网页 我不知道如何传递和读取列表中的所有值 我可以成功发布和读取 1 个值 但不能成功发布和读取多个值 这是我到目前为止所拥有的 jQuery var p
  • Bootstrap 输入组插件对齐问题

    我的输入组插件与我的输入文本框不对齐 我做错了什么 div class form group div
  • 我无法让 phpseclib 工作

    我想做的事 我想要upload download一个文件通过sftp using php The phpseclib library看起来很有前途 我已经做了什么 我将composer json更改为 require nicolab php
  • 如何在Azure中创建或使用本地文件夹?

    我需要从 SFTP 服务器下载文件 下载的文件存储到本地文件夹 D Data tempData csv 我必须从本地文件读取数据并在我的应用程序中使用以进行其他数据操作 此作业是使用 Azure Web 作业中的 Web 挂钩计划程序创建的
  • 我的“zipLatest”运算符是否已经存在?

    关于我自己写的一个运算符的快速问题 请原谅我可怜的大理石图表 zip aa bb cc dd ee ff gg 11 22 33 44 55 a1 b2 c3 d4 e5 combineLatest aa bb cc dd ee ff gg
  • 使用 f:convertNumber 时设置小数点分隔符

    我想知道如何在 JSF 应用程序上设置默认的小数点分隔符 我有一些
  • NodeJS UDP 多播如何

    我正在尝试将 UDP 多播数据包发送到 230 185 192 108 以便每个订阅的人都会收到 有点卡住了 我相信它的广播正确 但似乎无法从任何客户端获取任何信息 Server var news Borussia Dortmund win
  • 如何将多个参数传递给 Scrapy 蜘蛛(不再支持使用多个蜘蛛运行“scrapy scrapy”时出现错误)?

    我想将多个用户定义的参数传递给我的 scrapy spider 所以我尝试遵循这篇文章 如何在 scrapy 蜘蛛中传递用户定义的参数 https stackoverflow com questions 15611605 how to pa
  • CMTime 和 AVFoundation 中单帧的移动

    我正在尝试使用 AVFoundation 播放视频 我使用以下代码作为将播放前进一帧的按钮 它间歇性地工作 在某些执行中它会做正确的事情并前进一帧 但大多数时候我必须按按钮 3 或 4 次才能前进一帧 这让我认为这是某种精度问题 但我无法弄
  • 为什么单函数访问器似乎被认为是坏习惯?

    我经常看到 即在 Slim 框架内 单一函数访问器风格 如下面的 1 已弃用 取而代之的是经典的 Java ish 2 函数访问器 get set 如下面的 2 就我个人而言 我更喜欢更少的代码行 在 1 中 和更少的输入 get set
  • Java多线程数据库访问[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 对于多线程 Java 应用程序来说 确保所有线程同步访问数据库的最佳解决方案是什么 例如 每个线程代表单独的事务 并且首先检查数据库的
  • 使用 FFT 进行 Matlab 模板匹配

    我正在努力解决 Matlab 中傅立叶域中的模板匹配问题 这是我的图片 艺术家是 DeviantArt 上的 RamalamaCreatures 我的目标是在负鼠的耳朵周围放置一个边界框 就像这个例子 我使用normxcorr2执行模板匹配