0

pgm ファイルを読み取り、それに含まれる値の配列を 2D 配列に格納する必要があります。PGM 形式では、各ピクセルは 0 から MaxVal までのグレー値で指定されます。最初の 3 行は、画像に関連する情報 (マジック ナンバー、高さ、幅、および 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

Most likely its because of deprecated method readLine() from DataInputStream. As mentioned in its annotation

*This method does not properly convert bytes to characters. As of JDK 1.1, the preferred way to read lines of text is via the BufferedReader.readLine() method. Programs that use the DataInputStream class to read lines can be converted to use the BufferedReader class by replacing code of the form: DataInputStream d = new DataInputStream(in);

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

When I changed your program according to this advice, it worked for me (I made a couple of other changes as well:

(Updated to handle P2 and P5 flavors of PGM)

    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 に答える