IDL variable name based on input file name

878 views Asked by At

I'm trying to load multiple images and want to automate the variable naming to make the variable name = the file input name.

For example:

image1=read_binary('image1.img',DATA_START=0,DATA_TYPE=1,DATA_DIMS=[450, 750,3], ENDIAN=native)

Just wondering if this is possible and how?

4

There are 4 answers

0
Phillip Bitzer On

Mike's @mgalloy answer is the best way to do this.

The others could have issues depending on your situation (e.g., if you have have a lot of files or need to run this in the Virtual Machine), but certainly work.

Before hashes, this is how I used to do it:

files = ['image1.img', 'image2.img', 'image3.img']
FOR i=0, N_Elements(files)-1 DO BEGIN
  varName = File_BaseName(files[i], '.png')
  thisImg = Read_Binary(files[i])
  (Scope_VarFetch(varName), Level=0, /Enter) = thisImg
ENDFOR

The Scope_VarFetch is the magic command that creates a variable with a particular name (given as a string), and assigns data to it. You can also retrieve variables in a similar manner.

But, it's much easier to use some of the more modern features of IDL. That same code using hashes and a ForEach?

files = ['image1.img', 'image2.img', 'image3.img']
imgs = Hash()
FOREACH, f, files Do imgs[f] = Read_Binary(files[i])

If order matters, you can use a ordered hash

0
veda905 On

You could put all of the image names in a string array and loop over that. If your images are .png then I would suggest that you use the read_png function. This may not be the most efficient, but if the images all have the same size then it is easy to stack them all in a cube like:

;Make a string array containing the names of the images
names = ['image2.png', 'image2.png', 'image3.png']

;Make a byte array to contain the x and y dimensions, the rgb, for each image
image_stack = bytarr(dimension1,dimension2,3,n_elements(names))

for i=0,n_elements(names)-1 do begin
    img = READ_PNG(names[i],rpal,gpal,bpal)

    image_stack[*,*,0,i] = rpal  ;set r channel of image i
    image_stack[*,*,1,i] = gpal  ;set g channel of image i
    image_stack[*,*,2,i] = bpal  ;set b channel of image i
endfor

Now you have all of the images in a cube where the last dimension is the image number.

1
mgalloy On

Hashes are built to do this:

h = hash()

image1 = read_binary('image1.img', data_start=0, data_type=1, $
                     data_dimes=[450, 750, 3], endian=native)
h['image1.img'] = image1

And then later retrieve with:

tv, h['image1.img']
0
planetmaker On

I very much prefer the way with a 3D (or 4D) array like veda905 outlined above.

However, if you really want to create a new, independent variable for each image, you can create your own command as a string and execute it via the execute command.

Assuming you have the filenames in an array like above:

;Make a string array containing the names of the images
names = ['image2.png', 'image2.png', 'image3.png']
; you need to supply the filename extension
varnames = FILE_BASENAME(names, '.png')

FOR i=0, N_ELEMENTS(varnames)-1 DO BEGIN
    result = EXECUTE(varnames[i] + '= READ_PNG(names[' + STRING(i) + '])')
ENDFOR