如下图所示,共有120个子图,如何用MATLAB拼接起来?
1 读取数据
首先读取所有图像数据,存在X中,并用imshow显示。
clear all
%% 读取图片数据并显示
X = {
};
for i = 1:120
X{
i} = imread(['G:\图像处理\matlab\拼接图像\附件2-一般图片\00',num2str(i),'.bmp']);
end
for i=1:120
subplot(12,10,i)
imshow(X{
i})
end
如图所示,这是需要拼接的120个子图
2 预处理
%% 转化为二值图
X_01 = {
};
for i = 1:120
X_01{
i} = im2bw(rgb2gray(X{
i}));
end
%示意
subplot(131);imshow(X{
1})
subplot(132);imshow(rgb2gray(X{
1}))
subplot(133);imshow(im2bw(rgb2gray(X{
i})))
原图、rgb2gray变成的灰度图、以及二值图对比:
3 计算子图之间的相关性
只考虑边缘与边缘之间的关系。建立一个120×120的矩阵,里面分别存放着子图与子图之间的相关性。
如:如果图A左侧和图B右侧的二值接近,那么图A就在图B右边。
%% 计算分数
%score中保存着四种分数,分别对应两个图块的四种接法
score = zeros(120,120,4);
s=zeros(120,120,4);
for k = 1:4
for i = 1:120
img1 = X_01{
i};
for j = 1:120
if i~=j
img2 = X_01{
j};
%s(i,j,k) = img12img2(img1,img2,k);
if k==1
score(i,j,k) = sum((img1(:,1)-img2(:,end)).^2);
elseif k==2
score(i,j,k) = sum((img1(1,:)-img2(end,:)).^2);
elseif k==3
score(i,j,k) = sum((img1(:,end)-img2(:,1)).^2);
else
score(i,j,k) = sum((img1(end,:)-img2(1,:)).^2);
end
end
end
end
end
score1 = score(:,:,1);
score2 = score(:,:,2);
score3 = score(:,:,3);
score4 = score(:,:,4);
%注意:score1=score3'
4 列子图拼接
下一步开始拼接,这一步的拼接过程是数字判断+人工干预。
随机选择一个初始子图,然后往下拼接。
%% 拼接,首先把纵向的接好
%随机选择一个图块to,找上下图分别是?
bus_result = [];
%% 往下拼接
% eg to=99,找子图99的上下子图
to = 5;
from_bus = to;
X_show = [];
bus = from_bus;
X_show = X{
from_bus};
for i = 1:12
from_bus = bus(end);
s = score2(:,from_bus);
s(from_bus) = [];
[~,to_bus] = min(s);
if to_bus >= from_bus
to_bus = to_bus +1;
end
[~,idx] = sort(s);
j=1;
imshow([X_show;X{
to_bus}])
label = input('正常1,异常0,退出-1:');
if label==-1
break
end
while ismember(to_bus,bus) || ~label
to_bus = idx(j+1);
if to_bus > from_bus
to_bus = to_bus +1;
end
imshow([X_show;X{
to_bus}])
j=j+1;
label = input('正常1,异常0:');
if label==-1
return
end
end
if label==-1
return
end
imshow([X_show;X{
to_bus}])
X_show = [X_show;X{
to_bus}];
bus = [bus;to_bus];
from_bus = to_bus;
end
imshow(X_show)
%如果选中的to在中间,需要上下子图都找,99子图在最上面,所以只找下图就可
上图拼接正常,因此输入1.
拼接异常,输入0.
拼接正常,输入1
当向下拼接结束后,再向上拼接。
%% 往上拼接
from_bus = to;
for i = 1:12
from_bus = bus(1);
s = score4(:,from_bus);
s(from_bus) = [];
[~,to_bus] = min(s);
if to_bus >= from_bus
to_bus = to_bus +1;
end
[~,idx] = sort(s);
j=1;
imshow([X{
to_bus};X_show])
label = input('正常1,异常0,退出-1:');
if label==-1
break
end
while ismember(to_bus,bus) || ~label
to_bus = idx(j+1);
if to_bus > from_bus
to_bus = to_bus +1;
end
imshow([X{
to_bus};X_show])
j=j+1;
label = input('正常1,异常0:');
if label==-1
return
end
end
if label==-1
return
end
imshow([X{
to_bus};X_show])
X_show = [X{
to_bus};X_show];
bus = [to_bus;bus];
from_bus = to_bus;
end
imshow(X_show)
bus_result = [bus_result,bus];
上下都拼接结束后,结果如下:
重复,把十二个列图拼接完成。
下面是子图代码。
bus_result =[
99 35 6 91 22 40 92 32 34 119 35 55;
3 105 30 11 16 68 115 96 69 101 54 45;
77 51 33 62 74 113 72 60 78 70 107 7;
86 28 17 81 100 38 76 103 58 89 42 41;
120 104 93 46 98 111 14 47 80 56 63 117;
8 5 48 59 90 84 83 67 97 106 79 108;
53 49 27 37 25 21 109 29 52 64 31 110;
61 44 15 94 87 50 43 88 26 19 102 73;
1 4 18 65 82 116 23 36 71 2 114 85;
75 10 12 66 39 95 9 24 13 20 57 118;]
5 行子图拼接
% 把列子图二值化
X_col = {
};
for j = 1:12
Z = [];
for i = 1:10
Z = [Z;X{
bus_result(i,j)}];
end
X_col{
j} = Z;
end
X_med2 = X_col;
X_01 = {
};
for i = 1:12
X_01{
i} = im2bw(X_med2{
i});
end
%% 拼接算法(最简单的判断边缘距离的算法)
%score保存边缘之间的差值平方和
N=12;
score = zeros(N);
for i = 1:N
img1 = X_01{
i};
for j = 1:N
if i~=j
img2 = X_01{
j};
score(i,j) = sum((img1(:,end)-img2(:,1)).^2);
end
end
end
from_bus = 1;
X_show = X_med2{
from_bus};
bus=[from_bus];
for i = 1:12
s = score(from_bus,:)';
s(from_bus) = [];
[~,to_bus] = min(s);
if to_bus >= from_bus
to_bus = to_bus +1;
end
[~,idx] = sort(s);
j=1;
imshow([X_show,X_med2{
to_bus}])
label = input('正常1,异常0,退出-1:');
if label==-1
break
end
while ismember(to_bus,bus) || ~label
to_bus = idx(j+1);
if to_bus > from_bus
to_bus = to_bus +1;
end
imshow([X_med2{
to_bus},X_show])
j=j+1;
label = input('正常1,异常0:');
if label==-1
break
end
end
if label==-1
break
end
imshow([X_show,X_med2{
to_bus}])
X_show = [X_show,X_med2{
to_bus}];
bus = [bus,to_bus];
from_bus = to_bus;
end
% 没有用到左接,因为选择的是左边缘
最终结果:
一段没有用到的右连接代码,如果选择的初始子图是中间的列子图,需要这一段。
%%
bus_ = zeros(10,12);
for i = 1:12
bus_(:,i)=bus_result(:,bus(i));
end
%最终在GUI中使用的是bus_矩阵中的数据
%% 左接
% from_bus = 1;
% for i = 1:N-length(bus)
% s = score(:,from_bus);
% s(from_bus) = [];
% [~,to_bus] = min(s);
%
% if to_bus >= from_bus
% to_bus = to_bus +1;
% end
% [~,idx] = sort(s);
% j=1;
% imshow([X_med2{
to_bus},X_show])
% label = input('正常1,异常0,退出-1:');
% if label==-1
% break
% end
% while ismember(to_bus,bus) || ~label
%
% to_bus = idx(j+1);
% if to_bus > from_bus
% to_bus = to_bus +1;
% end
% imshow([X_med2{
to_bus},X_show])
% j=j+1;
% label = input('正常1,异常0:');
% if label==-1
% break
% end
% end
% if label==-1
% break
% end
% imshow([X_med2{
to_bus},X_show])
% X_show = [X_med2{
to_bus},X_show];
% bus = [to_bus,bus];
% from_bus = to_bus;
% end
今天的文章MATLAB图像拼接——怎么用MATLAB做拼图?分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/29908.html