zoukankan      html  css  js  c++  java
  • PGM图片格式与代码

    这两天在搞神经网络,里面的一个人脸数据库的图片格式是PGM,事实上之前早就知道了这个图片格式,可是没去深究这个图片格式的数据究竟是什么安排的。搜索了下百度百科,发现介绍的真是简单,以下就自己来系统地整理一下。                

    Jeremy Lin 

    PGM是Portable Gray Map的缩写。它是灰度图像格式中一种最简单的格式标准。另外两种与之相近的图片格式是PBM和PPM。它们分别相应着黑白图像和彩色图像。

    PGM的数据存放方式相比于JPG来说是非常easy的,由于它不进行数据压缩。自然的PGM的图片的大小也就比較大了。一个120*128 8-bit的灰度图像,PGM的大小是44kb,而将这个图片转化为JPG格式后。大小仅为4kb。

    所以。在日常各种网络应用中你是非常难见到PGM图片的,它太浪费流量了。


    PGM的数据格式

    就像上面说的,PGM是不进行数据压缩的,那么自然的。它的格式就非常直观了。你能够直接用一个记事本打开它,只是记事本打开后换行没了。不好看,以下用Sublime Text2打开:


    看了上面的图示,我想大部分都能猜出来一些东西了。

    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
    ");
        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'
    ", 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)
    ");
        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
    ");
        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
    ");
        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] = '';
                  found = 1;
    	    }
    	  }
    	}
            img_setpixel(newM, i, j, atoi(intbuf));
    
          }
        }
    
      } else {
        printf("IMGOPEN: Fatal impossible error
    ");
        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
    ");
      fprintf(iop, "%d %d
    ", nc, nr);
      fprintf(iop, "255
    ");
    
      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
    ", val, i, j);
            printf("           Setting it to zero
    ");
            val = 0;
          }
          if (k % 10) {
            fprintf(iop, "%d ", val);
          } else {
            fprintf(iop, "%d
    ", val);
          }
          k++;
        }
      }
      fprintf(iop, "
    ");
      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

  • 相关阅读:
    写了一个自动打包并发布到tomcat的脚本
    查看并更改mysql编码
    MyBatis无法根据中文条件查询出结果
    服务器端PHP多进程编程
    PHP-popen()&nbsp;函数打开进程文件指针
    php并发处理
    PHP能得到你是从什么页面过来的,r…
    PHP如何解决网站大流量与高并发的…
    基于PHP的cURL快速入门
    Mysql内存表的用处
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/6816981.html
Copyright © 2011-2022 走看看