In the previous posts (CA in MATLAB and C++) I’ve shown how to implement cancer stem sell driven tumor growth model. In both codes I have set the boundaries of the lattice to true without adding those sites to additional cells vector, so the boundary was treated as an occupied site, but not as a viable cell. This way of coding the system makes it easy to implement more complex domains. Today, I’ll show how to read the complex domains from bitmap (.bmp) file and use them for simulations using previously posted codes. The basic idea is that the image will be loaded into the program and the pixels with values “close” to white will be treated as free sites.
First we need to prepare the image. The posted codes will assume that the image is a square (image=width). We can draw anything we want, remembering that white pixels will be interpreted as free sites. We will write C++ code that will be able to read properly 24 bits bitmap images without the embedded information about the color space. In order to export image in that format we can use GIMP program with the following settings during the export.
I’ve prepared two exemplary images that I will use further in the simulations. The first one is adapted from the paper by Enderling et al. and the second is a generated text using PowerPoint.
Firt, the basic C++ code. We could use additional libraries to load images, but we want to make code as platform independent as possible. We assume that the array lattice and its size N are already defined as the global variables (see previous code).
#include <math.h> void domainFromImage(char* fileName) { FILE* f = fopen(fileName, "rb"); //open to read as binary unsigned char head[54]; fread(head, sizeof(unsigned char), 54, f); // read the header //in BMP format the size of each row is rounded up to multiple of 4 bytes int Nb = ceil(3.*(double)N/4.)*4; //true size of the row in bytes, including padding unsigned char* img = new unsigned char[Nb]; // allocate one row of pixels for(int i = 0; i < N; i++) { //for each row fread(img, sizeof(unsigned char), Nb, f);//read one row for (int j=0; j<N; j++) //set to free only those that have high intensity close to white (>240 in all three channels) lattice[i*N+j] = !(img[3*j]>250 && img[3*j+1]>250 && img[3*j+2]>250); } fclose(f);//close file //filling boundary for (int i=0; i<N; i++) {lattice[i]=true;};//left for (int i=0; i<N*N; i+=N) {lattice[i]=true;};//top for (int i=N-1; i<N*N; i+=N) {lattice[i]=true;};//bottom for (int i=N*(N-1); i<N*N; i++) {lattice[i]=true;};//right }
The same task in MATLAB is way easier to implement…
function [L, N] = domainFromImage( filename ) L = imread(filename); %reading image L = ~(L(:,:,1)>250 & L(:,:,2)>250 & L(:,:,3)>250); %setting those values... N = size(L,1);%size of the domain (assuming square) %filling border L([1:N 1:N:N*N N:N:N*N N*(N-1):N*N]) = true; %boundary end
What is most important MATLAB code is not so much dependent on the format of the image – it can be easily modified to other image types (imread function is very flexible).
Below is the exemplary result of simulation using image representing the tissue.
Tumor growth can be also simulated for the domain generated using PowerPoint text.
Nice post again Jan. I am beginning to see a trend for all your post to contain code. I wonder whether you could do with a github for this…
LikeLike
Thanks. I had the idea for post mostly with codes from the very beginning. Github is a good idea, especially when codes will become more complex – now they are quite simple in a copy and paste to a single file style. Now thinking about asking other IMOers if they have something to post. Some Python would be awesome
LikeLiked by 1 person
Now if you just add a little OpenCV to partition foreground from background in more complicated images, you could have a out-of-the-box way to initialize ABMs based on histologies. Cool stuff, Jan.
LikeLike