Я хочу использовать библиотеку DCMTK 3.6.1 в существующем проекте, который может создавать изображение DICOM. Я хочу использовать эту библиотеку, потому что хочу сделать сжатие изображений DICOM. В новом решении (Visual Studio 2013/C++) Следуя примеру официальной документации DCMTK, у меня есть этот код, который работает правильно.Как создать изображение DICOM из байта (DCMTK)
using namespace std;
int main()
{
DJEncoderRegistration::registerCodecs();
DcmFileFormat fileformat;
/**** MONO FILE ******/
if (fileformat.loadFile("Files/test.dcm").good())
{
DcmDataset *dataset = fileformat.getDataset();
DcmItem *metaInfo = fileformat.getMetaInfo();
DJ_RPLossless params; // codec parameters, we use the defaults
// this causes the lossless JPEG version of the dataset
//to be created EXS_JPEGProcess14SV1
dataset->chooseRepresentation(EXS_JPEGProcess14SV1, ¶ms);
// check if everything went well
if (dataset->canWriteXfer(EXS_JPEGProcess14SV1))
{
// force the meta-header UIDs to be re-generated when storing the file
// since the UIDs in the data set may have changed
delete metaInfo->remove(DCM_MediaStorageSOPClassUID);
delete metaInfo->remove(DCM_MediaStorageSOPInstanceUID);
metaInfo->putAndInsertString(DCM_ImplementationVersionName, "New Implementation Version Name");
//delete metaInfo->remove(DCM_ImplementationVersionName);
//dataset->remove(DCM_ImplementationVersionName);
// store in lossless JPEG format
fileformat.saveFile("Files/carrellata_esami_compresso.dcm", EXS_JPEGProcess14SV1);
}
}
DJEncoderRegistration::cleanup();
return 0;
}
Теперь я хочу, чтобы использовать один и тот же код в существующем приложении C++, где
if (infoDicom.arrayImgDicom.GetSize() != 0) //Things of existing previous code
{
//I have added here the registration
DJEncoderRegistration::registerCodecs(); // register JPEG codecs
DcmFileFormat fileformat;
DcmDataset *dataset = fileformat.getDataset();
DJ_RPLossless params;
dataset->putAndInsertUint16(DCM_Rows, infoDicom.rows);
dataset->putAndInsertUint16(DCM_Columns, infoDicom.columns,);
dataset->putAndInsertUint16(DCM_BitsStored, infoDicom.m_bitstor);
dataset->putAndInsertUint16(DCM_HighBit, infoDicom.highbit);
dataset->putAndInsertUint16(DCM_PixelRepresentation, infoDicom.pixelrapresentation);
dataset->putAndInsertUint16(DCM_RescaleIntercept, infoDicom.rescaleintercept);
dataset->putAndInsertString(DCM_PhotometricInterpretation,"MONOCHROME2");
dataset->putAndInsertString(DCM_PixelSpacing, "0.086\\0.086");
dataset->putAndInsertString(DCM_ImagerPixelSpacing, "0.096\\0.096");
BYTE* pData = new BYTE[sizeBuffer];
LPBYTE pSorg;
for (int nf=0; nf<iNumberFrames; nf++)
{
//this contains all the PixelData and I put it into the dataset
pSorg = (BYTE*)infoDicom.arrayImgDicom.GetAt(nf);
dataset->putAndInsertUint8Array(DCM_PixelData, pSorg, sizeBuffer);
dataset->chooseRepresentation(EXS_JPEGProcess14SV1, ¶ms);
//and I put it in my data set
//but this IF return false so che canWriteXfer fails...
if (dataset->canWriteXfer(EXS_JPEGProcess14SV1))
{
dataset->remove(DCM_MediaStorageSOPClassUID);
dataset->remove(DCM_MediaStorageSOPInstanceUID);
}
//the saveFile fails too, and the error is "Pixel
//rappresentation non found" but I have set the Pixel rep with
//dataset->putAndInsertUint16(DCM_PixelRepresentation, infoDicom.pixelrapresentation);
OFCondition status = fileformat.saveFile("test1.dcm", EXS_JPEGProcess14SV1);
DJEncoderRegistration::cleanup();
if (status.bad())
{
int error = 0; //only for test
}
thefile.Write(pSorg, sizeBuffer); //previous code
}
На самом деле я сделал тест с изображением, которые имеют на одном кадре, поэтому для цикла выполняется только один раз. Я не понимаю, почему если я выбираю dataset->chooseRepresentation(EXS_LittleEndianImplicit, ¶ms);
или dataset->chooseRepresentation(EXS_LittleEndianEXplicit, ¶ms);
работает отлично, но не тогда, когда я выбираю dataset->chooseRepresentation(EXS_JPEGProcess14SV1, ¶ms);
Если я использую один и тот же образ в первом приложении, я могу сжать изображение без проблем ...
EDIT: Я думаю, что основная проблема для решения - status = dataset->chooseRepresentation(EXS_JPEGProcess14SV1, &rp_lossless)
, которые возвращают «Tag not found». Как я могу узнать, что тег пропущен?
EDIT2: Как предполагают в форуме DCMTK я добавил тег о битов, выделенных и теперь работает для нескольких изображений, но не для всех. Для некоторых изображений у меня снова «Tag not found»: как я могу узнать, что один из тегов отсутствует? Как правило, лучше вставить все теги?
Спасибо за ваш ответ. Ops .. это ошибка в copy-paste, когда я написал вопрос, но в моем коде selectRepresentation делается после того, как я применил данные. Я исправлю вопрос, но это не решит проблему. С отладкой я вижу, что после метода selectRepresentation Xfer остается в LittleEndian и не изменяется в JPEGProcess14SV1 .... возможно, что по какой-то причине кодек не зарегистрирован ?? – GiordiX
Какое состояние возвращается выборомRepresentation? – JohnnyQ
В этом случае статус «Tag not found» и я не понимаю, почему. Я сделал еще один эксперимент: я делаю 'status = dataset-> chooseRepresentation (EXS_LittleEndianExplicit, & rp_lossless); // здесь статус в порядке status = fileformat.saveFile ("file_esplicito.dcm", EXS_LittleEndianExplicit); 'после того, как я снова загрузите файл и сделаю' status = dataset-> selectRepresentation (EXS_JPEGProcess14SV1, & rp_lossless); // здесь статус в порядке, но когда я пытаюсь сохранить файл с 'status = fileformat.saveFile (" prova1.dcm ", EXS_JPEGProcess14SV1);' здесь у меня есть 'здесь Pixel Rapresentation not found " – GiordiX