Importing an image into CC3D
So you have created an image in a drawing program (like PowerPoint), or perhaps you have a photo or perhaps even a microscope image and you want to import it into CC3D?
Here is how you do it, it has a couple steps, but isn't too difficult. (This is written for CompuCell3D 4.x and Python 3.x)
1. By default, the Python installed with CC3D does not include the Python Image Library (PIL) so you will have to install it. To do that:
Open a command window and browse to the Scripts folder in the Python directory installed with CC3D. On a windows machine it will be in the directory:
- C:\CompuCell3D-py3-64bit\python36\Scripts\
Run pip, the standard python installer, to install the Image library
- pip.exe install Image
- Hopefully every thing goes OK and you now have PIL installed, which includes the Image package.
2. You now need an image to import. The PIL-Image library supports several image formats, mostly those that are bit mapped.
- The supported formats include:
- jpg, jpeg
- png
- bmp
- Formats that are known to not work:
- GIF
- If you have a different image format you will need to convert it to one of the formats listed above.
3. Finally, you need a CC3D code to read the image and store it into a user defined field. This is pretty straight forward but there are a few things to keep track of.
- It is best if you know how big the image is and setup CC3D so that the simulation window is at least that big. Many image viewing programs will tell you the size of the image in pixels.
- CC3D uses the coordinate system where the pixel at (0,0) is the lower left corner. Most image formats have (0,0) in the upper left corner so we'll need to flip the image.
You need to import the Image library into CC3D, probably into the steppables file, using;
from PIL import Image
You then use the Image library commands to open the image (where imageFileName is the path and image file name);
img = Image.open(imageFileName)
You the invert the image with:
self.img=img.transpose(Image.FLIP_TOP_BOTTOM)
Then you can iterate over all the pixels in the image with:
for x in range(img.size[0]):
for y in range(img.size[1]):
# the red, green, blue values for this pixel in the image
(r,g,b) = self.img.getpixel((x,y))
You can convert the pixel's colors into a single value (or you could use a separate CC3D field for each color channel) with;
gr=(r+g+b)/(255.*3) # just map the r+g+b into 0-1
For displaying, you can create a user defined CC3D field. First you need to define a field in a steppable's _init_ function:
def __init__(self,frequency=1):
SteppableBasePy.__init__(self,frequency) self.create_scalar_field_py("BMP_image") # a field to store our image in
And then load the pointer for the field, and put the value in the field, in the start or step method of the steppable:
field = self.field.BMP_image
field[x,y,0] = gr # put the value in the CC3D user field
And that's it. You can of course now manipulate the image any way you want. Or create CC3D cells based on the pixel in the field.
You can see the needed code in this example zipped CC3D project.