我有两张我试图共同注册的图片 - 也就是说,一张可能是图片中心的一个球,另一张是靠近边缘的同一个球,我正试图找到麻木像素我必须移动第二个图像,以便球将在同一个地方。 (我实际上正在使用3D MRI脑部扫描,但原理是一样的。)
我写了一个函数,可以将球向左,向右,向上或向下移动一定数量的像素,以及另一个比较中心球图像与平移球的相关性的函数 - 边缘图像。当两个球在同一个地方时,相关函数将返回0,而对于其他位置则返回大于0的数字。
我正在尝试使用fminsearch
(documentation)来找到相关函数最小值的最佳平移(即,球在同一位置),如下所示:
global reference_im unknown_im;
starting_trans = [0 0 0];
trans_vector = fminsearch(@correlate_images,starting_trans)
correlate_images.m:
function r = correlate_images(translate)
global reference_im unknown_im;
new_im = move_image(unknown_im,translate(1),translate(2),translate(3));
% This bit is unimportant to the question
% but you can see how I calculate my correlation
r = 1 - corr(reshape(new_im,[],1),reshape(reference_im,[],1));
有两个问题,首先fminsearch
坚持将翻译向量的浮点值传递给correlate_images
函数。有没有办法告诉它只需要整数? (我会节省大量的cpu周期!)
其次,当我运行此程序时,生成的trans_vector
始终与starting_trans
相同 - 我认为这是因为没有找到最小值,但还有另一个原因,它只是显然不起作用吗?
非常感谢!
修改
我发现我认为输出trans_vector
始终与starting_trans
相同的原因。 fminsearch
查看起始值,然后从那里看每个方向的小增量,这个小增量总是小于1,这意味着相关的结果将是完美匹配(作为{{1}将返回与输入图像相同的子像素移动)。我将继续努力说服matlab只对整数值进行fmin搜索!
答案 0 :(得分:1)
首先,我要说Matlab可能不是解决这个问题的最佳工具。我会查看Elastix,这是ITK中注册函数的一个非常用户友好的包装器。您可以获得各种注册技术,两个程序的手册都可以很好地解释图像注册的具体细节。
其次,对于这种简单的平移配准,您可以使用FFT。正向变换两个图像,将图像相乘(逐点!即,使用A。* B,而不是A * B,因为那些是不同的操作,第一个是你想要的),并且在逆中应该有一个峰值变换,其偏离原点是您需要的平移量。 Numerical Recipes in C有一个很好的解释; here's a link to an index pdf。 FFT版本和直接相关版本之间的速度差异很大; FFT为O(N log N),而相关方法为O(N * M),其中M是搜索邻域中的像素数。如果要允许搜索整个图像,则相关性变为O(N * N),这将比FFT版本花费更长的时间。将参数从浮点数更改为整数不能解决问题。
fminsearch函数使用浮点数的原因(如果我能猜出编码器决策背后的原因)是对于不是测试问题的问题(即卷中的球体),你经常需要子像素分辨率执行正确的注册。请查看ITK文档,了解此方法背后的原因。
第三,我建议在Matlab中编写这个程序的好方法(如果你仍然想要这样做!)同时仍然强制整数相关将是避免使用浮点数的fminsearch函数。尝试类似:
startXPos = -10; %these parameters dictate the size of your search neighborhood
startYPos = -10; %corresponds to M in the above explanation
endXPos = 10;
endYPos = 10;
optimalX = 0;
optimalY = 0;
maxCorrVal = 0;
for i=startXPos:endXPos
for j = startYPos:endYPos
%test the correlation of the two images here, where one image is shifted to another
currCorrVal = Correlate(image1, image2OffsetByiAndj);
if (currCorrVal > maxCorrVal)
maxCorrVal = currCorrVal;
optimalX = i;
optimalY = j;
end
end
end
从这里开始,您只需编写偏移功能即可。这样,你就可以避免浮动问题,并且你也在增加你的平移向量(我没有看到任何方法让这个向量在你提供的函数中移动,这可能解释了你缺乏运动)。