Reading an image into an array?

2019-08-18 07:57发布

问题:

I'm attempting to write a program that utilizes the sobel filter to detect edges in images. So first off, I've written down some of the requirements in some basic code, such as the x and y direction filters as arrays and also an attempt to read in a pgm image:

program edges
implicit none
integer, dimension(:,:), allocatable :: inp, outim, GX, GY
integer, parameter :: dp = selected_real_kind(15,300)
integer :: ky, kx, x, y, out_unit = 10, M, N, sx, sy, i, j
real(kind=dp) :: G
M = 5
N = 5

allocate(inp(M,N))
allocate(outim(M-2,N-2))
allocate(GX(3,3))
allocate(GY(3,3))

open(file = 'clown.pgm',unit=out_unit,status= 'unknown') !opening file to         write to inp
read (out_unit,11) 'P2'      !pgm magic number
read (out_unit,12) 50,50     !width, height
read (out_unit,13) 1      !max gray value
do M=-25,25
    do N=-25,25
        read (out_unit,*) inp(M,N)
    end do
end do
11 format(a2)
12 format(i3,1x,i3)
13 format(i5)

This is my first time working with image manipulation in FORTRAN, apart from once when I printed an image out as a pbm file. The code for reading the image in is a replicate of what I used to print one out before, except I changed write to read.

So my question is, how can I read in an image that's in pgm format into the "inp" array, so that I can apply the sobel filter? When I run my attempt, I get the following errors:

read (out_unit,11) 'P2'      !pgm magic number
              1
Error: Expected variable in READ statement at (1)
sobel.f90:41:18:

 read (out_unit,12) 50,50     !width, height
              1
Error: Expected variable in READ statement at (1)
sobel.f90:42:18:

 read (out_unit,13) 1      !max gray value
              1
Error: Expected variable in READ statement at (1)

Thank you

回答1:

The first mistake is, as the compiler states quite clearly, in this line:

read (out_unit,11) 'P2'

The compiler expects, because that's the way that Fortran is defined, to be told to read a value from out_unit into a variable, but 'P2' is a character literal (or whatever the heck the standard calls them), it's a string, it's not a variable.

The same mistake occurs in the next lines too. The compiler expects something like

integer :: p2  ! pgm magic number
...
read (out_unit,11) p2

etc. After execution of this version of the read statement the variable p2 holds the magic number read from the pgm file.

While I'm writing, calling the unit to be read from out_unit is just perverse and will, eventually, confuse you.