Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to load a DICOM data with DCMTK
Forum Updated to NodeBB v4.3 + New Features

How to load a DICOM data with DCMTK

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 2 Posters 435 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    ManiRon28
    wrote on last edited by ManiRon28
    #1

    Is there a way to load DICOM data with DCMTK package

    the below code when tried to load the DICOM its gets crashed

    QImage convertRGBToGrayscale(const QImage &rgbImage) {
        QImage grayscaleImage(rgbImage.size(), QImage::Format_Grayscale8);
        for (int y = 0; y < rgbImage.height(); ++y) {
            for (int x = 0; x < rgbImage.width(); ++x) {
                int gray = qGray(rgbImage.pixel(x, y));
                grayscaleImage.setPixel(x, y, qRgb(gray, gray, gray));
            }
        }
        return grayscaleImage;
    }
    
    void MainWindow::loadDicomImage(const QString &filePath) {
        // Register JPEG decompression codecs
        DJDecoderRegistration::registerCodecs();
    
        DcmFileFormat fileFormat;
        OFCondition status = fileFormat.loadFile(filePath.toStdString().c_str());
    
        if (status.good()) {
            DcmDataset *dataset = fileFormat.getDataset();
            DicomImage image(dataset, EXS_Unknown);
    
            if (image.getStatus() == EIS_Normal) {
                // Check the photometric interpretation
                EP_Interpretation photometric = image.getPhotometricInterpretation();
                if (photometric != EPI_Monochrome1 && photometric != EPI_Monochrome2 && photometric != EPI_RGB) {
                    QMessageBox::critical(this, "Error", "Unsupported Photometric Interpretation (Monochrome or RGB expected)");
                    return;
                }
    
                // Convert DICOM image to QImage
                const DiPixel *pixelData = image.getInterData();
                if (pixelData) {
                    const Uint8 *pixelArray = (const Uint8 *)pixelData->getData();
                    if (pixelArray) {
                        QImage::Format format = QImage::Format_Invalid;
                        if (image.getDepth() == 8) {
                            format = QImage::Format_Grayscale8;
                        } else if (image.getDepth() == 16) {
                            // QImage does not support 16-bit grayscale directly, so we need to convert it
                            std::vector<Uint8> scaledData(image.getWidth() * image.getHeight());
                            for (unsigned long i = 0; i < image.getWidth() * image.getHeight(); ++i) {
                                scaledData[i] = pixelArray[i * 2] >> 8; // Simple scaling from 16-bit to 8-bit
                            }
                            pixelArray = scaledData.data();
                            format = QImage::Format_Grayscale8;
                        } else if (photometric == EPI_RGB) {
                            format = QImage::Format_RGB888;
                        }
    
                        if (format != QImage::Format_Invalid) {
                            QImage qImage(pixelArray, image.getWidth(), image.getHeight(), format);
    
                            // If the image is RGB, convert it to grayscale
                            if (photometric == EPI_RGB) {
                                qImage = convertRGBToGrayscale(qImage);
                            }
    
                            // Display the image in QGraphicsView
                            QGraphicsScene *graphic = new QGraphicsScene(this);
                            graphic->addPixmap(QPixmap::fromImage(qImage));
                            ui->graphicsView->setScene(graphic);
                        } else {
                            QMessageBox::critical(this, "Error", "Unsupported image depth");
                        }
                    } else {
                        QMessageBox::critical(this, "Error", "Failed to retrieve pixel array from DICOM image");
                    }
                } else {
                    QMessageBox::critical(this, "Error", "Failed to retrieve pixel data from DICOM image");
                }
            } else {
                QMessageBox::critical(this, "Error", QString("Cannot load DICOM image (%1)").arg(DicomImage::getString(image.getStatus())));
            }
        } else {
            QMessageBox::critical(this, "Error", QString("Cannot read DICOM file (%1)").arg(status.text()));
        }
    
        // Deregister JPEG decompression codecs
        DJDecoderRegistration::cleanup();
    }
    

    What is wrong here

    1 Reply Last reply
    0
    • M Offline
      M Offline
      ManiRon28
      wrote on last edited by
      #2

      This latest code is partially working as I couldnt see the DICOM properly is there something I am missing

      std::tuple<QImage, int, int> MainWindow::convertToQImage(DicomImage *dicomImageVal) {
          std::tuple<QImage, int, int> data;
      
          data = std::make_tuple(QImage(), 0, 0);
          if (!dicomImageVal || dicomImageVal->getStatus() != EIS_Normal) {
              qWarning("Failed to load DICOM image.");
              return data;
          }
      
          const int width = dicomImageVal->getWidth();
          const int height = dicomImageVal->getHeight();
      
          // Ensure valid dimensions
          if (width <= 0 || height <= 0) {
              qWarning("Invalid DICOM dimensions.");
              return data;
          }
      
          QImage image(width, height, QImage::Format_RGB888);
      
          // Handle monochrome images
          if (dicomImageVal->isMonochrome()) {
              dicomImageVal->setMinMaxWindow(); // Adjust brightness and contrast
              const uchar *pixelData = (uchar *)dicomImageVal->getOutputData(8); // 8 bits per sample
              if (pixelData) {
                  for (int y = 0; y < height; ++y) {
                      for (int x = 0; x < width; ++x) {
                          int value = pixelData[y * width + x];
                          image.setPixelColor(x, y, QColor(value, value, value));
                      }
                  }
              }
          } else {
              // Handle color images (e.g., RGB)
              const uchar *pixelData = (uchar *)dicomImageVal->getOutputData(24); // 24 bits per sample
              if (pixelData) {
                  memcpy(image.bits(), pixelData, width * height * 3); // Copy RGB data directly
              }
          }
          data = std::make_tuple(image, width, height);
          return data;
      }
      
      void MainWindow::loadDicomImage(const QString &filePath)
      {
          // Register JPEG decompression codecs
          DJDecoderRegistration::registerCodecs();
      
          DcmFileFormat fileFormat;
          OFCondition status = fileFormat.loadFile(filePath.toStdString().c_str());
      
          if (status.good()) {
              DicomImage image(filePath.toStdString().c_str(), EXS_Unknown);
      
              std::tuple dataVal = convertToQImage(&image);
              QGraphicsScene *graphic = new QGraphicsScene(this);
              QPixmap pixmap = QPixmap::fromImage(std::get<0>(dataVal));
              graphic->addPixmap(pixmap);
              graphic->setSceneRect(pixmap.rect());
              ui->graphicsView->setScene(graphic);
              ui->graphicsView->fitInView(pixmap.rect(), Qt::KeepAspectRatio);
          } else {
              QMessageBox::critical(this, "Error", QString("Cannot read DICOM file (%1)").arg(status.text()));
          }
      
          // Deregister JPEG decompression codecs
          DJDecoderRegistration::cleanup();
      }
      
      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        First thing, I would simplify the code to handle one known case, for example an RGB image and just show it on a QLabel.

        That said, from memory, DICOM images are pretty tricky and a library such as VTK is often used to handle them with Qt as front end.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        1

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved