HOW TO ADD ADDITIONAL FRAMES TO A MULTI FRAME DICOM

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
karun
Posts: 9
Joined: Mon, 2014-03-17, 09:18

HOW TO ADD ADDITIONAL FRAMES TO A MULTI FRAME DICOM

#1 Post by karun »

Hi ,
I am new to dicom . looking for a way to insert additional frames into an existing multiframe .
code i have done is

/* step 1: load dicom image and get data set from dicom image*/

/* step 2: modifiy frame count to required count */

dataset->putAndInsertString(DCM_NumberOfFrames, framecount+1);

/* step 3: get pixel data from existing dicom image */

Uint8* image_buffer = new Uint8[imglen];
image_buffer = (Uint8*)dcmimg->getOutputData(imglen,0,0);

/*step 4:create sequence and pixel item

//DcmPixelData* pixeldata = new DcmPixelData(DCM_PixelData); ;
DcmPixelSequence* sequence = new DcmPixelSequence(DcmTag(DCM_PixelData, EVR_OB));
DcmPixelItem* pixelItem = new DcmPixelItem(DcmTag(DCM_Item, EVR_OB));

OFCondition res = pixelItem->putUint8Array(image_buffer, imglen);

for(int i=0;i<framecount;i++)
{

sequence->insert(pixelItem);
}

/*step 5: added an extra frame using same buffer */

sequence->insert(pixelItem);

/*step 6: inserted the sequence to dataset and saved as .dcm */

dataset->insert(sequence, true ,OFFalse);

fileformat.saveFile("E:\\output\\test.dcm",EXS_LittleEndianExplicit);[/size]

i had given frame count as framecount+1 and relevant SOP . an extra frame is appended to the old image but the tag value (7fe0 0010) is -1 .
some of the open source viewer is showing and some not showing due to this . what is the mistake i had done in the code .
Last edited by karun on Mon, 2014-03-17, 10:33, edited 1 time in total.

J. Riesmeier
DCMTK Developer
Posts: 2501
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: INSERTING ADDITIONAL IMAGE TO EXSISTING SINGLE FRAME

#2 Post by J. Riesmeier »

but the tag value (7fe0 0010) is -1
Do you mean the element length is undefined?

Is your pixel data really uncompressed (as the transfer syntax indicates)? Then the Pixel Sequence is the wrong approach since it is only meant for compressed pixel data. Uncompressed pixel data is simply concatenated in the Pixel Data element value. See DICOM Part 5 for details.

karun
Posts: 9
Joined: Mon, 2014-03-17, 09:18

Re: HOW TO ADD ADDITIONAL FRAMES TO A MULTI FRAME DICOM

#3 Post by karun »

Thanku for the reply , yes the element tag has value before adding the extra frame , after inserting an extra frame . the value is changed to undefined .

my image use lossy image compression , whats the change i have to make in the above code .

J. Riesmeier
DCMTK Developer
Posts: 2501
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: HOW TO ADD ADDITIONAL FRAMES TO A MULTI FRAME DICOM

#4 Post by J. Riesmeier »

First of all, you should use putOriginalRepresentation() in order to add compressed pixel data (encapsulated in a Pixel Sequence) to the Pixel Data element. Examples on how to do this can be found in the source code of dump2dcm and xml2dcm.

Also the transfer syntax in your call to saveFile() should be adapted for your "lossy image compression".

karun
Posts: 9
Joined: Mon, 2014-03-17, 09:18

Re: HOW TO ADD ADDITIONAL FRAMES TO A MULTI FRAME DICOM

#5 Post by karun »

hi Riesmeier ,

i had tried putOriginalRepresentation() in the below code .also refered the source code of dump2dcm



/** Step 1: INITIALIZATION PART ****/


char uid[100];
DcmFileFormat fileformat;
OFCondition cond = fileformat.loadFile( csFileName.operator LPCTSTR());
DcmDataset *dataset = fileformat.getDataset();

dataset->putAndInsertString(DCM_SOPClassUID, UID_UltrasoundMultiframeImageStorage);
dataset->putAndInsertString(DCM_SOPInstanceUID,dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT)); //UID_UltrasoundMultiframeImageStorage);//
dataset->putAndInsertString(DCM_NumberOfFrames, "3");

CT2A Fpath(csFileName);
DicomImage* dcmimg = new DicomImage(Fpath ,CIF_UsePartialAccessToPixelData, 0,0);

unsigned long imgrow = dcmimg->getWidth();
unsigned long imgcln = dcmimg->getHeight();
unsigned long imgdpth= dcmimg->getDepth();
unsigned long imglen = imgrow*imgcln;//*imgdpth);
const E_TransferSyntax xfer= dataset->getOriginalXfer();


Uint8* image_buffer = new Uint8[imglen];
image_buffer = (Uint8*)dcmimg->getOutputData(imglen,0,0);
DcmPixelData* pixeldata = new DcmPixelData(DcmTag(DCM_PixelData));
DcmPixelSequence* sequence = new DcmPixelSequence(DcmTag(DCM_PixelData, EVR_OB))


DcmOffsetList offsetlist;
DcmPixelItem* pixelItem = new DcmPixelItem(DcmTag(DCM_Item, EVR_OB));
OFCondition res = pixelItem->putUint8Array(image_buffer, imglen);


/**** Step 2: STORING IMAGE BUFFER TO SEQUENCE ( as an initial try i had saved same image buffer into the sequence 3 times , giving the frame count as 3 )***********/


for(int k=0;k<3;k++)
{
sequence->storeCompressedFrame(offsetlist,image_buffer,imglen,0);
}



pixeldata->putOriginalRepresentation(xfer,NULL,sequence);
dataset->insert(pixeldata,true,OFFalse);
fileformat.saveFile("E:\\output\\test.dcm",xfer);


xfer is the original transfer syntax for the image .. after running this code the image sequence is not stored in the test.dcm

whats the change i could accomodate in this


Regards ,
Karun

J. Riesmeier
DCMTK Developer
Posts: 2501
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: HOW TO ADD ADDITIONAL FRAMES TO A MULTI FRAME DICOM

#6 Post by J. Riesmeier »

What does the logger say and what do the various DCMTK methods return (i.e. which OFCondition)?

You could also start a debugger, of course. And, it would be much easier to help you, if you would provide a complete and self-running example - with a minimum number of code lines.

karun
Posts: 9
Joined: Mon, 2014-03-17, 09:18

Re: HOW TO ADD ADDITIONAL FRAMES TO A MULTI FRAME DICOM

#7 Post by karun »

Hi Riesmeier ,

I had used visual studio for debugging the above code . All the conditions were returning OF_OK , except for the code
cond=dataset->insert(pixeldata,OFFalse,OFFalse);
Its returning OF_ERROR and the text output is "doubled tag " . The actual image is not replaced when i use OFFalse , So i used
cond=dataset->insert(pixeldata,true,OFFalse) ;


It will replace the actual pixel data but element length is undefined .

What am i missing here ?

Regards ,
Karun

J. Riesmeier
DCMTK Developer
Posts: 2501
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: HOW TO ADD ADDITIONAL FRAMES TO A MULTI FRAME DICOM

#8 Post by J. Riesmeier »

In your above sample code you were using "true" for the second parameter of insert()...

I can only repeat: If you want us to help you, we need precise information; a complete and self-running example - with a minimum number of code lines - would be the best.

karun
Posts: 9
Joined: Mon, 2014-03-17, 09:18

Re: HOW TO ADD ADDITIONAL FRAMES TO A MULTI FRAME DICOM

#9 Post by karun »

Hi Riesmeier ,

sorry , im now posting the self running code with minimum LOC .

int main()
{
char uid[100];
DcmFileFormat fileformat;
CString csFileName("E:\\input\\test.dcm"); //input is a single frame image
OFCondition cond = fileformat.loadFile( csFileName.operator LPCTSTR());
DcmDataset *dataset = fileformat.getDataset();

cond=dataset->putAndInsertString(DCM_SOPClassUID, UID_UltrasoundMultiframeImageStorage);
cond=dataset->putAndInsertString(DCM_SOPInstanceUID,dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT));
cond=dataset->putAndInsertString(DCM_NumberOfFrames, "3");

CT2A Fpath(csFileName);
DicomImage* dcmimg = new DicomImage(Fpath ,CIF_UsePartialAccessToPixelData, 0,0);

unsigned long imgrow = dcmimg->getWidth();
unsigned long imgcln = dcmimg->getHeight();
unsigned long imgdpth= dcmimg->getDepth();
unsigned long imglen = imgrow*imgcln;
const E_TransferSyntax xfer= dataset->getOriginalXfer();


Uint8* image_buffer = new Uint8[imglen];
image_buffer = (Uint8*)dcmimg->getOutputData(imglen,0,0);
DcmPixelData* pixeldata = new DcmPixelData(DcmTag(DCM_PixelData));
DcmPixelSequence* sequence = new DcmPixelSequence(DcmTag(DCM_PixelData, EVR_OB));

DcmOffsetList offsetlist;
DcmPixelItem* pixelItem = new DcmPixelItem(DcmTag(DCM_Item, EVR_OB));
OFCondition res = pixelItem->putUint8Array(image_buffer, imglen);

for(int k=0;k<3;k++)
{
cond=sequence->storeCompressedFrame(offsetlist,image_buffer,imglen,0);
}

pixeldata->putOriginalRepresentation(xfer,NULL,sequence);
cond=dataset->insert(pixeldata,OFFalse,OFFalse);
cond=fileformat.saveFile("E:\\output\\test.dcm",xfer); //output is a multiframe image with 3 frames

delete dcmimg;
return 1;
}
Im trying to work on any given DCM file by the client.

is this the required one ?? or any other information i have to provide???

J. Riesmeier
DCMTK Developer
Posts: 2501
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: HOW TO ADD ADDITIONAL FRAMES TO A MULTI FRAME DICOM

#10 Post by J. Riesmeier »

Your code does not really make sense...
  1. You still use "OFFalse" as the second parameter for the insert() call.
  2. You never check the returned status of the various functions/methods.
  3. If the input image is JPEG compressed, you need to register the JPEG decoders in order to read it with DicomImage().
  4. Do you really want to feed the rendered output (uncompressed pixel data) into storeCompressedFrame()?
  5. I'm not sure that your computed "imglen" is correct. This depends on the input image.
  6. Is your input image monochrome or color? In case of color, you also need to register "color support" to DicomImage().
  7. ...
  8. You also need to update the file meta information header since the SOP Class/Instance UID changed.
I'm sorry but there are so many errors/open issues in your code :shock:

(Btw, there are also unused code lines that are definitely not needed.)

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 1 guest