Skip to content

Commit 67a2550

Browse files
committed
Add dicom converter
1 parent fcbe3e5 commit 67a2550

File tree

9 files changed

+77
-24
lines changed

9 files changed

+77
-24
lines changed

docs/source/superannotate.sdk.rst

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,17 @@ ________________________
334334
.. _ref_filter_annotation_instances:
335335
.. autofunction:: superannotate.filter_annotation_instances
336336

337+
----------
338+
337339
Aggregating class distribution from annotations
338340
_____________________________________________________________
339341

340342
.. autofunction:: superannotate.class_distribution
341-
.. autofunction:: superannotate.attribute_distribution
343+
.. autofunction:: superannotate.attribute_distribution
344+
345+
----------
346+
347+
Utility functions
348+
--------------------------------
349+
350+
.. autofunction:: superannotate.dicom_to_rgb_sequence

docs/source/tutorial.sdk.rst

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,3 +415,36 @@ Similarly aggregation of class attributes across multiple projects can be obtain
415415
Here pandas DataFrame with columns identifying attribute and corresponding instance count is returned. Within visualized histogram attributes of the same class are grouped by color and sorted accordingly.
416416

417417
.. image:: attribute_distribution.png
418+
419+
----------
420+
421+
422+
Working with DICOM files
423+
_______________________________________________________
424+
425+
426+
To convert DICOM file images to JPEG images:
427+
428+
429+
.. code-block:: python
430+
431+
df = sa.dicom_to_rgb_sequence("<path_to_dicom_file>", "<path_to_output_dir>")
432+
433+
JPEG images with names :file:`<dicom_file_name>_<frame_num>.jpg` will be created
434+
in :file:`<path_to_output_dir>`. Those JPEG images can be uploaded to
435+
SuperAnnotate platform using the regular:
436+
437+
.. code-block:: python
438+
439+
sa.upload_images_from_folder_to_project(project, "<path_to_output_dir>")
440+
441+
Some DICOM files can have image frames that are compressed. To load them, `GDCM :
442+
Grassroots DICOM library <http://gdcm.sourceforge.net/wiki/index.php/Main_Page>`_ needs to be installed:
443+
444+
.. code-block:: bash
445+
446+
# using conda
447+
conda install -c conda-forge gdcm
448+
449+
# or on Ubuntu with versions above 19.04
450+
sudo apt install python3-gdcm

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
Version = f.read()
1616

1717
Version = Version.rstrip()
18-
Version = Version[11:-1]
18+
Version = Version[15:-1]
1919

2020
setup(
2121
name='superannotate',

superannotate/__init__.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
import_annotation_format
6464
)
6565
from .instance_filtering import filter_annotation_instances
66-
from .version import Version
66+
from .version import __version__
6767

6868
formatter = logging.Formatter(fmt='SA-PYTHON-SDK - %(levelname)s - %(message)s')
6969
#formatter = logging.Formatter(fmt='%(asctime)s - %(levelname)s - %(module)s - %(message)s')
@@ -79,23 +79,23 @@
7979
def _check_version():
8080
_req = requests.get('https://pypi.python.org/pypi/superannotate/json')
8181
if _req.ok:
82-
_Version = packaging.version.parse(Version)
82+
_version = packaging.version.parse(__version__)
8383
_version_on_pip = packaging.version.parse('0')
8484
_j = _req.json()
8585
_releases = _j.get('releases', [])
8686
for _release in _releases:
8787
_ver = packaging.version.parse(_release)
8888
if not _ver.is_prerelease:
8989
_version_on_pip = max(_version_on_pip, _ver)
90-
if _version_on_pip.major > _Version.major:
90+
if _version_on_pip.major > _version.major:
9191
logger.warning(
9292
"There is a major upgrade of SuperAnnotate Python SDK available on PyPI. We recommend upgrading. Run 'pip install --upgrade superannotate' to upgrade from your version %s to %s.",
93-
_Version, _version_on_pip
93+
_version, _version_on_pip
9494
)
95-
elif _version_on_pip > _Version:
95+
elif _version_on_pip > _version:
9696
logger.info(
9797
"There is a newer version of SuperAnnotate Python SDK available on PyPI. Run 'pip install --upgrade superannotate' to upgrade from your version %s to %s.",
98-
_Version, _version_on_pip
98+
_version, _version_on_pip
9999
)
100100

101101

superannotate/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def main():
5050
elif command == "export-project":
5151
export_project(further_args)
5252
elif command == "version":
53-
print(f"SuperAnnotate Python SDK version {sa.Version}")
53+
print(f"SuperAnnotate Python SDK version {sa.__version__}")
5454
else:
5555
raise SABaseException(0, "Wrong command to superannotate CLI")
5656

superannotate/api.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import urllib3
99

1010
from .exceptions import SABaseException
11-
from .version import Version
11+
from .version import __version__
1212

1313
logger = logging.getLogger("superannotate-python-sdk")
1414

@@ -48,26 +48,26 @@ def init(self, config_location=None):
4848
try:
4949
self._token = self._api_config["token"]
5050
except KeyError:
51-
logger.error(
52-
"'token' key is not present in the config file %s.",
53-
str(config_location)
51+
raise SABaseException(
52+
0,
53+
"Incorrect config file: 'token' key is not present in the config file "
54+
+ str(config_location)
5455
)
55-
raise SABaseException(0, "Incorrect config file.")
5656
try:
5757
self.team_id = int(self._token.split("=")[1])
5858
except Exception:
59-
logger.error(
60-
"token key is not valid in the config file %s.",
61-
str(config_location)
59+
raise SABaseException(
60+
0,
61+
"Incorrect config file: 'token' key is not valid in the config file "
62+
+ str(config_location)
6263
)
63-
raise SABaseException(0, "Incorrect config file.")
6464

6565
self._default_headers = {'Authorization': self._token}
6666
self._default_headers["authtype"] = "sdk"
6767
if "authtype" in self._api_config:
6868
self._default_headers["authtype"] = self._api_config["authtype"]
6969
self._default_headers['User-Agent'] = requests_toolbelt.user_agent(
70-
'superannotate', Version
70+
'superannotate', __version__
7171
)
7272

7373
self._main_endpoint = "https://api.annotate.online"

superannotate/dicom_converter.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,36 @@ def dicom_to_rgb_sequence(
1515
:type input_dicom_file: str or Pathlike
1616
:param output_dir: path to output directory
1717
:type output_dir: str or Pathlike
18+
:param output_image_quality: output JPEG quality setting in percents
19+
:type output_image_quality: int
20+
21+
:return: paths to output images
22+
:rtype: list of strs
1823
1924
"""
25+
input_dicom_file = Path(input_dicom_file)
2026
ds = pydicom.dcmread(str(input_dicom_file))
2127
# interp = ds.PhotometricInterpretation
2228
# print(interp)
2329

24-
input_dicom_file = Path(input_dicom_file)
25-
output_dir = Path(output_dir)
2630
arr = ds.pixel_array
2731
if "NumberOfFrames" in ds:
2832
number_of_frames = ds.NumberOfFrames
2933
else:
3034
number_of_frames = 1
3135
arr = arr[np.newaxis, :]
3236
# print(arr.shape)
37+
output_dir = Path(output_dir)
38+
output_paths = []
3339
for i in range(number_of_frames):
3440
image = Image.fromarray(arr[i])
3541
image = image.convert("RGB")
42+
path = output_dir / (input_dicom_file.stem + f"_{i:05}.jpg")
3643
image.save(
37-
output_dir / (input_dicom_file.stem + f"_{i:05}.jpg"),
44+
path,
3845
subsampling=0 if output_image_quality > 80 else 2,
3946
quality=output_image_quality
4047
)
48+
output_paths.append(str(path))
49+
50+
return output_paths

superannotate/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Version = "2.1.1"
1+
__version__ = "2.1.2"

tests/test_dicom.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55

66
def test_dicom_convesion(tmpdir):
7-
sa.dicom_to_rgb_sequence(
7+
paths = sa.dicom_to_rgb_sequence(
88
pydicom.data.get_testdata_file("CT_small.dcm"), tmpdir
99
)
10+
assert len(paths) == 1

0 commit comments

Comments
 (0)