dcmtk with QT
Moderator: Moderator Team
-
- Posts: 18
- Joined: Fri, 2007-04-13, 08:40
-
- ICSMED DICOM Services
- Posts: 2217
- Joined: Fri, 2004-10-29, 21:38
- Location: Oldenburg, Germany
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.How can i Know if the dicom image is an jpeg or bmp (compressed format)?
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".
-
- Posts: 18
- Joined: Fri, 2007-04-13, 08:40
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.
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.
-
- ICSMED DICOM Services
- Posts: 2217
- Joined: Fri, 2004-10-29, 21:38
- Location: Oldenburg, Germany
-
- Posts: 18
- Joined: Fri, 2007-04-13, 08:40
-
- ICSMED DICOM Services
- Posts: 2217
- Joined: Fri, 2004-10-29, 21:38
- Location: Oldenburg, Germany
-
- Posts: 18
- Joined: Fri, 2007-04-13, 08:40
-
- Posts: 18
- Joined: Fri, 2007-04-13, 08:40
-
- Posts: 18
- Joined: Fri, 2007-04-13, 08:40
-
- ICSMED DICOM Services
- Posts: 2217
- Joined: Fri, 2004-10-29, 21:38
- Location: Oldenburg, Germany
Use getOutputDataSize() in order to determine the number of bytes required for the buffer.
-
- Posts: 18
- Joined: Fri, 2007-04-13, 08:40
i try it. But it don't run with my image 16bits in graylevel.
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:
But after I don't know how access the value pixel. I need the values pixel to create pixmap.
thank to your answer
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
thank to your answer
-
- ICSMED DICOM Services
- Posts: 2217
- Joined: Fri, 2004-10-29, 21:38
- Location: Oldenburg, Germany
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.
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.
-
- Posts: 18
- Joined: Fri, 2007-04-13, 08:40
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:
After I call a function whose aims at converting DicomImage to pixmap.
My code is:
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...
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 );
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;
}
}
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...
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(); */
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(); */
Who is online
Users browsing this forum: Semrush [Bot] and 1 guest