{ "info": { "author": "Brent Huisman", "author_email": "mail@brenthuisman.net", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Healthcare Industry", "Intended Audience :: Science/Research", "License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Topic :: Scientific/Engineering :: Medical Science Apps.", "Topic :: Scientific/Engineering :: Physics" ], "description": "## medimage\n\nThis library supports r/w MetaImage (MHD,ITK), r/w AVSField (.xdr) and r/w Dicom images. XDR reading includes NKI compressed images (useful to work with your Elekta images). The `image` class is a thin wrapper around typed numpy array objects (the `.imdata` member) such that you can easily work with images in these data formats. Slicing, projections, mathematical operations, masking, stuff like that is very easy with numpy, so you can easily extend things to what you need.\n\nIncluded are some basic mathematical operations, some masking functions and crop and resampling functions. Of particular interest perhaps are the DVH analysis function, and the distance to agreement calculation. This calculation is quite slow though. For [NKI decompression](https://gitlab.com/plastimatch/plastimatch/tree/master/libs/nkidecompress) I supply a 64bit Linux and Windows lib, if you need support for other platforms you can compile the function in `medimage/nki_decomp` yourself. This component is governed by its own license.\n\nDicom write support *requires* `SimpleITK`, primarily because `pydicom` does not support dicom image write... Since you may not care, `medimage` package won't install `SimpleITK` for you and simply fail to save to dicom if `SimpleITK` is not found. *If* `SimpleITK` is found, it will *also* be used for dicom reading, because based on my limited testing, it's a bit more forgiving with the validity of input files.\n\n\n## Motivation\n\nThis project started out at a time when I was analyzing lots of [Gate](https://github.com/opengate/gate) image outputs. ITK's Python bindings (SimpleITK) was not pippable or easily usable yet, and I found working with image data as numpy arrays far preferable and faster than using ITK as a library in custom C++ programs which I'd need to compile and recompile as an analysis developed. Matplotlib after all is Python-only.\n\nI wanted to have a thin and pure Python wrapper around `numpy` that would allows me to read in and write out image data. Fortunately, the (uncompressed) MetaImage disk format was so straightforward even I could understand it, and it was even suprisingly performant. This `image` class grew to suit my needs as part of my `phd_tools` and later `postdoc_tools` repos, and in a new job I ported it to Python 3 and added filesupport for AVSFields and Dicom images. The idea is that you can take the `medimage` directory, drop it into any project, and be able to work with medical images as numpy arrays. It is now a core component to my analyses, and perhaps it can be useful to you too. A lot of machine learning tooling are heavy users of `numpy`, and therefore getting your images in is straightforward with this package.\n\n## Install\n\nYou can now use pip!\n\n $ pip(3) install medimage (--user)\n\nOr clone/download this repo and install manually with:\n\n $ python(3) setup.py install (--user)\n\nCurrently, the `pymedphys` component is NOT installed automatically, which is required when you are going to use the `compute_gamma` method. That is because it is a rather large package, and in developmental flux.\n\n## Usage\n\nAfter installation, you should be able to open and save an image like so:\n\n\tfrom medimage import image\n\tmyfirstimage = image(\"somefile.xdr\")\n\tmyfirstimage.saveas(\"somefile.mhd\")\n\n`image`s are instatiated with a string representing a file location, where the file extension indicates filetype. If not known extension is found, it assumes you're providing a dicom image or a dicom directory (of images).\n\nAlternatively, you can make a new zeroed out image of 30 by 40 by 50 voxels, spaced out 2mm in each dimension, centered at zero, like so:\n\n\tfrom medimage import image\n\tmyblankimage = image(DimSize=[30,40,50],ElementSpacing=[2,2,2],Offset=[0,0,0])\n\tmyblackimage.saveas(\"empty.mhd\")\n\n## Coordinates\n\nI've taken great care to make sure this library can work with images of any dimensionality, and that your image as represented by the `.imdata` numpy array member, and any class methods, have straightforward indexing (e.g. [x,y,z,], not [z,y,x]). PRs that fix any bugs in this regard are very welcome.\n\n### Take a slice or line profile\n\nYou may want to look at or work with a slice. Let's say you have a 3D image at `fname`:\n\n\timage = image.image(fname)\n\tx,y,z=image.get_slices_at_index() #defaults to central voxel\n\timport scipy.misc\n\tscipy.misc.imsave(\"d:/slicex.png\",x)\n\nNeed to look at a profile?\n\n\timage.get_profiles_at_index([10,10,10]) #get the lines through voxel [10,10,10]\n\nDon't care about indeces, but you know in physical dimensions where you want to slice? Say, through the point at 23.4mm,10mm,2.3mm?\n\n\timage.get_pixel_index([23.4,10,2.3])\n\n## Cropping\n\nApart from regular old cropping, the `.crop_as` method let's you 'crop' an image to the same size and pixelspacing as another image, provided that the images have overlap. For instance, you may have a CT and a dose image, where the dose image has larger voxel and covers only a subregion of the CT. You can get your CT values for each dose voxel like so:\n\n\tct = image.image('ct.dcm')\n\tdose = image.image('dose.dcm')\n\tct.crop_as(dose)\n\tct.saveas('ct_dosegrid')\n\n### DVH parameters within a subregion for which you have a mask\n\nSay you have a dose calculation and you want to have some DVH metrics (say, Dmax,D2,D50,D98,Dmean). Suppose you want those DVH metrics in the PTV region, and you have a PTV as mask image. How could `medimage` do this for you?\n\n\tfrom medimage import image\n\timport argparse\n\tfrom os import path\n\n\tparser = argparse.ArgumentParser(description='Supply an image and a mask or percentage for isodose contour in which to compute the DVH.')\n\tparser.add_argument('inputimage')\n\tparser.add_argument('--maskimage',default=None)\n\tparser.add_argument('--maskregion',default=None,type=float)\n\topt = parser.parse_args()\n\n\tim = image.image(path.abspath(opt.inputimage))\n\tmaskim = None\n\n\tif opt.maskregion == None and path.isfile(path.abspath(opt.maskimage)):\n\t\tprint('Using',opt.maskimage,'as region for DVH analysis.')\n\t\tmaskim = image.image(path.abspath(opt.maskimage))\n\telif opt.maskregion != None:\n\t\tassert 0 < opt.maskregion < 100\n\t\tprint('Using isodose contour at',opt.maskregion,'percent of maximum dose as region for DVH analysis.')\n\t\tmaskim = im.copy()\n\t\tmaskim.tomask_atthreshold((opt.maskregion/100.)*maskim.max())\n\telse:\n\t\tprint('No mask or maskregion specified; using whole volume for DVH analysis.')\n\n\tif maskim != None:\n\t\tim.applymask(maskim)\n\n\t# note: array is sorted in reverse for DVHs, i.e. compute 100-n%\n\tD2,D50,D98 = im.percentiles([98,50,2])\n\n\tprint(\"Dmax,D2,D50,D98,Dmean\")\n\tprint(im.imdata.max(),D2,D50,D98,im.mean())\n\n## Dependencies\n\n * numpy\n * pydicom\n * Optional (Dicom write): SimpleITK.\n\n### Changelog\n\n * 2019-10-08: v1.0.6: Bugfix, dicom write still incomplete.\n * 2019-10-08: v1.0.5: Dicom write\n * 2019-09-24: v1.0.4: New and much faster gamma computation (order of 5 minutes)\n * 2019-08-28: v1.0.3: Fixed a few sloppy bugs. Added CT rescaling when openingen Dicom image.\n * 2019-08-28: v1.0.0: Separated `image` class into its own `medimage` module.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/brenthuisman/medimage", "keywords": "medical image xdr mhd dicom numpy", "license": "LGPL", "maintainer": "", "maintainer_email": "", "name": "medimage", "package_url": "https://pypi.org/project/medimage/", "platform": "", "project_url": "https://pypi.org/project/medimage/", "project_urls": { "Homepage": "https://github.com/brenthuisman/medimage" }, "release_url": "https://pypi.org/project/medimage/1.0.6/", "requires_dist": [ "numpy", "pydicom" ], "requires_python": "", "summary": "Represent medical images as numpy array. Supported: .mhd (R/W),.xdr (R/W), dicom (R). Pure Python.", "version": "1.0.6" }, "last_serial": 5959803, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "6ae790a90743104eb26da42d52277730", "sha256": "aa0779862470abba026b2e091327f5cb0ecb762e2b48bcf5a92c22203d6e88fe" }, "downloads": -1, "filename": "medimage-1.0.0-py2-none-any.whl", "has_sig": false, "md5_digest": "6ae790a90743104eb26da42d52277730", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 21308, "upload_time": "2019-08-28T13:55:20", "url": "https://files.pythonhosted.org/packages/a2/3b/a38a0fb92eb1dbac16b0eaa9812a9715806220fd1ebff07934efa47074dd/medimage-1.0.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b8437ac2ea74c895804e29fbc522fd22", "sha256": "cbf7a704b49fb212323f0588b834556e03c02d0cb759992a622f6ba9c1690a89" }, "downloads": -1, "filename": "medimage-1.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "b8437ac2ea74c895804e29fbc522fd22", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 21308, "upload_time": "2019-08-28T13:55:23", "url": "https://files.pythonhosted.org/packages/10/60/f7360db8a85d0f87626b08c791c09fac487dfdee58bafc590be91091ba48/medimage-1.0.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "06e11f07ae5ee8027975b5cdb439fa66", "sha256": "a5e10d79ab4d679c34f030c4d93286a557b94749e0890b79aa9af0aecd69616f" }, "downloads": -1, "filename": "medimage-1.0.0.tar.gz", "has_sig": false, "md5_digest": "06e11f07ae5ee8027975b5cdb439fa66", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16115, "upload_time": "2019-08-28T13:55:24", "url": "https://files.pythonhosted.org/packages/55/32/5e613afc1ecc7faefba8d0131dc8f36531c694ca5907e0f705680ad3b3f3/medimage-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "13536dcc6cbc7ef0e7eef5c30491a63f", "sha256": "120ec9f60a896ade11a7b70e6092b246f715d65f7dee48ffcfa49503595391fa" }, "downloads": -1, "filename": "medimage-1.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "13536dcc6cbc7ef0e7eef5c30491a63f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 21564, "upload_time": "2019-09-17T16:06:18", "url": "https://files.pythonhosted.org/packages/43/64/9d13e12d3924e096ad51caf7bb909eec9a4c8029c811229071e663939e94/medimage-1.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9fdd827af540f7fa1f16a80ed902eeee", "sha256": "f0fc47c37fdc9b509b3d0d1bb974ddc225a2cbb13c894fbe67a572626f8a948b" }, "downloads": -1, "filename": "medimage-1.0.1.tar.gz", "has_sig": false, "md5_digest": "9fdd827af540f7fa1f16a80ed902eeee", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16415, "upload_time": "2019-09-17T16:06:20", "url": "https://files.pythonhosted.org/packages/da/eb/394730f7fb16bb0d95b4b1bb081ef15b2612d1ad61fffe88c037de637f8b/medimage-1.0.1.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "85488a03a0a351283ccc1818737444a3", "sha256": "805705374a9f93653c127e4e8ca01cdb66945aa63d20cf2fe8596f5213299755" }, "downloads": -1, "filename": "medimage-1.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "85488a03a0a351283ccc1818737444a3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 21571, "upload_time": "2019-09-17T16:12:03", "url": "https://files.pythonhosted.org/packages/e1/51/79b772673719b5d011ce1aef2835a7db3c43678e9ecb160edbee1d67002a/medimage-1.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c67ff0eda27d357951ad9bdb57010ef0", "sha256": "ed41aa40c871eb4d15c186ca5f243fd4005d652d2354f76a1875d09c6cd77229" }, "downloads": -1, "filename": "medimage-1.0.2.tar.gz", "has_sig": false, "md5_digest": "c67ff0eda27d357951ad9bdb57010ef0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16414, "upload_time": "2019-09-17T16:12:05", "url": "https://files.pythonhosted.org/packages/dc/f7/fc41fca998c91a1d3302263f49be1de20055454dffd26a00d5db52933908/medimage-1.0.2.tar.gz" } ], "1.0.3": [ { "comment_text": "", "digests": { "md5": "eb82477408b86635eab2a39a0ac89349", "sha256": "f9693778f6e03e4b1abc2c8224c251fe8d4933ee004c2f0c6e2a5a2d5697c411" }, "downloads": -1, "filename": "medimage-1.0.3-py2-none-any.whl", "has_sig": false, "md5_digest": "eb82477408b86635eab2a39a0ac89349", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 22203, "upload_time": "2019-09-19T08:29:20", "url": "https://files.pythonhosted.org/packages/05/07/179eb805bf0c120d6c4c4827b97dd015beb5338d175dcc4f4eef70e623de/medimage-1.0.3-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9d67e13edc55f5c1db9294cc573eeb05", "sha256": "8c96943f9dbd19013420ae34573a3a05fbc5b5302da7af197dfc28cb0b1d3e5c" }, "downloads": -1, "filename": "medimage-1.0.3.tar.gz", "has_sig": false, "md5_digest": "9d67e13edc55f5c1db9294cc573eeb05", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17116, "upload_time": "2019-09-19T08:29:22", "url": "https://files.pythonhosted.org/packages/dc/8c/1956759403130c39b0e8ae56c6992e0eb539bee8592a3c0e1fed33629155/medimage-1.0.3.tar.gz" } ], "1.0.4": [ { "comment_text": "", "digests": { "md5": "476a4c9f3623777fb53038df8ae60c4b", "sha256": "b933b9c38e1e07ed74e5986158d988dc45240fa279d301e7cd0158ca2ac95515" }, "downloads": -1, "filename": "medimage-1.0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "476a4c9f3623777fb53038df8ae60c4b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 23729, "upload_time": "2019-09-24T15:39:41", "url": "https://files.pythonhosted.org/packages/94/4f/68fc348e2ea2f68c71192d88febcd1a65c435ad03f68900774d65b1c405c/medimage-1.0.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f9c9b144a2f7e95413ce0be0b90c65c8", "sha256": "d4ab166500ea5e7107a244d34aad357d960c987bbcd380fcfcd3a9087c00fb74" }, "downloads": -1, "filename": "medimage-1.0.4.tar.gz", "has_sig": false, "md5_digest": "f9c9b144a2f7e95413ce0be0b90c65c8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18693, "upload_time": "2019-09-24T15:39:42", "url": "https://files.pythonhosted.org/packages/9e/f9/00aae0107bab3dac0d7f5359fcb77d307054ee9f1713c97b41e70583d0a2/medimage-1.0.4.tar.gz" } ], "1.0.5": [ { "comment_text": "", "digests": { "md5": "9e757785792f3d93eb097c242dcfbc20", "sha256": "80027eb05c7358d7a05663072db5ba248a48b578144f1c13dc4528c1bab16596" }, "downloads": -1, "filename": "medimage-1.0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "9e757785792f3d93eb097c242dcfbc20", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 23893, "upload_time": "2019-10-08T14:45:29", "url": "https://files.pythonhosted.org/packages/e0/c1/3844c959248dd65f3057a788cca2ffa04da7366f8b2b369ebc3fe7eabd2f/medimage-1.0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f687bf3fe6a3c60302dd7195e9250f35", "sha256": "48cccf16f5b5cd26096ee79cf8c9941f5654d9f66de9a9d1eca6eb18e5e68db3" }, "downloads": -1, "filename": "medimage-1.0.5.tar.gz", "has_sig": false, "md5_digest": "f687bf3fe6a3c60302dd7195e9250f35", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18851, "upload_time": "2019-10-08T14:45:31", "url": "https://files.pythonhosted.org/packages/00/cd/fef994e69cdd205c704f756e8244bc56b51388fcb0fa64681c63705b47e9/medimage-1.0.5.tar.gz" } ], "1.0.6": [ { "comment_text": "", "digests": { "md5": "cd9a3c54229a7f670729ce6b6e1ad527", "sha256": "c1430bcdc1ad6c463f7daacef745a47aa1fb774b405e269c6d985cdc24bbe443" }, "downloads": -1, "filename": "medimage-1.0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "cd9a3c54229a7f670729ce6b6e1ad527", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 23882, "upload_time": "2019-10-11T11:10:19", "url": "https://files.pythonhosted.org/packages/46/d9/2cd5dfae0e248bc23c239685142fcdf9175dc4c1cd3c77a4f6f668e242bb/medimage-1.0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "38b3bd57038127c1ac73b79405de2b21", "sha256": "812813fab693909945fcce515d8fe49631106760cd96c2076d4d22c54b9961b1" }, "downloads": -1, "filename": "medimage-1.0.6.tar.gz", "has_sig": false, "md5_digest": "38b3bd57038127c1ac73b79405de2b21", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18820, "upload_time": "2019-10-11T11:10:20", "url": "https://files.pythonhosted.org/packages/c7/38/0a0ec907e469fb0eb817197da3013f2121231006c739e54d9801afefff55/medimage-1.0.6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "cd9a3c54229a7f670729ce6b6e1ad527", "sha256": "c1430bcdc1ad6c463f7daacef745a47aa1fb774b405e269c6d985cdc24bbe443" }, "downloads": -1, "filename": "medimage-1.0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "cd9a3c54229a7f670729ce6b6e1ad527", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 23882, "upload_time": "2019-10-11T11:10:19", "url": "https://files.pythonhosted.org/packages/46/d9/2cd5dfae0e248bc23c239685142fcdf9175dc4c1cd3c77a4f6f668e242bb/medimage-1.0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "38b3bd57038127c1ac73b79405de2b21", "sha256": "812813fab693909945fcce515d8fe49631106760cd96c2076d4d22c54b9961b1" }, "downloads": -1, "filename": "medimage-1.0.6.tar.gz", "has_sig": false, "md5_digest": "38b3bd57038127c1ac73b79405de2b21", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18820, "upload_time": "2019-10-11T11:10:20", "url": "https://files.pythonhosted.org/packages/c7/38/0a0ec907e469fb0eb817197da3013f2121231006c739e54d9801afefff55/medimage-1.0.6.tar.gz" } ] }