摘要: matlab,数学建模,碎片拼接html
额,最近抠c++抠累了,忽然心血来潮翻看近年来的大学生数学建模题。相比当年参加比赛的题目,整体感受如今的题目愈来愈接近生活了。多是多了一些经历,对一些题特别有感受,加之联想起之前作完一道难题获得的兴奋感,一个想法涌上心头,为何不利用如今的知识来好好“收拾收拾”它们呢。所以便有了这篇的文章,一方面是分享下本身的想法,另外也是锻炼下本身的文笔,身为程序猿,是时候改变一下一些习惯了。选出特别感兴趣的题目《2013年数学建模B赛题-图像碎片拼接》,开弄!c++
题目连接:http://www.mcm.edu.cn/html_cn/block/8579f5fce999cdc896f78bca5d4f8237.html算法
题目按切割方式不一样归类为三个子问题:单面纵切,单面纵横切,双面纵横切,其中前两个又分为中英文纸张的状况,三个问题依次愈来愈复杂,愈来愈接近实际状况。不过相较于生活中的问题,《女子将5万钞票撕成碎片续:丈夫辞职在家拼钱》,http://news.qq.com/a/20120506/000091.htm,建模题仍是比较小儿科的。 网络
单面纵切:能够理解为对n个碎片块进行“行内”排列组合,最终要求是使碎片边界无缝接合起来。排列组合的话能够用神经网络,遗传算法等智能算法实现,“无缝”须要一个量来表征。前面智能算法对碎片不一样组合时的无缝量进行评估,以后获得的最优解。这是学院派的解法,以此思路进行下去,一篇华丽的文章就能够出炉了。另外两个子问题也能够做相似的分解。spa
下面是我实现的解法,之前面方法相比,这种方法有些“简单粗暴”,先上matlab代码先(复制后放在相应的文件夹里运行便可):htm
clear all;clc;close all %% 碎片拼接 file_list= dir('*.bmp'); % 获取文件列表 if size(file_list,1)>0 image_list = {file_list.name}; else error('no image') end file_num=size(image_list,2); score=zeros(1,file_num); feature=cell(1,file_num); for ind=1:file_num % 计算碎片特征 filename=cell2mat(image_list(ind)); a=imread(filename); [row,col,len]=size(a); if len==3 a=rgb2gray(a); end a_d=double(a); f=a_d(:,1)'; tmp1=f.*f; tmp2=sqrt( sum(tmp1) ); f=f/tmp2; one.left=f; one.left_std=std(f); f=a_d(:,end)'; tmp1=f.*f; tmp2=sqrt( sum(tmp1) ); f=f/tmp2; one.right=f; one.right_std=std(f); feature{ind}=one; end %% 计算碎块的类似性矩阵 score_left=zeros(file_num,file_num); score_right=zeros(file_num,file_num); std_thr=0.001; for y=1:file_num % compare for x=1:file_num if y==x continue; end score_left(y,x)=feature{y}.left*feature{x}.right'; score_right(y,x)=feature{y}.right*feature{x}.left'; if feature{y}.left_std<std_thr score_left(y,x)=0; end if feature{y}.right_std<std_thr score_right(y,x)=0; end end end %% 计算块间类似性 order=[1]; order_left=2:file_num; % order,第一个保证先后都有对象 while 1 order if isempty(order_left) break; end left=order(1);right=order(end); score=score_left(left,:); [c,i]=max(score); if c(1)>0.95 && any(order_left==i(1)) order=[i order]; order_left(order_left==i(1))=[]; end score=score_right(right,:); [c,i]=max(score); if c(1)>0.95 && any(order_left==i(1)) order=[order i]; order_left(order_left==i(1))=[]; end end %% 拼接 b=[]; for ind=1:file_num % 拼接 filename=cell2mat(image_list(order(ind))); a=imread(filename); [row,col,len]=size(a); if len==3 a=rgb2gray(a); end b=[b a]; end %% show imshow(b)
大概的思路是先计算块的特征,而后计算块间的类似性,最后进行拼接。其实看代码更容易理解,其中的无缝量选择,能够应用在前面方法的实现里。对象
拼接后的效果图:blog
中文: 英文:get
~~Yemuzi分享文章,欢迎拍砖~~数学