Salome HOME
fix conflict
[modules/med.git] / src / MEDCalc / tui / medimages.py
1 #  -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2007-2015  CEA/DEN, EDF R&D
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20
21 # Author : Guillaume Boulant (EDF)
22
23 import MEDCoupling as MC
24 import MEDLoader as ML
25
26 from PIL import Image
27 from PIL import ImageOps
28 import numpy
29
30 class FieldBuilder:
31
32     def image2med(self, imageFilepath, medFilepath=None):
33
34         # Load the image file in a numpy array using PIL.
35         img=Image.open(imageFilepath)
36         imgbw=ImageOps.grayscale(img)
37         # WARN: We keep only the grayscale. Maybe, it could be usefull
38         # to get the RGB scales each on one component of the field.
39
40         # Creating a cartesian mesh with a grid of the size of the image
41         # The sizes defined the number of pixel in a direction, then the
42         # number of cells to create in the mesh in that direction.
43         width,height=imgbw.size
44         mesh=self.createMesh("grid_%sx%s"%(width,height),width,height)
45         field=self.createField("imagefield",mesh,imgbw)
46
47         # The MEDLoader can be used to save all the stuff in a med file. You
48         # just have to specify the field and the MEDLoader will save the
49         # underlying mesh.
50         createFromScratch=True
51         ML.MEDLoader.WriteField(medFilepath,field,createFromScratch)
52
53     def createMesh(self, meshname, sizeX, sizeY):
54         """
55         Creating a cartesian mesh with a grid of the size of the image.
56         sizeX and sizeY should be respectively the width and heigth of the
57         image.
58         """
59         # >>>
60         # WARNING: remember the problem of tics and spaces. The data values
61         # are considered as values defined on cells. With size values in a
62         # direction, we have to create size+1 mesh nodes in that direction.
63         # <<<
64
65         # The mesh is created using MEDCoupling
66         cmesh=MC.MEDCouplingCMesh.New();
67         cmesh.setName(meshname)
68
69         # We use an arbitrary step between cells (the value does not matter)
70         stepX = 0.1
71         nbNodesX = sizeX+1
72         arrX = [float(i * stepX) for i in range(nbNodesX)]
73         coordsX=MC.DataArrayDouble.New()
74         coordsX.setValues(arrX,nbNodesX,1)
75
76         # For the Y dimension, we have to reverse the coordinates (the
77         # first pixel is at y=height and not at y=0).
78         stepY = 0.1
79         nbNodesY = sizeY+1
80         lengthY = sizeY*stepY
81         arrY=[float(lengthY - i * stepY) for i in range(nbNodesY)]
82         coordsY=MC.DataArrayDouble.New()
83         coordsY.setValues(arrY,nbNodesY,1)
84
85         cmesh.setCoords(coordsX,coordsY)
86         print "Imagem mesh dimension: %d"%cmesh.getSpaceDimension()
87
88         # WARN: In the current state of development of MEDLoader, only
89         # unstructured meshes are supported for writting function in med
90         # files. We just have to convert the cartesian mesh in an unstructured
91         # mesh before creating the field.
92         umesh=cmesh.buildUnstructured();
93         umesh.setName(cmesh.getName())
94
95         return umesh
96
97     def createField(self, fieldname, mesh, image):
98         """
99         Creating a scalar field on the mesh using image data
100         """
101         # Create the field using MEDCoupling
102         field = MC.MEDCouplingFieldDouble.New(MC.ON_CELLS,MC.ONE_TIME);
103         field.setName(fieldname);
104         field.setMesh(mesh);
105         # OPTIONAL: We set an arbitrary time step for test purpose
106         field.setIteration(0);
107         field.setOrder(0)
108
109         imagedata=list(image.getdata())
110         width,height=image.size
111         nbCells = width*height
112         dataArray=MC.DataArrayDouble.New();
113         nbComponents=1 # For a scalar field
114
115         dataArray.setValues(imagedata,nbCells,nbComponents)
116         field.setArray(dataArray);
117
118         return field
119
120 #
121 # ===================================================================
122 # use case functions
123 # ===================================================================
124 #
125
126 def getTestImagePath():
127     import os
128     MED_ROOT_DIR=os.environ["MED_ROOT_DIR"]
129     RESDIR=os.path.join(MED_ROOT_DIR, "share", "salome", "resources", "med", "medcalc_testfiles")
130     imgFileName="irm_test1.png"
131     imgFilePath=os.path.join(RESDIR,imgFileName)
132     return imgFilePath
133
134 def TEST_pil():
135     imgFilePath = getTestImagePath()
136     img=Image.open(imageFilepath)
137     imgbw=ImageOps.grayscale(img)
138
139
140 def TEST_image2med():
141     imgFilePath = getTestImagePath()
142     builder = FieldBuilder()
143     builder.image2med(imgFilePath,"image.med")
144
145 # ===================================================================
146 if __name__ == "__main__":
147     TEST_pil()
148     #TEST_image2med()