3

I'm using DCMTK for a C++ project and want to retrieve pixels from dicom files. I used thid basic example :

          DicomImage *image = new DicomImage("test.dcm");
          if (image != NULL)
          {
           if (image->getStatus() == EIS_Normal)
          {
            if (image->isMonochrome())
                 {
                     image->setMinMaxWindow();
                     Uint8 *pixelData = (Uint8 *)(image->getOutputData(8 /* bits */));
                    if (pixelData != NULL)
                    {
                    /* do something useful with the pixel data */
                    }
                      }
                  } else
           cerr << "Error: cannot load DICOM image (" <<        DicomImage::getString(image->getStatus()) << ")" << endl;
          }
          delete image;

in "do something useful with the pixel data" section , how can I use pixelData variable to get pixels

Youssef Korchi
  • 127
  • 1
  • 4
  • 14

1 Answers1

6

First of all: you already have the pixel data as an array of unsigned chars. You could - for example - transfer them to an 8-bit monochrome bitmap and display them on the screen. The height and width you need to construct the bitmap can be obtained from the DicomImage object

However, it strongly depends on what you consider "something useful" whether getOutputData() is the method of your choice. This is because getOutputData() is acually kind of a rendering method. Assumed, that you have a typical CT, MR or CR image, the grayscale range has alread been rescaled to 8-bit.

You might prefer to extract the pixel data in the full grayscale range and roll your own rendering and processing methods. In this case I would advise you to use getInterData() which returns the internally stored pixel data with the full grayscale range. The Modality LUT has been applied to the intermediate data so what you get is an encapsulation (class DiPixel) of an array of values each of which encodes the grayscale value measured by the device (e.g. Hounsfield Units in case of CT).

DiPixel returns these grayscales as a void pointer. To correctly handle the values, you need to determine their respresentation (e.g. Uint8, Sint16, ...).

Using this approach is obviously more effort, but for anything that goes beyond rendering the pixel data, it is the only approach that preserves the original gray values

Markus Sabin
  • 3,916
  • 14
  • 32
  • Thank you so much for your explanation, I have just one more question , I want to knwo how could I access to an DcmElement , let's say for example I want to get image height with this example : DcmElement element; MyDataset->findAndGetElement(tagOfRows,element); with element variable, I can get tag,VR,VM.. but I don't know how to get the value of element (in this case height ) – Youssef Korchi Jul 08 '16 at 09:22
  • There are type-safe methods to access attribute values in DcmDataset. They are named after the pattern findAndGet, in your case: MyDataset->findAndGetUint16(tagOfRows, &). They do not always behave as expected. findAndGetString works for almost all data types but puts the burden to convert the string to a useful type on you. – Markus Sabin Jul 08 '16 at 10:31
  • @kritzel_sw What do you mean by "They do not always behave as expected."? Since I'm one of the DCMTK developers, I'd be interested in what's unexpected. – J. Riesmeier Jul 08 '16 at 13:37
  • @Joerg: E.g. you can read an attribute with VR_IS to an integer number but you have to write to it as a string. Probably it is also unexpected (at least to me) that trying to read a VR_FL attribute to a double is impossible as well as reading VR_SS to int and so on. When using the DcmItem interface, it suggests you can do all that stuff (and other stuff that really would not make sense) but you get and EC_IllegalCall at runtime when you try. That is why I am using these methods very carefully. – Markus Sabin Jul 08 '16 at 13:55
  • @kritzel_sw Thank you for your comments. So, with "unexpected" you mean "you would have expected that it works" and not that it deviates from the documentation (which should be accurate). What the DcmItem interface provides in terms of findAndGetXX() as well as putAndInsertXX() methods is directly based on the underlying VR classes. I can only suggest to read the documentation of a method before using it. And, if you think the API should be extended in some regard, you are free to provide a patch. Btw, there is an findAndGetLongInt(), which supports the following VRs: IS, OL, SL, SS, UL, US. – J. Riesmeier Jul 08 '16 at 15:05
  • 1
    @Joerg: Sure, as far as I can see, the documentation is correct and helpful in this regard. I am referring to intuitiveness rather than correctness. Modern IDEs with auto-completion may fool you, unless you have the documented limitations in your mind. It was not meant as criticism, just as a hint for a beginner using dcmtk that the findAndGetXXX methods shall be used carefully. – Markus Sabin Jul 11 '16 at 06:07