void FillInstance(DcmDirectoryRecord& record, DcmItem& dicom, DcmMetaInfo& metaInfo, const char* path) { // cf. "DicomDirInterface::buildImageRecord()" /* copy attribute values from dataset to image record */ copyElementType1(dicom, DCM_InstanceNumber, record); //copyElementType1C(dicom, DCM_ImageType, record); copyElementType1C(dicom, DCM_ReferencedImageSequence, record); OFString tmp; DcmElement* item = record.remove(DCM_ReferencedImageSequence); if (item != NULL) { delete item; } if (record.putAndInsertString(DCM_ReferencedFileID, path).bad() || dicom.findAndGetOFStringArray(DCM_SOPClassUID, tmp).bad() || record.putAndInsertString(DCM_ReferencedSOPClassUIDInFile, tmp.c_str()).bad() || dicom.findAndGetOFStringArray(DCM_SOPInstanceUID, tmp).bad() || record.putAndInsertString(DCM_ReferencedSOPInstanceUIDInFile, tmp.c_str()).bad() || metaInfo.findAndGetOFStringArray(DCM_TransferSyntaxUID, tmp).bad() || record.putAndInsertString(DCM_ReferencedTransferSyntaxUIDInFile, tmp.c_str()).bad()) { throw OrthancException(ErrorCode_BadFileFormat); } }
// copy optional string value from dataset to directory record static void copyStringWithDefault(DcmItem& dataset, const DcmTagKey &key, DcmDirectoryRecord& record, const char *defaultValue, const OFBool printWarning) { OFCondition status; if (dataset.tagExistsWithValue(key)) { OFString stringValue; /* retrieve string value from source dataset and put it into the destination dataset */ status = dataset.findAndGetOFStringArray(key, stringValue); if (status.good()) status = record.putAndInsertString(key, stringValue.c_str()); } else { if (printWarning && (defaultValue != NULL)) { /* create warning message */ LOG(WARNING) << "DICOMDIR: " << DcmTag(key).getTagName() << " " << key << " missing, using alternative: " << defaultValue; } /* put default value */ status = record.putAndInsertString(key, defaultValue); } }
std::string Time::GetDicomFormatedTime() const { OFString formattedTime; AIMUtil::TimeConvert(*this).getISOFormattedTime(formattedTime, true, false, false, false); // can be empty return formattedTime.c_str(); }
// called when a data set is coming in from a server in // response to a CGET virtual OFCondition handleSTORERequest(const T_ASC_PresentationContextID presID, DcmDataset *incomingObject, OFBool& continueCGETSession, Uint16& cStoreReturnStatus) { if (this->retrieve) { OFString instanceUID; incomingObject->findAndGetOFString(DCM_SOPInstanceUID, instanceUID); QString qInstanceUID(instanceUID.c_str()); emit this->retrieve->progress("Got STORE request for " + qInstanceUID); emit this->retrieve->progress(0); continueCGETSession = !this->retrieve->wasCanceled(); if (this->retrieve && this->retrieve->database()) { this->retrieve->database()->insert(incomingObject); return EC_Normal; } else { return this->DcmSCU::handleSTORERequest( presID, incomingObject, continueCGETSession, cStoreReturnStatus); } } //return false; return EC_IllegalCall; };
Series::InstanceUIDContainer Series::toSeriesInstanceUIDContainer(OFList< QRResponse* > responses) { InstanceUIDContainer instanceUIDContainer; OFIterator< QRResponse* > it; DcmDataset dataset; OFCondition result; // Every while loop run will get all image for a specific study for (it = responses.begin(); it != responses.end(); ++it) { // Be sure we are not in the last response which does not have a dataset if ((*it)->m_dataset != NULL) { OFString seriesInstanceUID; result = (*it)->m_dataset->findAndGetOFStringArray(DCM_SeriesInstanceUID, seriesInstanceUID); // Only try to get study if we actually have study instance uid, otherwise skip it if (result.good()) { instanceUIDContainer.push_back(seriesInstanceUID.c_str()); } else { const std::string msg = "There is no \"SeriersInstanceUID\" tag in the selected series :" + std::string(result.text()); throw ::fwPacsIO::exceptions::TagMissing(msg); } } } return instanceUIDContainer; }
std::string Date::GetDicomFormatedDate() const { OFString formattedDate; AIMUtil::DateConvert(*this).getISOFormattedDate(formattedDate, false); // can be empty return formattedDate.c_str(); }
void FindService::WholeStudyInfoCallback( void *callbackData, T_DIMSE_C_FindRQ * /*request*/, int /*responseCount*/, T_DIMSE_C_FindRSP * /*rsp*/, DcmDataset *responseIdentifiers ) /* * This function.is used to indicate progress when findscu receives search results over the * network. This function will simply cause some information to be dumped to stdout. * * Parameters: * callbackData - [in] data for this callback function * request - [in] The original find request message. * responseCount - [in] Specifies how many C-FIND-RSP were received including the current one. * rsp - [in] the C-FIND-RSP message which was received shortly before the call to * this function. * responseIdentifiers - [in] Contains the record which was received. This record matches the search * mask of the C-FIND-RQ which was sent. */ { OFString str; std::string imageID; std::string setID; // Parse the response responseIdentifiers->findAndGetOFString( DCM_SOPInstanceUID, str); imageID = str.c_str(); responseIdentifiers->findAndGetOFString( DCM_SeriesInstanceUID, str); setID = str.c_str(); // get container that recieved values should go into StudyInfo *setInfo = static_cast<StudyInfo*>(callbackData); StringVector *setImages; // try to find if there is already just recieved setID within the container StudyInfo::iterator it = setInfo->find( setID); if( it == setInfo->end() ) { // create new StringVector & insert it into setInfo StringVector buddy; setInfo->insert( StudyInfo::value_type( setID, buddy) ); setImages = &setInfo->find( setID)->second; } else { setImages = &it->second; } // insert imageID setImages->push_back( imageID); D_PRINT( "Next record into study info arrived ..."); }
BOOST_FIXTURE_TEST_CASE(SetEmpty, Fixture) { odil::dcmtk::ElementAccessor<std::string>::set(this->dataset, DCM_PatientName, "FOO"); OFString value; OFCondition const condition = this->dataset.findAndGetOFString(DCM_PatientName, value); BOOST_REQUIRE(condition.good()); BOOST_CHECK_EQUAL(std::string(value.c_str()), "FOO"); }
Examen* ParserDicom::loadFile(string dirName) { // Open directory DIR* dir = opendir(dirName.c_str()); if (dir == NULL) { return NULL; } // Get examen informations ExamenParams* params = getInfos(dir, dirName); if (params == NULL) { return NULL; } // Create struct examen Volume* img = new Volume(params->width, params->height, params->depth); Examen* exam = new Examen(img, params); // Read data int index = 0; struct dirent* file; rewinddir(dir); string pathDirectory = dirName + PATH_SEPARATOR; int tabSize = params->width * params->height; float tab[tabSize]; while ((file = readdir(dir)) != NULL) { if (strcmp(file->d_name, ".") != 0 && strcmp(file->d_name, "..") != 0) { string fullpath = pathDirectory + file->d_name; DcmFileFormat dcm; OFCondition cond = dcm.loadFile(fullpath.c_str()); if (cond.bad()) { delete img; delete params; return NULL; } DiDocument* didoc = new DiDocument(fullpath.c_str()); DiMono2Image* dimg = new DiMono2Image(didoc, EIS_Normal); OFString s; dcm.getDataset()->findAndGetOFString(DCM_BitsStored, s); int bitsStored = atoi(s.c_str()); short* slice = (short*) dimg->getOutputData(0, bitsStored, 0); for(int i=0; i<tabSize; ++i) { tab[i] = (float) slice[i]; } img->setSlice(tab, index++); delete dimg; delete didoc; } } closedir(dir); return exam; }
mitk::DataNode::Pointer RTDoseReader:: LoadRTDose(const char* filename) { DcmFileFormat fileformat; OFCondition outp = fileformat.loadFile(filename, EXS_Unknown); if(outp.bad()) { MITK_ERROR << "Cant read the file" << std::endl; } DcmDataset *dataset = fileformat.getDataset(); std::string name = filename; itk::FilenamesContainer file; file.push_back(name); mitk::DicomSeriesReader* reader = new mitk::DicomSeriesReader; mitk::DataNode::Pointer originalNode = reader->LoadDicomSeries(file,false); if(originalNode.IsNull()) { MITK_ERROR << "Error reading the dcm file" << std::endl; return 0; } mitk::Image::Pointer originalImage = dynamic_cast<mitk::Image*>(originalNode->GetData()); DRTDoseIOD doseObject; OFCondition result = doseObject.read(*dataset); if(result.bad()) { MITK_ERROR << "Error reading the Dataset" << std::endl; return 0; } OFString gridScaling; Float32 gridscale; doseObject.getDoseGridScaling(gridScaling); gridscale = OFStandard::atof(gridScaling.c_str()); AccessByItk_1(originalImage, MultiplayGridScaling, gridscale); double prescripeDose = this->GetMaxDoseValue(dataset); originalNode->SetName("RT Dose"); originalNode->SetFloatProperty(mitk::Constants::PRESCRIBED_DOSE_PROPERTY_NAME.c_str(),prescripeDose); originalNode->SetFloatProperty(mitk::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(), 40); originalNode->SetBoolProperty(mitk::Constants::DOSE_PROPERTY_NAME.c_str(),true); return originalNode; }
const char* Association::GetKey(DcmDataset* query, const DcmTagKey& tag) { OFString val; static char buffer[129]; query->findAndGetOFString(tag, val, 0, OFTrue); #if defined(_WINDOWS) strncpy_s(buffer, val.c_str(), sizeof (buffer) - 1); #else strncpy(buffer, val.c_str(), sizeof (buffer) - 1); #endif buffer[sizeof (buffer) - 1] = 0; return buffer; }
/* * query all seriesinstanceuid's and the number series of a study */ int query_study_series(const std::string& studyinstanceuid, const std::string& server, const std::string& local_aet, std::list<std::string>& seriesinstanceuids) { DcmDataset query; DcmElement* e = NULL; e = newDicomElement(DCM_QueryRetrieveLevel); e->putString("SERIES"); query.insert(e); e = newDicomElement(DCM_StudyInstanceUID); e->putString(studyinstanceuid.c_str()); query.insert(e); e = newDicomElement(DCM_SeriesInstanceUID); query.insert(e); e = newDicomElement(DCM_SeriesNumber); query.insert(e); e = newDicomElement(DCM_Modality); query.insert(e); std::cout << "NEW QUERY:" << std::endl; query.print(COUT); NetClient<FindAssociation> a; a.QueryServer(&query, server, local_aet, UID_FINDStudyRootQueryRetrieveInformationModel); DcmStack* result = a.GetResultStack(); DcmDataset* dset; OFString ofstr; seriesinstanceuids.clear(); for(int i = 0; i < result->card(); i++) { dset = (DcmDataset*)result->elem(i); if(dset->findAndGetOFString(DCM_SeriesInstanceUID, ofstr).good()) { seriesinstanceuids.push_back(ofstr.c_str()); } } std::cout << result->card() << " Responses" << std::endl; int count = result->card(); return count; }
Glib::RefPtr< ImagePool::Series > create_query_series(DcmDataset* dset) { Glib::RefPtr< ImagePool::Series > result = Glib::RefPtr< ImagePool::Series >(new Series); OFString seriesUID; OFString desc; OFString ofstr; dset->findAndGetOFString(DCM_SeriesInstanceUID, seriesUID); dset->findAndGetOFString(DCM_SeriesDescription, desc); if(result->m_description.empty()) { dset->findAndGetOFString(DCM_StudyDescription, desc); } result->m_seriesinstanceuid = seriesUID.c_str(); result->m_description = desc.c_str(); if(result->m_description.empty()) { result->m_description = gettext("no description"); } dset->findAndGetOFString(DCM_Modality, ofstr); result->m_modality = ofstr.c_str(); dset->findAndGetOFString(DCM_SeriesTime, ofstr); result->m_seriestime = ofstr.c_str(); if(result->m_seriestime.empty()) { dset->findAndGetOFString(DCM_StudyTime, ofstr); result->m_seriestime = ofstr.c_str(); } dset->findAndGetOFString(DCM_StationName, ofstr); result->m_stationname = ofstr.c_str(); dset->findAndGetOFString(DCM_NumberOfSeriesRelatedInstances, ofstr); int i = atoi(ofstr.c_str()); if(i != 0) { result->m_instancecount = i; } fix_time(result->m_seriestime); return result; }
DcmDirectoryRecord* DicomdirLoader::find_study(const std::string &studyinstanceuid, class DcmDicomDir &dir) { DcmDirectoryRecord *patRec; DcmDirectoryRecord *studyRec; OFCondition ret; DcmDirectoryRecord &root = dir.getRootRecord(); for ( patRec = root.nextSub(NULL); patRec != NULL; patRec = root.nextSub(patRec) ) { if ( patRec->getRecordType() == ERT_Patient ) { for ( studyRec = patRec->nextSub(NULL); studyRec; studyRec = patRec->nextSub(studyRec) ) { if ( studyRec->getRecordType()==ERT_Study ) { OFString uid; if ( studyRec->findAndGetOFString(DCM_StudyInstanceUID, uid)==EC_Normal ) { if ( studyinstanceuid == uid.c_str() ) return studyRec; } } } } } return NULL; }
void ctkDICOMDataset::InitializeFromDataset(DcmDataset* dataset, bool takeOwnership) { Q_D(ctkDICOMDataset); if(d->m_DcmDataset != dataset) { if (d->m_TakeOwnership) { delete d->m_DcmDataset; } d->m_DcmDataset = NULL; } if (dataset) { d->m_DcmDataset=dataset; d->m_TakeOwnership = takeOwnership; if (!d->m_DICOMDataSetInitialized) { d->m_DICOMDataSetInitialized = true; OFString encoding; if ( CheckCondition( dataset->findAndGetOFString(DCM_SpecificCharacterSet, encoding) ) ) { d->m_SpecificCharacterSet = encoding.c_str(); } } if (d->m_SpecificCharacterSet.isEmpty()) { /// /// see Bug # 6458: /// There are cases, where different studies of the same person get encoded both with and without the SpecificCharacterSet attribute set. /// DICOM says: default is ASCII / ISO_IR 6 / ISO 646 /// Since we experienced such mixed data, we supplement missing characterset information with the ISO_IR 100 / Latin1 character set. /// Since Latin1 is a superset of ASCII, this will not cause problems. PLUS in most cases (Europe) we will guess right and suppress /// "double patients" in applications. /// SetElementAsString( DCM_SpecificCharacterSet, "ISO_IR 100" ); } } }
void open_dicomdir_series(const std::string& studyinstanceuid, const Glib::ustring& dicomdir, const sigc::slot< void, const Glib::RefPtr< ImagePool::Series >& >& resultslot) { DcmDicomDir dir(dicomdir.c_str()); DcmDirectoryRecord *patRec; DcmDirectoryRecord *studyRec; DcmDirectoryRecord *seriesRec; OFCondition ret; if ( dir.error() != ECC_Normal ) { std::cout << "DICOMDIR Error: " << ret.text() << std::endl; return; } DcmDirectoryRecord &root = dir.getRootRecord(); for ( patRec = root.nextSub(NULL); patRec!=NULL; patRec = root.nextSub(patRec) ) { switch ( patRec->getRecordType() ) { case ERT_Patient: for ( studyRec=patRec->nextSub(NULL); studyRec; studyRec = patRec->nextSub(studyRec) ) { if ( studyRec->getRecordType()==ERT_Study ) { OFString uid; if ( studyRec->findAndGetOFString(DCM_StudyInstanceUID, uid)==ECC_Normal ) { if ( studyinstanceuid == uid.c_str() ) { open_dicomdir_series_result(dicomdir, patRec, studyRec, resultslot); return; } } } } break; case ERT_HangingProtocol: // FALLTHROUGH case ERT_Private: break; default: break; } } std::cout << "WARNING: study[" << studyinstanceuid << "] not found in DICOMDIR\n"; }
/** Check whether given type 1 attribute is present and has a length > 0. * @param key - [in] The attribute tag check * @param targetDset - [out] targetDset * @param defaultValue - [in] value to be inserted if attribute is missing * (needs invent option for type 1 attributes enabled) * @return A string with an error message if attribute is not present * or has length of 0 */ OFString D2DCommon::checkAndInventType1Attrib(const DcmTagKey& key, DcmDataset* targetDset, const OFString& defaultValue) const { OFString err; OFBool exists = targetDset->tagExists(key); if (!exists) { OFString err = "Document2Dcm: Missing type 1 attribute: "; err += DcmTag(key).getTagName(); err += "\n"; return err; } DcmElement *elem; OFCondition cond = targetDset->findAndGetElement(key, elem); if (cond.bad() || !elem || (elem->getLength() == 0)) { if (!m_inventMissingType1Attribs) { err += "Document2Dcm: Empty value for type 1 attribute: "; err += DcmTag(key).getTagName(); err += "\n"; return err; } //holds element to insert in item DcmElement *elem = NULL; DcmTag tag(key); OFBool wasError = OFFalse; //if dicom element could be created, insert in to item and modify to value if (newDicomElement(elem, tag).good()) { if (targetDset->insert(elem, OFTrue).good()) { if (elem->putString(defaultValue.c_str()).good()) { if (m_debug) { OFString msg = "Document2Dcm: Inserting missing type 1 attribute "; msg += tag.getTagName(); msg += " with value "; msg += defaultValue; printMessage(m_logStream, msg); return err; } } else wasError = OFTrue; } else wasError = OFTrue; } else wasError = OFTrue; if (wasError) { err += "Unable to insert type 1 attribute "; err += tag.getTagName(); err += " with value "; err += defaultValue; err += "\n"; } } return err; }
IFileIO::ConfidenceLevel DICOMSegmentationIO::GetReaderConfidenceLevel() const { if (AbstractFileIO::GetReaderConfidenceLevel() == Unsupported) return Unsupported; const std::string fileName = this->GetLocalFileName(); DcmFileFormat dcmFileFormat; OFCondition status = dcmFileFormat.loadFile(fileName.c_str()); if (status.bad()) return Unsupported; OFString modality; if (dcmFileFormat.getDataset()->findAndGetOFString(DCM_Modality, modality).good()) { if (modality.compare("SEG") == 0) return Supported; else return Unsupported; } return Unsupported; }
bool DcmSend::queryDcm(QList <QString> &QueryPatientName, QList <QString> &QueryPatientID, QList <QString> &QueryAccessionNumber) { OFVector<QRResponse*> findResponses; DcmDataset req; req.insertEmptyElement(DCM_PatientName); req.insertEmptyElement(DCM_PatientID); req.insertEmptyElement(DCM_AccessionNumber); req.putAndInsertOFStringArray(DCM_QueryRetrieveLevel, "STUDY"); req.putAndInsertOFStringArray(DCM_StudyInstanceUID, ""); T_ASC_PresentationContextID presID = findUncompressedPC(UID_FINDStudyRootQueryRetrieveInformationModel, Sender); if (presID == 0) { DCMNET_ERROR("There is no uncompressed presentation context for Study Root FIND"); return 1; } result = Sender.sendFINDRequest(presID, &req,&findResponses); if (result.bad()) return false; OFString NamePatient; OFString PatientID; OFString AccessionNumber; for (int i=0;i<findResponses.size();i++){ if (findResponses.at(i)->m_dataset != NULL){ result= findResponses.at(i)->m_dataset->findAndGetOFString(DCM_PatientName,NamePatient); result= findResponses.at(i)->m_dataset->findAndGetOFString(DCM_AccessionNumber,AccessionNumber); result= findResponses.at(i)->m_dataset->findAndGetOFString(DCM_PatientID,PatientID); QueryPatientName << NamePatient.data(); QueryPatientID << PatientID.data(); QueryAccessionNumber << AccessionNumber.data(); } } return true; }
void mitk::DICOMDCMTKTagScanner::Scan() { this->PushLocale(); try { DcmPathProcessor processor; processor.setItemWildcardSupport(true); DICOMGenericTagCache::Pointer newCache = DICOMGenericTagCache::New(); for (const auto& fileName : this->m_InputFilenames) { DcmFileFormat dfile; OFCondition cond = dfile.loadFile(fileName.c_str()); if (cond.bad()) { MITK_ERROR << "Error when scanning for tags. Cannot open given file. File: " << fileName; } else { DICOMGenericImageFrameInfo::Pointer info = DICOMGenericImageFrameInfo::New(fileName); for (const auto& path : this->m_ScannedTags) { std::string tagPath = DICOMTagPathToDCMTKSearchPath(path); cond = processor.findOrCreatePath(dfile.getDataset(), tagPath.c_str()); if (cond.good()) { OFList< DcmPath * > findings; processor.getResults(findings); for (const auto& finding : findings) { auto element = dynamic_cast<DcmElement*>(finding->back()->m_obj); if (!element) { auto item = dynamic_cast<DcmItem*>(finding->back()->m_obj); if (item) { element = item->getElement(finding->back()->m_itemNo); } } if (element) { OFString value; cond = element->getOFStringArray(value); if (cond.good()) { info->SetTagValue(DcmPathToTagPath(finding), std::string(value.c_str())); } } } } } newCache->AddFrameInfo(info); } } m_Cache = newCache; this->PopLocale(); } catch (...) { this->PopLocale(); throw; } }
ExamenParams* ParserDicom::getInfos(DIR* dir, string dirName) { struct dirent* file = getOneFile(dir); if (file == NULL) { return NULL; } string fullpath = dirName + PATH_SEPARATOR + file->d_name; DcmFileFormat dcm; OFCondition cond = dcm.loadFile(fullpath.c_str()); if (cond.bad()) { return NULL; } Information* generalInfos = new Information(); OFString s; dcm.getDataset()->findAndGetOFString(DCM_PatientName, s); generalInfos->addInformation("Patient name", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_PatientID, s); generalInfos->addInformation("Patient ID", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_PatientBirthDate, s); generalInfos->addInformation("Patient birthday", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_PatientAge, s); generalInfos->addInformation("Patient age", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_PatientSex, s); generalInfos->addInformation("Patient sex", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_PatientSize, s); generalInfos->addInformation("Patient size", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_PatientWeight, s); generalInfos->addInformation("Patient weight", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_ImagePositionPatient, s); generalInfos->addInformation("Image position patient", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_ImageOrientationPatient, s); generalInfos->addInformation("Image orientation patient", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_StudyID, s); generalInfos->addInformation("Study data", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_StudyDate, s); generalInfos->addInformation("Study date", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_StudyTime, s); generalInfos->addInformation("Study time", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_StudyDescription, s); generalInfos->addInformation("Study description", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_BitsAllocated, s); generalInfos->addInformation("Bits allocated", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_BitsStored, s); generalInfos->addInformation("Bits stored", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_HighBit, s); generalInfos->addInformation("High bit", s.c_str()); generalInfos->addInformation("Intercept", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_RescaleIntercept, s); int intercept = atoi(s.c_str()); generalInfos->addInformation("Slope", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_RescaleSlope, s); int slope = atoi(s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_WindowCenter, s); generalInfos->addInformation("Window center", s.c_str()); int Wcenter=atoi(s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_WindowWidth, s); generalInfos->addInformation("Window width", s.c_str()); int Wwidth=atoi(s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_SliceThickness, s); generalInfos->addInformation("Slice thickness", s.c_str()); float Sthickness = atof(s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_WindowCenterWidthExplanation, s); generalInfos->addInformation("WindowCenterWidthExplanation", s.c_str()); dcm.getDataset()->findAndGetOFString(DCM_Manufacturer, s); generalInfos->addInformation("Manufacturer", s.c_str()); //--------------------------------------------- // Affectation des parametres de l'examen //--------------------------------------------- GrayTranslationFunction gtf(slope, intercept); ExamenParams* params = new ExamenParams(gtf, fullpath, generalInfos); params->getGrayViewWindow().setLuminosity(Wcenter); params->getGrayViewWindow().setContrast(Wwidth); //params->getGrayViewWindow().setMin(HundsfieldValue::min()); // Must choose ! //params->getGrayViewWindow().setMax(HundsfieldValue::max()); //params->setParametersSI(Sthickness); //--------------------------------------------- // Examen size informations //--------------------------------------------- DiDocument* didoc = new DiDocument(fullpath.c_str()); DiMono2Image* dimg = new DiMono2Image(didoc, EIS_Normal); params->width = dimg->getColumns(); params->height = dimg->getRows(); params->depth = nbFiles(dir); params->resolutionX = dimg->getPixelWidth();; params->resolutionY = dimg->getPixelHeight();; params->resolutionZ = Sthickness; // check ostringstream sNbSlice, sSize, sResX, sResY; sResX << params->resolutionX; sResY << params->resolutionY; sNbSlice << params->depth + 1; sSize << params->width << " " << params->height; generalInfos->addInformation("Slice number", sNbSlice.str()); generalInfos->addInformation("Scan resolution (x, y)", sSize.str()); generalInfos->addInformation("Pixel resolution X", sResX.str()); generalInfos->addInformation("Pixel resolution Y", sResY.str()); delete dimg; delete didoc; return params; }
Series::DicomSeriesContainer Series::toFwMedData(OFList< QRResponse* > responses) { DicomSeriesContainer seriesContainer; OFIterator< QRResponse* > it; OFCondition result; // Every while loop run will get all image for a specific study for (it = responses.begin(); it != responses.end(); ++it) { // Be sure we are not in the last response which does not have a dataset if ((*it)->m_dataset != NULL) { OFString data; // Create series ::fwMedData::DicomSeries::sptr series = ::fwMedData::DicomSeries::New(); ::fwMedData::Patient::sptr patient = ::fwMedData::Patient::New(); ::fwMedData::Study::sptr study = ::fwMedData::Study::New(); ::fwMedData::Equipment::sptr equipment = ::fwMedData::Equipment::New(); // Set informations to series series->setPatient(patient); series->setStudy(study); series->setEquipment(equipment); // ================================== // Series // ================================== result = (*it)->m_dataset->findAndGetOFStringArray(DCM_SeriesInstanceUID, data); series->setInstanceUID(data.c_str()); result = (*it)->m_dataset->findAndGetOFStringArray(DCM_Modality, data); series->setModality(data.c_str()); result = (*it)->m_dataset->findAndGetOFStringArray(DCM_SeriesDate, data); series->setDate(data.c_str()); result = (*it)->m_dataset->findAndGetOFStringArray(DCM_SeriesTime, data); series->setTime(data.c_str()); result = (*it)->m_dataset->findAndGetOFStringArray(DCM_SeriesDescription, data); series->setDescription(data.c_str()); result = (*it)->m_dataset->findAndGetOFStringArray(DCM_PerformingPhysicianName, data); ::fwMedData::DicomValuesType performingPhysiciansName; performingPhysiciansName.push_back(data.c_str()); series->setPerformingPhysiciansName(performingPhysiciansName); // ================================== // Patient // ================================== result = (*it)->m_dataset->findAndGetOFStringArray(DCM_PatientName, data); patient->setName(data.c_str()); result = (*it)->m_dataset->findAndGetOFStringArray(DCM_PatientID, data); patient->setPatientId(data.c_str()); result = (*it)->m_dataset->findAndGetOFStringArray(DCM_PatientBirthDate, data); patient->setBirthdate(data.c_str()); result = (*it)->m_dataset->findAndGetOFStringArray(DCM_PatientSex, data); patient->setSex(data.c_str()); // ================================== // Study // ================================== result = (*it)->m_dataset->findAndGetOFStringArray(DCM_StudyInstanceUID, data); study->setInstanceUID(data.c_str()); result = (*it)->m_dataset->findAndGetOFStringArray(DCM_StudyDate, data); study->setDate(data.c_str()); result = (*it)->m_dataset->findAndGetOFStringArray(DCM_StudyTime, data); study->setTime(data.c_str()); result = (*it)->m_dataset->findAndGetOFStringArray(DCM_ReferringPhysicianName, data); study->setReferringPhysicianName(data.c_str()); result = (*it)->m_dataset->findAndGetOFStringArray(DCM_StudyDescription, data); study->setDescription(data.c_str()); result = (*it)->m_dataset->findAndGetOFStringArray(DCM_PatientAge, data); study->setPatientAge(data.c_str()); // ================================== // Equipment // ================================== (*it)->m_dataset->findAndGetOFStringArray(DCM_InstitutionName, data); equipment->setInstitutionName(data.c_str()); // ================================== // Number of instances // ================================== long int nbinstances; (*it)->m_dataset->findAndGetLongInt(DCM_NumberOfSeriesRelatedInstances, nbinstances); series->setNumberOfInstances(nbinstances); // Add series to container seriesContainer.push_back(series); } } return seriesContainer; }
//------------------------------------------------------------------------------ void ctkDICOMDatabase::insert ( DcmDataset *dataset, bool storeFile, bool generateThumbnail) { Q_D(ctkDICOMDatabase); if (!dataset) { return; } // Check to see if the file has already been loaded OFString sopInstanceUID ; dataset->findAndGetOFString(DCM_SOPInstanceUID, sopInstanceUID); QSqlQuery fileExists ( d->Database ); fileExists.prepare("SELECT InsertTimestamp,Filename FROM Images WHERE SOPInstanceUID == ?"); fileExists.bindValue(0,QString(sopInstanceUID.c_str())); fileExists.exec(); if ( fileExists.next() && QFileInfo(fileExists.value(1).toString()).lastModified() < QDateTime::fromString(fileExists.value(0).toString(),Qt::ISODate) ) { logger.debug ( "File " + fileExists.value(1).toString() + " already added" ); return; } OFString patientsName, patientID, patientsBirthDate, patientsBirthTime, patientsSex, patientComments, patientsAge; OFString studyInstanceUID, studyID, studyDate, studyTime, accessionNumber, modalitiesInStudy, institutionName, performingPhysiciansName, referringPhysician, studyDescription; OFString seriesInstanceUID, seriesDate, seriesTime, seriesDescription, bodyPartExamined, frameOfReferenceUID, contrastAgent, scanningSequence; OFString instanceNumber; Sint32 seriesNumber = 0, acquisitionNumber = 0, echoNumber = 0, temporalPosition = 0; //If the following fields can not be evaluated, cancel evaluation of the DICOM file dataset->findAndGetOFString(DCM_PatientName, patientsName); dataset->findAndGetOFString(DCM_StudyInstanceUID, studyInstanceUID); dataset->findAndGetOFString(DCM_SeriesInstanceUID, seriesInstanceUID); dataset->findAndGetOFString(DCM_PatientID, patientID); dataset->findAndGetOFString(DCM_PatientBirthDate, patientsBirthDate); dataset->findAndGetOFString(DCM_PatientBirthTime, patientsBirthTime); dataset->findAndGetOFString(DCM_PatientSex, patientsSex); dataset->findAndGetOFString(DCM_PatientAge, patientsAge); dataset->findAndGetOFString(DCM_PatientComments, patientComments); dataset->findAndGetOFString(DCM_StudyID, studyID); dataset->findAndGetOFString(DCM_StudyDate, studyDate); dataset->findAndGetOFString(DCM_StudyTime, studyTime); dataset->findAndGetOFString(DCM_AccessionNumber, accessionNumber); dataset->findAndGetOFString(DCM_ModalitiesInStudy, modalitiesInStudy); dataset->findAndGetOFString(DCM_InstitutionName, institutionName); dataset->findAndGetOFString(DCM_PerformingPhysicianName, performingPhysiciansName); dataset->findAndGetOFString(DCM_ReferringPhysicianName, referringPhysician); dataset->findAndGetOFString(DCM_StudyDescription, studyDescription); dataset->findAndGetOFString(DCM_SeriesDate, seriesDate); dataset->findAndGetOFString(DCM_SeriesTime, seriesTime); dataset->findAndGetOFString(DCM_SeriesDescription, seriesDescription); dataset->findAndGetOFString(DCM_BodyPartExamined, bodyPartExamined); dataset->findAndGetOFString(DCM_FrameOfReferenceUID, frameOfReferenceUID); dataset->findAndGetOFString(DCM_ContrastBolusAgent, contrastAgent); dataset->findAndGetOFString(DCM_ScanningSequence, scanningSequence); dataset->findAndGetSint32(DCM_SeriesNumber, seriesNumber); dataset->findAndGetSint32(DCM_AcquisitionNumber, acquisitionNumber); dataset->findAndGetSint32(DCM_EchoNumbers, echoNumber); dataset->findAndGetSint32(DCM_TemporalPositionIdentifier, temporalPosition); // store the file if the database is not in memomry QString filename; if ( storeFile && !this->isInMemory() ) { DcmFileFormat* fileformat = new DcmFileFormat ( dataset ); QString destinationDirectoryName = databaseDirectory() + "/dicom/"; QDir destinationDir(destinationDirectoryName); QString studySeriesDirectory = QString(studyInstanceUID.c_str()) + "/" + seriesInstanceUID.c_str(); destinationDir.mkpath(studySeriesDirectory); filename = databaseDirectory() + "/dicom/" + pathForDataset(dataset); logger.debug ( "Saving file: " + filename ); OFCondition status = fileformat->saveFile ( filename.toAscii() ); if ( !status.good() ) { logger.error ( "Error saving file: " + filename + "\nError is " + status.text() ); delete fileformat; return; } delete fileformat; } QSqlQuery check_exists_query(d->Database); //The patient UID is a unique number within the database, generated by the sqlite autoincrement int patientUID = -1; if ( patientID != "" && patientsName != "" ) { //Check if patient is already present in the db check_exists_query.prepare ( "SELECT * FROM Patients WHERE PatientID = ? AND PatientsName = ?" ); check_exists_query.bindValue ( 0, QString ( patientID.c_str() ) ); check_exists_query.bindValue ( 1, QString ( patientsName.c_str() ) ); check_exists_query.exec(); if (check_exists_query.next()) { patientUID = check_exists_query.value(check_exists_query.record().indexOf("UID")).toInt(); } else { // Insert it QSqlQuery statement ( d->Database ); statement.prepare ( "INSERT INTO Patients ('UID', 'PatientsName', 'PatientID', 'PatientsBirthDate', 'PatientsBirthTime', 'PatientsSex', 'PatientsAge', 'PatientsComments' ) values ( NULL, ?, ?, ?, ?, ?, ?, ? )" ); statement.bindValue ( 0, QString ( patientsName.c_str() ) ); statement.bindValue ( 1, QString ( patientID.c_str() ) ); statement.bindValue ( 2, QString ( patientsBirthDate.c_str() ) ); statement.bindValue ( 3, QString ( patientsBirthTime.c_str() ) ); statement.bindValue ( 4, QString ( patientsSex.c_str() ) ); // TODO: shift patient's age to study, since this is not a patient level attribute in images // statement.bindValue ( 5, QString ( patientsAge.c_str() ) ); statement.bindValue ( 6, QString ( patientComments.c_str() ) ); statement.exec (); patientUID = statement.lastInsertId().toInt(); logger.debug ( "New patient inserted: " + QString().setNum ( patientUID ) ); } } if ( studyInstanceUID != "" ) { check_exists_query.prepare ( "SELECT * FROM Studies WHERE StudyInstanceUID = ?" ); check_exists_query.bindValue ( 0, QString ( studyInstanceUID.c_str() ) ); check_exists_query.exec(); if(!check_exists_query.next()) { QSqlQuery statement ( d->Database ); statement.prepare ( "INSERT INTO Studies ( 'StudyInstanceUID', 'PatientsUID', 'StudyID', 'StudyDate', 'StudyTime', 'AccessionNumber', 'ModalitiesInStudy', 'InstitutionName', 'ReferringPhysician', 'PerformingPhysiciansName', 'StudyDescription' ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ); statement.bindValue ( 0, QString ( studyInstanceUID.c_str() ) ); statement.bindValue ( 1, patientUID ); statement.bindValue ( 2, QString ( studyID.c_str() ) ); statement.bindValue ( 3, QDate::fromString ( studyDate.c_str(), "yyyyMMdd" ) ); statement.bindValue ( 4, QString ( studyTime.c_str() ) ); statement.bindValue ( 5, QString ( accessionNumber.c_str() ) ); statement.bindValue ( 6, QString ( modalitiesInStudy.c_str() ) ); statement.bindValue ( 7, QString ( institutionName.c_str() ) ); statement.bindValue ( 8, QString ( referringPhysician.c_str() ) ); statement.bindValue ( 9, QString ( performingPhysiciansName.c_str() ) ); statement.bindValue ( 10, QString ( studyDescription.c_str() ) ); if ( !statement.exec() ) { logger.error ( "Error executing statament: " + statement.lastQuery() + " Error: " + statement.lastError().text() ); } } } if ( seriesInstanceUID != "" ) { check_exists_query.prepare ( "SELECT * FROM Series WHERE SeriesInstanceUID = ?" ); check_exists_query.bindValue ( 0, QString ( seriesInstanceUID.c_str() ) ); logger.warn ( "Statement: " + check_exists_query.lastQuery() ); check_exists_query.exec(); if(!check_exists_query.next()) { QSqlQuery statement ( d->Database ); statement.prepare ( "INSERT INTO Series ( 'SeriesInstanceUID', 'StudyInstanceUID', 'SeriesNumber', 'SeriesDate', 'SeriesTime', 'SeriesDescription', 'BodyPartExamined', 'FrameOfReferenceUID', 'AcquisitionNumber', 'ContrastAgent', 'ScanningSequence', 'EchoNumber', 'TemporalPosition' ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" ); statement.bindValue ( 0, QString ( seriesInstanceUID.c_str() ) ); statement.bindValue ( 1, QString ( studyInstanceUID.c_str() ) ); statement.bindValue ( 2, static_cast<int>(seriesNumber) ); statement.bindValue ( 3, QString ( seriesDate.c_str() ) ); statement.bindValue ( 4, QDate::fromString ( seriesTime.c_str(), "yyyyMMdd" ) ); statement.bindValue ( 5, QString ( seriesDescription.c_str() ) ); statement.bindValue ( 6, QString ( bodyPartExamined.c_str() ) ); statement.bindValue ( 7, QString ( frameOfReferenceUID.c_str() ) ); statement.bindValue ( 8, static_cast<int>(acquisitionNumber) ); statement.bindValue ( 9, QString ( contrastAgent.c_str() ) ); statement.bindValue ( 10, QString ( scanningSequence.c_str() ) ); statement.bindValue ( 11, static_cast<int>(echoNumber) ); statement.bindValue ( 12, static_cast<int>(temporalPosition) ); if ( !statement.exec() ) { logger.error ( "Error executing statament: " + statement.lastQuery() + " Error: " + statement.lastError().text() ); } } } if ( !filename.isEmpty() ) { check_exists_query.prepare ( "SELECT * FROM Images WHERE Filename = ?" ); check_exists_query.bindValue ( 0, filename ); check_exists_query.exec(); if(!check_exists_query.next()) { QSqlQuery statement ( d->Database ); statement.prepare ( "INSERT INTO Images ( 'SOPInstanceUID', 'Filename', 'SeriesInstanceUID', 'InsertTimestamp' ) VALUES ( ?, ?, ?, ? )" ); statement.bindValue ( 0, QString ( sopInstanceUID.c_str() ) ); statement.bindValue ( 1, filename ); statement.bindValue ( 2, QString ( seriesInstanceUID.c_str() ) ); statement.bindValue ( 3, QDateTime::currentDateTime() ); statement.exec(); } } if(generateThumbnail){ if(d->thumbnailGenerator){ QString studySeriesDirectory = QString(studyInstanceUID.c_str()) + "/" + QString(seriesInstanceUID.c_str()); //Create thumbnail here QString thumbnailPath = databaseDirectory() + "/thumbs/" + this->pathForDataset(dataset) + ".png"; //QString(studyInstanceUID.c_str()) + "/" + //QString(seriesInstanceUID.c_str()) + "/" + //QString(sopInstanceUID.c_str()) + ".png"; QFileInfo thumbnailInfo(thumbnailPath); if(!(thumbnailInfo.exists() && (thumbnailInfo.lastModified() > QFileInfo(filename).lastModified()))){ QDir(databaseDirectory() + "/thumbs/").mkpath(studySeriesDirectory); DicomImage dcmImage(QDir::toNativeSeparators(filename).toAscii()); d->thumbnailGenerator->generateThumbnail(&dcmImage, thumbnailPath); } } } if (isInMemory()) { emit databaseChanged(); } }
virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const { notice()<<"Reading DICOM file "<<file<<" using DCMTK"<<std::endl; std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = file; if (ext=="dicom") { fileName = osgDB::getNameLessExtension(file); } fileName = osgDB::findDataFile( fileName, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; Files files; osgDB::FileType fileType = osgDB::fileType(fileName); if (fileType==osgDB::DIRECTORY) { getDicomFilesInDirectory(fileName, files); } else { #if 1 files.push_back(fileName); #else if (!getDicomFilesInDirectory(osgDB::getFilePath(fileName), files)) { files.push_back(fileName); } #endif } if (files.empty()) { return ReadResult::FILE_NOT_FOUND; } osg::ref_ptr<osg::RefMatrix> matrix = new osg::RefMatrix; osg::ref_ptr<osg::Image> image; unsigned int imageNum = 0; EP_Representation pixelRep = EPR_Uint8; int numPlanes = 0; GLenum pixelFormat = 0; GLenum dataType = 0; unsigned int pixelSize = 0; typedef std::list<FileInfo> FileInfoList; FileInfoList fileInfoList; typedef std::map<double, FileInfo> DistanceFileInfoMap; typedef std::map<osg::Vec3d, DistanceFileInfoMap> OrientationFileInfoMap; OrientationFileInfoMap orientationFileInfoMap; unsigned int totalNumSlices = 0; for(Files::iterator itr = files.begin(); itr != files.end(); ++itr) { DcmFileFormat fileformat; OFCondition status = fileformat.loadFile((*itr).c_str()); if(!status.good()) return ReadResult::ERROR_IN_READING_FILE; FileInfo fileInfo; fileInfo.filename = *itr; double pixelSize_y = 1.0; double pixelSize_x = 1.0; double sliceThickness = 1.0; double imagePositionPatient[3] = {0, 0, 0}; double imageOrientationPatient[6] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0 }; Uint16 numOfSlices = 1; double value = 0.0; if (fileformat.getDataset()->findAndGetFloat64(DCM_PixelSpacing, value,0).good()) { pixelSize_y = value; fileInfo.matrix(1,1) = pixelSize_y; } if (fileformat.getDataset()->findAndGetFloat64(DCM_PixelSpacing, value,1).good()) { pixelSize_x = value; fileInfo.matrix(0,0) = pixelSize_x; } // Get slice thickness if (fileformat.getDataset()->findAndGetFloat64(DCM_SliceThickness, value).good()) { sliceThickness = value; notice()<<"sliceThickness = "<<sliceThickness<<std::endl; fileInfo.sliceThickness = sliceThickness; } notice()<<"tagExistsWithValue(DCM_NumberOfFrames)="<<fileformat.getDataset()->tagExistsWithValue(DCM_NumberOfFrames)<<std::endl; notice()<<"tagExistsWithValue(DCM_NumberOfSlices)="<<fileformat.getDataset()->tagExistsWithValue(DCM_NumberOfSlices)<<std::endl; Uint32 numFrames; if (fileformat.getDataset()->findAndGetUint32(DCM_NumberOfFrames, numFrames).good()) { fileInfo.numSlices = numFrames; notice()<<"Read number of frames = "<<numFrames<<std::endl; } OFString numFramesStr; if (fileformat.getDataset()->findAndGetOFString(DCM_NumberOfFrames, numFramesStr).good()) { fileInfo.numSlices = atoi(numFramesStr.c_str()); notice()<<"Read number of frames = "<<numFramesStr<<std::endl; } if (fileformat.getDataset()->findAndGetUint16(DCM_NumberOfFrames, numOfSlices).good()) { fileInfo.numSlices = numOfSlices; notice()<<"Read number of frames = "<<numOfSlices<<std::endl; } if (fileformat.getDataset()->findAndGetUint16(DCM_NumberOfSlices, numOfSlices).good()) { fileInfo.numSlices = numOfSlices; notice()<<"Read number of slices = "<<numOfSlices<<std::endl; } // patient position for(int i=0; i<3; ++i) { if (fileformat.getDataset()->findAndGetFloat64(DCM_ImagePositionPatient, imagePositionPatient[i],i).good()) { notice()<<"Read DCM_ImagePositionPatient["<<i<<"], "<<imagePositionPatient[i]<<std::endl; } else { notice()<<"Have not read DCM_ImagePositionPatient["<<i<<"]"<<std::endl; } } //notice()<<"imagePositionPatient[2]="<<imagePositionPatient[2]<<std::endl; fileInfo.matrix.setTrans(imagePositionPatient[0],imagePositionPatient[1],imagePositionPatient[2]); for(int i=0; i<6; ++i) { double value = 0.0; if (fileformat.getDataset()->findAndGetFloat64(DCM_ImageOrientationPatient, value,i).good()) { imageOrientationPatient[i] = value; notice()<<"Read imageOrientationPatient["<<i<<"], "<<imageOrientationPatient[i]<<std::endl; } else { notice()<<"Have not read imageOrientationPatient["<<i<<"]"<<std::endl; } } osg::Vec3d dirX(imageOrientationPatient[0],imageOrientationPatient[1],imageOrientationPatient[2]); osg::Vec3d dirY(imageOrientationPatient[3],imageOrientationPatient[4],imageOrientationPatient[5]); osg::Vec3d dirZ = dirX ^ dirY; dirZ.normalize(); dirX *= pixelSize_x; dirY *= pixelSize_y; fileInfo.matrix(0,0) = dirX[0]; fileInfo.matrix(1,0) = dirX[1]; fileInfo.matrix(2,0) = dirX[2]; fileInfo.matrix(0,1) = dirY[0]; fileInfo.matrix(1,1) = dirY[1]; fileInfo.matrix(2,1) = dirY[2]; fileInfo.matrix(0,2) = dirZ[0]; fileInfo.matrix(1,2) = dirZ[1]; fileInfo.matrix(2,2) = dirZ[2]; fileInfo.distance = dirZ * (osg::Vec3d(0.0,0.0,0.0)*fileInfo.matrix); notice()<<"dirX = "<<dirX<<std::endl; notice()<<"dirY = "<<dirY<<std::endl; notice()<<"dirZ = "<<dirZ<<std::endl; notice()<<"matrix = "<<fileInfo.matrix<<std::endl; notice()<<"pos = "<<osg::Vec3d(0.0,0.0,0.0)*fileInfo.matrix<<std::endl; notice()<<"dist = "<<fileInfo.distance<<std::endl; notice()<<std::endl; (orientationFileInfoMap[dirZ])[fileInfo.distance] = fileInfo; totalNumSlices += fileInfo.numSlices; } if (orientationFileInfoMap.empty()) return 0; typedef std::map<double, FileInfo> DistanceFileInfoMap; typedef std::map<osg::Vec3d, DistanceFileInfoMap> OrientationFileInfoMap; for(OrientationFileInfoMap::iterator itr = orientationFileInfoMap.begin(); itr != orientationFileInfoMap.end(); ++itr) { notice()<<"Orientation = "<<itr->first<<std::endl; DistanceFileInfoMap& dfim = itr->second; for(DistanceFileInfoMap::iterator ditr = dfim.begin(); ditr != dfim.end(); ++ditr) { FileInfo& fileInfo = ditr->second; notice()<<" d = "<<fileInfo.distance<<" "<<fileInfo.filename<<std::endl; } } DistanceFileInfoMap& dfim = orientationFileInfoMap.begin()->second; if (dfim.empty()) return 0; double totalDistance = 0.0; if (dfim.size()>1) { totalDistance = fabs(dfim.rbegin()->first - dfim.begin()->first); } else { totalDistance = dfim.begin()->second.sliceThickness * double(dfim.begin()->second.numSlices); } notice()<<"Total Distance including ends "<<totalDistance<<std::endl; double averageThickness = totalNumSlices<=1 ? 1.0 : totalDistance / double(totalNumSlices-1); notice()<<"Average thickness "<<averageThickness<<std::endl; for(DistanceFileInfoMap::iterator ditr = dfim.begin(); ditr != dfim.end(); ++ditr) { FileInfo& fileInfo = ditr->second; std::auto_ptr<DicomImage> dcmImage(new DicomImage(fileInfo.filename.c_str())); if (dcmImage.get()) { if (dcmImage->getStatus()==EIS_Normal) { // get the pixel data const DiPixel* pixelData = dcmImage->getInterData(); if(!pixelData) { warning()<<"Error: no data in DicomImage object."<<std::endl; return ReadResult::ERROR_IN_READING_FILE; } osg::ref_ptr<osg::Image> imageAdapter = new osg::Image; EP_Representation curr_pixelRep; int curr_numPlanes; GLenum curr_pixelFormat; GLenum curr_dataType; unsigned int curr_pixelSize; // create the new image convertPixelTypes(pixelData, curr_pixelRep, curr_numPlanes, curr_dataType, curr_pixelFormat, curr_pixelSize); imageAdapter->setImage(dcmImage->getWidth(), dcmImage->getHeight(), dcmImage->getFrameCount(), curr_pixelFormat, curr_pixelFormat, curr_dataType, (unsigned char*)(pixelData->getData()), osg::Image::NO_DELETE); if (!image) { pixelRep = curr_pixelRep; numPlanes = curr_numPlanes; dataType = curr_dataType; pixelFormat = curr_pixelFormat; pixelSize = curr_pixelSize; (*matrix)(0,0) = fileInfo.matrix(0,0); (*matrix)(1,0) = fileInfo.matrix(1,0); (*matrix)(2,0) = fileInfo.matrix(2,0); (*matrix)(0,1) = fileInfo.matrix(0,1); (*matrix)(1,1) = fileInfo.matrix(1,1); (*matrix)(2,1) = fileInfo.matrix(2,1); (*matrix)(0,2) = fileInfo.matrix(0,2) * averageThickness; (*matrix)(1,2) = fileInfo.matrix(1,2) * averageThickness; (*matrix)(2,2) = fileInfo.matrix(2,2) * averageThickness; image = new osg::Image; image->setUserData(matrix.get()); image->setFileName(fileName.c_str()); image->allocateImage(dcmImage->getWidth(), dcmImage->getHeight(), totalNumSlices, pixelFormat, dataType); matrix->preMult(osg::Matrix::scale(double(image->s()), double(image->t()), double(image->r()))); notice()<<"Image dimensions = "<<image->s()<<", "<<image->t()<<", "<<image->r()<<" pixelFormat=0x"<<std::hex<<pixelFormat<<" dataType=0x"<<std::hex<<dataType<<std::dec<<std::endl; } else if (pixelData->getPlanes()>numPlanes || pixelData->getRepresentation()>pixelRep) { notice()<<"Need to reallocated "<<image->s()<<", "<<image->t()<<", "<<image->r()<<std::endl; // record the previous image settings to use when we copy back the content. osg::ref_ptr<osg::Image> previous_image = image; // create the new image convertPixelTypes(pixelData, pixelRep, numPlanes, dataType, pixelFormat, pixelSize); image = new osg::Image; image->setUserData(previous_image->getUserData()); image->setFileName(fileName.c_str()); image->allocateImage(dcmImage->getWidth(), dcmImage->getHeight(), totalNumSlices, pixelFormat, dataType); osg::copyImage(previous_image.get(), 0,0,0, previous_image->s(), previous_image->t(), imageNum, image.get(), 0, 0, 0, false); } osg::copyImage(imageAdapter.get(), 0,0,0, imageAdapter->s(), imageAdapter->t(), imageAdapter->r(), image.get(), 0, 0, imageNum, false); imageNum += dcmImage->getFrameCount(); } else { warning()<<"Error in reading dicom file "<<fileName.c_str()<<", error = "<<DicomImage::getString(dcmImage->getStatus())<<std::endl; } } } if (!image) { return ReadResult::ERROR_IN_READING_FILE; } notice()<<"Spacing = "<<*matrix<<std::endl; return image.get(); }
bool CreateResource(DcmDirectoryRecord*& target, ResourceType level, DcmFileFormat& dicom, const char* filename, const char* path) { DcmDataset& dataset = *dicom.getDataset(); OFCondition result; OFString id; E_DirRecType type; switch (level) { case ResourceType_Patient: result = dataset.findAndGetOFString(DCM_PatientID, id); type = ERT_Patient; break; case ResourceType_Study: result = dataset.findAndGetOFString(DCM_StudyInstanceUID, id); type = ERT_Study; break; case ResourceType_Series: result = dataset.findAndGetOFString(DCM_SeriesInstanceUID, id); type = ERT_Series; break; case ResourceType_Instance: result = dataset.findAndGetOFString(DCM_SOPInstanceUID, id); type = ERT_Image; break; default: throw OrthancException(ErrorCode_InternalError); } if (!result.good()) { throw OrthancException(ErrorCode_InternalError); } IndexKey key = std::make_pair(level, std::string(id.c_str())); Index::iterator it = index_.find(key); if (it != index_.end()) { target = it->second; return false; // Already existing } std::auto_ptr<DcmDirectoryRecord> record(new DcmDirectoryRecord(type, NULL, filename)); switch (level) { case ResourceType_Patient: FillPatient(*record, dataset); break; case ResourceType_Study: FillStudy(*record, dataset); break; case ResourceType_Series: FillSeries(*record, dataset); break; case ResourceType_Instance: FillInstance(*record, dataset, *dicom.getMetaInfo(), path); break; default: throw OrthancException(ErrorCode_InternalError); } if (record->isAffectedBySpecificCharacterSet()) { copyElementType1C(dataset, DCM_SpecificCharacterSet, *record); } target = record.get(); GetRoot().insertSub(record.release()); index_[key] = target; return true; // Newly created }
std::vector<BaseData::Pointer> DICOMSegmentationIO::Read() { mitk::LocaleSwitch localeSwitch("C"); LabelSetImage::Pointer labelSetImage; std::vector<BaseData::Pointer> result; const std::string path = this->GetLocalFileName(); MITK_INFO << "loading " << path << std::endl; if (path.empty()) mitkThrow() << "Empty filename in mitk::ItkImageIO "; try { // Get the dcm data set from file path DcmFileFormat dcmFileFormat; OFCondition status = dcmFileFormat.loadFile(path.c_str()); if (status.bad()) mitkThrow() << "Can't read the input file!"; DcmDataset *dataSet = dcmFileFormat.getDataset(); if (dataSet == nullptr) mitkThrow() << "Can't read data from input file!"; // Read the DICOM SEG images (segItkImages) and DICOM tags (metaInfo) dcmqi::ImageSEGConverter *converter = new dcmqi::ImageSEGConverter(); pair<map<unsigned, ImageType::Pointer>, string> dcmqiOutput = converter->dcmSegmentation2itkimage(dataSet); map<unsigned, ImageType::Pointer> segItkImages = dcmqiOutput.first; // For each itk image add a layer to the LabelSetImage output for (auto &element : segItkImages) { // Get the labeled image and cast it to mitkImage typedef itk::CastImageFilter<itkInternalImageType, itkInputImageType> castItkImageFilterType; castItkImageFilterType::Pointer castFilter = castItkImageFilterType::New(); castFilter->SetInput(element.second); castFilter->Update(); Image::Pointer layerImage; CastToMitkImage(castFilter->GetOutput(), layerImage); // Get pixel value of the label itkInternalImageType::ValueType segValue = 1; typedef itk::ImageRegionIterator<const itkInternalImageType> IteratorType; // Iterate over the image to find the pixel value of the label IteratorType iter(element.second, element.second->GetLargestPossibleRegion()); iter.GoToBegin(); while (!iter.IsAtEnd()) { itkInputImageType::PixelType value = iter.Get(); if (value != 0) { segValue = value; break; } ++iter; } dcmqi::JSONSegmentationMetaInformationHandler metaInfo(dcmqiOutput.second.c_str()); metaInfo.read(); MITK_INFO << "Input " << metaInfo.getJSONOutputAsString(); // TODO: Read all DICOM Tags // Get the label information from segment attributes vector<map<unsigned, dcmqi::SegmentAttributes *>>::const_iterator segmentIter = metaInfo.segmentsAttributesMappingList.begin(); map<unsigned, dcmqi::SegmentAttributes *> segmentMap = (*segmentIter); map<unsigned, dcmqi::SegmentAttributes *>::const_iterator segmentMapIter = (*segmentIter).begin(); dcmqi::SegmentAttributes *segmentAttr = (*segmentMapIter).second; OFString labelName; if (segmentAttr->getSegmentedPropertyTypeCodeSequence() != nullptr) segmentAttr->getSegmentedPropertyTypeCodeSequence()->getCodeMeaning(labelName); else { labelName = std::to_string(segmentAttr->getLabelID()).c_str(); if (labelName.empty()) labelName = "Unnamed"; } float tmp[3] = {0.0, 0.0, 0.0}; if (segmentAttr->getRecommendedDisplayRGBValue() != nullptr) { tmp[0] = segmentAttr->getRecommendedDisplayRGBValue()[0] / 255.0; tmp[1] = segmentAttr->getRecommendedDisplayRGBValue()[1] / 255.0; tmp[2] = segmentAttr->getRecommendedDisplayRGBValue()[2] / 255.0; } // If labelSetImage do not exists (first image) if (labelSetImage.IsNull()) { // Initialize the labelSetImage with the read image labelSetImage = LabelSetImage::New(); labelSetImage->InitializeByLabeledImage(layerImage); // Already a label was generated, so set the information to this Label *activeLabel = labelSetImage->GetActiveLabel(labelSetImage->GetActiveLayer()); activeLabel->SetName(labelName.c_str()); activeLabel->SetColor(Color(tmp)); activeLabel->SetValue(segValue); } else { // Add a new layer to the labelSetImage. Background label is set automatically labelSetImage->AddLayer(layerImage); // Add new label Label *newLabel = new Label; newLabel->SetName(labelName.c_str()); newLabel->SetColor(Color(tmp)); newLabel->SetValue(segValue); labelSetImage->GetLabelSet(labelSetImage->GetActiveLayer())->AddLabel(newLabel); } ++segmentIter; } // Clean up if (converter != nullptr) delete converter; } catch (const std::exception &e) { MITK_ERROR << "An error occurred while reading the DICOM Seg file: " << e.what(); return result; } // Set active layer to th first layer of the labelset image if (labelSetImage->GetNumberOfLayers() > 1 && labelSetImage->GetActiveLayer() != 0) labelSetImage->SetActiveLayer(0); result.push_back(labelSetImage.GetPointer()); return result; }
std::vector<itk::SmartPointer<mitk::BaseData> > mitk::FiberBundleDicomReader::Read() { std::vector<itk::SmartPointer<mitk::BaseData> > output_fibs; try { const std::string& locale = "C"; const std::string& currLocale = setlocale( LC_ALL, nullptr ); setlocale(LC_ALL, locale.c_str()); std::string filename = this->GetInputLocation(); OFCondition result; TrcTractographyResults *trc = nullptr; result = TrcTractographyResults::loadFile(filename.c_str(), trc); if (result.bad()) mitkThrow() << "Unable to load tractography dicom file: " << result.text(); OFString val = "-"; trc->getPatient().getPatientName(val); MITK_INFO << "Patient Name: " << val; val = "-"; trc->getStudy().getStudyInstanceUID(val); MITK_INFO << "Study : " << val; val = "-"; trc->getSeries().getSeriesInstanceUID(val); MITK_INFO << "Series : " << val; val = "-"; trc->getSOPCommon().getSOPInstanceUID(val); MITK_INFO << "Instance : " << val; val = "-"; MITK_INFO << "-------------------------------------------------------------------------"; size_t numTrackSets = trc->getNumberOfTrackSets(); OFVector<TrcTrackSet*>& sets = trc->getTrackSets(); for (size_t ts = 0; ts < numTrackSets; ts++) { size_t numTracks = sets[ts]->getNumberOfTracks(); MITK_INFO << " Track Set #" << ts << ": " << numTracks << " Tracks, " << sets[ts]->getNumberOfTrackSetStatistics() << " Track Set Statistics, " << sets[ts]->getNumberOfTrackStatistics() << " Track Statistics, " << sets[ts]->getNumberOfMeasurements() << " Measurements "; vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New(); for (size_t t = 0; t < numTracks; t++) { vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New(); TrcTrack* track = sets[ts]->getTracks()[t]; const Float32* vals = nullptr; size_t numPoints = track->getTrackData(vals); for (size_t v = 0; v < numPoints; ++v) { vtkIdType id = vtkNewPoints->InsertNextPoint(vals[v*3],vals[v*3+1],vals[v*3+2]); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } vtkSmartPointer<vtkPolyData> fiberPolyData = vtkSmartPointer<vtkPolyData>::New(); fiberPolyData->SetPoints(vtkNewPoints); fiberPolyData->SetLines(vtkNewCells); // // transform polydata from RAS (MRtrix) to LPS (MITK) // mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); // vtkSmartPointer< vtkMatrix4x4 > matrix = vtkSmartPointer< vtkMatrix4x4 >::New(); // matrix->Identity(); // matrix->SetElement(0,0,-matrix->GetElement(0,0)); // matrix->SetElement(1,1,-matrix->GetElement(1,1)); // geometry->SetIndexToWorldTransformByVtkMatrix(matrix); // vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New(); // transformFilter->SetInputData(fiberPolyData); // transformFilter->SetTransform(geometry->GetVtkTransform()); // transformFilter->Update(); FiberBundle::Pointer fib = FiberBundle::New(fiberPolyData); CodeSequenceMacro* algoCode = sets[ts]->getTrackingAlgorithmIdentification().at(0); val = "-"; algoCode->getCodeValue(val); fib->GetPropertyList()->SetStringProperty("DICOM.algo_code.value",val.c_str()); val = "-"; algoCode->getCodeMeaning(val); fib->GetPropertyList()->SetStringProperty("DICOM.algo_code.meaning",val.c_str()); CodeSequenceMacro modelCode = sets[ts]->getDiffusionModelCode(); val = "-"; modelCode.getCodeValue(val); fib->GetPropertyList()->SetStringProperty("DICOM.model_code.value",val.c_str()); val = "-"; modelCode.getCodeMeaning(val); fib->GetPropertyList()->SetStringProperty("DICOM.model_code.meaning",val.c_str()); CodeWithModifiers anatomy = sets[ts]->getTrackSetAnatomy(); val = "-"; anatomy.getCodeValue(val); fib->GetPropertyList()->SetStringProperty("DICOM.anatomy.value",val.c_str()); val = "-"; anatomy.getCodeMeaning(val); fib->GetPropertyList()->SetStringProperty("DICOM.anatomy.meaning",val.c_str()); val = "-"; trc->getPatient().getPatientID(val); fib->GetPropertyList()->SetStringProperty("DICOM.patient_id",val.c_str()); val = "-"; trc->getPatient().getPatientName(val); fib->GetPropertyList()->SetStringProperty("DICOM.patient_name",val.c_str()); val = "-"; trc->getStudy().getStudyInstanceUID(val); fib->GetPropertyList()->SetStringProperty("DICOM.study_instance_uid",val.c_str()); val = "-"; trc->getSeries().getSeriesInstanceUID(val); fib->GetPropertyList()->SetStringProperty("DICOM.series_instance_uid",val.c_str()); val = "-"; trc->getSOPCommon().getSOPInstanceUID(val); fib->GetPropertyList()->SetStringProperty("DICOM.sop_instance_uid",val.c_str()); val = "-"; trc->getSOPCommon().getSOPClassUID(val); fib->GetPropertyList()->SetStringProperty("DICOM.sop_class_uid",val.c_str()); val = "-"; trc->getFrameOfReference().getFrameOfReferenceUID(val); fib->GetPropertyList()->SetStringProperty("DICOM.frame_of_reference_uid",val.c_str()); output_fibs.push_back(fib.GetPointer()); MITK_INFO << "Fiber bundle read"; } delete trc; setlocale(LC_ALL, currLocale.c_str()); return output_fibs; } catch(...) { throw; } return output_fibs; }
//------------------------------------------------------------------------------ bool ctkDICOMRetrievePrivate::retrieve ( QString UID, RetrieveType retriveType ) { if ( !this->RetrieveDatabase ) { logger.error ( "Must have RetrieveDatabase for retrieve transaction" ); return false; } // Register the JPEG libraries in case we need them // (registration only happens once, so it's okay to call repeatedly) // register global JPEG decompression codecs DJDecoderRegistration::registerCodecs(); // register global JPEG compression codecs DJEncoderRegistration::registerCodecs(); // register RLE compression codec DcmRLEEncoderRegistration::registerCodecs(); // register RLE decompression codec DcmRLEDecoderRegistration::registerCodecs(); // Set the DCMTK log level log4cplus::Logger rootLogger = log4cplus::Logger::getRoot(); rootLogger.setLogLevel(log4cplus::DEBUG_LOG_LEVEL); // TODO: use this->SCU instead ? DcmSCU scu; scu.setAETitle ( OFString(this->CallingAETitle.toStdString().c_str()) ); scu.setPort ( this->CallingPort ); scu.setPeerAETitle ( OFString(this->CalledAETitle.toStdString().c_str()) ); scu.setPeerHostName ( OFString(this->Host.toStdString().c_str()) ); scu.setPeerPort ( this->CalledPort ); scu.setMoveDestinationAETitle ( OFString(this->MoveDestinationAETitle.toStdString().c_str()) ); logger.info ( "Setting Transfer Syntaxes" ); OFList<OFString> transferSyntaxes; transferSyntaxes.push_back ( UID_LittleEndianExplicitTransferSyntax ); transferSyntaxes.push_back ( UID_BigEndianExplicitTransferSyntax ); transferSyntaxes.push_back ( UID_LittleEndianImplicitTransferSyntax ); scu.addPresentationContext ( UID_FINDStudyRootQueryRetrieveInformationModel, transferSyntaxes ); scu.addPresentationContext ( UID_MOVEStudyRootQueryRetrieveInformationModel, transferSyntaxes ); if ( !scu.initNetwork().good() ) { logger.error ( "Error initializing the network" ); return false; } logger.debug ( "Negotiating Association" ); if ( !scu.negotiateAssociation().good() ) { logger.error ( "Error negotiating association" ); return false;; } logger.debug ( "Setting Parameters" ); // Clear the query unsigned long elements = this->parameters->card(); // Clean it out for ( unsigned long i = 0; i < elements; i++ ) { this->parameters->remove ( 0ul ); } if ( retriveType == RetrieveSeries ) { this->parameters->putAndInsertString ( DCM_QueryRetrieveLevel, "SERIES" ); this->parameters->putAndInsertString ( DCM_SeriesInstanceUID, UID.toStdString().c_str() ); } else { this->parameters->putAndInsertString ( DCM_QueryRetrieveLevel, "STUDY" ); this->parameters->putAndInsertString ( DCM_StudyInstanceUID, UID.toStdString().c_str() ); } logger.debug ( "Sending Move Request" ); MOVEResponses *responses = new MOVEResponses(); OFCondition status = scu.sendMOVERequest ( 0, this->parameters, responses ); if (!status.good()) { logger.error ( "MOVE Request failed: " + QString ( status.text() ) ); return false; } logger.debug ( "Find succeded" ); logger.debug ( "Making Output Directory" ); QDir directory = QDir( RetrieveDatabase->databaseDirectory() ); if ( responses->begin() == responses->end() ) { logger.error ( "No responses!" ); throw std::runtime_error( std::string("No responses!") ); } // Write the responses out to disk for ( OFListIterator(FINDResponse*) it = responses->begin(); it != responses->end(); it++ ) { DcmDataset *dataset = (*it)->m_dataset; if ( dataset != NULL ) { logger.debug ( "Got a valid dataset" ); // Save in correct directory E_TransferSyntax output_transfersyntax = dataset->getOriginalXfer(); dataset->chooseRepresentation( output_transfersyntax, NULL ); if ( !dataset->canWriteXfer( output_transfersyntax ) ) { // Pick EXS_LittleEndianExplicit as our default output_transfersyntax = EXS_LittleEndianExplicit; } DcmXfer opt_oxferSyn( output_transfersyntax ); if ( !dataset->chooseRepresentation( opt_oxferSyn.getXfer(), NULL ).bad() ) { DcmFileFormat* fileformat = new DcmFileFormat ( dataset ); // Follow dcmdjpeg example fileformat->loadAllDataIntoMemory(); OFString SOPInstanceUID; dataset->findAndGetOFString ( DCM_SOPInstanceUID, SOPInstanceUID ); QFileInfo fi ( directory, QString ( SOPInstanceUID.c_str() ) ); logger.debug ( "Saving file: " + fi.absoluteFilePath() ); status = fileformat->saveFile ( fi.absoluteFilePath().toStdString().c_str(), opt_oxferSyn.getXfer() ); if ( !status.good() ) { logger.error ( "Error saving file: " + fi.absoluteFilePath() + " Error is " + status.text() ); } RetrieveDatabase->insert( dataset, true ); delete fileformat; } } } delete responses; //if ( !scu.dropNetwork().good() ) //{ //logger.error ( "Error dropping the network" ); //return false; //} return true; }
bool IODicom<T>::GetAttributes(PGCore::MetaData<T>& oMetaDataObject, const std::string &iFilePath) { #ifdef _DEBUG LOG0("{ IODicom::GetAttributes"); #endif if (iFilePath.empty()) { LOG0("IO/IODicom::GetAttributes Empty filename"); return false; } #ifdef _PG_GDDCM_ #else OFCondition status = m_fileformat.loadFile(iFilePath.c_str()); if (!status.good()) { LOG2("IO/IODicom::GetAttributes: Cannot read dicom file %s: (%s).", iFilePath.c_str(), status.text()); return false; } #ifdef _DEBUG LOG2("\tIODicom::GetAttributes: Successfully read dicom file %s: (%s).", iFilePath.c_str(), status.text()); #endif // read the meta file here //LOG1("IO/IOBase::ReadMetaData: File: %s", iMetaFileName.c_str()); DcmDataset *dataset = m_fileformat.getDataset(); if (dataset==NULL) { return false; } // patient name OFString patientsName; bool res = dataset->findAndGetOFString(DCM_PatientsName, patientsName).good(); if (!res) { LOG0("IO/IODicom::Read: Cannot fetch patient name"); return false; } oMetaDataObject.SetPatientName(std::string(patientsName.c_str())); #ifdef _DEBUG LOG1("\tIODicom::Read: Successfully read PatientName: (%s).", patientsName.c_str()); #endif // modality OFString modalityStr; res = dataset->findAndGetOFString(DCM_Modality, modalityStr).good(); if (!res) { LOG0("IO/IODicom::Read: Cannot fetch modality"); return false; } PGCore::ePGModality modality = PGCore::MetaData<T>::StrToModality(modalityStr.c_str()); oMetaDataObject.SetModality(modality); #ifdef _DEBUG LOG1("\tIODicom::Read: Successfully read Modality: (%s).", modalityStr.c_str()); #endif // SOP Class UID OFString sopClassUIDStr; DcmMetaInfo *metaInfo = m_fileformat.getMetaInfo(); if (metaInfo) { metaInfo->findAndGetOFString(DCM_MediaStorageSOPClassUID, sopClassUIDStr); PGCore::ePGSOPClass sopClass = PGCore::MetaData<T>::StrToSOPClass(sopClassUIDStr.c_str()); oMetaDataObject.SetSOPClass(sopClass); // DCM_TransferSyntaxUID OFString transferSyntaxStr; res = metaInfo->findAndGetOFString(DCM_TransferSyntaxUID, transferSyntaxStr).good(); if (!res) { LOG0("IO/IODicom::Read:Warning: Cannot fetch TransferSyntaxUID"); } else { if (!strcmp(kPgTransferSyntaxUIDRawImplicitVRLittleEndian, transferSyntaxStr.c_str())) { oMetaDataObject.SetMSBFirst(0); } else if (!strcmp(kPgTransferSyntaxUIDRawExplicitVRLittle, transferSyntaxStr.c_str())) { oMetaDataObject.SetMSBFirst(0); } else if (!strcmp(kPgTransferSyntaxUIDRawExplicitVRLittle, transferSyntaxStr.c_str())) { oMetaDataObject.SetMSBFirst(1); } else if (!strcmp(kPgTransferSyntaxUIDLossLessRLE, transferSyntaxStr.c_str())) { LOG0("IO/IODicom::Read: Cannot read RLE compressed images yet"); return false; } else { std::string tstr(transferSyntaxStr.c_str()); std::string filterStr(kPgTransferSyntaxUIDJPEG); PGCore::ToUpper(tstr); PGCore::ToUpper(filterStr); size_t found=tstr.find(filterStr); bool isJPEG = (found!=string::npos); if (isJPEG) { LOG0("IO/IODicom::Read: Cannot read JPEG images yet"); return false; } } } } DcmItem *ditem = OFstatic_cast(DcmItem *, dataset); if (!ditem) { LOG0("IO/IODicom::Read: Cannot fetch ditem"); return false; } // Samples Per Pixel Uint16 samplesPerPixel = 0; res = ditem->findAndGetUint16(DCM_SamplesPerPixel, samplesPerPixel).good(); if (!res) { LOG0("IO/IODicom::Read: Warning: Cannot fetch SamplesPerPixel"); } else if (samplesPerPixel > sizeof(T)) { LOG2("IO/IODicom::Read: Cannot read SamplesPerPixel: %d, target resolution smaller: %d yet", samplesPerPixel, sizeof(T)); return false; } oMetaDataObject.SetSamplesPerPixel(samplesPerPixel); // DCM_PhotometricInterpretation OFString photoInterpretationStr; res = metaInfo->findAndGetOFString(DCM_PhotometricInterpretation, photoInterpretationStr).good(); if (!res) { #ifdef _DEBUG LOG0("IO/IODicom::Read:Warning Cannot fetch PhotometricInterpretation"); #endif } else if (strcmp(kPgPhotometricRepresentationMChrome2, photoInterpretationStr.c_str())) { #ifdef _DEBUG LOG1("IO/IODicom::Read: Cannot read PhotometricInterpretation %s", photoInterpretationStr.c_str()); #endif return false; } // DCM_NumberOfFrames long numFrames = 1; res = dataset->findAndGetLongInt(DCM_NumberOfFrames, numFrames).good(); if (!res) { #ifdef _DEBUG LOG0("IO/IODicom::Read: Warning: Cannot fetch NumberOfFrames"); #endif oMetaDataObject.SetFrameCount(1); } else { oMetaDataObject.SetFrameCount(numFrames); } // size Uint16 imageRows = 0; Uint16 imageColumns = 0; res = ditem->findAndGetUint16(DCM_Rows, imageRows).good(); if (!res) { LOG0("IO/IODicom::Read: Cannot fetch rows"); return false; } res = ditem->findAndGetUint16(DCM_Columns, imageColumns).good(); if (!res) { LOG0("IO/IODicom::Read: Cannot fetch columns"); return false; } oMetaDataObject.SetSize(PGMath::Vector3D<int>(imageColumns, imageRows, 1)); #ifdef _DEBUG LOG2("\tIODicom::Read: Size: Rows: %d, Columns: %d", imageRows, imageColumns); #endif // number of bits Uint16 imageBitsAllocated = 0; res = ditem->findAndGetUint16(DCM_BitsAllocated, imageBitsAllocated).good(); if (!res) { LOG0("IO/IODicom::Read: Cannot fetch bits allocated"); return false; } oMetaDataObject.SetNumberOfBits(imageBitsAllocated); #ifdef _DEBUG LOG1("\tIODicom::Read: bits allocated: %d", imageBitsAllocated); #endif // spacing Float64 sx=1, sy=1; DcmElement *elem = 0; OFCondition cond = dataset->findAndGetElement(DCM_PixelSpacing, elem); if(!cond.good()) { LOG1("IO/IODicom::Read:Warning Cannot fetch pixel spacing (%s)", cond.text()); } else { cond = elem->getFloat64(sx, 0); if(!cond.good()) { LOG1("IO/IODicom::Read:Warning Cannot fetch pixel X spacing (%s)", cond.text()); } cond = elem->getFloat64(sy, 1); if(!cond.good()) { LOG1("IO/IODicom::Read:Warning Cannot fetch pixel Y spacing (%s)", cond.text()); } } if (sx!=sy) { LOG2("IO/IODicom::Read:Warning: X/Y spacings (%3.2f, %3.2f) mismatch. Ignoring anisotrpy", sx, sy); sy = sx; } #ifdef _DEBUG LOG2("\tIODicom::Read: pixel X and Y spacings (%3.5f %3.5f)",sx, sy); #endif oMetaDataObject.SetSpacing(PGMath::Vector3D<float>(sx, sy, 1)); // STUDY UID OFString studyUIDStr; res = dataset->findAndGetOFString(DCM_StudyInstanceUID, studyUIDStr).good(); if (!res) { LOG0("IO/IODicom::Read:Warning Cannot fetch StudyUID"); } else { oMetaDataObject.SetStudyUID(std::string(studyUIDStr.c_str())); } // series UID OFString seriesUIDStr; res = dataset->findAndGetOFString(DCM_SeriesInstanceUID, seriesUIDStr).good(); if (!res) { LOG0("IO/IODicom::Read:Warning Cannot fetch seriesUID"); } else { oMetaDataObject.SetSeriesUID(std::string(seriesUIDStr.c_str())); //LOG1("IO/IODicom::Read:seriesUID : %s", oMetaDataObject.GetSeriesUID().c_str()); } // orientation Float64 rowOr[3] = { 1.0f, 0.0f, 0.0f }, colOr[3] = { 0.0f, 1.0f, 0.0f }; std::vector<PGMath::Vector3D<float> > orXs; std::vector<PGMath::Vector3D<float> > orYs; cond = dataset->findAndGetElement(DCM_ImageOrientationPatient, elem); if(!cond.good()) { LOG1("IO/IODicom::Read:Warning Cannot fetch DCM_ImageOrientationPatient (%s)", cond.text()); } else { elem->getFloat64(rowOr[0], 0); elem->getFloat64(rowOr[1], 1); elem->getFloat64(rowOr[2], 2); elem->getFloat64(colOr[0], 3); elem->getFloat64(colOr[1], 4); elem->getFloat64(colOr[2], 5); } orXs.push_back(PGMath::Vector3D<float>(rowOr[0], rowOr[1], rowOr[2])); oMetaDataObject.SetImageOrientationsPatientX(orXs); #ifdef _DEBUG LOG3("\tIODicom::Read: Image Row vector orientation (%3.5f %3.5f %3.5f)", rowOr[0], rowOr[1], rowOr[2]); #endif orYs.push_back(PGMath::Vector3D<float>(colOr[0], colOr[1], colOr[2])); oMetaDataObject.SetImageOrientationsPatientY(orYs); #ifdef _DEBUG LOG3("\tIODicom::Read: Image Col vector orientation (%3.5f %3.5f %3.5f)", colOr[0], colOr[1], colOr[2]); #endif // position Float64 imgPos[3] = { 0.0f, 0.0f, 0.0f }; std::vector<PGMath::Vector3D<float> > positions; cond = dataset->findAndGetElement(DCM_ImagePositionPatient, elem); if(!cond.good()) { LOG1("IO/IODicom::Read:Warning Cannot fetch DCM_ImagePositionPatient (%s)", cond.text()); } else { elem->getFloat64(imgPos[0], 0); elem->getFloat64(imgPos[1], 1); elem->getFloat64(imgPos[2], 2); } positions.push_back(PGMath::Vector3D<float>(imgPos[0], imgPos[1], imgPos[2])); oMetaDataObject.SetImagePositionsPatient(positions); #ifdef _DEBUG LOG3("\tIODicom::Read: Image Position (%3.5f %3.5f %3.5f)", imgPos[0], imgPos[1], imgPos[2]); #endif // slope / intercept if (modality==PGCore::kPGModalityCT || modality==PGCore::kPGModalityPT) { Float64 slope = -999.0f; cond = dataset->findAndGetElement(DCM_RescaleSlope, elem); if(!cond.good()) { LOG1("IO/IODicom::Read:Warning Cannot fetch DCM_RescaleSlope (%s)", cond.text()); } else { cond = elem->getFloat64(slope, 0); if(cond.good()) //if (dataset->findAndGetFloat64(DCM_RescaleIntercept, slope) == EC_Normal) { oMetaDataObject.SetSlope(slope); //LOG1("IO/IODicom::Read: Cannot fetch pixel Y spacing (%s)", cond.text()); } } Float64 intercept = -999.0f; //dataset->findAndGetFloat64(DCM_RescaleIntercept, intercept); cond = dataset->findAndGetElement(DCM_RescaleIntercept, elem); if(!cond.good()) { LOG1("IO/IODicom::Read:Warning Cannot fetch DCM_RescaleIntercept (%s)", cond.text()); } else { cond = elem->getFloat64(intercept, 0); if(cond.good()) //if (dataset->findAndGetFloat64(DCM_RescaleIntercept, intercept) == EC_Normal) { oMetaDataObject.SetIntercept(intercept); } } } /* Uint16 imageBytesAllocated = 0; Uint16 imagePlanarConfiguration = 0; Uint16 imageSamplesPerPixel = 0; Sint32 imageFrames = 1; Uint16 imageBitsAllocated = 0; if (result.good()) result = ditem->findAndGetUint16(DCM_BitsAllocated, imageBitsAllocated); res = ditem->findAndGetUint16(DCM_SamplesPerPixel, imageSamplesPerPixel); // slope / intercept // high bit // planar configuration // endianness oMetaData->SetMSBFirst(getValueI(iStr,std::string(kPGTagMSBFirst))); */ #endif #ifdef _DEBUG LOG0("} IODicom::GetAttributes"); #endif return true; }
const char* Association::GetKey(DcmDataset* query, const DcmTagKey& tag) { OFString val; static char buffer[129]; query->findAndGetOFString(tag, val, 0, OFTrue); strncpy(buffer, val.c_str(), sizeof(buffer)); return buffer; }