From afea5d8d88b4ca49e8a9c61c3a74e58ac72e6d1f Mon Sep 17 00:00:00 2001 From: Krad Date: Fri, 4 Mar 2022 13:53:15 +0800 Subject: [PATCH] Replace SeriesInfo_t with ExtendMedicalImageProperties,remove SeriesInfo,DicomTasInfo. Change GetImageFormDcmFile to GetThumbnail, use ExtendMedicalImageProperties as parameter. --- src/src/base/DicomLoader.cpp | 76 ++-------------------------- src/src/base/DicomLoader.h | 13 +++-- src/src/global/QGlobals.h | 74 +-------------------------- src/src/util/QDicomUtility.cpp | 63 +++++++++++++++++++++++ src/src/util/QDicomUtility.h | 58 ++------------------- src/src/view/thumbnailImage.cpp | 13 +++-- src/src/view/thumbnailImage.h | 10 ++-- src/src/view/thumbnailbarwidget.cpp | 56 ++++++-------------- src/src/view/thumbnailbarwidget.h | 3 +- src/src/view/viewcontainerwidget.cpp | 15 ++---- 10 files changed, 108 insertions(+), 273 deletions(-) create mode 100644 src/src/util/QDicomUtility.cpp diff --git a/src/src/base/DicomLoader.cpp b/src/src/base/DicomLoader.cpp index eb641fc..a84ff8f 100644 --- a/src/src/base/DicomLoader.cpp +++ b/src/src/base/DicomLoader.cpp @@ -88,21 +88,6 @@ std::vector* orientationHelper::getOrientationStrList(const std::st return &(it->second); } -void copyDicomTasInfo(DicomTagInfo_t* dicom, ExtendMedicalImageProperties* properties){ - dicom->m_PatientID = properties->GetPatientID(); - dicom->m_PatientName = properties->GetPatientName(); - dicom->m_PatientBirth = properties->GetPatientBirthDate(); - dicom->m_Institution = properties->GetInstitutionName(); - dicom->m_Modality = properties->GetModality(); - dicom->m_SeriesNumber = properties->GetSeriesNumber(); - dicom->m_SeriesDescription = properties->GetSeriesDescription(); - dicom->m_StudyDate = properties->GetStudyDate(); - dicom->m_StudyDescription = properties->GetStudyDescription(); - dicom->m_StudyTime = properties->GetStudyTime(); - char buffer[16]={}; - dicom->m_SliceNumber = itoa(properties->GetFileNames()->size(),buffer,10); -} - DicomLoader* DicomLoader::instance = new DicomLoader(); DicomLoader* DicomLoader::GetInstance() { //lazy man @@ -160,7 +145,7 @@ SeriesImageSet* DicomLoader::getSeriesImageSet(const std::string& uniqueID)//, D } -SeriesInfo_t* DicomLoader::getSerieInfo(const std::string& seriesUnique) +ExtendMedicalImageProperties* DicomLoader::getSerieInfo(const std::string& seriesUnique) { auto idx = seriesUnique.find('_'); std::string patient_name= seriesUnique.substr(0,idx); @@ -217,47 +202,6 @@ void DicomLoader::readTags(const std::string &dir, SeriesOpenMode openMode) } -DicomTagInfo_t* DicomLoader::createDicomTagsInfo() -{ - - DicomTagInfo_t* info = new DicomTagInfo_t(); - - char PatientName[255]; - char StudyDescription[255]; - char Institution[255]; - char StudyDate[255]; - char Modality[255]; - - std::string s_wl; - std::string s_ww; - - info->spacing[0] = currentImageProperty->GetSpacing()[0]; - info->spacing[1] = currentImageProperty->GetSpacing()[1]; - info->spacing[2] = currentImageProperty->GetSliceThicknessAsDouble(); - - info->m_PatientName = currentImageProperty->GetPatientName(); - info->m_StudyDescription = currentImageProperty->GetStudyDescription(); - - info->m_Institution = currentImageProperty->GetInstitutionName(); - - info->m_StudyDate = currentImageProperty->GetStudyDate(); - - info->m_Modality = currentImageProperty->GetModality(); - info->lbl_ser_num = currentImageProperty->GetSeriesNumber(); - info->m_SeriesNumber = currentImageProperty->GetSeriesNumber(); - info->m_SeriesDescription = currentImageProperty->GetSeriesDescription(); - info->m_StudyTime = currentImageProperty->GetStudyTime(); - info->m_PatientBirth = currentImageProperty->GetPatientBirthDate(); - char buffer[16]={0}; - info->m_SliceNumber = itoa(currentImageProperty->GetFileNames()->size(), buffer,10); - - info->m_orientation = ""; - info->WL = currentImageProperty->GetNthWindowLevelPreset(0)[1]; - info->WW = currentImageProperty->GetNthWindowLevelPreset(0)[0]; - return info; -} - - SeriesImageSet* DicomLoader::createSeries(const std::string& uniqueID) { @@ -271,15 +215,9 @@ void DicomLoader::readSeries() { for (ExtendMedicalImageProperties* property: imageProperties){ - std::string unique = ""; std::string patient_name = property->GetPatientName(); std::string study_uid = property->GetStudyUID(); std::string series_uid = property->GetSeriesUID(); - unique.append(patient_name); - unique.append("_"); - unique.append(study_uid); - unique.append("_"); - unique.append(series_uid); //patient level PatientInfo_t* patient = nullptr; //get from store @@ -308,22 +246,16 @@ void DicomLoader::readSeries() { study->study_time = property->GetStudyTime(); study->series = new SeriesMapType(); } - SeriesInfo_t* series = nullptr; if (study->series->count(series_uid)>0){ - series = study->series->at(series_uid); +// series = study->series->at(series_uid); //TODO:need to add override logic!! } else { - series = new SeriesInfo_t(); - study->series->insert({series_uid,series}); - DicomTagInfo_t *dicom = new DicomTagInfo_t; - copyDicomTasInfo(dicom, property); - series->tag_info = dicom; - series->unique_id = unique; + study->series->insert({series_uid,property}); + double *wlww = property->GetNthWindowLevelPreset(0); int ww = wlww ? ((int) wlww[0]) : (512); int wl = wlww ? ((int) wlww[1]) : (256); - series->series_pixmap = GetImageFormDcmFile(property->GetThumbnailFileName(), wl, ww, property->GetSamplePerPixel()); } } diff --git a/src/src/base/DicomLoader.h b/src/src/base/DicomLoader.h index f9c5779..a0fd8fe 100644 --- a/src/src/base/DicomLoader.h +++ b/src/src/base/DicomLoader.h @@ -32,12 +32,11 @@ public: // static void itkReaderEndCallbackFunction(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data); - DicomTagInfo_t* createDicomTagsInfo(); - /** - * 读取数据Tag - * @param dir - * @param openMode - */ + /** + * 读取数据Tag + * @param dir + * @param openMode + */ void readTags(const std::string &dir, SeriesOpenMode openMode); const std::string& getDefaultUniqueID(){ @@ -52,7 +51,7 @@ public: SeriesImageSet* getSeriesImageSet(const std::string& uniqueID); - SeriesInfo_t* getSerieInfo(const std::string& seriesUnique); + ExtendMedicalImageProperties* getSerieInfo(const std::string& seriesUnique); void reset(); private: diff --git a/src/src/global/QGlobals.h b/src/src/global/QGlobals.h index 644031a..83c6694 100644 --- a/src/src/global/QGlobals.h +++ b/src/src/global/QGlobals.h @@ -15,6 +15,7 @@ #include #include +#include "base/ExtendMedicalImageProperties.h" using namespace std; // ����汾 @@ -151,50 +152,6 @@ enum AddDicomType //OVERRIDE_IMAGE }; - - - - -typedef struct DicomTasInfo -{ - int WL; - int WW; - double spacing[3]; - std::string lbl_ser_num; - - std::string m_dicomName; - std::string m_PatientName; - std::string m_PatientID; - std::string m_PatientBirth; - //std::string m_PatientDOB; - //std::string m_StudyID; - std::string m_StudyDescription; - std::string m_StudyDate; - std::string m_StudyTime; - std::string m_SeriesNumber; - std::string m_SeriesDescription; - std::string m_Modality; - std::string m_SliceNumber; - - //std::string m_BodyPart; - //std::string m_NumberOfSeriesInStudy; - //std::string m_NumberOfStudyRelatedSeries; - //std::string m_PatientSex; - //std::string m_PatientAge; - //std::string m_StudyDate; - //std::string m_Modality; - //std::string m_Manufacturer; - std::string m_Institution; - //std::string m_Model; - //std::string m_ScanOptions; - std::string m_orientation; - //std::string m_StudyInstanceUID; - //std::string m_SeriesInstanceUID; - -}DicomTagInfo_t; - - - enum SeriesOpenMode { FILE_OPEN_MODE, DIR_OPEN_MODE @@ -204,10 +161,6 @@ enum SeriesOpenMode { //typedef std::shared_ptr DicomTagInfo_t*; //typedef std::shared_ptr UniqueIDInfo_t*; -namespace DicomUtil -{ - -} class FlipExportHelper { @@ -362,27 +315,7 @@ private: }; - -//typedef std::vector InstancesVecType; - -typedef struct SeriesInfo -{ - SeriesOpenMode open_mode; - std::string instance_num; - bool pixmap_valid; - QPixmap series_pixmap; - std::string unique_id; - DicomTagInfo_t* tag_info; - thumbnailImage* thumb_nail; -// InstancesVecType* instances; - SeriesInfo() : pixmap_valid(false), unique_id(""), tag_info(nullptr), thumb_nail(nullptr) {} - ~SeriesInfo(){ - delete tag_info; - //delete thumb_nail; - } -}SeriesInfo_t; -typedef std::map SeriesMapType; - +typedef std::map SeriesMapType; typedef struct StudyInfo { @@ -393,9 +326,6 @@ typedef struct StudyInfo SeriesMapType *series; StudyInfo():study_label(nullptr), series(nullptr) {} ~StudyInfo(){ - for(auto item: *series){ - delete item.second; - } delete series; } }StudyInfo_t; diff --git a/src/src/util/QDicomUtility.cpp b/src/src/util/QDicomUtility.cpp new file mode 100644 index 0000000..8bbc649 --- /dev/null +++ b/src/src/util/QDicomUtility.cpp @@ -0,0 +1,63 @@ +// +// Created by Krad on 2022/3/4. +// +#include "QDicomUtility.h" +#include +#include +#include +#include +#include +#include +#include +#include "base\ExtendMedicalImageProperties.h" + +QPixmap DicomUtil::GetThumbnail(ExtendMedicalImageProperties *property) { + double *wlww = property->GetNthWindowLevelPreset(0); + int ww = wlww ? ((int) wlww[0]) : (512); + int wl = wlww ? ((int) wlww[1]) : (256); + int sample = property->GetSamplePerPixel(); + DcmRLEDecoderRegistration::registerCodecs(OFFalse, OFTrue);//注册解码器 + /// register JPEG decompression codecs + DJDecoderRegistration::registerCodecs();//注册解码器 + DJLSDecoderRegistration::registerCodecs();// +// FMJPEG2KDecoderRegistration::registerCodecs();//jpeg2000 + DcmFileFormat *fileFormat = new DcmFileFormat();//读取文件获取传输语法 + QPixmap pixmap(100, 100); + pixmap.fill(Qt::black); + if (fileFormat->loadFile(property->GetThumbnailFileName()).good()) { + DcmDataset *dset = fileFormat->getDataset(); + + //将原始传输语法输入DicomImage编译类库自我解压压缩的图像 + DicomImage dcmImage(fileFormat, dset->getOriginalXfer(), CIF_MayDetachPixelData); + unsigned long w = 100; + bool flag = dcmImage.getWidth() > dcmImage.getHeight(); + DicomImage *sdcmImage = dcmImage.createScaledImage(w, 0, 0, 1); + sdcmImage->setWindow(wl, ww); + if (sample == 1) { + uchar *data = (uchar *) sdcmImage->getOutputData(8);//按8位的位宽取数据 + QImage image(data, sdcmImage->getWidth(), sdcmImage->getHeight(), + QImage::Format_Grayscale8);//使用8位深度的灰度图做输出 + if (sdcmImage->getHeight() > 100) image = image.scaledToHeight(100); + QPainter p(&pixmap); + p.drawPixmap(50 - image.width() / 2, 50 - image.height() / 2, QPixmap::fromImage(image)); + } + //RGB color image + else { + uchar *data = (uchar *) sdcmImage->getOutputData(8);//按8位的位宽取数据 + QImage image(data, sdcmImage->getWidth(), sdcmImage->getHeight(), + QImage::Format_RGB888);//使用8位深度的rgb图做输出 + if (sdcmImage->getHeight() > 100) image = image.scaledToHeight(100); + QPainter p(&pixmap); + p.drawPixmap(50 - image.width() / 2, 50 - image.height() / 2, QPixmap::fromImage(image)); + } + + + // p.save(); + } + delete fileFormat; + DcmRLEDecoderRegistration::cleanup(); + DJDecoderRegistration::cleanup(); + DJLSDecoderRegistration::cleanup(); +// FMJPEG2KDecoderRegistration::cleanup(); + return pixmap; +} diff --git a/src/src/util/QDicomUtility.h b/src/src/util/QDicomUtility.h index b3f8c5f..8927f15 100644 --- a/src/src/util/QDicomUtility.h +++ b/src/src/util/QDicomUtility.h @@ -7,60 +7,8 @@ #include -#include -#include -#include -#include -#include -#include -#include - -QPixmap GetImageFormDcmFile(const QString& filepath, int wl, int ww, unsigned short sample) -{ - DcmRLEDecoderRegistration::registerCodecs(OFFalse, OFTrue);//注册解码器 - /// register JPEG decompression codecs - DJDecoderRegistration::registerCodecs();//注册解码器 - DJLSDecoderRegistration::registerCodecs();// -// FMJPEG2KDecoderRegistration::registerCodecs();//jpeg2000 - DcmFileFormat *fileFormat = new DcmFileFormat();//读取文件获取传输语法 - QPixmap pixmap(100,100); - pixmap.fill(Qt::black); - if (fileFormat->loadFile(filepath.toLatin1().data()).good()) - { - DcmDataset * dset = fileFormat->getDataset(); - - //将原始传输语法输入DicomImage编译类库自我解压压缩的图像 - DicomImage dcmImage(fileFormat, dset->getOriginalXfer(),CIF_MayDetachPixelData); - unsigned long w = 100; - bool flag = dcmImage.getWidth() > dcmImage.getHeight(); - DicomImage* sdcmImage = dcmImage.createScaledImage(w,0,0,1); - sdcmImage->setWindow(wl, ww); - if (sample==1){ - uchar* data = (uchar*)sdcmImage->getOutputData(8);//按8位的位宽取数据 - QImage image(data, sdcmImage->getWidth(), sdcmImage->getHeight(), QImage::Format_Grayscale8);//使用8位深度的灰度图做输出 - if (sdcmImage->getHeight() > 100) image = image.scaledToHeight(100); - QPainter p(&pixmap); - p.drawPixmap(50 - image.width()/2, 50-image.height()/2, QPixmap::fromImage(image)); - } - //RGB color image - else{ - uchar* data = (uchar*)sdcmImage->getOutputData(8);//按8位的位宽取数据 - QImage image(data, sdcmImage->getWidth(), sdcmImage->getHeight(), QImage::Format_RGB888);//使用8位深度的rgb图做输出 - if (sdcmImage->getHeight() > 100) image = image.scaledToHeight(100); - QPainter p(&pixmap); - p.drawPixmap(50 - image.width()/2, 50-image.height()/2, QPixmap::fromImage(image)); - } - - - // p.save(); - } - delete fileFormat; - DcmRLEDecoderRegistration::cleanup(); - DJDecoderRegistration::cleanup(); - DJLSDecoderRegistration::cleanup(); -// FMJPEG2KDecoderRegistration::cleanup(); - return pixmap; +class ExtendMedicalImageProperties; +namespace DicomUtil { + QPixmap GetThumbnail(ExtendMedicalImageProperties *property); } - - #endif //OMEGAV_QDICOMUTILITY_H diff --git a/src/src/view/thumbnailImage.cpp b/src/src/view/thumbnailImage.cpp index 5be1769..214edbb 100644 --- a/src/src/view/thumbnailImage.cpp +++ b/src/src/view/thumbnailImage.cpp @@ -5,6 +5,7 @@ #include "global/QGlobals.h" #include "qstyleoption.h" #include "qpainter.h" +#include "util/QDicomUtility.h" static QString unpick_style = "*{background-color:#7f7f7f;border: 1px;}" "QLabel#m_descri{color:white}"; @@ -12,10 +13,7 @@ static QString unpick_style = "*{background-color:#7f7f7f;border: 1px;}" static QString pick_style = "*{background-color:#c5c5c5;border: 1px;}" "QLabel#m_descri{color:black;}"; -thumbnailImage::thumbnailImage(QWidget *parent, SeriesInfo_t* series_info) : - m_series_info(series_info) - //, m_color(UnpickThumbRGB) - , QFrame(parent) +thumbnailImage::thumbnailImage(QWidget *parent, ExtendMedicalImageProperties* property) : QFrame(parent) { this->setObjectName(QString::fromUtf8("frame")); @@ -60,7 +58,7 @@ thumbnailImage::thumbnailImage(QWidget *parent, SeriesInfo_t* series_info) : m_pixmap->setMaximumSize(QSize(100, 100)); m_pixmap->setLayoutDirection(Qt::LeftToRight); m_pixmap->setFrameShape(QFrame::StyledPanel); - m_pixmap->setPixmap(series_info->series_pixmap); + m_pixmap->setPixmap(DicomUtil::GetThumbnail(property)); m_pixmap->setScaledContents(true); m_pixmap->setAlignment(Qt::AlignCenter); horizontalLayout_2->addWidget(m_pixmap); @@ -91,8 +89,9 @@ thumbnailImage::thumbnailImage(QWidget *parent, SeriesInfo_t* series_info) : horizontalLayout->addWidget(m_slicenum); verticalLayout->addWidget(widget); - m_descri->setText(QString::fromStdString(series_info->tag_info->m_SeriesDescription)); - m_slicenum->setText(QString::fromStdString(series_info->tag_info->m_SliceNumber)); + m_descri->setText(property->GetSeriesDescription()); + m_slicenum->setText(QString("%1").arg(property->GetSliceCount())); + seriesProperty = property; } //void thumbnailImage::setBackgroundColor(QColor pickColor) diff --git a/src/src/view/thumbnailImage.h b/src/src/view/thumbnailImage.h index dca0d1a..690a390 100644 --- a/src/src/view/thumbnailImage.h +++ b/src/src/view/thumbnailImage.h @@ -16,12 +16,12 @@ class thumbnailImage : public QFrame Q_OBJECT public: - thumbnailImage(QWidget *parent, SeriesInfo_t* series_info); + thumbnailImage(QWidget *parent, ExtendMedicalImageProperties* property); ~thumbnailImage(); void setHighlight(bool yes); - SeriesInfo_t* getSeriesInfo() + ExtendMedicalImageProperties* getSeriesInfo() { - return m_series_info; + return seriesProperty; } //protected: // void paintEvent(QPaintEvent *event)override; @@ -43,9 +43,7 @@ private: QLabel *m_descri; QLabel *m_slicenum; QLabel *m_pixmap; - SeriesInfo_t* m_series_info; + ExtendMedicalImageProperties* seriesProperty = nullptr; QPoint drag_org_; - //bool m_isTransparent; - //QColor m_color; }; diff --git a/src/src/view/thumbnailbarwidget.cpp b/src/src/view/thumbnailbarwidget.cpp index 0a90d96..c4b4287 100644 --- a/src/src/view/thumbnailbarwidget.cpp +++ b/src/src/view/thumbnailbarwidget.cpp @@ -57,14 +57,6 @@ public: return tmp.str(); } - static std::string Format(SeriesInfo_t *series) - { - std::stringstream tmp; - tmp << series->open_mode << "\n"; - //tmp << series->instance_num << "\n" << series->open_mode; - return tmp.str(); - } - }; @@ -153,35 +145,15 @@ void ThumbnailBarWidget::updateThumbnailBar() SeriesMapType *series = it_st->second->series; for (SeriesMapType::const_iterator it_se = series->cbegin(); it_se != series->cend(); it_se++) { - thumbnailImage *thumbnail = it_se->second->thumb_nail; - if (it_se->second->pixmap_valid == false) { - //OVERRIDE_LEVEL - if (thumbnail) { - //if thumbnail is currentImageLabel,set nullptr, or crash - if (currentImageLabel == thumbnail) { - currentImageLabel = nullptr; - } - delete thumbnail; - thumbnail = nullptr; - } - //wait for update - //thumbnail = new thumbnailImage(this, it_se->second); - thumbnail = createThumbnailImage(seriesPanel, it_se->second); - - //update pointer point to new thumbnail - it_se->second->thumb_nail = thumbnail; - it_se->second->pixmap_valid = true; - } + thumbnailImage *thumbnail = createThumbnailImage(seriesPanel, it_se->second); seriesPanel->layout()->addWidget(thumbnail); //save all thumbnail in one list LabelList << thumbnail; - //imageLabelList << thumbnail; - } } } } -thumbnailImage* ThumbnailBarWidget::createThumbnailImage(QWidget *parent, SeriesInfo_t* series_info) +thumbnailImage* ThumbnailBarWidget::createThumbnailImage(QWidget *parent, ExtendMedicalImageProperties* series_info) { thumbnailImage* t = new thumbnailImage(parent, series_info); @@ -199,17 +171,19 @@ void ThumbnailBarWidget::Slot_setCurrentThumbnail(DicomImageView *view) { if (view->HasSeries()) { SeriesImageSet *series = view->getSeriesInstance(); - //set to another - DicomLoader *helper = DicomLoader::GetInstance(); - SeriesInfo_t* cur_serie = helper->getSerieInfo(series->getUniqueID()); - if (cur_serie) - { - thumbnailImage *thumb = cur_serie->thumb_nail; - if (thumb) - { - setCurrentImageLabel(thumb); - } - } + auto iter = std::find_if(LabelList.begin(),LabelList.end(),[=](QWidget* widget){ + if(0 == strcmp(widget->metaObject()->className(),"thumbnailImage")){ + thumbnailImage* image= static_cast(widget); + if (image->getSeriesInfo()==series->GetProperty()){ + return true; + } + } + return false; + }); + if (iter != LabelList.end()){ + thumbnailImage* image = static_cast(*iter); + setCurrentImageLabel(image); + } } else { diff --git a/src/src/view/thumbnailbarwidget.h b/src/src/view/thumbnailbarwidget.h index f4348dc..0ad20b2 100644 --- a/src/src/view/thumbnailbarwidget.h +++ b/src/src/view/thumbnailbarwidget.h @@ -29,7 +29,6 @@ class ThumbnailBarWidget : public QFrame { // void paintEvent(QPaintEvent *)override; Q_SIGNALS: - void Signal_CopyDicomView(SeriesInfo_t* serie_info); void Signal_ThumbClicked(thumbnailImage* thumb); public Q_SLOTS: @@ -39,7 +38,7 @@ class ThumbnailBarWidget : public QFrame { private: void setCurrentImageLabel(thumbnailImage *imageLabel); - thumbnailImage* createThumbnailImage(QWidget *parent, SeriesInfo_t* series_info); + thumbnailImage* createThumbnailImage(QWidget *parent, ExtendMedicalImageProperties* series_info); QWidgetList LabelList; QList imageLabelList; diff --git a/src/src/view/viewcontainerwidget.cpp b/src/src/view/viewcontainerwidget.cpp index d417cd3..1559c0e 100644 --- a/src/src/view/viewcontainerwidget.cpp +++ b/src/src/view/viewcontainerwidget.cpp @@ -372,15 +372,8 @@ void ViewContainerWidget::Slot_ViewEmpty(DicomImageView *view) void ViewContainerWidget::Slot_DragDropEvent(DicomImageView *view, thumbnailImage* tb) { - SeriesInfo_t* serie_info = tb->getSeriesInfo(); - SeriesImageSet* old = nullptr; - bool copy = true; - - if (view->HasSeries()) - { - old = view->getSeriesInstance(); - } - replaceViewWithSerie(serie_info->unique_id, view); + auto serie_info = tb->getSeriesInfo(); + replaceViewWithSerie(serie_info->GetUniqueID(), view); setCurrentView(view); } @@ -391,8 +384,8 @@ void ViewContainerWidget::Slot_ThumbnailClickEvent(thumbnailImage* tb) { return; } - SeriesInfo_t* serie_info = tb->getSeriesInfo(); - replaceViewWithSerie(serie_info->unique_id, view); + auto serie_info = tb->getSeriesInfo(); + replaceViewWithSerie(serie_info->GetUniqueID(), view); setCurrentView(view); }