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);
}