dicom 0.9.6 → 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,80 +1,80 @@
1
- module DICOM
2
-
3
- # This module is the general interface between the ImageItem class and the
4
- # image methods found in the specific image processor modules.
5
- #
6
- module ImageProcessor
7
-
8
- # Creates image objects from one or more compressed, binary string blobs.
9
- #
10
- # @param [Array<String>, String] blobs binary string blob(s) containing compressed pixel data
11
- # @return [Array<MagickImage>, FalseClass] - an array of images, or false (if decompression failed)
12
- #
13
- def decompress(blobs)
14
- raise ArgumentError, "Expected Array or String, got #{blobs.class}." unless [String, Array].include?(blobs.class)
15
- blobs = [blobs] unless blobs.is_a?(Array)
16
- begin
17
- return image_module.decompress(blobs)
18
- rescue
19
- return false
20
- end
21
- end
22
-
23
- # Extracts an array of pixels (integers) from an image object.
24
- #
25
- # @param [MagickImage] image a Magick image object
26
- # @param [String] photometry a code describing the photometry of the pixel data (e.g. 'MONOCHROME1' or 'COLOR')
27
- # @return [Array<Integer>] an array of pixel values
28
- #
29
- def export_pixels(image, photometry)
30
- raise ArgumentError, "Expected String, got #{photometry.class}." unless photometry.is_a?(String)
31
- image_module.export_pixels(image, photometry)
32
- end
33
-
34
- # Creates an image object from a binary string blob.
35
- #
36
- # @param [String] blob binary string blob containing pixel data
37
- # @param [Integer] columns the number of columns
38
- # @param [Integer] rows the number of rows
39
- # @param [Integer] depth the bit depth of the encoded pixel data
40
- # @param [String] photometry a code describing the photometry of the pixel data (e.g. 'MONOCHROME1' or 'COLOR')
41
- # @return [MagickImage] a Magick image object
42
- #
43
- def import_pixels(blob, columns, rows, depth, photometry)
44
- raise ArgumentError, "Expected String, got #{blob.class}." unless blob.is_a?(String)
45
- image_module.import_pixels(blob, columns, rows, depth, photometry)
46
- end
47
-
48
- # Gives an array containing the image objects that are supported by the image processor.
49
- #
50
- # @return [Array<String>] the valid image classes
51
- #
52
- def valid_image_objects
53
- return ['Magick::Image', 'MiniMagick::Image']
54
- end
55
-
56
-
57
- private
58
-
59
-
60
- # Gives the specific image processor module corresponding to the specified
61
- # image_processor module option.
62
- #
63
- # @raise [RuntimeError] if an unknown image processor is specified
64
- # @return [DcmMiniMagick, DcmRMagick] the image processor module to be used
65
- #
66
- def image_module
67
- case DICOM.image_processor
68
- when :mini_magick
69
- require 'mini_magick'
70
- DcmMiniMagick
71
- when :rmagick
72
- require 'rmagick'
73
- DcmRMagick
74
- else
75
- raise "Uknown image processor #{DICOM.image_processor}"
76
- end
77
- end
78
-
79
- end
1
+ module DICOM
2
+
3
+ # This module is the general interface between the ImageItem class and the
4
+ # image methods found in the specific image processor modules.
5
+ #
6
+ module ImageProcessor
7
+
8
+ # Creates image objects from one or more compressed, binary string blobs.
9
+ #
10
+ # @param [Array<String>, String] blobs binary string blob(s) containing compressed pixel data
11
+ # @return [Array<MagickImage>, FalseClass] - an array of images, or false (if decompression failed)
12
+ #
13
+ def decompress(blobs)
14
+ raise ArgumentError, "Expected Array or String, got #{blobs.class}." unless [String, Array].include?(blobs.class)
15
+ blobs = [blobs] unless blobs.is_a?(Array)
16
+ begin
17
+ return image_module.decompress(blobs)
18
+ rescue
19
+ return false
20
+ end
21
+ end
22
+
23
+ # Extracts an array of pixels (integers) from an image object.
24
+ #
25
+ # @param [MagickImage] image a Magick image object
26
+ # @param [String] photometry a code describing the photometry of the pixel data (e.g. 'MONOCHROME1' or 'COLOR')
27
+ # @return [Array<Integer>] an array of pixel values
28
+ #
29
+ def export_pixels(image, photometry)
30
+ raise ArgumentError, "Expected String, got #{photometry.class}." unless photometry.is_a?(String)
31
+ image_module.export_pixels(image, photometry)
32
+ end
33
+
34
+ # Creates an image object from a binary string blob.
35
+ #
36
+ # @param [String] blob binary string blob containing pixel data
37
+ # @param [Integer] columns the number of columns
38
+ # @param [Integer] rows the number of rows
39
+ # @param [Integer] depth the bit depth of the encoded pixel data
40
+ # @param [String] photometry a code describing the photometry of the pixel data (e.g. 'MONOCHROME1' or 'COLOR')
41
+ # @return [MagickImage] a Magick image object
42
+ #
43
+ def import_pixels(blob, columns, rows, depth, photometry)
44
+ raise ArgumentError, "Expected String, got #{blob.class}." unless blob.is_a?(String)
45
+ image_module.import_pixels(blob, columns, rows, depth, photometry)
46
+ end
47
+
48
+ # Gives an array containing the image objects that are supported by the image processor.
49
+ #
50
+ # @return [Array<String>] the valid image classes
51
+ #
52
+ def valid_image_objects
53
+ return ['Magick::Image', 'MiniMagick::Image']
54
+ end
55
+
56
+
57
+ private
58
+
59
+
60
+ # Gives the specific image processor module corresponding to the specified
61
+ # image_processor module option.
62
+ #
63
+ # @raise [RuntimeError] if an unknown image processor is specified
64
+ # @return [DcmMiniMagick, DcmRMagick] the image processor module to be used
65
+ #
66
+ def image_module
67
+ case DICOM.image_processor
68
+ when :mini_magick
69
+ require 'mini_magick'
70
+ DcmMiniMagick
71
+ when :rmagick
72
+ require 'rmagick'
73
+ DcmRMagick
74
+ else
75
+ raise "Uknown image processor #{DICOM.image_processor}"
76
+ end
77
+ end
78
+
79
+ end
80
80
  end
@@ -1,72 +1,72 @@
1
- module DICOM
2
- module ImageProcessor
3
-
4
- # This module contains methods for interacting with pixel data using the mini_magick gem.
5
- #
6
- module DcmMiniMagick
7
-
8
- class << self
9
-
10
- # Creates image objects from an array of compressed, binary string blobs.
11
- #
12
- # @param [Array<String>] blobs an array of binary string blobs containing compressed pixel data
13
- # @return [Array<MiniMagick::Image>, FalseClass] - an array of images, or false (if decompression failed)
14
- #
15
- def decompress(blobs)
16
- images = Array.new
17
- # We attempt to decompress the pixels using ImageMagick:
18
- blobs.each do |string|
19
- images << MiniMagick::Image.read(string)
20
- end
21
- return images
22
- end
23
-
24
- # Extracts an array of pixels (integers) from an image object.
25
- #
26
- # @note This feature is not available as of yet in the mini_magick image processor.
27
- # If this feature is needed, please try another image processor (RMagick).
28
- #
29
- # @param [MiniMagick::Image] image a mini_magick image object
30
- # @param [String] photometry a code describing the photometry of the pixel data (e.g. 'MONOCHROME1' or 'COLOR')
31
- # @return [Array<Integer>] an array of pixel values
32
- #
33
- def export_pixels(image, photometry)
34
- raise ArgumentError, "Expected MiniMagick::Image, got #{image.class}." unless image.is_a?(MiniMagick::Image)
35
- raise "Exporting pixels is not yet available with the mini_magick processor. Please try another image processor (RMagick)."
36
- end
37
-
38
- # Creates an image object from a binary string blob.
39
- #
40
- # @param [String] blob binary string blob containing pixel data
41
- # @param [Integer] columns the number of columns
42
- # @param [Integer] rows the number of rows
43
- # @param [Integer] depth the bit depth of the encoded pixel data
44
- # @param [String] photometry a code describing the photometry of the pixel data (e.g. 'MONOCHROME1' or 'COLOR')
45
- # @param [String] format the image format to use
46
- # @return [Magick::Image] a mini_magick image object
47
- #
48
- def import_pixels(blob, columns, rows, depth, photometry, format='png')
49
- image = MiniMagick::Image.import_pixels(blob, columns, rows, depth, im_map(photometry), format)
50
- end
51
-
52
- # Converts a given DICOM photometry string to a mini_magick pixel map string.
53
- #
54
- # @param [String] photometry a code describing the photometry of the pixel data (e.g. 'MONOCHROME1' or 'COLOR')
55
- # @return [String] a mini_magick pixel map string
56
- #
57
- def im_map(photometry)
58
- raise ArgumentError, "Expected String, got #{photometry.class}." unless photometry.is_a?(String)
59
- if photometry.include?('COLOR') or photometry.include?('RGB')
60
- return 'rgb'
61
- elsif photometry.include?('YBR')
62
- return 'ybr'
63
- else
64
- return 'gray' # (Assuming monochromeX - greyscale)
65
- end
66
- end
67
-
68
- end
69
-
70
- end
71
- end
1
+ module DICOM
2
+ module ImageProcessor
3
+
4
+ # This module contains methods for interacting with pixel data using the mini_magick gem.
5
+ #
6
+ module DcmMiniMagick
7
+
8
+ class << self
9
+
10
+ # Creates image objects from an array of compressed, binary string blobs.
11
+ #
12
+ # @param [Array<String>] blobs an array of binary string blobs containing compressed pixel data
13
+ # @return [Array<MiniMagick::Image>, FalseClass] - an array of images, or false (if decompression failed)
14
+ #
15
+ def decompress(blobs)
16
+ images = Array.new
17
+ # We attempt to decompress the pixels using ImageMagick:
18
+ blobs.each do |string|
19
+ images << MiniMagick::Image.read(string)
20
+ end
21
+ return images
22
+ end
23
+
24
+ # Extracts an array of pixels (integers) from an image object.
25
+ #
26
+ # @note This feature is not available as of yet in the mini_magick image processor.
27
+ # If this feature is needed, please try another image processor (RMagick).
28
+ #
29
+ # @param [MiniMagick::Image] image a mini_magick image object
30
+ # @param [String] photometry a code describing the photometry of the pixel data (e.g. 'MONOCHROME1' or 'COLOR')
31
+ # @return [Array<Integer>] an array of pixel values
32
+ #
33
+ def export_pixels(image, photometry)
34
+ raise ArgumentError, "Expected MiniMagick::Image, got #{image.class}." unless image.is_a?(MiniMagick::Image)
35
+ raise "Exporting pixels is not yet available with the mini_magick processor. Please try another image processor (RMagick)."
36
+ end
37
+
38
+ # Creates an image object from a binary string blob.
39
+ #
40
+ # @param [String] blob binary string blob containing pixel data
41
+ # @param [Integer] columns the number of columns
42
+ # @param [Integer] rows the number of rows
43
+ # @param [Integer] depth the bit depth of the encoded pixel data
44
+ # @param [String] photometry a code describing the photometry of the pixel data (e.g. 'MONOCHROME1' or 'COLOR')
45
+ # @param [String] format the image format to use
46
+ # @return [Magick::Image] a mini_magick image object
47
+ #
48
+ def import_pixels(blob, columns, rows, depth, photometry, format='png')
49
+ image = MiniMagick::Image.import_pixels(blob, columns, rows, depth, im_map(photometry), format)
50
+ end
51
+
52
+ # Converts a given DICOM photometry string to a mini_magick pixel map string.
53
+ #
54
+ # @param [String] photometry a code describing the photometry of the pixel data (e.g. 'MONOCHROME1' or 'COLOR')
55
+ # @return [String] a mini_magick pixel map string
56
+ #
57
+ def im_map(photometry)
58
+ raise ArgumentError, "Expected String, got #{photometry.class}." unless photometry.is_a?(String)
59
+ if photometry.include?('COLOR') or photometry.include?('RGB')
60
+ return 'rgb'
61
+ elsif photometry.include?('YBR')
62
+ return 'ybr'
63
+ else
64
+ return 'gray' # (Assuming monochromeX - greyscale)
65
+ end
66
+ end
67
+
68
+ end
69
+
70
+ end
71
+ end
72
72
  end
@@ -1,107 +1,107 @@
1
- module DICOM
2
- module ImageProcessor
3
-
4
- # This module contains methods for interacting with pixel data using the RMagick gem.
5
- #
6
- module DcmRMagick
7
-
8
- class << self
9
-
10
- # Creates image objects from an array of compressed, binary string blobs.
11
- #
12
- # === Note
13
- #
14
- # The method tries to use RMagick for unpacking, but unortunately, it seems that
15
- # ImageMagick is not able to handle most of the compressed image variants used in the DICOM
16
- # standard. To get a more robust implementation which is able to handle most types of
17
- # compressed DICOM files, something else is needed.
18
- #
19
- # Probably a good candidate to use is the PVRG-JPEG library, which seems to be able to handle
20
- # everything that is jpeg. It exists in the Ubuntu repositories, where it can be installed and
21
- # run through terminal. For source code, and some additional information, check out this link:
22
- # http://www.panix.com/~eli/jpeg/
23
- #
24
- # Another idea would be to study how other open source libraries, like GDCM handle these files.
25
- #
26
- # @param [Array<String>] blobs an array of binary string blobs containing compressed pixel data
27
- # @return [Array<Magick::Image>, FalseClass] - an array of images, or false (if decompression failed)
28
- #
29
- def decompress(blobs)
30
- # FIXME:
31
- # The following transfer syntaxes have been verified as failing with ImageMagick:
32
- # TXS_JPEG_LOSSLESS_NH is not supported by (my) ImageMagick version: "Unsupported JPEG process: SOF type 0xc3"
33
- # TXS_JPEG_LOSSLESS_NH_FOP is not supported by (my) ImageMagick version: "Unsupported JPEG process: SOF type 0xc3"
34
- # TXS_JPEG_2000_PART1_LOSSLESS is not supported by (my) ImageMagick version: "jpc_dec_decodepkts failed"
35
- #
36
- images = Array.new
37
- # We attempt to decompress the pixels using ImageMagick:
38
- blobs.each do |string|
39
- images << Magick::Image.from_blob(string).first
40
- end
41
- return images
42
- end
43
-
44
- # Extracts an array of pixels (integers) from an image object.
45
- #
46
- # @param [Magick::Image] image an RMagick image object
47
- # @param [String] photometry a code describing the photometry of the pixel data (e.g. 'MONOCHROME1' or 'COLOR')
48
- # @return [Array<Integer>] an array of pixel values
49
- #
50
- def export_pixels(image, photometry)
51
- raise ArgumentError, "Expected Magick::Image, got #{image.class}." unless image.is_a?(Magick::Image)
52
- pixels = image.export_pixels(0, 0, image.columns, image.rows, rm_map(photometry))
53
- return pixels
54
- end
55
-
56
- # Creates an image object from a binary string blob.
57
- #
58
- # @param [String] blob binary string blob containing pixel data
59
- # @param [Integer] columns the number of columns
60
- # @param [Integer] rows the number of rows
61
- # @param [Integer] depth the bit depth of the encoded pixel data
62
- # @param [String] photometry a code describing the photometry of the pixel data (e.g. 'MONOCHROME1' or 'COLOR')
63
- # @param [String] format the image format to use
64
- # @return [Magick::Image] an RMagick image object
65
- #
66
- def import_pixels(blob, columns, rows, depth, photometry, format='png')
67
- image = Magick::Image.new(columns,rows).import_pixels(0, 0, columns, rows, rm_map(photometry), blob, rm_data_type(depth))
68
- end
69
-
70
- # Converts a given bit depth to an RMagick StorageType.
71
- #
72
- # @raise [ArgumentError] if given an unsupported bit depth
73
- # @param [Integer] bit_depth the bit depth of the pixel data
74
- # @return [Magick::CharPixel, Magick::ShortPixel] the proper storage type
75
- #
76
- def rm_data_type(bit_depth)
77
- return case bit_depth
78
- when 8
79
- Magick::CharPixel
80
- when 16
81
- Magick::ShortPixel
82
- else
83
- raise ArgumentError, "Unsupported bit depth: #{bit_depth}."
84
- end
85
- end
86
-
87
- # Converts a given DICOM photometry string to an RMagick pixel map string.
88
- #
89
- # @param [String] photometry a code describing the photometry of the pixel data (e.g. 'MONOCHROME1' or 'COLOR')
90
- # @return [String] an RMagick pixel map string
91
- #
92
- def rm_map(photometry)
93
- raise ArgumentError, "Expected String, got #{photometry.class}." unless photometry.is_a?(String)
94
- if photometry.include?('COLOR') or photometry.include?('RGB')
95
- return 'RGB'
96
- elsif photometry.include?('YBR')
97
- return 'YBR'
98
- else
99
- return 'I' # (Assuming monochromeX - greyscale)
100
- end
101
- end
102
-
103
- end
104
-
105
- end
106
- end
1
+ module DICOM
2
+ module ImageProcessor
3
+
4
+ # This module contains methods for interacting with pixel data using the RMagick gem.
5
+ #
6
+ module DcmRMagick
7
+
8
+ class << self
9
+
10
+ # Creates image objects from an array of compressed, binary string blobs.
11
+ #
12
+ # === Note
13
+ #
14
+ # The method tries to use RMagick for unpacking, but unortunately, it seems that
15
+ # ImageMagick is not able to handle most of the compressed image variants used in the DICOM
16
+ # standard. To get a more robust implementation which is able to handle most types of
17
+ # compressed DICOM files, something else is needed.
18
+ #
19
+ # Probably a good candidate to use is the PVRG-JPEG library, which seems to be able to handle
20
+ # everything that is jpeg. It exists in the Ubuntu repositories, where it can be installed and
21
+ # run through terminal. For source code, and some additional information, check out this link:
22
+ # http://www.panix.com/~eli/jpeg/
23
+ #
24
+ # Another idea would be to study how other open source libraries, like GDCM handle these files.
25
+ #
26
+ # @param [Array<String>] blobs an array of binary string blobs containing compressed pixel data
27
+ # @return [Array<Magick::Image>, FalseClass] - an array of images, or false (if decompression failed)
28
+ #
29
+ def decompress(blobs)
30
+ # FIXME:
31
+ # The following transfer syntaxes have been verified as failing with ImageMagick:
32
+ # TXS_JPEG_LOSSLESS_NH is not supported by (my) ImageMagick version: "Unsupported JPEG process: SOF type 0xc3"
33
+ # TXS_JPEG_LOSSLESS_NH_FOP is not supported by (my) ImageMagick version: "Unsupported JPEG process: SOF type 0xc3"
34
+ # TXS_JPEG_2000_PART1_LOSSLESS is not supported by (my) ImageMagick version: "jpc_dec_decodepkts failed"
35
+ #
36
+ images = Array.new
37
+ # We attempt to decompress the pixels using ImageMagick:
38
+ blobs.each do |string|
39
+ images << Magick::Image.from_blob(string).first
40
+ end
41
+ return images
42
+ end
43
+
44
+ # Extracts an array of pixels (integers) from an image object.
45
+ #
46
+ # @param [Magick::Image] image an RMagick image object
47
+ # @param [String] photometry a code describing the photometry of the pixel data (e.g. 'MONOCHROME1' or 'COLOR')
48
+ # @return [Array<Integer>] an array of pixel values
49
+ #
50
+ def export_pixels(image, photometry)
51
+ raise ArgumentError, "Expected Magick::Image, got #{image.class}." unless image.is_a?(Magick::Image)
52
+ pixels = image.export_pixels(0, 0, image.columns, image.rows, rm_map(photometry))
53
+ return pixels
54
+ end
55
+
56
+ # Creates an image object from a binary string blob.
57
+ #
58
+ # @param [String] blob binary string blob containing pixel data
59
+ # @param [Integer] columns the number of columns
60
+ # @param [Integer] rows the number of rows
61
+ # @param [Integer] depth the bit depth of the encoded pixel data
62
+ # @param [String] photometry a code describing the photometry of the pixel data (e.g. 'MONOCHROME1' or 'COLOR')
63
+ # @param [String] format the image format to use
64
+ # @return [Magick::Image] an RMagick image object
65
+ #
66
+ def import_pixels(blob, columns, rows, depth, photometry, format='png')
67
+ image = Magick::Image.new(columns,rows).import_pixels(0, 0, columns, rows, rm_map(photometry), blob, rm_data_type(depth))
68
+ end
69
+
70
+ # Converts a given bit depth to an RMagick StorageType.
71
+ #
72
+ # @raise [ArgumentError] if given an unsupported bit depth
73
+ # @param [Integer] bit_depth the bit depth of the pixel data
74
+ # @return [Magick::CharPixel, Magick::ShortPixel] the proper storage type
75
+ #
76
+ def rm_data_type(bit_depth)
77
+ return case bit_depth
78
+ when 8
79
+ Magick::CharPixel
80
+ when 16
81
+ Magick::ShortPixel
82
+ else
83
+ raise ArgumentError, "Unsupported bit depth: #{bit_depth}."
84
+ end
85
+ end
86
+
87
+ # Converts a given DICOM photometry string to an RMagick pixel map string.
88
+ #
89
+ # @param [String] photometry a code describing the photometry of the pixel data (e.g. 'MONOCHROME1' or 'COLOR')
90
+ # @return [String] an RMagick pixel map string
91
+ #
92
+ def rm_map(photometry)
93
+ raise ArgumentError, "Expected String, got #{photometry.class}." unless photometry.is_a?(String)
94
+ if photometry.include?('COLOR') or photometry.include?('RGB')
95
+ return 'RGB'
96
+ elsif photometry.include?('YBR')
97
+ return 'YBR'
98
+ else
99
+ return 'I' # (Assuming monochromeX - greyscale)
100
+ end
101
+ end
102
+
103
+ end
104
+
105
+ end
106
+ end
107
107
  end