dcmtk with QT

All other questions regarding DCMTK

Moderator: Moderator Team

Message
Author
Géant Vert
Posts: 18
Joined: Fri, 2007-04-13, 08:40

#16 Post by Géant Vert »

Roger! I resolve my problem with using decode codec before the creation of PPM or PGM.

Thank a lot for your help

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#17 Post by Jörg Riesmeier »

How can i Know if the dicom image is an jpeg or bmp (compressed format)?
First of all, a DICOM image is never "bmp compressed" - whatever that is. The compression of the pixel data can be determined by the transfer syntax. DCMTK supports a couple of well-established JPEG compression schemes which are defined in the DICOM standard.

In order to add support for JPEG (or RLE) compressed DICOM images, you have to register the corresponding decoders in your application. See documentation of module "dcmjpeg" and/or source code of "dcm2pnm/dcmj2pnm".

Géant Vert
Posts: 18
Joined: Fri, 2007-04-13, 08:40

#18 Post by Géant Vert »

Thanks. But now I 've got problem with 16bits images.

int lenght=width*height;
int min=256,max=-1;
Ushort *tab=new Ushort (lenght);
Uint8 *tab8b=new Uint8 (length);
imageDic->getOutputData((void *)(tab), length, 16);

for(int i=0;i<lenght;i++)
{
if(min>tab)min=tab;
if(max<tab)max=tab;
}

for(int i=0;i<lenght;i++)
{
tab8b=(tab-min)*255/((int)(max-min));
}


So I try to convert 16bit to 8bits to write a pgm. But after this step, I don"t know what will I do.

cxl2253
Posts: 10
Joined: Mon, 2007-03-19, 05:38

#19 Post by cxl2253 »

why do you want to find the max and min value?I think maybe that we can convert from 16 to 24 bits.Then deal with the ppm like before.Is it right?

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#20 Post by Jörg Riesmeier »

Géant Vert wrote:So I try to convert 16bit to 8bits to write a pgm.
Why don't you just instruct DicomImage to create an output bitmap with 8 bits depth by calling getOutputData() with "bits = 8"?

Géant Vert
Posts: 18
Joined: Fri, 2007-04-13, 08:40

#21 Post by Géant Vert »

I must convert the image 16bits to 8bits because I work only on the 256 level's gray.

If i search the max and the min,it aims to doing an dynamic expansion of the image.

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#22 Post by Jörg Riesmeier »

I must convert the image 16bits to 8bits because I work only on the 256 level's gray.
As I wrote in my last posting, this (linear scaling) is done automatically by getOutputData(). Just specify the number of bits for your output data.

Géant Vert
Posts: 18
Joined: Fri, 2007-04-13, 08:40

#23 Post by Géant Vert »

Before the conversion: when i use the dcmtk function getMinMax, I find 0 and 65536 so after conversion i have find 0 and 255.

After the convert.
I did this but when I search the maximum and the minimum the both is equalizing to 0.

Géant Vert
Posts: 18
Joined: Fri, 2007-04-13, 08:40

#24 Post by Géant Vert »

When I use DicomWorks to read the image, it displays. But my program don't displays this image correctly
.

Géant Vert
Posts: 18
Joined: Fri, 2007-04-13, 08:40

#25 Post by Géant Vert »

If I understand GetOutputdata copy the pixel data to an pointer.

But ,does this function copy an other information?

I ask this because when i allocate my pointer with the size of the image, this function don't run. But when i allocate with greater than the size it run :? .

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#26 Post by Jörg Riesmeier »

Use getOutputDataSize() in order to determine the number of bytes required for the buffer.

Géant Vert
Posts: 18
Joined: Fri, 2007-04-13, 08:40

#27 Post by Géant Vert »

i try it. But it don't run with my image 16bits in graylevel.

Code: Select all

 Uint16 *imgData = new Uint16[(imageDic->getOutputDataSize (16))];
  if (buffer != NULL) 
     { 
     // copy header to buffer  
     OFBitmanipTemplate<Uint8>::copyMem((const Uint8 *)header, buffer, offset); //on copie l'entéte du header dasn le buffer
      bool t=imageDic->getOutputData(/*(void *)*/(imgData), (imageDic->getOutputDataSize (16)), 16);//on copie les données images à l'adresse buffer+offset aprés l'entéte du buffer
  

t is true but all values pixel in imgData are equal to 0. Maybe can I try to copy the values pixel with this code:

Code: Select all

const DiPixel *tab;
tab=imageDic->getInterData();//on récup les pixels
But after I don't know how access the value pixel. I need the values pixel to create pixmap.

thank to your answer

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#28 Post by Jörg Riesmeier »

I thought you want to get a rendered bitmap with 8 bits per pixel? If this is the case, you should set the parameter "bits" of method getOutputData() to "8" as I already wrote. In case the image is all black or all white, you should first check whether the VOI window is appropriate (e.g. use setMinMaxWindow as shown in the example).

Your example code from the last posting seems to be a mixture of things that don't fit together, e.g. getOutputDataSize() returns the number of bytes required for the buffer and not the number of entries. That means, in your code the buffer is twice as large as necessary. And the PGM header is not used at all (btw, there is no 16 bit binary PGM format as far as I know, only an ASCII format - see output options of dcm2pnm).

So, as long as we do not know exactly what you really intend to do we will not be able to help you substantially.

Géant Vert
Posts: 18
Joined: Fri, 2007-04-13, 08:40

#29 Post by Géant Vert »

ok I want view this image.
Here the dump of the image:

Photometric interpretaion:MONOCHROME2
Bits Allocated: 16
Bits Stored:16
Hight Bit:15

Pixel Representation:0

So I create a DicomImage like this:

Code: Select all

E_TransferSyntax xfer = fileformat->getDataset()->getOriginalXfer();
        DicomImage *imageDic=new DicomImage(fileformat,xfer,CIF_MayDetachPixelData,0,1 );
After I call a function whose aims at converting DicomImage to pixmap.
My code is:

Code: Select all

char header[32];
     if (PPM!=0 &&PPM!=2)//cas lorsque l'on est en couleur
        sprintf(header, "P6\n%i %i\n65535\n",width, height); //entéte du PPM format image non compressé
     else//ici N&B
        sprintf(header, "P5\n%i %i\n65535\n",width, height); //entéte du PGM format image non compressé}
     int offset = strlen(header); //on prend la longueur de l'entéte
     unsigned int length=(imageDic->getOutputDataSize (8));//on calcul la longueur de l'image
 Uint8 *buffer = new Uint8[length+offset];
 if (buffer != NULL) 
     { 
     // copy header to buffer  
     OFBitmanipTemplate<Uint8>::copyMem((const Uint8 *)header, buffer, offset); //on copie l'entéte du header dasn le buffer
      bool t=imageDic->getOutputData((buffer+offset), length, 8);//on copie les données images à l'adresse buffer+offset aprés l'entéte du buffer
      if (pixmap != NULL) 
        { 
          if (PPM!=0){//on a un PPM
              if (!pixmap->loadFromData((const unsigned char *)buffer, (length+offset), "PPM",Qt::AvoidDither)) 
              { 
              // delete pixmap; 
                 pixmap = NULL; 
              } 
          }
          else//on charge un PGM
          {
              if (!pixmap->loadFromData((const unsigned char *)buffer,(length+offset), "PGM", Qt::AvoidDither)) 
              { 
              // delete pixmap; 
                 pixmap = NULL; 
              } 
          }
    
PPM=2 when we work on 16bits image.

This code run with almost images. But Don't run with this image, and I don't understand. Maybe getOutpudata don't run with image 16bit graylevels...

cxl2253
Posts: 10
Joined: Mon, 2007-03-19, 05:38

#30 Post by cxl2253 »

i use follwing code to show image in QT,Almost is ok

DJDecoderRegistration::registerCodecs();
DcmRLEDecoderRegistration::registerCodecs();

QPixmap *pixmap = NULL;

DcmFileFormat *dfile = new DcmFileFormat();
QString fileName = QFileDialog::getOpenFileName(
0,
"Select one or more files to open",
"D:\\gdcmData",
"Images (*.*)");
OFCondition cond = dfile->loadFile(fileName.toAscii().data(), EXS_Unknown, EGL_withoutGL, DCM_MaxReadLength, ERM_autoDetect);
if (cond.bad())
{
printf("eror"); return;

}

E_TransferSyntax xfer = dfile->getDataset()->getOriginalXfer();
DicomImage *image = new DicomImage(dfile, xfer);

int i;
QColor color;
QImage* img;
void * pDicomDibits;
uchar *px;
uchar pixel[4];
const int width = (int)(image->getWidth());
const int height = (int)(image->getHeight());
if (image->isMonochrome())
{
img=new QImage(width,height,QImage::Format_Indexed8);
img->setNumColors(256);
// define gray palette here
for (i=0; i<256; i++) {
color.setRgb(i, i, i);
img->setColor(i, color.rgb());
}
image->createWindowsDIB(pDicomDibits, 0, 0, 8, 0, 1);
unsigned char * pd;
pd=(unsigned char *)pDicomDibits;
for (int y=0; y < (long) height; y++)
{
px = img->scanLine(y);
for (int x=0; x < (ulong) width; x++)
{
px[x] = (unsigned char) (*pd);
pd++;

}
}
}
else
{
img=new QImage(width,height,QImage::Format_RGB32);
image->createWindowsDIB(pDicomDibits, 0, 0, 24, 0, 1);
unsigned char * pd;
pd=(unsigned char *)pDicomDibits;
for (int y=0; y < (long) height; y++)
{
px = img->scanLine(y);
for (int x=0; x < (ulong) width; x++)
{
QRgb *row = (QRgb*) px;

pixel[2] = (unsigned char) (*(pd+3*y*width+3*x));
pixel[1] = (unsigned char) (*(pd+3*y*width+3*x+1));
pixel[0] = (unsigned char) (*(pd+3*y*width+3*x+2));

//pixel[3] = (unsigned char) (*pd++);

row[x] = qRgb(pixel[0], pixel[1], pixel[2]);

}
}

}

img->save("c:\\test2.bmp"); // now can show on QLable or save
DJDecoderRegistration::cleanup();
DcmRLEDecoderRegistration::cleanup(); */

Post Reply

Who is online

Users browsing this forum: Semrush [Bot] and 1 guest