用MIL做图像处理首先得学会如何输入图像Buffer来做处理和处理完的图像Buffer如何保存。本文详述详述了MIL中加载图像的三种方式、MIL支持的图像文件格式和MIL保存图像方法。
#include<stdio.h> #include <mil.h> #pragma comment(lib, "mil.lib") int main(int argc, char* argv[]) { MIL_ID MilApplication, /* Application identifier. */ MilSystem, /* System identifier. */ MilDisplay, /* Display identifier. */ MilBufferRestore, MilBufferImportR, MilBufferLoad, MilBufferDraw; /* Image buffer identifier. */ //初始化 MilApplication = MilSystem = MilDisplay = MilBufferRestore = MilBufferImportR = MilBufferLoad = MilBufferDraw = M_NULL; //分配默认的应用、系统、显示,注意默认的显示是显示在MIL内建的演示windows窗口 MappAllocDefault(M_SETUP, &MilApplication, &MilSystem, &MilDisplay, M_NULL, M_NULL); /************************************************************************/ /* 第一种: 从已有的图像文件(.bmp,.jpg格式文件)读入图像数据新建MIL Buffer,新建的Buffer 内存大小由图像大小来确定 */ /************************************************************************/ MbufRestore(".\\image\\1.JPG", MilSystem, &MilBufferRestore); //显示 printf("按<Enter>键显示Retore的图像\n"); getchar(); MdispSelect(MilDisplay, MilBufferRestore); // 关闭显示. printf("按<Enter>键停止显示Retore的图像\n"); getchar(); MdispSelect(MilDisplay, M_NULL); MbufImport(".\\image\\bird.mim", M_MIL, M_RESTORE, MilSystem, &MilBufferImportR); //显示 printf("按<Enter>键显示Import-Restore的图像\n"); getchar(); MdispSelect(MilDisplay, MilBufferImportR); // 关闭显示. printf("按<Enter>键停止显示Import-Restore的图像\n"); getchar(); MdispSelect(MilDisplay, M_NULL); /************************************************************************/ /* 第二种: 先分配固定大小的MIL Buffer,再将图像文件(.bmp,.jpg格式文件)数据读到新建 MIL Buffer,图像文件分辨率不能比新建的Buffer大 */ /************************************************************************/ //分配Buffer MbufAlloc2d(MilSystem, MbufDiskInquire(".\\image\\1.JPG", M_SIZE_X, M_NULL), MbufDiskInquire(".\\image\\1.JPG", M_SIZE_Y, M_NULL), 32+M_UNSIGNED, M_IMAGE + M_DISP, &MilBufferLoad); MbufLoad(".\\image\\1.JPG", MilBufferLoad); //显示 printf("按<Enter>键显示Load的图像\n"); getchar(); MdispSelect(MilDisplay, MilBufferLoad); // 关闭显示. printf("按<Enter>键停止显示Load的图像\n"); getchar(); MdispSelect(MilDisplay, M_NULL); MbufImport(".\\image\\1.JPG", MbufDiskInquire(".\\image\\1.JPG", M_FILE_FORMAT, M_NULL), M_LOAD, MilSystem, &MilBufferLoad); //显示 printf("按<Enter>键显示Import-Load的图像\n"); getchar(); MdispSelect(MilDisplay, MilBufferLoad); // 关闭显示. printf("按<Enter>键停止显示Import-Load的图像\n"); getchar(); MdispSelect(MilDisplay, M_NULL); /************************************************************************/ /* 第三种: 先分配固定大小的MIL Buffer,自己绘制图像内容并显示 */ /************************************************************************/ //分配Buffer MbufAlloc2d(MilSystem, 500, 500, 8+M_UNSIGNED, M_IMAGE + M_DISP, &MilBufferDraw); //初始化buffer颜色 MbufClear(MilBufferDraw, 125); //显示 printf("按<Enter>键显示初始化绘制的图像\n"); getchar(); MdispSelect(MilDisplay, MilBufferDraw); // 关闭显示. printf("按<Enter>键停止显示初始化绘制的图像\n"); getchar(); MdispSelect(MilDisplay, M_NULL); //文字图像 MgraColor(M_DEFAULT, 200); MgraText(M_DEFAULT, MilBufferDraw, 100, 100, "MIL Text"); //显示 printf("按<Enter>键显示自绘制的文字图像\n"); getchar(); MdispSelect(MilDisplay, MilBufferDraw); // 关闭显示. printf("按<Enter>键停止显示自绘制的文字图像\n"); getchar(); MdispSelect(MilDisplay, M_NULL); // 释放资源 if (M_NULL != MilBufferRestore) { MbufFree(MilBufferRestore); } if (M_NULL != MilBufferImportR) { MbufFree(MilBufferImportR); } if (M_NULL != MilBufferLoad) { MbufFree(MilBufferLoad); } if (M_NULL != MilBufferDraw) { MbufFree(MilBufferDraw); } if (M_NULL != MilApplication) { MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL); } return 0; }对于三种加载方式流程,上面的程序已经讲得很清楚,结合注释和手册可以加深理解。
使用MbufRestore加载图像会自动识别图像文件格式和大小,保存成对应大小的最合适的图像内存存储格式(参见博文),也可以使用MbufImport指明M_STORE参数加载指定文件格式的图像。但是注意MIL支持加载的图像文件格式是有限的(MIL,RAW,JPG,TIF,BMP),同时还需要注意的就是即使要加载的图像格式是MIL支持的也有可能不成功,这是因为同一图像格式文件的标准也在不断发展和改变(如JPEG和JPEG2000等,具体参见MIL手册),另外同一格式的文件可能有不同的深度如有8bit BMP和16bit BMP等等,注意加载MIL支持的图像的格式、版本和深度,如果你发现用加载JPG不成功,那么很有可能是你的JPG文件版本或深度不对。其中,MIL格式文件是MIL内建的基于TIFF 6.0的图像格式,后缀名为MIM,你可以用一般的能打开tiff格式文件的图像查看软件来打开它(如windows自带的图像查看器),RAW格式文件只是为了保存矩阵数据而建立的内建格式,只支持MIL对应的规则来解析打开。
先分配固定大小的图像Buffer,再MbufLoad自动识别图像文件格式导入不大于它的图像文件,也可以使用MbufImport指明M_LOAD参数加载指定文件格式的图像。这里我们为了得到图像文件保存的图像格式和大小,使用MbufDiskInquire函数对硬盘上图像文件信息做相关查询工作,这是常用的技巧。如果待加载的图像格式是压缩的,分配的图像Buffer是不压缩的,加载时会自动解压缩,同样加载的图像格式是不压缩的,分配的图像Buffer是压缩的,加载时会自动压缩,总之,在待加载图像文件格式和Buffer存储格式之间做一个转换匹配。
如果是自己绘制图像的话,一般我们会使用MbufClear对整个Buffer做一个初始化操作,然后使用Mgra开头函数做绘制点、线、圆、文字等操作,类似windows的GDI。
下面给出图像保存流程代码,具体参看注释和手册自行分析
/************************************************************************/ /* 图像保存*/ /************************************************************************/ //保存为TIFF 6.0兼容 printf("按<Enter>键保存自绘制的文字图像为TIF兼容格式\n"); getchar(); MbufSave("1.tif", MilBufferDraw); //保存为JPG printf("按<Enter>键保存自绘制的文字图像为JPG格式\n"); getchar(); MbufExport("1.jpg", M_JPEG2000_LOSSY, MilBufferDraw); //保存为BMP printf("按<Enter>键保存自绘制的文字图像为BMP格式\n"); getchar(); MbufExport("1.bmp", M_BMP, MilBufferDraw); //保存为TIFF printf("按<Enter>键保存自绘制的文字图像为TIF格式\n"); getchar(); MbufExport("2.tif", M_TIFF, MilBufferDraw);
保存成功后,用windows自带图像查看器查看,笔者用的是Windows XP MIL8.0,可以发现1.tif,1.bmp,2.tif均可以正常打开而1.jpg无法打开,这估计是MIL总用的JPEG压缩格式标准太老的原因吧。和加载图像一样,在图像Buffer和保存的图像文件之间会做一个转换匹配,具体参见MIL手册。
博客中源代码下载链接
需要指出的是编写MIL程序时,为了防止操作"悬垂指针",最好对MIL_ID标识变量做初始化和释放时检测操作。