• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

用Matlab解《2013年数据建模比赛》图像碎片拼接题

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

摘要: matlab,数学建模,碎片拼接

  额,最近抠c++抠累了,突然心血来潮翻看近年来的大学生数学建模题。相比当年参加比赛的题目,总体感觉现在的题目越来越接近生活了。可能是多了一些经历,对一些题特别有感觉,加之联想起以前做完一道难题得到的兴奋感,一个想法涌上心头,为什么不利用现在的知识来好好“收拾收拾”它们呢。因此便有了这篇的文章,一方面是分享下自己的想法,另外也是锻炼下自己的文笔,身为程序猿,是时候改变一下一些习惯了。选出特别感兴趣的题目《2013年数学建模B赛题-图像碎片拼接》,开弄!

 

  题目链接:http://www.mcm.edu.cn/html_cn/block/8579f5fce999cdc896f78bca5d4f8237.html

  题目按切割方式不同归类为三个子问题:单面纵切,单面纵横切,双面纵横切,其中前两个又分为中英文纸张的情况,三个问题依次越来越复杂,越来越接近实际情况。不过相较于生活中的问题,《女子将5万钞票撕成碎片续:丈夫辞职在家拼钱》,http://news.qq.com/a/20120506/000091.htm,建模题还是比较小儿科的。 

  单面纵切:可以理解为对n个碎片块进行“行内”排列组合,最终要求是使碎片边界无缝接合起来。排列组合的话可以用神经网络,遗传算法等智能算法实现,“无缝”需要一个量来表征。前面智能算法对碎片不同组合时的无缝量进行评估,之后得到的最优解。这是学院派的解法,以此思路进行下去,一篇华丽的文章就可以出炉了。另外两个子问题也可以作类似的分解。

 

  下面是我实现的解法,以前面方法相比,这种方法有些“简单粗暴”,先上matlab代码先(复制后放在相应的文件夹里运行即可):

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)

  大概的思路是先计算块的特征,然后计算块间的相似性,最后进行拼接。其实看代码更容易理解,其中的无缝量选择,可以应用在前面方法的实现里。

拼接后的效果图:

中文:                                                                                英文:

           

 

~~Yemuzi分享文章,欢迎拍砖~~


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
在DELPHI中嵌入脚本语言发布时间:2022-07-18
下一篇:
delphi中使用webbrowser提交表单发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap