【问题标题】:Issue when reading a matrix from a PGM file C从 PGM 文件 C 读取矩阵时的问题
【发布时间】:2015-08-28 11:13:05
【问题描述】:

我想读取一个 PGM 文件(没有 #cmets)并将图像数据(矩阵)导出到一个新的文本文件。到目前为止,我确实设法编写了代码,但我认为不是很好。 我的问题是,当我将矩阵从内存中打印到文本文件时,它会给我一些零行。当我想从内存中打印矩阵时也是如此。

有代码:

#include<stdio.h>
#include<stdlib.h>

int main(){
int i,j;
FILE *fd;
FILE *fdd;

//Extract the file info from header 
char type;
int row=0,col=0,depht=0,a=0;
fd=fopen("file.pgm","rb");
fscanf(fd,"%s %d %d %d",&type,&row,&col,&depht);

//Malloc
int** sudo=(int **)malloc(row*sizeof(int *));
if ( sudo != NULL){
   for (k=0; k<row ;k++){
       sudo[k] =(int*) calloc (col,sizeof (int));
         }
       }

//Read the image data from the rest of the file
for(i=0;i<row;i++){
   for(j=0;j<col;j++){
        fscanf(fd,"%c ", &sudo[i][j]);
         }
      }
fclose(fd);

//
printf("Header:\nfile type: %s\nrow: %d\ncol: %d\ndepht: %d\n",&type,row,col,depht);

//Copy the matrix from memory to a new file
fdd=fopen("matrice.txt","wb");

for(i=0;i<row;i++){
   for(j=0;j<col;j++){
      fprintf(fdd,"%d ",sudo[i][j]);
      }
    fprintf(fdd,"\n");
 }

 free(sudo);
 fclose(fdd);
 return 0;
}

有什么想法吗?

【问题讨论】:

  • 一个主要问题是您以二进制 模式打开PGM 文件,即使它是一个文本文件。这很可能会导致行尾出现问题,具体取决于您的平台和创建 PGM 文件的平台。当您写入新文件时也是如此,因为您以二进制模式打开它,所以您打印的换行符对于您所在的平台可能是错误的。
  • 顺便说一句,和你的问题无关,但是你在程序结束时有内存泄漏。你释放了sudo 但不是sudo 的内容(即sudo[0]sudo[1] 等)。
  • 我也以正常模式打开文件。它的行为比二进制模式更糟糕(超过 3/4 的文件为零)。*修复了内存泄漏
  • 你为什么用%c输入,%d输出?
  • 看起来评论者可能会互相交谈,因为没有人提到有 2 种 pgm 格式的事实:原始(所有文本)和 rawbits(标题是文本,像素不是)。它们通过类型 P2 或 P5 进行区分。说到类型,你有一个type 变量,它是一个单一的char,你正在用%s 读取它;那肯定会溢出。

标签: c file matrix pgm


【解决方案1】:

这是 .pgm 文件的格式,如下所示:

<http://netpbm.sourceforge.net/doc/pgm.html>:

A PGM file consists of a sequence of one or more PGM images. 
There are no data, delimiters, or padding before, after, or between images.

Each PGM image consists of the following:

    A "magic number" for identifying the file type. 
        A pgm image's magic number is the two characters "P5".
    Whitespace (blanks, TABs, CRs, LFs).
    A width, formatted as ASCII characters in decimal.
    Whitespace.
    A height, again in ASCII decimal.
    Whitespace.
    The maximum gray value (Maxval), again in ASCII decimal. 
        Must be less than 65536, and more than zero.
    A single whitespace character (usually a newline).
    A raster of Height rows, in order from top to bottom. 
       Each row consists of Width gray values, in order from left to right. 
    Each gray value is a number from 0 through Maxval, with 0 being black and Maxval being white. 
    Each gray value is represented in pure binary by either 1 or 2 bytes. 
    If the Maxval is less than 256, it is 1 byte. Otherwise, it is 2 bytes. 
    The most significant byte is first.

    A row of an image is horizontal. 
    A column is vertical. 
    The pixels in the image are square and contiguous.

    Each gray value is a number proportional to the intensity of the pixel, 
    adjusted by the ITU-R Recommendation BT.709 gamma transfer function.  
    (That transfer function specifies a gamma number of 2.2 and has a linear section for small intensities). 
    A value of zero is therefore black. 
    A value of Maxval represents CIE D65 white 
       and the most intense value in the image 
       and any other image to which the image might be compared.

    Note that a common variation on the PGM format 
       is to have the gray value be "linear," 
       i.e. as specified above except without the gamma adjustment.
       `pnmgamma` takes such a PGM variant as input and produces a true PGM as output.

    In the transparency mask variation on PGM, the value represents opaqueness. It is proportional to the fraction of intensity of a pixel that would show in place of an underlying pixel. So what normally means white represents total opaqueness and what normally means black represents total transparency. In between, you would compute the intensity of a composite pixel of an "under" and "over" pixel as under * (1-(alpha/alpha_maxval)) + over * (alpha/alpha_maxval). 
    Note that there is no gamma transfer function in the transparency mask. 

Strings starting with "#" may be comments, the same as with PBM.

Note that you can use `pamdepth` to convert between a the format with 1 byte per gray value and the one with 2 bytes per gray value.

All characters referred to herein are encoded in ASCII. 
"newline" refers to the character known in ASCII as Line Feed or LF. 
A "white space" character is space, CR, LF, TAB, VT, or FF 
    (I.e. what the ANSI standard C isspace() function calls white space). 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    相关资源
    最近更新 更多