wilfred202
wilfred202

Reputation: 51

IDL variable name based on input file name

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?

Upvotes: 0

Views: 958

Answers (4)

Phillip Bitzer
Phillip Bitzer

Reputation: 61

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

Upvotes: 1

mgalloy
mgalloy

Reputation: 2386

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']

Upvotes: 1

planetmaker
planetmaker

Reputation: 6044

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

Upvotes: 1

veda905
veda905

Reputation: 772

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.

Upvotes: 1

Related Questions