pgm
1.PGM图像详解
PGM 是便携式灰度图像格式(portable graymap file format),在黑白超声图像系统中经常使用PGM格式的图像.文件的后缀名为".pgm",PGM格式图像格式分为两类:P2和P5类型.不管是P2还是P5类型的PGM文件,都由两部分组成,文件头部分和数据部分.
文件头部分
文件头包括的信息依次是:
1.PGM文件的格式类型(是P2还是P5);
2.图像的宽度;
3.图像的高度;
4.图像灰度值可能的最大值;
文件头的这四部分信息都是以ASCII码形式存储的,所以可以直接在将P2或P5格式的PGM文件在记事本中打开看到文件头的信息.
P5格式
P5格式的文件,每个像素用可以用二进制表示.比如有一幅P5格式图像,灰度值可能的最大值为255,它的第一行第一列像素值为100,那么该图像每个像素使用一个字节表示,第一行第一列为数值为100的二进制一个字节表示.如果这副图灰度值可能的最大值是65535,那么它的第一行第一列为数值为100的二进制两个字节表示(因为表示到65535需要两个字节).每个像素数据之间没有间隔的连续存储,图像一行信息结束后从下一行第一列继续,两行图像数据之间也没有间隔的连续存储,直到将图像的所有信息表示完.因为是以二进制表示,所以数据部分在记事本中打开后看到的将会是乱码.
P2格式
P2格式的文件,每个像素使用字符串来表示,比如一副P2格式图像,灰度值可能的最大值为255,它的第一行第一列像素值为100,那么该图像图像每个像素使用3个ASCII字符表示,第一行第一列数据为ASII表示的"100".不同于P5格式,每个像素数据之间需要用一个空格符分开存储,在图像的每一行数据结束时需要换行.还有一点需要注意,P2格式文件数据部分当数据超过70个字节的时候,会自动换行.也就是说图像的每一行数据末尾,或者存储时超过70个字节时,需要进行换行.
opencv code
#include <iostream> #include <string> #include <fstream> #include <sstream> #include <opencv2/opencv.hpp> #include <opencv2/core/core.hpp> //#include <opencv2/core/utility.hpp> #include <opencv2/imgproc/imgproc.hpp> //#include <opencv2/imgcodecs.hpp> #include <opencv2/highgui/highgui.hpp> using namespace std; using namespace cv; /* *将IplImage转储为p5格式的图像 * *filename: 保存的图像名称 * *srcImage: 输入的图像 * *type:转换后pgm的类型,2--p2,5--p5 */ void cvConvertImage2pgm(char* filename,IplImage* srcImage,int type) { int width=srcImage->width; int height=srcImage->height; FILE *pgmPict; int rSize=width*height; int i,j; pgmPict=fopen(filename,"w"); if(type==2) { fprintf(pgmPict,"P2\n"); } else if(type==5) { fprintf(pgmPict,"P5\n"); } fprintf(pgmPict,"%d %d \n%d\n",width,height,255); if(type==5) { unsigned char temp=0; for( i=0;i<srcImage->height;i++) { for( j=0;j<srcImage->width;j++) { temp=srcImage->imageData[i*srcImage->widthStep+j*3+2]; fwrite((void*)&temp,sizeof(unsigned char),1,pgmPict); } } } else if(type==2) { for( i=0;i<srcImage->height;i++) { for( j=0;j<srcImage->width;j++) { int temp=(int)srcImage->imageData[i*srcImage->widthStep+j*3+2]; if(temp<0) temp+=256; fprintf(pgmPict,"%d ",temp); } } } fclose(pgmPict); } int main(){ IplImage * image=cvLoadImage("src/TSD-Lane-00001-00037.png"); cvConvertImage2pgm("out.pgm",image,5); }