用DOS批处理来做数字图像处理
redraiment, 2009-07-03
前言
我最近对语言挺着迷的,很想学习一下《编译原理》。询问了老师才知道我们已经取消了这么课程(他们觉得学了没用) ,一时间也没找到什么好的教材,如果有好心的朋友可以推荐几本关于编译原理的经典书籍,感激不尽!
正文
图灵机是由输入、输出和状态转移函数三要素组成的,广义上的自动机模型。理论上讲任何任何完备图灵机语言都可用于通用编程,并且和其他完备图灵机语言一样有效。但实际上有些此类语言作用在其特定领域之外时可能令人非常痛苦。例如m4是一种有意的完备图灵机,但实践中把m4当作通用语言使用则非常困难。
最近对一些计算机语言进行分析,总结一门最简单的可编程的语言也应该具备:
- 输入输出。获得待处理的数据,可以是从标准输入输出,也可以从文件;
- 算数运算。计算机的核心当然是“计算”,就是普通计算机上提供的加减乘除运算;
- 内存管理:临时变量值的获取和存储管理,其实有点像通过变量名来查找值的Hash表(这在DOS的批处理中体现的很到位);
- 按条件跳转:拥有条件判断(test),加上语句跳转(jump),就能模拟出if、while、for和goto等语句(其中goto的条件为永真,就执行“test(true) jump xxx”一样)。
按照上面的说法,程序解释器很像是一个功能加强了的计算器(原来写个计算器也这么不容易,以前低估它了T_T)。纵观周围的工 具,很多看似简陋的小工具原来都符合上面的要求。像UNIX里的命令行计算器bc(1)/dc(1),都是完备图灵机;DOS的批处理同样也具备,下面来详细讨论。
批处理中可以用set 给变量赋值; set /a 可以进行算数运算,在命令行中执行set /? 可以查看所有支持的运算符;另外还有if、for、call、goto等语句支持跳转; set /p 和echo 可以实现从键盘和屏幕上输出文本信息,但对二进制文件的操作显得有点力不从心(可以用debug 来实现,但貌似 挺复杂)。所以我用C语言写了两个小程序(Bmp2Txt和Txt2Bmp,可到子清行下载二进制文件和C语言源码),解决批处理对BMP文件的输入输出。下面是我用这两个小工具写的拉普拉斯算子求边缘检测的批处理源码:
::用拉普拉斯算子来做边缘检测@echo offsetlocal enabledelayedexpansionif not "%~x1"==".bmp" goto errorif not "%~x2"==".bmp" goto error
Bmp2Txt %1 $$temp$$.txt::将BMP的像素集合保存到数bcall Txt2Array b < $$temp$$.txtset t.width=!b.width!set t.height=!b.height!for /l %%y in (0,1,!b.height!) do (for /l %%x in (0,1,!b.width!) do (set ny=%%y
set nx=%%xcall :calc))
::将数组转换成文本文件call Array2Txt t > $$temp$$.txtTxt2Bmp %2 $$temp$$.txtdel /q $$temp$$.txtgoto end
::Functions:errorecho.&echo usage: %0 Input_BMP_File Output_BMP_Filegoto end
:calcset /a t[%ny%][%nx%]=4*!b[%ny%][%nx%]!set /a dy=%ny%-1set /a dx=%nx%if defined b[%dy%][%dx%] set /a t[%ny%][%nx%]-=!b[%dy%][%dx%]!
set /a dy=%ny%+1set /a dx=%nx%if defined b[%dy%][%dx%] (set /a t[%ny%][%nx%]-=!b[%dy%][%dx%]!)
set /a dy=%ny%set /a dx=%nx%-1if defined b[%dy%][%dx%] (set /a t[%ny%][%nx%]-=!b[%dy%][%dx%]!)
set /a dy=%ny%set /a dx=%nx%+1if defined b[%dy%][%dx%] (set /a t[%ny%][%nx%]-=!b[%dy%][%dx%]!)
goto :eof
:end
在我的机子上跑了一两分钟居然也跑出结果来了,相应的效果图如下。
原始图:
处理后的图片:
评论
发表评论