0

I have a dicom 3D image which is [512,512,5] (rows, cols, slices). I want to read it with DCMTK toolkit and convert it to a OpenCV Mat object. The image is 16 bits unsigned int.

My question is: Does anyone know the correct way to convert this dicom image into a Mat object? How to properly read all the slices with the method getOutputData?

rvimieiro
  • 1,043
  • 1
  • 10
  • 17
  • `getOutputData(16)` will return the data for frame `0` only. There is no method in `DicomImage` to get all the images in a single buffer. – Alan Birtles Jan 09 '20 at 15:45
  • I guess you'll have to retrieve the frames one at a time and somehow feed them into openCV, I'm not familiar with openCV I'm afraid – Alan Birtles Jan 09 '20 at 16:53
  • `getOutputData(16, 1)` returns the second frame, see the [reference](https://support.dcmtk.org/docs/classDicomImage.html#ac1b5118cbae9e797aa55940fcd60258e) – Alan Birtles Jan 09 '20 at 17:02

1 Answers1

2

Based on the comments of @Alan Birtles, there is the possibility to specify the frame you want to read on the getOutputData method. After reading each frame, you simply merge the Mat objects into a single Mat.

I wrote this code to get the whole volume:

DicomImage *image = new DicomImage(file);

// Get the information
unsigned int nRows = image->getHeight();
unsigned int nCols = image->getWidth();
unsigned int nImgs = image->getFrameCount();

vector <Mat> slices(nImgs);

// Loop for each slice
for(int k = 0; k<nImgs; k++){

    (Uint16 *) pixelData = (Uint16 *)(image->getOutputData(16 /* bits */,k /* slice */));

    slices[k] = Mat(nRows, nCols, CV_16U, pixelData).clone();

}

Mat img;

// Merge the slices in a single img
merge(slices,img);

cout << img.size() << endl;
cout << img.channels() << endl;

// Output:
// [512 x 512]
// 5
rvimieiro
  • 1,043
  • 1
  • 10
  • 17
  • I'd be surprised if this works as the pointer returned from `getOutputData` is only valid until the next call to `getOutputData` and I don't think `Mat` is copying the passed in data. Also why do you treat slice 0 separately? Can't you just change your for loop to `for(int k = 0`? – Alan Birtles Jan 10 '20 at 10:43
  • The documentation doesn't mention that it copies: https://docs.opencv.org/trunk/d3/d63/classcv_1_1Mat.html#a51615ebf17a64c968df0bf49b4de6a3a – Alan Birtles Jan 10 '20 at 12:56