From: Cédric Aguerre Date: Wed, 22 Jul 2015 16:38:16 +0000 (+0200) Subject: loading image as datasource relies on tui X-Git-Tag: V8_0_0a1~5^2~39 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=45d2f452482fbfd88ff15b75bb8b099f50a5bc1a;p=modules%2Fmed.git loading image as datasource relies on tui --- diff --git a/src/MEDOP/exe/image2med/CMakeLists.txt b/src/MEDOP/exe/image2med/CMakeLists.txt index 1a91aa5d3..7629f5802 100644 --- a/src/MEDOP/exe/image2med/CMakeLists.txt +++ b/src/MEDOP/exe/image2med/CMakeLists.txt @@ -19,7 +19,6 @@ SET(MED_PYTHON_SCRIPTS image2med.py - xmedimages.py ) INSTALL(FILES ${MED_PYTHON_SCRIPTS} DESTINATION ${SALOME_INSTALL_BINS}/med PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ) diff --git a/src/MEDOP/exe/image2med/xmedimages.py b/src/MEDOP/exe/image2med/xmedimages.py deleted file mode 100644 index 4bc0c1ee7..000000000 --- a/src/MEDOP/exe/image2med/xmedimages.py +++ /dev/null @@ -1,148 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF R&D -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -# Author : Guillaume Boulant (EDF) - -import MEDCoupling as MC -import MEDLoader as ML - -from PIL import Image -from PIL import ImageOps -import numpy - -class FieldBuilder: - - def image2med(self, imageFilepath, medFilepath=None): - - # Load the image file in a numpy array using PIL. - img=Image.open(imageFilepath) - imgbw=ImageOps.grayscale(img) - # WARN: We keep only the grayscale. Maybe, it could be usefull - # to get the RGB scales each on one component of the field. - - # Creating a cartesian mesh with a grid of the size of the image - # The sizes defined the number of pixel in a direction, then the - # number of cells to create in the mesh in that direction. - width,height=imgbw.size - mesh=self.createMesh("grid_%sx%s"%(width,height),width,height) - field=self.createField("imagefield",mesh,imgbw) - - # The MEDLoader can be used to save all the stuff in a med file. You - # just have to specify the field and the MEDLoader will save the - # underlying mesh. - createFromScratch=True - ML.MEDLoader.WriteField(medFilepath,field,createFromScratch) - - def createMesh(self, meshname, sizeX, sizeY): - """ - Creating a cartesian mesh with a grid of the size of the image. - sizeX and sizeY should be respectively the width and heigth of the - image. - """ - # >>> - # WARNING: remember the problem of tics and spaces. The data values - # are considered as values defined on cells. With size values in a - # direction, we have to create size+1 mesh nodes in that direction. - # <<< - - # The mesh is created using MEDCoupling - cmesh=MC.MEDCouplingCMesh.New(); - cmesh.setName(meshname) - - # We use an arbitrary step between cells (the value does not matter) - stepX = 0.1 - nbNodesX = sizeX+1 - arrX = [float(i * stepX) for i in range(nbNodesX)] - coordsX=MC.DataArrayDouble.New() - coordsX.setValues(arrX,nbNodesX,1) - - # For the Y dimension, we have to reverse the coordinates (the - # first pixel is at y=height and not at y=0). - stepY = 0.1 - nbNodesY = sizeY+1 - lengthY = sizeY*stepY - arrY=[float(lengthY - i * stepY) for i in range(nbNodesY)] - coordsY=MC.DataArrayDouble.New() - coordsY.setValues(arrY,nbNodesY,1) - - cmesh.setCoords(coordsX,coordsY) - print "Imagem mesh dimension: %d"%cmesh.getSpaceDimension() - - # WARN: In the current state of development of MEDLoader, only - # unstructured meshes are supported for writting function in med - # files. We just have to convert the cartesian mesh in an unstructured - # mesh before creating the field. - umesh=cmesh.buildUnstructured(); - umesh.setName(cmesh.getName()) - - return umesh - - def createField(self, fieldname, mesh, image): - """ - Creating a scalar field on the mesh using image data - """ - # Create the field using MEDCoupling - field = MC.MEDCouplingFieldDouble.New(MC.ON_CELLS,MC.ONE_TIME); - field.setName(fieldname); - field.setMesh(mesh); - # OPTIONAL: We set an arbitrary time step for test purpose - field.setIteration(0); - field.setOrder(0) - - imagedata=list(image.getdata()) - width,height=image.size - nbCells = width*height - dataArray=MC.DataArrayDouble.New(); - nbComponents=1 # For a scalar field - - dataArray.setValues(imagedata,nbCells,nbComponents) - field.setArray(dataArray); - - return field - -# -# =================================================================== -# use case functions -# =================================================================== -# - -def getTestImagePath(): - import os - MED_ROOT_DIR=os.environ["MED_ROOT_DIR"] - RESDIR=os.path.join(MED_ROOT_DIR, "share", "salome", "resources", "med", "medop_testfiles") - imgFileName="irm_test1.png" - imgFilePath=os.path.join(RESDIR,imgFileName) - return imgFilePath - -def TEST_pil(): - imgFilePath = getTestImagePath() - img=Image.open(imageFilepath) - imgbw=ImageOps.grayscale(img) - - -def TEST_image2med(): - imgFilePath = getTestImagePath() - builder = FieldBuilder() - builder.image2med(imgFilePath,"image.med") - -# =================================================================== -if __name__ == "__main__": - TEST_pil() - #TEST_image2med() diff --git a/src/MEDOP/gui/DatasourceController.cxx b/src/MEDOP/gui/DatasourceController.cxx index e59ebc048..4b5b8cbf0 100644 --- a/src/MEDOP/gui/DatasourceController.cxx +++ b/src/MEDOP/gui/DatasourceController.cxx @@ -123,6 +123,7 @@ void DatasourceController::createActions() { * informations to the GUI, and the GUI creates a tree view of these * data in the study object browser. */ +// This function emits a signal that will be caught by workspace to delegate command (datasource creation) to python console. void DatasourceController::addDatasource(const char* filename) { @@ -131,7 +132,7 @@ DatasourceController::addDatasource(const char* filename) event->objectalias = filename; emit datasourceSignal(event); } -// call to this function is trigerred by workspace (itself from python console) +// After above data source creation, python console emits a signal, forwarded by workspace, to update the GUI void DatasourceController::updateTreeViewWithNewDatasource(const MEDOP::DatasourceHandler* datasourceHandler) { @@ -182,7 +183,6 @@ DatasourceController::updateTreeViewWithNewDatasource(const MEDOP::DatasourceHan } } - void DatasourceController::OnAddDatasource() { // Dialog to get the filename where the input data are read from @@ -193,14 +193,6 @@ void DatasourceController::OnAddDatasource() if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() ) anInitialPath = QDir::currentPath(); - /* - QString filename = SUIT_FileDlg::getFileName(_salomeModule->getApp()->desktop(), - "", - filter, - tr("IMPORT_MED_FIELDS"), - true); - */ - QStringList filenames = SUIT_FileDlg::getOpenFileNames( _salomeModule->getApp()->desktop(), anInitialPath, filter, @@ -216,8 +208,8 @@ void DatasourceController::OnAddDatasource() } #include "DlgImageToMed.hxx" -#include -#include +//#include +//#include void DatasourceController::OnAddImagesource() { @@ -230,6 +222,7 @@ void DatasourceController::OnAddImagesource() } QString imageFilename = dialog.getImageFilepath(); + /* QString medFilename = dialog.getMedFilepath(); bool autoLoad = dialog.isAutoLoaded(); @@ -249,7 +242,12 @@ void DatasourceController::OnAddImagesource() this->addDatasource(QCHARSTAR(medFilename)); _salomeModule->updateObjBrowser(true); } + */ + DatasourceEvent* event = new DatasourceEvent(); + event->eventtype = DatasourceEvent::EVENT_ADD_IMAGE_AS_DATASOURCE; + event->objectalias = imageFilename; + emit datasourceSignal(event); } void DatasourceController::OnExpandField() diff --git a/src/MEDOP/gui/DatasourceController.hxx b/src/MEDOP/gui/DatasourceController.hxx index 63d3fc960..bc1732758 100644 --- a/src/MEDOP/gui/DatasourceController.hxx +++ b/src/MEDOP/gui/DatasourceController.hxx @@ -55,7 +55,9 @@ typedef struct { EVENT_USE_OBJECT, // Import in the workspace AND define a proxy // variable in the tui console to use it EVENT_VIEW_OBJECT_SCALAR_MAP, - EVENT_ADD_DATASOURCE // to forward action to workspace (and then to python console) + // these ones forward actions to workspace (and then to python console) + EVENT_ADD_DATASOURCE, + EVENT_ADD_IMAGE_AS_DATASOURCE }; int eventtype; XmedDataObject * objectdata; diff --git a/src/MEDOP/gui/WorkspaceController.cxx b/src/MEDOP/gui/WorkspaceController.cxx index 6d28d336d..2f19a740a 100644 --- a/src/MEDOP/gui/WorkspaceController.cxx +++ b/src/MEDOP/gui/WorkspaceController.cxx @@ -504,6 +504,12 @@ void WorkspaceController::processDatasourceEvent(const DatasourceEvent * event) commands += QString("LoadDataSource('%1')").arg(event->objectalias); _consoleDriver->exec(commands); } + else if ( event->eventtype == DatasourceEvent::EVENT_ADD_IMAGE_AS_DATASOURCE ) { + QStringList commands; + commands += QString("from medpresentation import LoadImageAsDataSource"); + commands += QString("LoadImageAsDataSource('%1')").arg(event->objectalias); + _consoleDriver->exec(commands); + } else { STDLOG("The event "<eventtype<<" is not implemented yet"); } diff --git a/src/MEDOP/tui/medpresentation/CMakeLists.txt b/src/MEDOP/tui/medpresentation/CMakeLists.txt index c76faf093..04121212d 100644 --- a/src/MEDOP/tui/medpresentation/CMakeLists.txt +++ b/src/MEDOP/tui/medpresentation/CMakeLists.txt @@ -20,6 +20,7 @@ SET(PYFILES_TO_INSTALL __init__.py medpresentation.py + xmedimages.py ) SALOME_INSTALL_SCRIPTS("${PYFILES_TO_INSTALL}" ${SALOME_INSTALL_PYTHON}/medpresentation) diff --git a/src/MEDOP/tui/medpresentation/__init__.py b/src/MEDOP/tui/medpresentation/__init__.py index 8c9de9e25..6f4106b15 100644 --- a/src/MEDOP/tui/medpresentation/__init__.py +++ b/src/MEDOP/tui/medpresentation/__init__.py @@ -18,4 +18,6 @@ # from medpresentation import LoadDataSource +from medpresentation import LoadImageAsDataSource + from medpresentation import MakeScalarMap diff --git a/src/MEDOP/tui/medpresentation/medpresentation.py b/src/MEDOP/tui/medpresentation/medpresentation.py index 1fb6d8618..086b4d7a0 100644 --- a/src/MEDOP/tui/medpresentation/medpresentation.py +++ b/src/MEDOP/tui/medpresentation/medpresentation.py @@ -29,6 +29,19 @@ def LoadDataSource(filename): notifyGui_addsource(filename) # +def LoadImageAsDataSource(filename): + # get temp file name to generate med file from image + import tempfile + temp = tempfile.NamedTemporaryFile(suffix='.cfg') + medfilename = temp.name + temp.close() + + from xmedimages import FieldBuilder + builder = FieldBuilder() + builder.image2med(filename, medfilename) + LoadDataSource(medfilename) +# + def MakeScalarMap(proxy, viewMode=MEDOP.VIEW_MODE_REPLACE): # Create the presentation instance in CORBA engine # The engine in turn creates the ParaView pipeline elements diff --git a/src/MEDOP/tui/medpresentation/xmedimages.py b/src/MEDOP/tui/medpresentation/xmedimages.py new file mode 100644 index 000000000..a08d6adc3 --- /dev/null +++ b/src/MEDOP/tui/medpresentation/xmedimages.py @@ -0,0 +1,148 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# Author : Guillaume Boulant (EDF) + +import MEDCoupling as MC +import MEDLoader as ML + +from PIL import Image +from PIL import ImageOps +import numpy + +class FieldBuilder: + + def image2med(self, imageFilepath, medFilepath=None): + + # Load the image file in a numpy array using PIL. + img=Image.open(imageFilepath) + imgbw=ImageOps.grayscale(img) + # WARN: We keep only the grayscale. Maybe, it could be usefull + # to get the RGB scales each on one component of the field. + + # Creating a cartesian mesh with a grid of the size of the image + # The sizes defined the number of pixel in a direction, then the + # number of cells to create in the mesh in that direction. + width,height=imgbw.size + mesh=self.createMesh("grid_%sx%s"%(width,height),width,height) + field=self.createField("imagefield",mesh,imgbw) + + # The MEDLoader can be used to save all the stuff in a med file. You + # just have to specify the field and the MEDLoader will save the + # underlying mesh. + createFromScratch=True + ML.MEDLoader.WriteField(medFilepath,field,createFromScratch) + + def createMesh(self, meshname, sizeX, sizeY): + """ + Creating a cartesian mesh with a grid of the size of the image. + sizeX and sizeY should be respectively the width and heigth of the + image. + """ + # >>> + # WARNING: remember the problem of tics and spaces. The data values + # are considered as values defined on cells. With size values in a + # direction, we have to create size+1 mesh nodes in that direction. + # <<< + + # The mesh is created using MEDCoupling + cmesh=MC.MEDCouplingCMesh.New(); + cmesh.setName(meshname) + + # We use an arbitrary step between cells (the value does not matter) + stepX = 0.1 + nbNodesX = sizeX+1 + arrX = [float(i * stepX) for i in range(nbNodesX)] + coordsX=MC.DataArrayDouble.New() + coordsX.setValues(arrX,nbNodesX,1) + + # For the Y dimension, we have to reverse the coordinates (the + # first pixel is at y=height and not at y=0). + stepY = 0.1 + nbNodesY = sizeY+1 + lengthY = sizeY*stepY + arrY=[float(lengthY - i * stepY) for i in range(nbNodesY)] + coordsY=MC.DataArrayDouble.New() + coordsY.setValues(arrY,nbNodesY,1) + + cmesh.setCoords(coordsX,coordsY) + print "Imagem mesh dimension: %d"%cmesh.getSpaceDimension() + + # WARN: In the current state of development of MEDLoader, only + # unstructured meshes are supported for writting function in med + # files. We just have to convert the cartesian mesh in an unstructured + # mesh before creating the field. + umesh=cmesh.buildUnstructured(); + umesh.setName(cmesh.getName()) + + return umesh + + def createField(self, fieldname, mesh, image): + """ + Creating a scalar field on the mesh using image data + """ + # Create the field using MEDCoupling + field = MC.MEDCouplingFieldDouble.New(MC.ON_CELLS,MC.ONE_TIME); + field.setName(fieldname); + field.setMesh(mesh); + # OPTIONAL: We set an arbitrary time step for test purpose + field.setIteration(0); + field.setOrder(0) + + imagedata=list(image.getdata()) + width,height=image.size + nbCells = width*height + dataArray=MC.DataArrayDouble.New(); + nbComponents=1 # For a scalar field + + dataArray.setValues(imagedata,nbCells,nbComponents) + field.setArray(dataArray); + + return field + +# +# =================================================================== +# use case functions +# =================================================================== +# + +def getTestImagePath(): + import os + MED_ROOT_DIR=os.environ["MED_ROOT_DIR"] + RESDIR=os.path.join(MED_ROOT_DIR, "share", "salome", "resources", "med", "medop_testfiles") + imgFileName="irm_test1.png" + imgFilePath=os.path.join(RESDIR,imgFileName) + return imgFilePath + +def TEST_pil(): + imgFilePath = getTestImagePath() + img=Image.open(imageFilepath) + imgbw=ImageOps.grayscale(img) + + +def TEST_image2med(): + imgFilePath = getTestImagePath() + builder = FieldBuilder() + builder.image2med(imgFilePath,"image.med") + +# =================================================================== +if __name__ == "__main__": + TEST_pil() + #TEST_image2med()