Replace SeriesInfo_t with ExtendMedicalImageProperties,remove SeriesInfo,DicomTasInfo. Change GetImageFormDcmFile to GetThumbnail, use ExtendMedicalImageProperties as parameter.

This commit is contained in:
Krad
2022-03-04 13:53:15 +08:00
parent 731d4ae4dd
commit afea5d8d88
10 changed files with 108 additions and 273 deletions

View File

@@ -88,21 +88,6 @@ std::vector<std::string>* 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());
}
}

View File

@@ -32,7 +32,6 @@ public:
// static void itkReaderEndCallbackFunction(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data);
DicomTagInfo_t* createDicomTagsInfo();
/**
* 读取数据Tag
* @param dir
@@ -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:

View File

@@ -15,6 +15,7 @@
#include <QScreen>
#include <sstream>
#include "base/ExtendMedicalImageProperties.h"
using namespace std;
// <20><><EFBFBD><EFBFBD>
@@ -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> DicomTagInfo_t*;
//typedef std::shared_ptr<UniqueIDInfo_t> UniqueIDInfo_t*;
namespace DicomUtil
{
}
class FlipExportHelper
{
@@ -362,27 +315,7 @@ private:
};
//typedef std::vector <SeriesImageSet*> 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<std::string, SeriesInfo_t*> SeriesMapType;
typedef std::map<std::string, ExtendMedicalImageProperties*> 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;

View File

@@ -0,0 +1,63 @@
//
// Created by Krad on 2022/3/4.
//
#include "QDicomUtility.h"
#include <QPaintEngine>
#include <QPainter>
#include <dcmtk/dcmdata/dcrledrg.h>
#include <dcmtk/dcmjpeg/djdecode.h>
#include <dcmtk/dcmjpls/djdecode.h>
#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmimgle/dcmimage.h>
#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;
}

View File

@@ -7,60 +7,8 @@
#include <QtGui/qpixmap.h>
#include <QPaintEngine>
#include <QPainter>
#include <dcmtk/dcmdata/dcrledrg.h>
#include <dcmtk/dcmjpeg/djdecode.h>
#include <dcmtk/dcmjpls/djdecode.h>
#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmimgle/dcmimage.h>
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));
class ExtendMedicalImageProperties;
namespace DicomUtil {
QPixmap GetThumbnail(ExtendMedicalImageProperties *property);
}
//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;
}
#endif //OMEGAV_QDICOMUTILITY_H

View File

@@ -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)

View File

@@ -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;
};

View File

@@ -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,16 +171,18 @@ 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<thumbnailImage*>(widget);
if (image->getSeriesInfo()==series->GetProperty()){
return true;
}
}
return false;
});
if (iter != LabelList.end()){
thumbnailImage* image = static_cast<thumbnailImage*>(*iter);
setCurrentImageLabel(image);
}
}
else

View File

@@ -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<thumbnailImage*> imageLabelList;

View File

@@ -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);
}