예제 #1
0
std::vector<ImportDescriptor*> DicomImporter::getImportDescriptors(const std::string &filename)
{
   mErrors.clear();
   mWarnings.clear();
   std::vector<ImportDescriptor*> descriptors;

   DcmFileFormat fileformat;
   OFCondition status;
   if((status = fileformat.loadFile(filename.c_str())).bad())
   {
      return descriptors;
   }

   ImportDescriptorResource pImportDescriptor(filename, TypeConverter::toString<RasterElement>());
   VERIFYRV(pImportDescriptor.get() != NULL, descriptors);
   descriptors.push_back(pImportDescriptor.release());

   DicomImage img(fileformat.getDataset(), fileformat.getDataset()->getOriginalXfer());
   if(img.getStatus() != EIS_Normal)
   {
      mErrors.push_back(std::string("Unable to decode image: ") + DicomImage::getString(img.getStatus()));
      pImportDescriptor->setDataDescriptor(RasterUtilities::generateRasterDataDescriptor(filename, NULL, 0, 0, INT1UBYTE, IN_MEMORY));
      return descriptors;
   }
   InterleaveFormatType interleave(BSQ);
   EncodingType encoding(INT4UBYTES);
   bool rgb = false;
   unsigned long rows = img.getHeight(), columns = img.getWidth(), frames = img.getFrameCount();
   int imgDepth = img.getDepth();
   switch(img.getPhotometricInterpretation())
   {
   case EPI_Monochrome1:
   case EPI_Monochrome2:
      // do nothing special....this is single or multi-frame grayscale, 1 or 2 byte
      break;
   case EPI_RGB:
   case EPI_PaletteColor:
      // supported if there's only 1 frame
      if(frames == 1)
      {
         frames = 3;
         rgb = true;
      }
      else
      {
         mWarnings.push_back("RGB and palette color not supported when multiple frames are present. Converting to grayscale.");
      }
      break;
   default:
      mWarnings.push_back(std::string(DicomImage::getString(img.getPhotometricInterpretation())) +
         " not supported. Attempting to convert to grayscale.");
   }

   if(imgDepth <= 8)
   {
      encoding = INT1UBYTE;
   }
   else if(imgDepth <= 16)
   {
      encoding = INT2UBYTES;
   }
   else if(imgDepth <= 32)
   {
      encoding = INT4UBYTES;
   }
   else
   {
      mWarnings.push_back("Bit depth " + StringUtilities::toDisplayString(imgDepth) + " not supported. Downgrading to 32 bits.");
      encoding = INT4UBYTES;
   }

   RasterDataDescriptor *pDescriptor = RasterUtilities::generateRasterDataDescriptor(
      filename, NULL, rows, columns, frames, interleave, encoding, IN_MEMORY);
   if(pDescriptor != NULL)
   {
      if(rgb)
      {
         pDescriptor->setDisplayBand(RED, pDescriptor->getBands()[0]);
         pDescriptor->setDisplayBand(GREEN, pDescriptor->getBands()[1]);
         pDescriptor->setDisplayBand(BLUE, pDescriptor->getBands()[2]);
         pDescriptor->setDisplayMode(RGB_MODE);
      }
      pImportDescriptor->setDataDescriptor(pDescriptor);
      FactoryResource<DynamicObject> pMeta;
      int idx = 0;
      DcmElement *pElmnt;
      while((pElmnt = fileformat.getDataset()->getElement(idx++)) != NULL)
      {
         if(pElmnt->error().bad())
         {
            continue;
         }
         const DcmTag &tag = pElmnt->getTag();
         std::string name = const_cast<DcmTag&>(tag).getTagName();
         if(name.empty())
         {
            name = QString("(%1,%2)").arg(pElmnt->getGTag(), 4, 16, QChar('0')).arg(pElmnt->getETag(), 4, 16, QChar('0')).toStdString();
         }
         pMeta->setAttributeByPath(std::string("DICOM/") + name, dcmElementToDataVariant(*pElmnt));
      }
      pImportDescriptor->getDataDescriptor()->setMetadata(pMeta.release());
   }
   RasterUtilities::generateAndSetFileDescriptor(pImportDescriptor->getDataDescriptor(), filename, std::string(), LITTLE_ENDIAN_ORDER);

   return descriptors;
}
예제 #2
0
void query_from_net(
			const std::string& patientid,
			const std::string& name,
			const std::string& modality,
			const std::string& date_from,
			const std::string& date_to,
			const std::string& studydescription,
			const std::string& accessionnumber,
			const std::string& local_aet,
			const std::set<std::string>& groups,
			const sigc::slot< void, const Glib::RefPtr< ImagePool::Study >& >& resultslot
			)
{
	// get encodings
	std::string dicom_enc = ImagePool::get_encoding();
	std::string system_enc = ImagePool::get_system_encoding(dicom_enc);
	
	// create patientsname querystring
	std::string patientsname;

	if(name.empty()) {
		patientsname = "*";
	}
	else {
		patientsname = convert_string_to(name.c_str(), system_enc);
	}

	std::string description;
	if(!studydescription.empty()) {
		description = convert_string_to(studydescription.c_str(), system_enc);
	}
	
	// create date querystring
	std::string date;
	if(date_from.empty() && date_to.empty()) {
		date = "";
	}
	else if(date_to.empty()) {
		date = date_from + "-";
	}
	else if(date_from.empty()) {
		date = "-" + date_to;
	}
	else {
		date = date_from + "-" + date_to;
	}

	if(date_from == date_to) {
		date = date_from;
	}

	/*std::string station;
	if(!stationname.empty()) {
		station = "*" + convert_string_to(stationname.c_str(), system_enc) + "*";
	}*/

	DcmDataset query;
	DcmElement* e = NULL;
	
	e = newDicomElement(DCM_QueryRetrieveLevel);
	e->putString("STUDY");
	query.insert(e);

	e = newDicomElement(DCM_SpecificCharacterSet);
	e->putString(dicom_enc.c_str());
	query.insert(e);

	e = newDicomElement(DCM_PatientsName);
	e->putString(patientsname.c_str());
	query.insert(e);

	e = newDicomElement(DCM_PatientID);
	e->putString(convert_string_to(patientid.c_str(), system_enc).c_str());
	query.insert(e);

	e = newDicomElement(DCM_SOPClassesInStudy);
	query.insert(e);

	e = newDicomElement(DCM_ModalitiesInStudy);
	e->putString(modality.c_str());
	query.insert(e);

	e = newDicomElement(DCM_PatientsBirthDate);
	query.insert(e);

	e = newDicomElement(DCM_PatientsSex);
	query.insert(e);

	e = newDicomElement(DCM_StudyDate);
	e->putString(date.c_str());
	query.insert(e);

	e = newDicomElement(DCM_StudyTime);
	query.insert(e);

	e = newDicomElement(DCM_NumberOfStudyRelatedSeries);
	query.insert(e);

	e = newDicomElement(DCM_NumberOfStudyRelatedInstances);
	query.insert(e);

	e = newDicomElement(DCM_AccessionNumber);
	e->putString(accessionnumber.c_str());
	query.insert(e);

	e = newDicomElement(DCM_StudyID);
	query.insert(e);

	e = newDicomElement(DCM_StudyInstanceUID);
	query.insert(e);

	e = newDicomElement(DCM_StudyDescription);
	e->putString(description.c_str());
	query.insert(e);

	// StationName not allowed in StudyRoot
	/*e = newDicomElement(DCM_StationName);
	e->putString(station.c_str());
	query.insert(e);*/

	std::cout << "NEW QUERY:" << std::endl;
	query.print(COUT);

	NetClient<FindAssociation> a;
	a.signal_server_result.connect(sigc::bind(sigc::ptr_fun(on_query_from_net_result), resultslot));

	//std::set<std::string> groups = get_servergroups();
	std::set<std::string>::iterator i = groups.begin();

	// do we have groups defined ?
	if(groups.size() > 0) {
		while(i != groups.end()) {
			a.QueryServerGroup(&query, *i, local_aet, UID_FINDStudyRootQueryRetrieveInformationModel);
			i++;
		}
	}
	
	// no query all servers
	else {
		a.QueryServerGroup(&query, "", local_aet, UID_FINDStudyRootQueryRetrieveInformationModel);
	}
}
예제 #3
0
tissuestack::imaging::DicomFileWrapper::DicomFileWrapper(const std::string filename, const bool isTempFile) :
	_file_name(filename), _isTemp(isTempFile)
{
	if (!tissuestack::utils::System::fileExists(filename))
		THROW_TS_EXCEPTION(tissuestack::common::TissueStackApplicationException,
			"Supposed Dicom File does not exist in that location!");

	// load file to read header tags
	DcmFileFormat dicomFormat;
	OFCondition status = dicomFormat.loadFile(filename.c_str());
	if (!status.good())
		THROW_TS_EXCEPTION(tissuestack::common::TissueStackApplicationException,
			"Given dicom file is no good!");

	OFString value;
	if (dicomFormat.getDataset()->findAndGetOFString(DCM_TransferSyntaxUID, value).good())
	{
		std::string transferSyntaxUID = value.c_str();
		std::transform(transferSyntaxUID.begin(), transferSyntaxUID.end(), transferSyntaxUID.begin(), toupper);
		if (transferSyntaxUID.find("JPEG2000") != std::string::npos)
			THROW_TS_EXCEPTION(tissuestack::common::TissueStackApplicationException,
				"We don't support JPEG2000!");
	}

	if (!dicomFormat.getDataset()->findAndGetOFString(DCM_SeriesInstanceUID, value).good())
		if (!dicomFormat.getDataset()->findAndGetOFString(DCM_SeriesNumber, value).good())
			this->_series_number = "0";
		else
			this->_series_number = std::string(value.c_str());
	else
		this->_series_number = std::string(value.c_str());

	if (!dicomFormat.getDataset()->findAndGetOFString(DCM_InstanceNumber, value).good())
		THROW_TS_EXCEPTION(tissuestack::common::TissueStackApplicationException,
			"Could not read dicom instance number!");
	this->_instance_number = strtoul(value.c_str(), NULL, 10);

	if (!dicomFormat.getDataset()->findAndGetOFStringArray(DCM_ImagePositionPatient, value).good())
		this->_image_position_patient = "0\\0\\0";
	else
		this->_image_position_patient = std::string(value.c_str());

	if (dicomFormat.getDataset()->findAndGetOFString(DCM_MRAcquisitionType, value).good()) // are we 3D
		this->_acquisitionType = std::string(value.c_str());

	if (dicomFormat.getDataset()->findAndGetOFString(DCM_PatientPosition, value).good())
		this->_patient_position = std::string(value.c_str());

	if (dicomFormat.getDataset()->findAndGetOFStringArray(DCM_ImageType, value).good()) // are we a mosaic
	{
		std::string v = std::string(value.c_str());
		std::transform(v.begin(), v.end(), v.begin(), toupper);
		if (v.find("MOSAIC") != std::string::npos) // have a look for numbers of images in mosaic
		{
			if (dicomFormat.getDataset()->findAndGetOFString(CSA_NumberOfImagesInMosaic, value).good())
				this->_number_of_images_in_mosaic = strtoul(value.c_str(), NULL, 10);

			DcmElement * csaImageHeaderInfo =
				const_cast<DcmElement *>(
						this->findDcmElement(dicomFormat.getDataset(), CSA_ImageSeriesHeaderInfo));
			if (csaImageHeaderInfo != nullptr)
			{
				Uint8 * csaImageHeaderContent = nullptr;
				unsigned long int length =
					csaImageHeaderInfo->getLength();
				status = csaImageHeaderInfo->getUint8Array(csaImageHeaderContent);
				if (status.good())
				{
					std::string tmp = std::string((const char *) csaImageHeaderContent, length);
					size_t ascconf_start = tmp.find(ASCCONV_BEGIN);
					if (ascconf_start == std::string::npos) // plan B: try other header
					{
						csaImageHeaderInfo =
							const_cast<DcmElement *>(
								this->findDcmElement(dicomFormat.getDataset(), CSA_ImageHeaderInfo));
						if (csaImageHeaderInfo != nullptr)
						{
							csaImageHeaderContent = nullptr;
							length = csaImageHeaderInfo->getLength();
							status = csaImageHeaderInfo->getUint8Array(csaImageHeaderContent);
							tmp = std::string((const char *) csaImageHeaderContent, length);
							ascconf_start = tmp.find(ASCCONV_BEGIN); // try again with backup header
						}
					}
					if (ascconf_start != std::string::npos)
					{
						ascconf_start += strlen(ASCCONV_BEGIN) + 1;
						size_t ascconf_end = tmp.find(ASCCONV_END) - 1;
						if (ascconf_end != std::string::npos)
							this->_ascconv = tmp.substr(ascconf_start, ascconf_end-ascconf_start);
					}
				}
			}

			if (this->_number_of_images_in_mosaic == 0 &&
				!this->_ascconv.empty()) // plan B for number of images in mosaic
			{
				size_t lSize_start = this->_ascconv.find(LSIZE);
				if (lSize_start != std::string::npos)
				{
					lSize_start = this->_ascconv.find("=", lSize_start);
					if (lSize_start != std::string::npos)
					{
						lSize_start++;
						size_t lSize_end = this->_ascconv.find("\n", lSize_start);
						if (lSize_end != std::string::npos)
						{
							std::string lSizeString = this->_ascconv.substr(lSize_start, lSize_start-lSize_end);
							this->_number_of_images_in_mosaic = strtoul(lSizeString.c_str(), NULL, 10);
						}
					}
				}
			}
		}

	}

	if (dicomFormat.getDataset()->findAndGetOFStringArray(DCM_ImagesInAcquisition, value).good())
		this->_number_of_images_in_series_or_acquisition = strtoul(value.c_str(), NULL, 10);

	if (this->_number_of_images_in_series_or_acquisition == 0 &&
		dicomFormat.getDataset()->findAndGetOFStringArray(DCM_ACR_NEMA_ImagesInSeries, value).good())
		this->_number_of_images_in_series_or_acquisition = strtoul(value.c_str(), NULL, 10);

	if (!dicomFormat.getDataset()->findAndGetOFStringArray(DCM_PixelSpacing, value).good())
		this->_pixel_spacing = "1\\1";
	else
		this->_pixel_spacing = std::string(value.c_str());

	if (!dicomFormat.getDataset()->findAndGetOFStringArray(DCM_ImageOrientationPatient, value).good())
		this->_image_orientation = "1\\0\\0\\0\\1\\0";
	else
		this->_image_orientation = std::string(value.c_str());

	if (!dicomFormat.getDataset()->findAndGetOFString(DCM_Rows, value).good())
		THROW_TS_EXCEPTION(tissuestack::common::TissueStackApplicationException,
			"Could not extract number of rows for given dicom!");
	this->_rows = strtoull(value.c_str(), NULL, 10);

	if (!dicomFormat.getDataset()->findAndGetOFString(DCM_Columns, value).good())
		THROW_TS_EXCEPTION(tissuestack::common::TissueStackApplicationException,
			"Could not extract number of columns for given dicom!");
	this->_columns = strtoull(value.c_str(), NULL, 10);

	if (!dicomFormat.getDataset()->findAndGetOFString(DCM_BitsAllocated, value).good())
		THROW_TS_EXCEPTION(tissuestack::common::TissueStackApplicationException,
			"Could not extract number of allocated bits for given dicom!");
	this->_allocated_bits = strtoul(value.c_str(), NULL, 10);

	if (!dicomFormat.getDataset()->findAndGetOFString(DCM_PixelRepresentation, value).good())
		this->_is_signed_data = 0;
	else
		this->_is_signed_data = static_cast<unsigned short>(strtoul(value.c_str(), NULL, 10));

	if (!dicomFormat.getDataset()->findAndGetOFString(DCM_PhotometricInterpretation, value).good())
		this->_photometric_interpretation = "MONOCHROME2";
	else
		this->_photometric_interpretation = std::string(value.c_str());

	if (this->isColor())
	{
		if (!dicomFormat.getDataset()->findAndGetOFString(DCM_PlanarConfiguration, value).good())
			this->_planar_configuration = 0;
		else
			this->_planar_configuration = static_cast<unsigned short>(strtoul(value.c_str(), NULL, 10));
	}
}