Simplicity
Simplicity

Reputation: 48916

Return the file name of the list item

I have a list called pairs: pairs = []

Each item in the pairs list is a pair of images:

pair = (im1,im2)
pairs.append(pair)

im1 and im2 are simply image files on the hard disk:

im1 = cv2.imread('im1.jpg')
im2 = cv2.imread('im2.jpg')

When I print the items in the pairs list, I get a matrix representing the elements (images). How can I return the image file names (im1.jpg and im2.jpg) instead?

Thanks.

Upvotes: 1

Views: 1594

Answers (2)

kingJulian
kingJulian

Reputation: 6180

The imread() function of the opencv library returns a numpy array. So you can't really access the file name from this. I would try something like this:

class Image(object):
    def __init__(self, image_name):
        self.image_name = cv2.imread(image_name)
        self.name = image_name

    def __str__(self):
        return self.name

Create your images:

im1 = Image('im1.jpg')
im2 = Image('im2.jpg')

Append the (im1, im2) pair to your pairs list. Then, when you print the the items in the pairs list just make sure to print their __str__ representation:

for p in pairs:
    print (str(p[0]), str(p[1])) 

Upvotes: 0

alkasm
alkasm

Reputation: 23012

You cannot get the filename from the array. The variable im1 = cv2.imread(...) only stores the array values. It is stored as a standard numpy ndarray object and there is no attribute referencing the filenames.

However, there are a lot of options here to do what you want, some that are very typical patterns for Python. Generally, you're looking to store two pieces of information: the filename and the image array. One option is just to have two lists, one being the filenames and the other the images:

>>> filename_list = ['im1.jpg', 'im2.jpg', ...]
>>> im_list = [cv2.imread(filename) for filename in filename_list]

Another way is to store these as pairs:

>>> filename1 = 'im1.jpg'
>>> filename2 = 'im2.jpg'
>>> im1 = cv2.imread(filename1)
>>> im2 = cv2.imread(filename2)
>>> im_pairs = [(filename1, im1), (filename2, im2), ...]

or if you already have the filenames and images as lists (as in the first case) you can use a list comprehension to build the pairs:

>>> im_pairs = [(filename, im) for filename, im in zip(filename_list, im_list)]

A better option (in terms of code reuse in actual projects) with the same idea as above is to create a namedtuple so it's more explicit what each item is:

>>> from collections import namedtuple
>>> Img = namedtuple('Img', ['name', 'data'])
>>> im1 = Img('im1.jpg', np.array([5, 4, 3, 2, 1]))
>>> im1.name
'im1.jpg'
>>> im1.data
array([5, 4, 3, 2, 1])

And here you can just create a list of Img objects.

A fourth option is to use a Python dictionary with the key being the name and the value being the arrays:

>>> filename1 = 'im1.jpg'
>>> filename2 = 'im2.jpg'
>>> im1 = cv2.imread(filename1)
>>> im2 = cv2.imread(filename2)
>>> im_pairs = {filename1: im1, filename2: im2, ...}

or again with a dictionary comprehension:

>>> im_pairs = {filename: im for filename, im in zip(filename_list, im_list)}

All of these methods are pretty standard so it's up to you how you'd want to use them. There are tons of other ways too, but I think the above are the most common.

Upvotes: 1

Related Questions