0

我需要读取一个 pgm 文件并将其中包含的值数组存储在一个二维数组中。在 PGM 格式中,每个像素由 0 到 MaxVal 之间的灰度值指定。前三行给出了与图像相关的信息:幻数、高度、宽度和 maxVal。该文件还包括空格。以# 开头的行是注释。这是我写到现在的。

public class PGM{

public static void main(String args[]) throws Exception {
    FileInputStream f = new FileInputStream("C:\\......\\brain_001.pgm");
    DataInputStream d = new DataInputStream(f);
    d.readLine();//first line contains P5
    String line = d.readLine();//second line contains height and width
    Scanner s = new Scanner(line);
    int width = s.nextInt();
    int height = s.nextInt();
    line = d.readLine();//third line contains maxVal
    s = new Scanner(line);
    int maxVal = s.nextInt();
    byte[][] im = new byte[height][width];
    for (int i = 0; i < 258; i++) {
        for (int j = 0; j < 258; j++) {
            im[i][j] = -1;
        }
    }
    int count = 0;
    byte b;
    try {
        while (true) {
            b = (byte) (d.readUnsignedByte());
            if (b == '\n') { //do nothing if new line encountered
            } else if (b == '#') {
                d.readLine();
            } else if (Character.isWhitespace(b)) { // do nothing if whitespace encountered
            } else {
                im[count / width][count % width] = b;
                count++;
            }
        }
    } catch (EOFException e) {
    }
    System.out.println("Height=" + height);
    System.out.println("Width=" + height);
    System.out.println("Required elemnts=" + (height * width));
    System.out.println("Obtained elemnets=" + count);

}
}

当程序运行时,我得到以下输出:

Height=258
Width=258
Required elemnts=66564
Obtained elemnets=43513

元素的数量(每个对应一个灰度值)少于所需的数量。当我用 PGM 查看器打开文件时,一切都正确显示。此外,当我打印数组的内容时,我看到很多负值。但它们都必须大于或等于零。我哪里出错了?

4

2 回答 2

1

很可能是因为不推荐使用的方法readLine()DataInputStream如其注释中所述

*此方法不能正确地将字节转换为字符。从 JDK 1.1 开始,读取文本行的首选方法是通过 BufferedReader.readLine() 方法。使用 DataInputStream 类读取行的程序可以通过替换以下形式的代码转换为使用 BufferedReader 类: DataInputStream d = new DataInputStream(in);

与: BufferedReader d = new BufferedReader(new InputStreamReader(in));*

当我根据此建议更改您的程序时,它对我有用(我还进行了其他一些更改:

已更新以处理 PGM 的 P2 和 P5 口味

    public static void main(String args[]) throws Exception {
        try {
            InputStream f = ClassLoader.getSystemClassLoader().getResourceAsStream("lena.pgm");
            BufferedReader d = new BufferedReader(new InputStreamReader(f));
            String magic = d.readLine();    // first line contains P2 or P5
            String line = d.readLine();     // second line contains height and width
            while (line.startsWith("#")) {
                line = d.readLine();
            }
            Scanner s = new Scanner(line);
            int width = s.nextInt();
            int height = s.nextInt();
            line = d.readLine();// third line contains maxVal
            s = new Scanner(line);
            int maxVal = s.nextInt();
            byte[][] im = new byte[height][width];

            int count = 0;
            int b = 0;
            try {
                while (count < height*width) {
                    b = d.read() ;
                    if ( b < 0 ) 
                        break ;

                    if (b == '\n') { // do nothing if new line encountered
                    } 
//                  else if (b == '#') {
//                      d.readLine();
//                  } 
//                  else if (Character.isWhitespace(b)) { // do nothing if whitespace encountered
//                  } 
                    else {
                        if ( "P5".equals(magic) ) { // Binary format
                            im[count / width][count % width] = (byte)((b >> 8) & 0xFF);
                            count++;
                            im[count / width][count % width] = (byte)(b & 0xFF);
                            count++;
                        }
                        else {  // ASCII format
                            im[count / width][count % width] = (byte)b ;
                            count++;
                        }
                    }
                }
            } catch (EOFException eof) {
                eof.printStackTrace(System.out) ;
            }
            System.out.println("Height=" + height);
            System.out.println("Width=" + height);
            System.out.println("Required elements=" + (height * width));
            System.out.println("Obtained elements=" + count);
        }
        catch(Throwable t) {
            t.printStackTrace(System.err) ;
            return ;
        }

    }
于 2012-08-12T14:30:41.160 回答
0

以下代码适用于我:

FileInputStream f;
    try {
        f = new FileInputStream(fileLocation);
        BufferedReader br = new BufferedReader(new InputStreamReader(f));
        String magic = br.readLine();    // first line contains P2 or P5
        String line = br.readLine();     // second line contains height and width

        //-scan width and height
        Scanner s = new Scanner(line);
        int width = s.nextInt();
        int height = s.nextInt();
        s.close();

        //-scan max value
        line = br.readLine();// third line contains maxVal
        s = new Scanner(line);
        //          int maxVal = s.nextInt();
        //-close scanner
        s.close();
        //-close buffer
        br.close();
        f.close();

        xvec=new DenseMatrix64F(height*width, 1);

        int b=0;
        int counter=0;
        f = new FileInputStream(fileLocation);
        DataInputStream dis = new DataInputStream(f);
        //-move across unused lines
        dis.readLine();
        dis.readLine();
        dis.readLine();
        while ((b=dis.read()) >= 0) {
            xvec.set(counter, 0, b);
            counter++;
        }
        dis.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
于 2015-05-23T00:05:51.450 回答