使用MATLAB来计算连续图像之间的偏移量
我使用隧道显微镜拍摄图像。但是,范围在连续的图像之间漂移。我正在尝试使用MatLab来计算图像之间的偏移量。下面的代码计算小图像(例如64x64像素)的秒数,但需要2个小时才能处理我正在处理的512x512像素图像。你对加速这段代码有什么建议吗?或者你知道更好的方式来跟踪MatLab中的图像吗?谢谢你的帮助!使用MATLAB来计算连续图像之间的偏移量
%Test templates
template = .5*ones(32);
template(25:32,:) = 0;
template(:,25:64) = 0;
data_A = template;
close all
imshow(data_A);
template(9:32,41:64) = .5;
template(:,1:24) = 0;
data_B = template;
figure, imshow(data_B);
tic
[m n] = size(data_B);
z = [];
% Loop over all possible displacements
for x = -n:n
for y = -m:m
paddata_B = data_B;
ax = abs(x);
zerocols = zeros(m,ax);
if x > 0
paddata_B(:,1:ax) = [];
paddata_B = [paddata_B zerocols];
else
paddata_B(:,(n-ax+1):n) = [];
paddata_B = [zerocols paddata_B];
end
ay = abs(y);
zerorows = zeros(ay,n);
if y < 0
paddata_B(1:ay,:) = [];
paddata_B = vertcat(paddata_B, zerorows);
else
paddata_B((m-ay+1):m,:) = [];
paddata_B = vertcat(zerorows, paddata_B);
end
% Full matrix sum after array multiplication
C = paddata_B.*data_A;
matsum = sum(sum(C));
% Populate array of matrix sums for each displacement
z(x+n+1, y+m+1) = matsum;
end
end
toc
% Plot matrix sums
figure, surf(z), shading flat
% Find maximum value of z matrix
[max_z, imax] = max(abs(z(:)));
[xpeak, ypeak] = ind2sub(size(z),imax(1))
% Calculate displacement in pixels
corr_offset = [(xpeak-n-1) (ypeak-m-1)];
xoffset = corr_offset(1)
yoffset = corr_offset(2)
你正在计算的是两个图像的cross-correlation。您可以一次计算所有偏移的互相关using Discrete Fourier Transforms(DFT或FFT)。因此,尝试像
z = ifft2(fft2(dataA) .* fft2(dataB).');
如果你垫在傅立叶域零,你甚至可以用这种数学得到补偿的像素的分数,并应用像素的分数偏移图像。
这种问题的一个典型方法是使用这样一个事实,即它可以快速为小图像工作,以使您受益。当你有大的图像时,将它们抽成小图像。快速注册小图像,并将计算出的偏移量用作下一次迭代的初始值。在下一次迭代中,您不会多次抽取图像,但是您首先对偏移进行了良好的初始估计,以便您可以将搜索解决方案限制在最初估计附近的小邻域。
尽管没有用隧道显微镜记录,但可能有一些帮助的评论文章是:Pluim,Maintz和Viergever在IEEE Transactions on Medical上发表的“基于互信息的医学图像注册:调查”成像,卷。 22,No.8,p。 986.
下面的函数是我试图手动计算两个图像的互相关。有些事情不太正确。如果我有时间的话,这周末再看一遍。您可以调用该函数的东西,如:
>> oldImage = rand(64); >> newImage = circshift(oldImage, floor(64/2)*[1 1]); >> offset = detectOffset(oldImage, newImage, 10) offset = 32 -1
function offset = detectOffset(oldImage, newImage, margin)
if size(oldImage) ~= size(newImage)
offset = [];
error('Test images must be the same size.');
end
[imageHeight, imageWidth] = size(oldImage);
corr = zeros(2 * imageHeight - 1, 2 * imageWidth - 1);
for yIndex = [1:2*imageHeight-1; ...
imageHeight:-1:1 ones(1, imageHeight-1); ...
imageHeight*ones(1, imageHeight) imageHeight-1:-1:1];
oldImage = circshift(oldImage, [1 0]);
for xIndex = [1:2*imageWidth-1; ...
imageWidth:-1:1 ones(1, imageWidth-1); ...
imageWidth*ones(1, imageWidth) imageWidth-1:-1:1];
oldImage = circshift(oldImage, [0 1]);
numPoint = abs(yIndex(3) - yIndex(2) + 1) * abs(xIndex(3) - xIndex(2) + 1);
corr(yIndex(1),xIndex(1)) = sum(sum(oldImage(yIndex(2):yIndex(3),xIndex(2):xIndex(3)) .* newImage(yIndex(2):yIndex(3),xIndex(2):xIndex(3)))) * imageHeight * imageWidth/numPoint;
end
end
[value, yOffset] = max(corr(margin+1:end-margin,margin+1:end-margin));
[dummy, xOffset] = max(value);
offset = [yOffset(xOffset)+margin-imageHeight xOffset+margin-imageWidth];
下面的链接将帮助您找到2个图像和正确/恢复失真之间的转换(在你的情况下,图像的偏移量)
http://in.mathworks.com/help/vision/ref/estimategeometrictransform.html
index_pairs = matchFeatures(featuresOriginal,featuresDistorted, 'unique', true);
matchedPtsOriginal = validPtsOriginal(index_pairs(:,1));
matchedPtsDistorted = validPtsDistorted(index_pairs(:,2));
[tform,inlierPtsDistorted,inlierPtsOriginal] = estimateGeometricTransform(matchedPtsDistorted,matchedPtsOriginal,'similarity');
figure; showMatchedFeatures(original,distorted,inlierPtsOriginal,inlierPtsDistorted);
inlierPtsDistored,inlierPtsOriginal具有称为位置的属性。 这些只不过是一个图像在另一个图像上的匹配位置。我认为从这一点来计算偏移量非常容易。
你有没有考虑[康莱特追踪器](http://www.ces.clemson.edu/~stb/klt/)? – rwong 2011-02-27 00:53:31