c语言sscanf函数的用法是什么
264
2022-11-16
暑假matlab最后一次训练(编程题)碎纸片的拼接复原(前2题)
对于给定的来自同一页印刷文字文件的碎纸机破碎纸片(仅纵切),建立碎纸片拼接复原模型和算法,并针对附件1、附件2给出的中、英文各一页文件的碎片数据进行拼接复原。如果复原过程需要人工干预,请写出干预方式及干预的时间节点。复原结果以图片形式及表格形式表达(见【结果表达格式说明】)。对于碎纸机既纵切又横切的情形,请设计碎纸片拼接复原模型和算法,并针对附件3、附件4给出的中、英文各一页文件的碎片数据进行拼接复原。如果复原过程需要人工干预,请写出干预方式及干预的时间节点。复原结果表达要求同上。上述所给碎片数据均为单面打印文件,从现实情形出发,还可能有双面打印文件的碎纸片拼接复原问题需要解决。附件5给出的是一页英文印刷文字双面打印文件的碎片数据。请尝试设计相应的碎纸片拼接复原模型与算法,并就附件5的碎片数据给出拼接复原结果,结果表达要求同上。
关键词: 灰色分析关联度,matlab,单面纵横交错切;,聚类,人工干预,相关性矩阵
一.第一题
思想:第一题是中文和英文图片,各19张,只需找出每行的首图,继续分析每张前面的图的右列像素和下一张图的左像素的相关性。(中文和英文的代码一样,只需要改一下位置)代码1:```bashclear allclose allclcfileform = 'C:\Users\Lenovo\Pictures\附件1\*.bmp';filepathsrc = 'C:\Users\Lenovo\Pictures\附件1\';files = dir(fileform);for i = 1:length(files) image{i} = imread([filepathsrc, files(i).name]);endn=numel(files);[h,z]=size(image{1,1})for k=1:n byz(:,k)=image{1,k}(:,1); %将第k张图片的最左边一列放入矩阵byz的第k列 byy(:,k)=image{1,k}(:,z);%将第k张图片的最右边一列放入矩阵byy的第k列end%利用页边距寻找第一张图片 for i=1:n Sum=0; for j=1:h if byz(j,i)==255 Sum=Sum+1; else break; end end if Sum = = h f=i; end endpaixu=zeros(1,n);index=1;paixu(index)=f; %关联度guanliandu = ones(n, 1);% set rho 分辨系数rho = 0.45; % 分辨系数i=f;while index <= n - 1 x0 = byy(:, i); byz(:, i)= nan; t = repmat(x0, [1, n]) - byz(: ,: ) ; mmin = min(min(t)); mmax = max(max(t)); xishu = (mmin + rho .* mmax) ./ (t +rho .* mmax); guanliandu = mean(xishu); [gsort, ind] = sort(guanliandu, 'descend'); i = ind(1); index = index + 1; paixu(index) = i;end temp=image{paixu(1)};for i=2:n temp=[temp image{paixu(i)}]; %将排序好的图片存放于tempendimshow(temp,'InitialMagnification','fit');%完整显示整张纸片
clear allclose allclcfileform = 'C:\Users\Lenovo\Pictures\附件2\*.bmp';filepathsrc = 'C:\Users\Lenovo\Pictures\附件2\';%这里要分开写,我不知道为什么直接写在那个image赋值的函数里就报错files = dir(fileform);for i = 1:length(files) image{i} = imread([filepathsrc, files(i).name]);endn=numel(files);[h,z]=size(image{1,1})for k=1:n byz(:,k)=image{1,k}(:,1); %将第k张图片的最左边一列放入矩阵byz的第k列 byy(:,k)=image{1,k}(:,z);%将第k张图片的最右边一列放入矩阵byy的第k列end%利用页边距寻找第一张图片 for i=1:n Sum=0; for j=1:h if byz(j,i)==255 Sum=Sum+1; else break; end end if Sum= = h f=i; end endpaixu=zeros(1,n);index=1;paixu(index)=f; %关联度guanliandu = ones(n, 1);% set rho 分辨系数rho = 0.45; % 分辨系数i=f;** 灰色关联度的套路代码如下 **while index <= n - 1 x0 = byy(:, i); byz(:, i)= nan; t = repmat(x0, [1, n]) - byz(: ,: ) ; mmin = min(min(t)); mmax = max(max(t)); xishu = (mmin + rho .* mmax) ./ (t +rho .* mmax); guanliandu = mean(xishu); [gsort, ind] = sort(guanliandu, 'descend'); i = ind(1); index = index + 1; paixu(index) = i;end temp=image{paixu(1)};for i=2:n temp=[temp image{paixu(i)}]; %将排序好的图片存放于tempendimshow(temp,'InitialMagnification','fit');%完整显示整张纸片
下面是英语的
灰色关联度公式
二.209张中文图和209张英文图
第二问比较复杂,第一问在第一天下午就做好了,这个复杂在于方法找的还不是最好的。我们用聚类把209张图分成了11类,我试了3种聚类(kmeans 模糊均值聚类,还有这个常见的根据距离聚类)最后发现这个根据聚类效果还可以。
这个是用相关度函数做到的
用到的新的函数(不过在这个题里的聚类效果不知道为甚么不好就没用它了):
我们组长的版本:
clear;clc;fileform = 'C:\Users\Lenovo\Pictures\附件3\*.bmp';filepathsrc = 'C:\Users\Lenovo\Pictures\附件3\';files = dir(fileform);for i = 1:length(files) image{i} = imread([filepathsrc, files(i).name]);endbyz=[];byy=[];for i=1:length(image) byz=[byz image{i}(:,1)]; byy=[byy image{i}(:,end)];endbyz=im2double(byz);byy=im2double(byy); a= [30 6 11 38 45 49 56 60 65 76 93 99 105 112 172 173 181 202 207];aa=[];y=a(1);c=[];c=[c y];m=0;ok=[];s=start;aa=[];while m~=18 ok=union(ok,c);aa=setdiff(a,ok);cc=[last(:,y) s(:,aa)];r=corrcoef(cc);[x,y]=max(r(1,2:length(r)))y=aa(y)c=[c y]% if isnan(x)% rr1=[63 68 81 136 144];% y=intersect(rr1,a);%找两不同维度矩阵相同元素% c(end)=y;% end%%% cc1=c;n1=1;% while x<0.1 && n1~=0 % rr=([aa(1:end);r(1,2:end)])';% rr=sortrows(rr,-2);% b=intersect(rr(:,1),cc1);% for i=1:length(b)% for j=1:length(rr)-1% if rr(j,1)==b(i);% rr(j,:)=[];% end% end% end% temp1=[];% for i=1:length(c)% temp1=[temp1 image{c(i)}];% end% imshow(temp1);% n1=input('请输入n1值:');% if n1~=0 % c(end)=rr(1);% cc1=[cc1 rr(1)];% end% % % end% y=c(end);%%m=m+1;endtemp1=[];for i=1:length(c) temp1=[temp1 image{c(i)}];endimshow(temp1);fileform = 'D:\2019数学建模\第六次模拟(8月28日-8月30日)--编程类专题\A题\附件3\*.bmp';filepathsrc = 'D:\2019数学建模\第六次模拟(8月28日-8月30日)--编程类专题\A题\附件3\';file = dir(fileform);for i = 1:length(file) image{i} = imread([filepathsrc, file(i).name]);endstart=[];last=[];for i=1:length(image) start=[start image{i}(:,1)]; last=[last image{i}(:,end)];endstart=im2double(start);last=im2double(last);
我的版本(比较复杂):
P是同行的一组,F是从之前聚类后再人工比对后多余的图片序号新组成的一组
clear allclose allclcfileform = 'C:\Users\Lenovo\Pictures\附件3\*.bmp';filepathsrc = 'C:\Users\Lenovo\Pictures\附件3\';files = dir(fileform);for i = 1:length(files) image{i} = imread([filepathsrc, files(i).name]);endn=numel(files);[h,z]=size(image{1,1});for k=1:n byz(:,k)=image{1,k}(:,1); %将第k张图片的最左边一列放入矩阵byz的第k列 byz的z表示左 byy(:,k)=image{1,k}(:,z);%将第k张图片的最右边一列放入矩阵byy的第k列 byy的y表示右 end%利用页边距寻找第一张图片f=[];t=0; for i=1:n Sum=0; for j=1:h t=t+1; if byz(j,i)== 255 &image{1,i}(:,2) == 255 & image{1,i}(:,3) == 255 &image{1,i}(:,4) == 255 Sum=Sum+1; else break; end end if Sum==h f=[f;i]; end end %把各列加起来,聚类Julei=zeros(209,180);a=sum(image{1,1},2);for i=1:209 Julei(i,:)= sum(image{1,i},2);endX2=zscore(Julei); %标准化数据y=pdist(Julei); %用于计算成对距离 x:m*n m个对象 n的长度z=linkage(y,'ward') ; %创建系统聚类数T=cluster(z,11) ; %创建聚类矩阵% [T,C,sumD,D]=kmeans(Julei,11) % 这里的聚类会把大部分的同行图片聚在一起,但需要人工调制位置,算法毕竟不是万能的。index(1).t = find(T== 1);index(2).t = find(T== 2);index(3).t = find(T== 3);index(4).t = find(T== 4);index(5).t = find(T== 5);index(6).t = find(T== 6);index(7).t = find(T== 7);index(8).t = find(T == 8 );index(9).t = find(T == 9);index(10).t = find(T== 10);index(11).t = find(T==11);
可以先去了解一下Matlab中kmeans函数用法
重点的分析过程在下面
%-----------------------------------聚类分组后--------------------------------------------------------------------------------% %先对19个 p1=[30 6 11 38 45 49 56 60 65 76 93 99 105 112 172 173 181 202 207]; p2=[50;12;23;29;3;55;58;66;92;96;119;130;142;144;179;187;189;191;193] p3=[62;20;21;37;53;7;64;68;70;73;79;80;97;100;117;132;163;164;178]; % %21个 p4=[14 16 18 28 34 61 72 81 84 86 126 133 134 153 157 166 171 199 201 203 206 ] ; p5=[5 15 31 41 90 102 103 109 114 115 118 120 124 141 147 152 155 156 186 195 208 ] ; %29个的 p6=[1 8 35 43 44 48 54 59 69 78 85 91 95 98 113 122 125 127 128 137 138 145 150 159 165 175 176 184 209 ]; %18个的 p7=[2 19 24 27 42 51 63 77 87 88 101 121 143 148 169 180 192 196 ]; p8=[4 13 32 40 52 74 83 108 116 129 135 136 160 161 170 177 200 204 ]; %17个的 % p9=[17 22 67 107 110 111 140 146 151 158 174 182 183 185 188 198 205]; %14个 p10=[25 36 39 47 82 89 104 123 131 149 162 168 190 194 ]; p11=[9 10 26 33 46 57 71 75 94 106 139 154 167 197 ]; %-----------------------------挑选剩下后-------------------------------------------------------------------------------------------% %21 和29剩下的 p12=[126 14 15 31 ,1,8,54,69,127,138,159,175,176,209] %% [8 209]是一组 %p7剩下的 p13=[1,8,14,15,54,69,126,127,138,159,175,176,209]; %%[ 8 209]、[126 14]各是一组 %p8剩下的 p14=[1,8,14,54,69,126,127,138,159,175,176,209]; %%[ 8 209]、[126 14]各是一组 %p9剩下的 p15=[1,8,54,69,127,138,159,175,176,209]; %%[ 8 209]各是一组 %p11剩下的 p16=[9,10,26,75,106]; %------------p10的数量不够一行数量,需要拿多余的组的图片来比较,下面是一个模板----------------------------------------------------------------------------------% p=[p10 p16]; % 先组合起来,选出合适的就把p10扩充,不合适的继续在p16; % 此时的p =[25,36,39,47,82,89,104,123,131,149,162,168,190,194,9,10,26,75,106] q=[8;15;30;39;50;62;72;90;95;126;169]; % 第一列的像素值 F= intersect(p,q); % F=39 说明p和q有交集,元素是39,由于q为排好的,p要剔除39这个数字 Index=1; paixu(Index)=F % 一整列归为F(值为39) % set rho 分辨系数 rho = 0.45; % 分辨系数;这个题的经验值 guanliandu = ones(19, 1) i=find(p==F); % 准备从p中删除交集{39}里的所有元素,由于只有一个,所以只需要一个i表示p中39数字的位置 x0 = byy(:, p(i)); % byy的作用:将第k张图片的最右边一列放入矩阵byy的第k列 p(p==p(i))=[]; % 相当于删掉了p的39这个元素 temp=image{paixu(1,1)}; while Index <= 18 cyz=byz(:,p); t = repmat(x0, [1, length(cyz(1,:) ) ]) - cyz(:, : ) ; % 把p的复制,扩大列的规模,t是deta差值数组 mmin = min(min(t)); mmax = max(max(t)); xishu = (mmin + rho .* mmax) ./ (t +rho .* mmax); guanliandu = mean(xishu); [gsort, ind] = sort(guanliandu, 'descend'); % mode为'descend'时,进行降序排序 sort(guanliandu, 'descend') i = ind(1) % 关联度最高的列的序号 Index = Index + 1; paixu(Index) = p(i); temp=[temp image{1,paixu(Index)}]; imshow(temp) % 查看由关联度匹配的对不对 I=1; while input('需要修改吗')==1 % 人工修改,一个一个判断 nextchoice=ind(I+1) paixu(Index) = p(nextchoice) temp(:,(Index-1)*72+1:end) =image{1,paixu(Index)}; imshow(temp); I=I+1; i=find(p==p(nextchoice)) end x0 = byy(:, p(i)); p(p==p(i))=[]; end Temp=image{paixu(1,1)};for i=2:19 Temp=[Temp image{paixu(1,i)}]; %将排序好的图片存放与tempendimshow(Temp,'InitialMagnification','fit');%完整显示整张纸片
这个代码其实第二天晚上就想好了,但是有个地方我太粗心了,一直没发现。 ”
=find(p==p(nextchoice)) end x0 = byy(:, p(i)); p(p==p(i))=[];
=image{paixu(1,1)}; for i=2:19 Temp=[Temp image{paixu(1,i)}]; %将排序好的图片存放与temp end imshow(Temp,'InitialMagnification','fit');%完整显示整张纸片// 不过很耗时间,我在第三天自己搞出完整的图。
下面是我在查找的详细过程:类中为19个的:
类1.1: p1=[30 6 11 38 45 49 56 60 65 76 93 99 105 112 172 173 181 202 207];
排序: 30 65 112 202 6 93 181 49 38 76 56 45 207 11 105 99 173 172 60
类1.2: p2=[50;12;23;29;3;55;58;66;92;96;119;130;142;144;179;187;189;191;193] 排序: 50 55 66 144 187 3 58 193 179 119 191 96 12 23 130 29 92 189 142
类1.3: p3=[62;20;21;37;53;7;64;68;70;73;79;80;97;100;117;132;163;164;178]; 排序: 62 20 79 68 70 100 163 97 132 80 64 117 164 73 7 178 21 53 37
类中为21个的: 类2.1: p4=[14 16 18 28 34 61 72 81 84 86 126 133 134 153 157 166 171 199 201 203 206 ] ;
由于F=[72;126] 分2种情况: 1.)剔除126,结果是 排序后: 72 157 84 133 201 18 81 34 203 199 16 134 171 206 86 153 166 28 61
2.)剔除72,发现:
排序后为: 12614 203 126和14应该不是属于同一组
类2.2: p5=[5 15 31 41 90 102 103 109 114 115 118 120 124 141 147 152 155 156 186 195 208 ] ; F=[15;90],同上: (1)先去除15 排序: 90 147 103 155 115 41 152 208 156 141 186 109 118 5 102 114 195 120 124
(2)再去除90 结果:
15和31也不是同一行的图
3.类中有29个: p6=[1 8 35 43 44 48 54 59 69 78 85 91 95 98 113 122 125 127 128 137 138 145 150 159 165 175 176 184 209 ];
F=[8;95] (1)去除95:
结果:[8,209,98] 收获:8和209在一个组里 (2)去除8 排序:95 35 85 184 91 48 122 43 125 145 78 113 150 98 137 165 128 59 44 结果:
从后面开始都是会少的,所以代码要改动 先来统计刚才剩下的数字: p12=[126 14 15 31 ,1,8,54,69,127,138,159,175,176,209] %% 其中[8 209]是一组
4.类中有18个的: 4.1 p7=[2 19 24 27 42 51 63 77 87 88 101 121 143 148 169 180 192 196 ]; 与p12合并后操作: F=[8;15;126;169] 分成4类 (1)先剔除15 126 169 排序:
收获:8和209同行,但不是这个类 (2)剔除126 169 外再剔除8和209
收获15也不是这个类 (3)留下126 结果:
收获 126和14为同一行,不在这个类里 (4)留下169 排序:169 101 77 63 143 31 42 24 148 192 51 180 121 87 196 27 2 88 19
再统计“孤儿数字”:
p13=[1,8,14,15,54,69,126,127,138,159,175,176,209]; %%[ 8 209]、[126 14]各是一组
4.2 p8=[4 13 32 40 52 74 83 108 116 129 135 136 160 161 170 177 200 204 ];
F=[8;15;126] (1)F=8
8和209同行 (2)F=15 排序: [15 129 4 160 83 200 136 13 74 161 204 170 135 40 32 52 108 116 177]
(3)
收获 126和14为同一行,不在这个类里5.类中有17个 p9=[17 22 67 107 110 111 140 146 151 158 174 182 183 185 188 198 205];
F=[8;126] (1)F=8
8和209
(2)排序: 126 14 183 110 198 17 185 111 188 67 107 151 22 174 158 182 205 140 146
6.类中有14个 P15=[1,8,54,69,127,138,159,175,176,209]
6.1 p10=[25 36 39 47 82 89 104 123 131 149 162 168 190 194 ];
F=[8;39] (1)F=8 8和209 (2)F=39 排序结果:
Paixu=[39 149 47 162 25 36 82 190 123 104 131 194 89 168 69] 数目为15,69不是这个类的。暂让后面先组合
6.2 p11=[9 10 26 33 46 57 71 75 94 106 139 154 167 197 ]; 结果: Paixu=[8 209 139 159 127 69 176 46 175 1 138 54 57 94 154 71 167 33 197]
剩下了:[9 10 26 75 106]和p10
结果: Paixu=[39 149 47 162 25 36 82 190 123 104 131 194 89 168 26 9 10 106 75]
综上所诉,总结果是
每行最后的索引:
50 55 66 144 187 3 58 193 179 119 191 96 12 23 130 29 92 189 142
62 20 79 68 70 100 163 97 132 80 64 117 164 73 7 178 21 53 37
169 101 77 63 143 31 42 24 148 192 51 180 121 87 196 27 2 88 19
39 149 47 162 25 36 82 190 123 104 131 194 89 168 26 9 10 106 75
15 129 4 160 83 200 136 13 74 161 204 170 135 40 32 52 108 116 177
95 35 85 184 91 48 122 43 125 145 78 113 150 98 137 165 128 59 44
126 14 183 110 198 17 185 111 188 67 107 151 22 174 158 182 205 140 146
30 65 112 202 6 93 181 49 38 76 56 45 207 11 105 99 173 172 60
8 209 139 159 127 69 176 46 175 1 138 54 57 94 154 71 167 33 197
72 157 84 133 201 18 81 34 203 199 16 134 171 206 86 153 166 28 61
90 147 103 155 115 41 152 208 156 141 186 109 118 5 102 114 195 120 124
辅助函数1
(setdiff函数找出2个数组的不一样的数字,前一个数组里减少,位置放错,答案是不一样的,如离散数学里说的集合AB之间,A-B不等于B-A) aa=[9 10 26 33 46 57 71 75 94 106 139 154 167 197 ]; bb=[1,8,54,69,127,138,159,175,176,209]; %%[ 8 209]各是一组 cc=[aa,bb]; ab=[8,209,139,159,127,69,176,46,175,1,138,54,57,94,154,71,167,33,197]; c=setdiff(cc,ab);
辅助函数2 出最后一张大图 imshow函数
clear allclose allclcfileform = 'C:\Users\Lenovo\Pictures\附件3\*.bmp';filepathsrc = 'C:\Users\Lenovo\Pictures\附件3\';files = dir(fileform);for i = 1:length(files) image{i} = imread([filepathsrc, files(i).name]);endpaixu=[50 55 66 144 187 3 58 193 179 119 191 96 12 23 130 29 92 189 14262 20 79 68 70 100 163 97 132 80 64 117 164 73 7 178 21 53 37169 101 77 63 143 31 42 24 148 192 51 180 121 87 196 27 2 88 1939 149 47 162 25 36 82 190 123 104 131 194 89 168 26 9 10 106 7515 129 4 160 83 200 136 13 74 161 204 170 135 40 32 52 108 116 17795 35 85 184 91 48 122 43 125 145 78 113 150 98 137 165 128 59 44126 14 183 110 198 17 185 111 188 67 107 151 22 174 158 182 205 140 14630 65 112 202 6 93 181 49 38 76 56 45 207 11 105 99 173 172 608 209 139 159 127 69 176 46 175 1 138 54 57 94 154 71 167 33 19772 157 84 133 201 18 81 34 203 199 16 134 171 206 86 153 166 28 6190 147 103 155 115 41 152 208 156 141 186 109 118 5 102 114 195 120 124]; for i=0:10 for j=0:18 Temp( ( i*180+1):(i+1)*180, (j*72+1):(j+1)*72 ) =image{paixu(i+1,j+1)}; endendimshow(Temp,'InitialMagnification','fit');%完整显示整张纸片求英语图同上
三.第三题是把前2题重复,由于时间问题放弃了。
四、分析:
我们这个题有2个致命的缺点: 1.聚类不是很好,没有说都在【19-2,19+2】左右范围里,其中在最后面的2行在比较时要让最后一行先排序,有个梗,倒数第二类需要一个点的数据在最后一个类里。 2.第2问的关联度没有找多一点变量关系,只是把每一列加到第一列,就根据这个距离来确定关联度,这个导致人工耗费多,因为想要的图可能关联度不高。
五.暑假数学建模思想总结:
1.要敢于向自己不会的领域学习,例如建模和写论文,不要局限于写代码 2.绝对要相信你的队友,因为她或他可能是其他专业的但建模和打代码可能超过你,要抱着学习的态度合作 3.多看论文,但重要的是能形成自己队伍里统一的idea,而不是你个人的idea,要形成统一的思想
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~