1

I'm really stuck here. I am working on a project at work that requires me to merge several images into one. I have seen several posts describing how to do it using PIL, but none of them answered the question of what to do if you have any arbitrary number of channels.

The project is specifically an algorithm for image segmentation. The data supplied to it will be data gathered from an x-ray microscope of various biological samples. The final product is a collection of many grayscale images, each one representing a different elemental channel. Meaning, there is a grayscale image of the location of Fe, K, P, Si, etc., in the sample. This is no different than pulling an RGB image apart into 3 separate, one-dimensional images (arrays).

It is simple to merge those RGB channels back together so that

R: (2,3,6... 3) G: (5,5,7... 4) B: (1,3,2 ... 2)

becomes

RGB: [(2,5,1), (3,5,3), (6,7,2),... (3,4,2)]

But I need to know how to do this when there are more (or less) than three channels. Some of the users of the microscope gather dozens and dozens of elemental channels, while some gather 2 or 3. I can fairly simply build the final array of data as shown in the example above, I just don't know how to actually write it to an image. Here is a shortened version of what I have:

def mergeImages(imageList):

    allData = []
    allSizes = []
    mergedData = numpy.zeros((max(allSizes), len(imageList)))

    for image in imageList:
        data = ImageFileData(image)
        allData.append(data.GetImageData())

    for data in allData:
        allSizes.append(data1.GetImageSize())

    try:
        for i in range(len(allData)):
            for j in range(len(allData[i])):
                mergedData[j][i] = allData[i][j]
        return True

    except:
        qt.QMessageBox('Image merge failed.')
        return False

Where data is an image object, and 'data.GetImageData()` simply returns a list of integer intensity values (since each image given should be grayscale).

I have tested this, and mergedData ends up being correctly built, as a 2-dimensional array with as many components for each pixel as there are images.

But for the actual segmentation part of my algorithm to work, I need to pass it an image file, not the raw data. I'm sure I could make it so it can accept the raw data, and work fine, but I don't want to have to do that yet (because I would also like the merged image to be viewable).

So I want to be able to write mergedData to an image file, to do an assortment of things.

However, PIL says that it does not support user-defined image modes, and to call Image.write(), you must supply the image mode as an argument (none of which go beyond 4 channels).

So I dunno, if anyone here has experience with Image Processing that would be fantastic. I'm not even sure if an image with an arbitrary number of pixel values could be viewable. Maybe I would have to map a color to each component. I dunno. Before I even get to viewing, though, I want this to be able to write mergedData to an image file.

Thank you

pretzlstyle
  • 2,774
  • 5
  • 23
  • 40
  • Are you allowed to use `numpy`? You can use `numpy.dstack` to stack all of the images together, then you can convert back to a PIL image. – rayryeng Aug 06 '15 at 19:26
  • @rayryeng Yes I can use whatever I want, I have Anaconda running, and I use a numpy array in the example above. Thanks for the suggestion, I'll give it a try and report back – pretzlstyle Aug 06 '15 at 20:24
  • Cool. Simply supply a list of 2D images into `numpy.dstack` to create a 3D stack of images. Let me know how it goes! – rayryeng Aug 06 '15 at 20:28
  • BTW, if you want to support multiple stacks of images beyond 3, consider using the TIF standard. It's especially used in medical images and microscopy data. http://stackoverflow.com/questions/7569553/working-with-tiffs-import-export-in-python-using-numpy . I haven't tried it, but if you tried reading in a multi-stack TIF, you should be able to get this in a 3D stack. Same goes for saving too. Try that out and see how that goes. I'd love to write an answer if it works! – rayryeng Aug 06 '15 at 20:30

0 Answers0