广义距离变换
距离变换操作在二值图像上,广义距离变换可以操作的任何函数上。需要注意的是,常见的距离变换采用的欧式距离为:
dis=(p−q)2−−−−−−−√
而广义距离的变换,采用的是欧式距离的平方。
Df(p)=minq∈G((p−q)2+f(q))
入口:
%%
clearall;
maxval=1e12;
%% 设置
isShow=true;% 是否显示结果
isUsed=true;%是否使用和显示慢方法。
isShowC=true;%是否显示使用c语言的方法。
%% change Status to look at the different results
Status=true; % Status==true表示0的代价无穷大,非0的代价为0.即黑的代价为无穷大,白的代价为0,反之亦然。
%%
img=imread('img\tst8.png');
img=rgb2gray(img);
%img=imresize(img,[100 100]);
if isShow
figure(1);
subplot(2,4,1);
imshow(img);
title('原图像');
end
[h,w]=size(img);
fprintf(' 图像的大小:\n 高*宽=%d*%d\n',h,w);
f=zeros(size(img));%函数f
if Status
f(:,:)=0;
f(find(img<255))=maxval;
else
f(:,:)=maxval;
f(find(img<255))=0;
end
if isShow
subplot(2,4,2);
imshow(f,[]);
title('代价函数');
end
%%
child=f;
father=zeros(size(child));
%% 使用遍历
if isUsed
disp('慢方法的计算时间:');
tic;
res_s=zeros(size(father));%% res_s :res_slow
for i2=1:size(father,1)
for j2=1:size(father,2);
temp=zeros(size(child));
for i1=1:size(child,1)
for j1=1:size(child,2)
%temp(i1,j1)=child(i1,j1)+sqrt((i1-i2)^2+(j2-j1)^2);
temp(i1,j1)=child(i1,j1)+(i1-i2)^2+(j2-j1)^2;
end
end
% find min value
res_s(i2,j2)=min(min(temp));
%[h,w]=find(temp==max(max(temp)));
end
end
toc;
if isShow
subplot(2,4,3);
imshow(res_s,[]);
title('慢方法');
end
end
%% 距离变换,采用x' y的形式。即采用公式(3)和公式(4)
% x' y的形式表示,首先,固定x',然后计算括号内的min,然后固定y计算最外层的min
% D_f(x,y)=min_x'((x-x')^2+min_y'((y-y')^2+f(x',y')))
% D_f(x,y)=min_x'((x-x')^2+D_f|x'(y))
disp('广义距离变换quick1:');
tic;
temp_res=zeros(size(child,1),size(father,2));%x'y
%% 固定x'
for i=1:size(child,1)% x'
child2=child(i,:);
father2=zeros(1,size(father,2));% y
temp_res(i,:)=my_testdp(child2,father2);
end
res_q1=zeros(size(father));%% res_q1 : res_quick1
%% 固定y
for j=1:size(temp_res,2)%y
child2=temp_res(:,j);
father2=zeros(1,size(father,1));%x
res_q1(:,j)=my_testdp(child2,father2)';
end
if isShow
subplot(2,4,5);
maxv=max(max(res_q1));
imshow(res_q1,[0 maxv]);
title('广义距离变换quick1');
end
toc;
%% 距离变换,采用y' x的形式。即采用公式(5)和公式(6)
% x' y的形式表示,首先,固定y',然后计算括号内的min,然后固定x计算最外层的min
% D_f(x,y)=min_y'((y-y')^2+min_x'((x-x')^2+f(x',y')))
% D_f(x,y)=min_y'((y-y')^2+D_f|y'(x))
disp('广义距离变换quick2:');
tic;
temp_res=zeros(size(father,1),size(child,2));%y'x
%% 固定y'
for i=1:size(child,2)% y'状态的数目
child2=child(:,i);
father2=zeros(1,size(father,1));
temp_res(:,i)=my_testdp(child2,father2)';
end
res_q2=zeros(size(father));%% res_quick2
%% 固定x
for j=1:size(temp_res,1)%
child2=temp_res(j,:);
father2=zeros(1,size(father,2));%x
res_q2(j,:)=my_testdp(child2,father2);
end
if isShow
subplot(2,4,6);
maxv=max(max(res_q2));
imshow(res_q2,[0 maxv]);
title('广义距离变换quick2');
end
toc;
%% 换了参数传递的方式
disp('广义距离变换quick3:');
tic;
temp_res=zeros(size(child,1),size(father,2));%x'y
for i=1:size(child,1)% x'
child2=child(i,:);
%father2=zeros(1,size(father,2));% y
temp_res(i,:)=disTrans(child2,1,length(child2),1,size(father,2))';
end
res_l=zeros(size(father));
for j=1:size(temp_res,2)%y
child2=temp_res(:,j);
%father2=zeros(1,size(father,1));%
res_l(:,j)=disTrans(child2,1,length(child2),1,size(father,1))';
end
if isShow
subplot(2,4,7);
maxv=max(max(res_l));
imshow(res_l,[0 maxv]);
title('广义距离变换quick3');
end
toc;
%% C++ 距离变换,采用x' y的形式。即采用公式(3)和公式(4)
% x' y的形式表示,首先,固定x',然后计算括号内的min,然后固定y计算最外层的min
% D_f(x,y)=min_x'((x-x')^2+min_y'((y-y')^2+f(x',y')))
% D_f(x,y)=min_x'((x-x')^2+D_f|x'(y))
disp('广义距离变换quick1 C++:');
% clear memory
% clear res_s res_l res_q1 res_q2 ;
tic;
temp_res=zeros(size(child,1),size(father,2));%x'y
%% 固定x'
if isShowC
for i=1:size(child,1)% x'
child2=child(i,:);
father2=zeros(1,size(father,2));% y
temp_res(i,:)=dp(child2,father2);
end
res_qc=zeros(size(father));%% res_q1 : res_quick1
%% 固定y
for j=1:size(temp_res,2)%y
child2=temp_res(:,j);
father2=zeros(1,size(father,1));%x
res_qc(:,j)=dp(child2,father2)';
end
if isShow
subplot(2,4,8);
maxv=max(max(res_qc));
imshow(res_qc,[0 maxv]);
title('广义距离变换quick1 C++');
end
toc;
end