每日签到积分充值书码绑定

MATLAB技术论坛

 找回密码
 注册帐号

QQ登录

只需一步,快速开始

查看: 5173|回复: 16

[其它] 【原创】文件名排序Matlab程序 [复制链接]

Rank: 20Rank: 20Rank: 20Rank: 20

该用户从未签到

UID
102
主题
35
帖子
383
积分
3446
威望
268
贝壳
1492
贡献
1791

管理团队

发表于 2009-8-15 14:16:42 |显示全部楼层 | 百度  谷歌 |
由来:
手头上有一组100多张的jpg文件(尺寸一致),想把它们通过matlab弄成avi文件,然而通过sortrows函数对这些文件名排序时,发现它的顺序是
1.jpg
10.jpg
100.jpg
101.jpg
就是说sortrows是按文件的ASCII来排序的,没有考虑到字符串的长度因素。

当然如果文件名命名是001.jpg,002.jpg之类的。那么排序应当没有问题。
当然如果文件名是连续的话,我们也可以用num2str(i)来构建相应的文件名。
如果不是上面两种情况的话,本文就是实现从小到大排序。


提示1:文件名的获取
通过dir可以得到目录下的文件名,比如:
jpgfile=dir('*.jpg');  %可以得到本目录下所有jpg文件的相关信息。
filename=str2mat(jpgfile.name);  

提示2:字符串数组
先试一下:
str1=['mat';'lab';'sky']         %这句没有问题,因为每个字符串长度相同
str2=['matlab';'sky';'love']  %这句会出问题,因为每个字符串长度不同
str3=strvcat('matlab','sky','love')  %这句没有问题,虽说每个字符串长度不同,但是它可以组合成字符串数组,不过str3是3*6的字符串数组,每行的长度都是6,系统给字符串不足6的后面自动补空格。

这样就导致上面得到的filename每行的长度都相同。


本文原理:
先判断每行最后面有多少个空格,
然后在每行的最前面加与空格数相同的字符(该字符的ASCII码要很小),组成新的字符串
这样排序就可以实现上述的文件名排序功能。


本文代码:
  1. function varargout=LengthSortStr(str)
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. %Argment:                str文件名组成的字符串数组
  4. %        :                输出参数同sort函数
  5. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6. ch_ascii=1;                                %用ascii码相应的字符放在文件名前,这个值越小越好

  7. [N,MAXLEN]=size(str);        %个数以及每行的长度
  8. newname=[''];

  9. for i=1:N
  10.         BlackSpace=0;
  11.         while (str(i,MAXLEN-BlackSpace)==' ') %本行有多少个空格
  12.                 BlackSpace=BlackSpace+1;
  13.         end
  14.                 %将本行后面的空格用ch_ascii补在最前面,并去掉行尾的空格
  15.         newstr(i,:)=[repmat(char(ch_ascii),1,BlackSpace), str(i,1:MAXLEN-BlackSpace)];
  16. end
  17. [sortstr,order]=sortrows(newstr);          %新字符排序,主要要得到排序的序号
  18. sortstr=str(order,:);                                %由这个序号生成原始的排序名

  19. if nargout<=1
  20.         varargout{1}=sortstr;
  21. elseif nargout==2
  22.         varargout{1}=sortstr;
  23.         varargout{2}=order;
  24. end
复制代码
实例:
  1. %对D盘下面的bmp图的文件名进行排序
  2. clear
  3. dirpath='d:\';                %路径
  4. extname='bmp';                %扩展名

  5. if dirpath(end)~='\'                %如果路径后面没有加\,添加
  6.         dirpath=[dirpath,'\'];
  7. end

  8. %先取出目录下的文件信息
  9. pic=dir([dirpath,'*.',extname]);
  10. filename=str2mat(pic.name); %取得文件名

  11. %调用函数
  12. sortfile=LengthSortStr(filename)
复制代码
已有 1 人评分威望 贝壳 收起 理由
dynamic + 5 + 10 分析很透彻

总评分: 威望 + 5  贝壳 + 10   查看全部评分

Rank: 20Rank: 20Rank: 20Rank: 20

该用户从未签到

UID
102
主题
35
帖子
383
积分
3446
威望
268
贝壳
1492
贡献
1791

管理团队

发表于 2009-8-15 14:27:30 |显示全部楼层

接上述文件生成连续的avi文件

  1. %取文件的数量:num
  2. num=size(pic,1);
  3. for i=1:num
  4.         im(:,:,:,i)=imread([dirpath,sortfile(i,:)]);
  5.         imshow(im(:,:,:,i))
  6.         M(i) = getframe;
  7. end

  8. movie2avi(M,'out.avi','FPS',15)%输出视频,这里的FPS是帧率,可以理解为一秒多少张图片
复制代码
这里注意的是:每张图片的尺寸必须一样,否则生成不了avi文件。

[ 本帖最后由 wacs5 于 2009-8-15 14:30 编辑 ]

道具 举报

Rank: 20Rank: 20Rank: 20Rank: 20

该用户从未签到

UID
102
主题
35
帖子
383
积分
3446
威望
268
贝壳
1492
贡献
1791

管理团队

发表于 2009-8-15 14:34:31 |显示全部楼层
MATLAB技术论坛"有偿编程担保制度" "技术团队资格认证""官方有偿编程团队",保证您有偿编程安全。
上面提到
当然如果文件名命名是001.jpg,002.jpg之类的。那么排序应当没有问题。
这里主要是将文件名变成001.jpg之类的形式。
就是
1.jpg  变成 001.jpg
10.jpg 变成 010.jpg
这一种方法一般要求文件我要是纯数字。


法一:批处理
  1. @echo off
  2. setlocal enabledelayedexpansion

  3. set extname=bmp

  4. for /r %%a in (*.%extname%) do (
  5. set /a ok=%%~na+100000
  6. ren %%a !!ok:~-3!!%%~xa
  7. )
复制代码
打开记事本,将上面代码复制进去,然后保存到图片文件所在的路径,并命令为myren.bat,双击这个bat文件就可以实再重命名。
这里注意的一点是上面的 ren %%a !!ok:~-3!!%%~xa,这里的3的意思是说生成的是三个字节的文件名。
此法注意以下几点:
1.文件名要纯数字,不能有字母
2.文件名不能超过8位,要符合DOS的8.3规范。




法二:Matlab
  1. %思路,运用matlab进行批处理
  2. %matlab通过调用DOS的ren命令
  3. %具体调用格式:在命令前加一个感叹号!
  4. clear
  5. dirpath='d:\';                %路径
  6. extname='bmp';                %扩展名

  7. if dirpath(end)~='\'                %如果路径后面没有加\,添加
  8.         dirpath=[dirpath,'\'];
  9. end

  10. %先取出目录下的文件信息
  11. pic=dir([dirpath,'*.',extname]);
  12. filename=str2mat(pic.name); %取得文件名


  13. %取文件的数量:num
  14. num=size(pic,1);
  15. for i=1:num
  16.         filenum=str2num(filename(i,1:(strfind(filename(i,:),extname)-2)));  %获得数字
  17.         eval(['! ren ',[dirpath,filename(i,:)],' ',[sprintf('%03d',filenum),'.',extname]]);  %调用DOS的ren
  18. end
复制代码

[ 本帖最后由 wacs5 于 2009-8-15 21:04 编辑 ]

道具 举报

Rank: 20Rank: 20Rank: 20Rank: 20

该用户从未签到

UID
102
主题
35
帖子
383
积分
3446
威望
268
贝壳
1492
贡献
1791

管理团队

发表于 2009-8-15 14:34:47 |显示全部楼层
若干天后的今天,发现MATLAB中有一个现成的,类似的函数。

strjust(str);

这个函数将str每行中的字符串右对齐,左边被空格。
  1. %对D盘下面的bmp图的文件名进行排序
  2. clear
  3. dirpath='d:\';                %路径
  4. extname='bmp';                %扩展名

  5. if dirpath(end)~='\'                %如果路径后面没有加\,添加
  6.         dirpath=[dirpath,'\'];
  7. end

  8. %先取出目录下的文件信息
  9. pic=dir([dirpath,'*.',extname]);
  10. filename=str2mat(pic.name); %取得文件名

  11. newfilename=strjust(filename);
  12. [temp,order]=sortrows(newfilename);
  13. sortfile=filename(order,:);

  14. %至此sortfile已经参考了文件名的长度,再进行排序,对数字进行排序了
复制代码

[ 本帖最后由 wacs5 于 2009-8-21 14:44 编辑 ]

道具 举报

Rank: 20Rank: 20Rank: 20Rank: 20

该用户从未签到

UID
102
主题
35
帖子
383
积分
3446
威望
268
贝壳
1492
贡献
1791

管理团队

发表于 2009-8-15 14:35:21 |显示全部楼层
MATLAB技术论坛"有偿编程担保制度" "技术团队资格认证""官方有偿编程团队",保证您有偿编程安全。
这个坑自己保留

道具 举报

Rank: 3

该用户从未签到

UID
5880
主题
21
帖子
102
积分
388
威望
12
贝壳
137
贡献
86
发表于 2009-8-15 14:42:01 |显示全部楼层

道具 举报

管理员

风雪夜归人

Rank: 30Rank: 30Rank: 30Rank: 30

签到天数: 12 天

[LV.3]偶尔看看II

UID
1
主题
1390
帖子
5053
积分
70501
威望
778
贝壳
53863
贡献
4889

管理团队 技术小组 原创先锋 宣传大使

发表于 2009-8-15 14:57:49 |显示全部楼层
MATLAB技术论坛"有偿编程担保制度" "技术团队资格认证""官方有偿编程团队",保证您有偿编程安全。
wacs5的文章和创作,一定要顶

另外在字符连接方面char和strvcat的效果相似

>> str1=strvcat('matlab','sky','love')

str1 =

matlab
sky   
love  

>> size(str1)

ans =

     3     6

>> str2=char('matlab','sky','love')

str2 =

matlab
sky   
love  

>> size(str2)

ans =

     3     6

道具 举报

Rank: 3

该用户从未签到

UID
14969
主题
2
帖子
155
积分
492
威望
23
贝壳
242
贡献
167
发表于 2009-8-15 15:15:49 |显示全部楼层

道具 举报

Rank: 2Rank: 2

该用户从未签到

UID
17189
主题
3
帖子
42
积分
126
威望
0
贝壳
52
贡献
10
发表于 2009-8-15 15:22:51 |显示全部楼层
MATLAB技术论坛"有偿编程担保制度" "技术团队资格认证""官方有偿编程团队",保证您有偿编程安全。
支持,支持,大力支持!

道具 举报

管理员

风雪夜归人

Rank: 30Rank: 30Rank: 30Rank: 30

签到天数: 12 天

[LV.3]偶尔看看II

UID
1
主题
1390
帖子
5053
积分
70501
威望
778
贝壳
53863
贡献
4889

管理团队 技术小组 原创先锋 宣传大使

发表于 2009-8-15 16:27:45 |显示全部楼层
哈哈,我也写了一个类似的程序,参考了wacs5的一些想法,但是在添加'0'的时候
使用了sprintf函数,没有使用循环语句进行判断
  1. clc
  2. clear
  3. rpstr='0';
  4. path='D:\My Documents\MATLAB';
  5. ext='m';
  6. path=fullfile(path,['*.',ext]);
  7. file=dir(path);
  8. filestr=char(file.name);
  9. [m,n]=size(filestr);
  10. filecell=cellstr(filestr);
  11. for ii=1:m
  12.     filenew(ii,:)=sprintf(['%',num2str(n),'s'],filecell{ii});
  13. end
  14. filenew(filenew==' ')=rpstr;
  15. [tmp2,ind]=sortrows(filenew);
  16. filesort=filestr(ind,:)
复制代码

道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

关闭

站长推荐

热烈庆祝Mathworks中国成立5周年系列活动
热烈庆祝Mathworks中国成立5周年系列活动
五年前的今天,Mathworks中国成立,到现在MATLAB在中国研究者业内已经具有相当的规模和影响了,我们可喜的看到:现在的高校、科研机构越来越多地购买正版MATLAB软件,MATLAB的推广在中国逐步开展起来。

查看 »

网站简介 | 发展历程 | 特色业务 | 管理团队 | 免责声明 | 广告服务 | 联系我们 | 付款方式 | 友情链接 | 帮助中心

商务合作:455681698   服务邮箱:matlabsky@gmail.com   支付宝:yuthreestone@163.com

合作站点:数模联盟 函数百科 网上商城   出版单位:北航出版社 道然科技   开发平台:Discuz! X2

CopyRight © 2008-2012 迈粉网 ( 陕ICP备08102094号 ) All Rights Reserved

排行热榜|网站地图|手机浏览|管理邮箱||     

GMT+8, 2012-5-19 06:13 , Processed in 0.151910 second(s), 26 queries , Gzip On, Xcache On.

回顶部