How to load a DICOM data with DCMTK
Unsolved
General and Desktop
-
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
-
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(); }
-
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.