PGM图片格式与代码
这两天在搞神经网络,里面的一个人脸数据库的图片格式是PGM,事实上之前早就知道了这个图片格式,可是没去深究这个图片格式的数据究竟是什么安排的。搜索了下百度百科,发现介绍的真是简单,以下就自己来系统地整理一下。
PGM是Portable Gray Map的缩写。它是灰度图像格式中一种最简单的格式标准。另外两种与之相近的图片格式是PBM和PPM。它们分别相应着黑白图像和彩色图像。
PGM的数据存放方式相比于JPG来说是非常easy的,由于它不进行数据压缩。自然的PGM的图片的大小也就比較大了。一个120*128 8-bit的灰度图像,PGM的大小是44kb,而将这个图片转化为JPG格式后。大小仅为4kb。
所以。在日常各种网络应用中你是非常难见到PGM图片的,它太浪费流量了。
PGM的数据格式
就像上面说的,PGM是不进行数据压缩的,那么自然的。它的格式就非常直观了。你能够直接用一个记事本打开它,只是记事本打开后换行没了。不好看,以下用Sublime Text2打开:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlual9t/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="348" height="324" alt="">
看了上面的图示,我想大部分都能猜出来一些东西了。
PGM图片的数据:
首先。以一个“Magic Number”来标识图片格式,这个magic number是P2,不能是p2。或者P 2;
然后。第二行是图片宽度、图片高度,在上图中是128和120。
第三行是这个图片数据的最大值。上图中是146;
最后,就是图片的像素数据值了。这些数据是以“row-major order”存放的,即是说按行存放的。当然,你认真看上图的话会发现,从第4行開始,每行都仅仅有16个数据,默认情况下。每行长度不能超过70个字符,可是详细几个并没有要求,一种安全的做法是每行存放一个像素。
在有些PGM图片你可能会看到以#开头的行。这个是comment,比方说用#linjianmin.pgm来表示图片名称。
图片读取与创建代码:
#ifndef _PGM_ #define _PGM_ #include <stdio.h>
#include <string.h>
#include <stdlib.h> #define ROWS(img) ((img)->rows)
#define COLS(img) ((img)->cols)
#define NAME(img) ((img)->name) typedef struct
{
char *name;
int rows, cols;
int *data;
} IMAGE; char *img_basename(char *filename)
{
char *newM, *part;
int len, dex; len = strlen(filename);
dex = len - 1;
while (dex > -1)
{
if (filename[dex] == '/')
{
break;
}
else
{
dex--;
}
}
dex++;
part = &(filename[dex]);
len = strlen(part);
newM = (char *) malloc ((unsigned) ((len + 1) * sizeof (char)));
strcpy(newM, part);
return(newM);
} IMAGE *img_alloc()
{
IMAGE *newM; newM = (IMAGE *) malloc (sizeof (IMAGE));
if (newM == NULL)
{
printf("IMGALLOC: Couldn't allocate image structure\n");
return (NULL);
}
newM->rows = 0;
newM->cols = 0;
newM->name = NULL;
newM->data = NULL;
return (newM);
} IMAGE *img_creat(char *name, int nr, int nc)
{
int i, j;
IMAGE *newM; newM = img_alloc();
newM->data = (int *) malloc ((unsigned) (nr * nc * sizeof(int)));
newM->name = img_basename(name);
newM->rows = nr;
newM->cols = nc;
for (i = 0; i < nr; i++)
{
for (j = 0; j < nc; j++)
{
img_setpixel(newM, i, j, 0);
}
}
return (newM);
} void img_free(IMAGE* img)
{
if (img->data) free ((char *) img->data);
if (img->name) free ((char *) img->name);
free ((char *) img);
} void img_setpixel(IMAGE *img,int r, int c, int val)
{
int nc; nc = img->cols;
img->data[(r * nc) + c] = val;
} int img_getpixel(IMAGE *img, int r, int c)
{
int nc; nc = img->cols;
return (img->data[(r * nc) + c]);
} IMAGE *img_open(char *filename)
{
IMAGE *newM;
FILE *pgm;
char line[512], intbuf[100], ch;
int type, nc, nr, maxval, i, j, k, found; newM = img_alloc();
if ((pgm = fopen(filename, "r")) == NULL)
{
printf("IMGOPEN: Couldn't open '%s'\n", filename);
return(NULL);
} newM->name = img_basename(filename); /*** Scan pnm type information, expecting P5 ***/
fgets(line, 511, pgm);
sscanf(line, "P%d", &type);
if (type != 5 && type != 2)
{
printf("IMGOPEN: Only handles pgm files (type P5 or P2)\n");
fclose(pgm);
return(NULL);
} /*** Get dimensions of pgm ***/
fgets(line, 511, pgm);
sscanf(line, "%d %d", &nc, &nr);
newM->rows = nr;
newM->cols = nc; /*** Get maxval ***/
fgets(line, 511, pgm);
sscanf(line, "%d", &maxval);
if (maxval > 255)
{
printf("IMGOPEN: Only handles pgm files of 8 bits or less\n");
fclose(pgm);
return(NULL);
} newM->data = (int *) malloc ((unsigned) (nr * nc * sizeof(int)));
if (newM->data == NULL)
{
printf("IMGOPEN: Couldn't allocate space for image data\n");
fclose(pgm);
return(NULL);
} if (type == 5)
{ for (i = 0; i < nr; i++) {
for (j = 0; j < nc; j++) {
img_setpixel(newM, i, j, fgetc(pgm));
}
} }
else if (type == 2)
{ for (i = 0; i < nr; i++) {
for (j = 0; j < nc; j++) { k = 0; found = 0;
while (!found) {
ch = (char) fgetc(pgm);
if (ch >= '0' && ch <= '9') {
intbuf[k] = ch; k++;
} else {
if (k != 0) {
intbuf[k] = '\0';
found = 1;
}
}
}
img_setpixel(newM, i, j, atoi(intbuf)); }
} } else {
printf("IMGOPEN: Fatal impossible error\n");
fclose(pgm);
return (NULL);
} fclose(pgm);
return (newM);
} int img_write(IMAGE *img, char *filename)
{
int i, j, nr, nc, k, val;
FILE *iop; nr = img->rows; nc = img->cols;
iop = fopen(filename, "w");
fprintf(iop, "P2\n");
fprintf(iop, "%d %d\n", nc, nr);
fprintf(iop, "255\n"); k = 1;
for (i = 0; i < nr; i++) {
for (j = 0; j < nc; j++) {
val = img_getpixel(img, i, j);
if ((val < 0) || (val > 255)) {
printf("IMG_WRITE: Found value %d at row %d col %d\n", val, i, j);
printf(" Setting it to zero\n");
val = 0;
}
if (k % 10) {
fprintf(iop, "%d ", val);
} else {
fprintf(iop, "%d\n", val);
}
k++;
}
}
fprintf(iop, "\n");
fclose(iop);
return (1);
} #endif
本文地址:http://blog.csdn.net/linj_m/article/details/40477699
很多其它资源请关注 博客:LinJM-机器视觉 微博:林建民-机器视觉
Refs:
[1]http://netpbm.sourceforge.net/doc/pgm.html
[2]Netpbm format Wikipedia
PGM图片格式与代码的更多相关文章
- 【faster-rcnn】训练自己的数据——修改图片格式、类别
修改图片格式 matlab代码 其实内部一些代码是用了rbg的fast-rcnn代码的. \datasets\VOCdevkit2007\VOCcode\VOCinit.m里面,查找'jpg',改成' ...
- TensorFlow笔记五:将cifar10数据文件复原成图片格式
cifar10数据集(http://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz)源格式是数据文件,因为训练需要转换成图片格式 转换代码: 注意文件路 ...
- PPM图片格式及其C读写代码
PPM图像格式介绍 PPM图像格式是由Jef Poskanzer 大叔,在我出生那一年,也就是1991年所创造的,碰巧的是PPM也是天蝎座. PPM(Portable Pixmap Format)还有 ...
- 图片格式PGM缩写
PGM是Portable Gray Map的缩写.它是灰度图像格式中一种最简单的格式标准.另外两种与之相近的图片格式是PBM和PPM.它们分别相应着黑白图像和彩色图像. PGM的数据存放方式相比于JP ...
- 【VC++技术杂谈007】使用GDI+进行图片格式转换
本文主要介绍如何使用GDI+对图片进行格式转换,可以转换的图片格式为bmp.jpg.png. 1.加载GDI+库 GDI+是GDI图形库的一个增强版本,提供了一系列Visual C++ API.为了使 ...
- 用php实现百度网盘图片直链的代码分享
第一种代码:代码量较少通过正则表达式获取百度网盘的文件真实地址,来实现直链的效果 将下面的代码保存为downbd.php 复制代码代码如下: <?php $canshu=$_SERVER[&qu ...
- Souerce 之 图片格式
一.基本概念 1.矢量图与位图 1)矢量图-完美的几何图形 矢量图是通过组成图形的一些基本元素,如点.线.面,边框,填充色等信息通过计算的方式来显示图形的.就好比我们在几何学里面描述一个圆可以通过它的 ...
- JAVA将Excel中的报表导出为图片格式(一)问题背景
如题所示,先抛出一个问题,如何使用JAVA将Excel中的报表导出为图片格式? 首先说一下这个问题的背景,也就是为什么博主会碰到这个问题 随着微信,易信之流大行其道,企业内部的办公交流.绩效考评甚至考 ...
- java批量转换图片格式
废话不多直接上代码,代码其实也不多.... package com.qiao.testImage; import java.awt.image.BufferedImage; import java.i ...
随机推荐
- 使用CORS解决flask前端页面跨域问题
from flask import Flask from flask_cors import CORS app = Flask(__name__) CORS(app) @app.route(" ...
- ubuntu下安装JDK(复制)
ubuntu 安装jdk 的两种方式:(本来jdk应该安装到/usr/lib/jvm下,但我安装到了/usr/local/lib/jvm下了) 1:通过ppa(源) 方式安装. 2:通过官网下载安装包 ...
- log4net实现多实例记录
原文地址:实现多个LOG4NET日志记录器实例 本文内容为摘抄,请查看原文. 对于.NET Framework开发者来说,使用Log4Net进行日志记录是非常方便的,通常只要写好配置文件和简单的编码就 ...
- socket实例C语言:一个简单的聊天程序
我们老师让写一个简单的聊天软件,并且实现不同机子之间的通信,我用的是SOCKET编程.不废话多说了,先附上代码: 服务器端server.c #include <stdio.h> #incl ...
- 物理课(physics)
物理课(physics) 题目描述 wzy正在上物理课!他发现了一个完全不会的题目:caoxia在一个奇妙的星球上(重力加速度为gg)踢了一只猫,猫飞起的路线与地面夹角为θθ (角度制),初速度为vv ...
- exit() 与 return() 的区别
exit()与 return() 的区别为: 1. return返回函数值,是关键字: exit 是一个函数. 2. return是语言级别的,它表示了调用堆栈的返回:而exit是系统调用级别的,它 ...
- django model:auto_now_add 和 auto_now
创建django的model时,有DateTimeField.DateField和TimeField三种类型可以用来创建日期字段,其值分别对应着datetime().date().time()三中对象 ...
- AssetDatabase.RenameAsset 重命名文件失败
今天想写一段Unity Editor 的代码将在 Project Panel 中选中的所有 Texture 改变 Format,然后重命名 成 xxx.Dither.png 然后自动进行上一篇文章提到 ...
- 【CF1016C】Vasya And The Mushrooms(模拟)
题意:给定一个2*n的矩阵,每一个点有一个权值,从左上角出发,时间t=0开始,连续的走,将矩阵走完, 每走一步,t++,并且得到t*当前格子的权值的值,求最大的权值和 n<=3e5,1<= ...
- EOJ Monthly 2018.1 F 最小OR路径
题目链接 Description 给定一个有 \(n\) 个点和 \(m\) 条边的无向图,其中每一条边 \(e_i\) 都有一个权值记为 \(w_i\) . 对于给出的两个点 \(a\) 和 \(b ...