对于固定和给定的tform,图像处理工具箱中的imwarp命令
B = imwarp(A,tform)
相对于A是线性的,意味着存在一些稀疏矩阵W,取决于tform但不依赖于A ,这样可以等效地实现上述
B(:)=W*A(:)
对于所有固定已知尺寸的A [n,n]。我的问题是是否有快速/有效的计算选项W.当我需要转置操作W时,矩阵形式是必要的。'* B(:),或者如果我需要做W \ B(:)或类似的线性代数我不能直接通过imwarp做的事情。
我知道可以通过
逐列计算W E=zeros(n);
W=spalloc(n^2,n^2,4*n^2);
for i=1:n^2
E(i)=1;
tmp=imwarp(E,tform);
E(i)=0;
W(:,i)=tmp(:);
end
但这是蛮力而且缓慢。
例程FUNC2MAT稍微更优,因为它使用循环来计算/收集每列W(:,i)的稀疏条目数据I,J,S。然后,在循环之后,它使用它来构造整个稀疏矩阵。它还提供使用PARFOR循环的选项。但是,这仍然比我想要的慢。
有人可以提出更多速度最佳的替代方案吗?
修改
对于那些对我的说法感到不舒服的说法,即(a,tform)是线性的w.r.t. A,我在下面包含了演示脚本,它测试了随机输入图像和tform数据的叠加属性。它可以反复运行,看nonlinearityError
总是很小,很容易归因于浮点噪声。
tform=affine2d(rand(3,2));
%tform=projective2d(rand(3));
fun=@(A) imwarp(A,tform,'cubic');
I1=rand(100); I2=rand(100);
c1=rand; c2=rand;
LHS=fun(c1*I1+c2*I2); %left hand side
RHS=c1*fun(I1)+c2*fun(I2); %right hand side
linearityError = norm(LHS(:)-RHS(:),'inf')
答案 0 :(得分:0)
实际上非常简单:
W = sparse(B(:)/A(:));
请注意,W不是唯一的,但此操作可能会产生最稀疏的结果。另一种计算方法是
W = sparse( B(:) * pinv(A(:)) );
但这导致稀疏(但仍然有效)的结果要少得多。
答案 1 :(得分:0)
我使用光流场[u,v]构建了变形矩阵,它适用于我的应用
% this function computes the warping matrix
% M x N is the size of the image
function [ Fw ] = generateFwi( u,v,M,N )
Fw = zeros(M*N, M*N);
k =1;
for i=1:M
for j= 1:N
newcoord(1) = i+u(i,j);
newcoord(2) = j+v(i,j);
newi = newcoord(1);
newj = newcoord(2);
if newi >0 && newj >0
newi1x = floor(newi);
newi1y = floor(newj);
newi2x = floor(newi);
newi2y = ceil(newj);
newi3x = ceil(newi); % four nearest points to the given point
newi3y = floor(newj);
newi4x = ceil(newi);
newi4y = ceil(newj);
x1 = [newi,newj;newi1x,newi1y];
x2 = [newi,newj;newi2x,newi2y];
x3 = [newi,newj;newi3x,newi3y];
x4 = [newi,newj;newi4x,newi4y];
w1 = pdist(x1,'euclidean');
w2 = pdist(x2,'euclidean');
w3 = pdist(x3,'euclidean');
w4 = pdist(x4,'euclidean');
if ceil(newi) == floor(newi) && ceil(newj)==floor(newj) % both the new coordinates are integers
Fw(k,(newi1x-1)*N+newi1y) = 1;
else if ceil(newi) == floor(newi) % one of the new coordinates is an integer
w = w1+w2;
w1new = w1/w;
w2new = w2/w;
W = w1new*w2new;
y1coord = (newi1x-1)*N+newi1y;
y2coord = (newi2x-1)*N+newi2y;
if y1coord <= M*N && y2coord <=M*N
Fw(k,y1coord) = W/w2new;
Fw(k,y2coord) = W/w1new;
end
else if ceil(newj) == floor(newj) % one of the new coordinates is an integer
w = w1+w3;
w1 = w1/w;
w3 = w3/w;
W = w1*w3;
y1coord = (newi1x-1)*N+newi1y;
y2coord = (newi3x-1)*N+newi3y;
if y1coord <= M*N && y2coord <=M*N
Fw(k,y1coord) = W/w3;
Fw(k,y2coord) = W/w1;
end
else % both the new coordinates are not integers
w = w1+w2+w3+w4;
w1 = w1/w;
w2 = w2/w;
w3 = w3/w;
w4 = w4/w;
W = w1*w2*w3 + w2*w3*w4 + w3*w4*w1 + w4*w1*w2;
y1coord = (newi1x-1)*N+newi1y;
y2coord = (newi2x-1)*N+newi2y;
y3coord = (newi3x-1)*N+newi3y;
y4coord = (newi4x-1)*N+newi4y;
if y1coord <= M*N && y2coord <= M*N && y3coord <= M*N && y4coord <= M*N
Fw(k,y1coord) = w2*w3*w4/W;
Fw(k,y2coord) = w3*w4*w1/W;
Fw(k,y3coord) = w4*w1*w2/W;
Fw(k,y4coord) = w1*w2*w3/W;
end
end
end
end
else
Fw(k,k) = 1;
end
k=k+1;
end
end
end