How Dicomparser Can Read Multiple Dcm Files
Background:
This column "DICOM medical prototype processing" has a narrow audition. At first, it only wanted to be a simple system of their ain learning aggregating and piece of work experience. After a slow browsing a few days ago, I found that the reading volume was seriously polarized, mainly focusing on "about BMP (jpg) and DCM format conversion" and "DICOM communication protocol", specially the first weblog post a long fourth dimension agoLearning notes for DCMTK open source library 1: salvage DCM files as BMP files or information streams (i.east. arrays)。 Therefore, I intend to write several articles on DCM format conversion earlier the stop of 2014. This time, I mainly focus on"How to save BMP, JPG and other conventional images equally DCM files", a simple example is given based on DCMTK library.
These posts use flashback Offset give the source code that tin exist run straight, then focus on the mistakes that are like shooting fish in a barrel to make, and finally supplement the cognition points.
Employ DCMTK to store multi BMP into DCM:
The source code is based on DCMTK, and the thought refers to the img2dcm toolkit of DCMTK. The dependent library includes: netapi32.lib; wsock32.lib; ofstd.lib; oflog.lib; dcmimgle.lib; ijg8.lib; ijg12.lib; ijg16.lib; dcmdata.lib; dcmimage.lib; dcmjpeg.lib; dcmnet.lib; zlib.lib;libi2d.lib;(Annotation: libi2d.lib library is used to import BMP files)
The source code is as follows:
//Dcmpixeldatatest.cpp: defines the entry indicate for the panel application. // #include "stdafx.h" #include "dcmtk/config/osconfig.h" #include "dcmtk/dcmdata/dctk.h" #include "dcmtk/dcmdata/dcistrmf.h" #include "dcmtk/dcmdata/libi2d/i2dbmps.h" #include "DicomUtils.h" #include <direct.h> int _ tmain(int argc, _TCHAR* argv[]) { OFCondition status; DcmFileFormat fileformat; DcmDataset* mydatasete=fileformat.getDataset(); DicomUtils::AddDicomElements((DcmDataset*&)mydatasete); Uint16 rows,cols,samplePerPixel,bitsAlloc,bitsStored,highBit,pixelRpr,planConf,pixAspectH,pixAspectV; OFString photoMetrInt; Uint32 length; E_TransferSyntax ts; char* mydata=new char[1024*1024*10]; memset(mydata,0,sizeof(char)*1024*1024*ten); char* tmpData=mydata; char curDir[100]; getcwd(curDir,100); //Wheel to add together 4 pictures for(int i=0;i<iv;++i) { OFString num; char numtmp[100]; memset(numtmp,0,sizeof(char)*100); sprintf(numtmp,"%s\\test\\%d.bmp",curDir,i+one); OFString filename=OFString(numtmp); I2DBmpSource* bmpSource=new I2DBmpSource(); bmpSource->setImageFile(filename); char* pixData=Nothing; bmpSource->readPixelData(rows,cols,samplePerPixel,photoMetrInt,bitsAlloc,bitsStored,highBit,pixelRpr,planConf,pixAspectH,pixAspectV,pixData,length,ts); memcpy(tmpData,pixData,length); tmpData+=length; delete bmpSource; }; mydatasete->putAndInsertUint16(DCM_SamplesPerPixel,samplePerPixel); mydatasete->putAndInsertString(DCM_NumberOfFrames,"four"); mydatasete->putAndInsertUint16(DCM_Rows,rows); mydatasete->putAndInsertUint16(DCM_Columns,cols); mydatasete->putAndInsertUint16(DCM_BitsAllocated,bitsAlloc); mydatasete->putAndInsertUint16(DCM_BitsStored,bitsStored); mydatasete->putAndInsertUint16(DCM_HighBit,highBit); mydatasete->putAndInsertUint8Array(DCM_PixelData,(Uint8*)mydata,4*length); mydatasete->putAndInsertOFStringArray(DCM_PhotometricInterpretation,photoMetrInt); //mydatasete->putAndInsertString(DCM_PlanarConfiguration,"ane"); condition=fileformat.saveFile("c:\\Multibmp2dcmtest.dcm",ts); if(condition.bad()) { std::cout<<"Error:("<<condition.text()<<")\n"; } return 0; }
The dicomutils class in the lawmaking is a method class that provides a static method adddicomelement to construct DICOM bones elements. The lawmaking is equally follows:
#include "DicomUtils.h" DicomUtils::DicomUtils(void) { } DicomUtils::~DicomUtils(void) { } void DicomUtils::AddDicomElements(DcmDataset*& dataset) { //Build test data /* Add patient data */ dataset->putAndInsertUint16(DCM_AccessionNumber,0); dataset->putAndInsertString(DCM_PatientName,"zssure",truthful); dataset->putAndInsertString(DCM_PatientID,"2234"); dataset->putAndInsertString(DCM_PatientBirthDate,"20141221"); dataset->putAndInsertString(DCM_PatientSex,"M"); /* Add written report information */ dataset->putAndInsertString(DCM_StudyDate,"20141221"); dataset->putAndInsertString(DCM_StudyTime,"195411"); char uid[100]; dcmGenerateUniqueIdentifier(uid,SITE_STUDY_UID_ROOT); dataset->putAndInsertString(DCM_StudyInstanceUID,uid); dataset->putAndInsertString(DCM_StudyID,"1111"); /* Add series information */ dataset->putAndInsertString(DCM_SeriesDate,"20141221"); dataset->putAndInsertString(DCM_SeriesTime,"195411"); memset(uid,0,sizeof(char)*100); dcmGenerateUniqueIdentifier(uid,SITE_SERIES_UID_ROOT); dataset->putAndInsertString(DCM_SeriesInstanceUID,uid); /* Add image information */ dataset->putAndInsertString(DCM_ImageType,"ORIGINAL\\PRIMARY\\Axial"); dataset->putAndInsertString(DCM_ContentDate,"20141221"); dataset->putAndInsertString(DCM_ContentTime,"200700"); dataset->putAndInsertString(DCM_InstanceNumber,"i"); dataset->putAndInsertString(DCM_SamplesPerPixel,"1"); dataset->putAndInsertString(DCM_PhotometricInterpretation,"MONOCHROME2"); dataset->putAndInsertString(DCM_PixelSpacing,"0.three\\0.three"); dataset->putAndInsertString(DCM_BitsAllocated,"16"); dataset->putAndInsertString(DCM_BitsStored,"16"); dataset->putAndInsertString(DCM_HighBit,"15"); dataset->putAndInsertString(DCM_WindowCenter,"600"); dataset->putAndInsertString(DCM_WindowWidth,"800"); dataset->putAndInsertString(DCM_RescaleIntercept,"0"); dataset->putAndInsertString(DCM_RescaleSlope,"one"); }
Problem analysis:
ane) File format mistake:
The value of the sampleperpixel tag I added past default in the method class dicomutils is ane. If the pixel information is finally read (i.e. the readpixeldata role is called) and the corresponding sampleperpixel field of BMP is not rewritten, the file format error will be acquired. Open up it in the santesoft DICOM editor software and the post-obit error will pop up:
Using the dcmdump.exe tool provided by DCMTK, the analysis results are as follows:
It can be seen that pixel data reading failed.
two) Image information display error:
The above figure is a right prototype, and the following figure is caused by a write fault in the photometric interpretation field. The default photometric interpretation value in the static class dicomutils is monochrome2. After modifying information technology to the photometrint parameter returned by the readpixeldata function in i2dbmpsource, the image data is displayed correctly, as shown in the following effigy:
3) Epitome color display error:
The planar configuration field is non added in the static class dicomutils, and then DCMTK automatically fills this field as 0. If nosotros modify information technology to 1, an epitome color error volition occur, as shown in the post-obit figure:
BMP format:
At that place are many blog posts about BMP format introduction, which can be used for referencehttp://prog3.com/sbdm/blog/zhandoushi1982/article/details/5196017perhapshttp://prog3.com/sbdm/weblog/gwwgle/article/details/4775396。 BMP file data is mainly composed of the following parts: 1) file header, i.e. construction bitmapfileheader, * pbitmapfileheader, which is like to dcmmetainfo in DCM; 2) An paradigm description data block, which records the size of the image information cake, the width and height of the epitome, the number of image channels (i.e. aeroplane), the number of pixels (i.due east. samplesperpixel in the later DICOM standard), the image compression mode, the size of the image data expanse, etc; three) A color table, or palette. This function is different from the color palette in DICOM standard. The size of the color table varies with the number of pixels. When the number of pixels is 24 or more, that is, samplesperpixel = 3, the pixel data itself can represent the color, so the color table is not required; 4) The image data area is the real pixel data stored in the file. [notation]: in that location is a coordinate conversion here. The standard BMP file pixel storage order is from left to right and from lesser to acme, that is, the coordinate origin is the lower left corner of the prototype; The DICOM standard storage social club is from left to right, from top to bottom, and the coordinate origin is the upper left corner of the paradigm, and then it needs to be reversed when reading past yourself.
Method for obtaining BMP paradigm information:
1) Direct read binary
Later on agreement the specific format of BMP file, you tin can straight extract pixel information from the file by using the common binary operation fashion. There are many such codes on the Internet, for reference:http://world wide web.jb51.net/article/56274.htm。
2) DCMTK Library
The i2dbmpsource class in DCMTK library is specially used to parse BMP files, and provides the conversion from BMP to DICOM data format. For specific use, please refer to the example above and the img2dcm toolkit source lawmaking given by DCMTK.
3) CXIMAGE third political party Library
CXIMAGE is a free and excellent paradigm operation class library, which can quickly access, display and convert various images, such equally BMP, GIF, ICO, TGA, JPEG, PCX, PNG, tiff, MNG, RAS, etc; CXIMAGE is easy to apply and documented in detail, with just ane API interface file; It supports multiple platforms such as windows, Linux and UNIX, and supports 32-bit and 64 fleck.
For the complex employ of CXIMAGE, please refer to the web log post of neat God in CodeProject:http://world wide web.codeproject.com/Articles/1300/CxImage。
Besides, I'm bloggingLearning notes for DCMTK open source library 1: relieve DCM files equally BMP files or data streams (i.e. arrays)The source code given in is a combination of CXIMAGE and DCMTK open up source libraries, which is also a mutual combination. For details, please refer to the source lawmaking on my GitHub.
DICOM file format:
1)Samples Per Pixel:
The label is (00280002), which is detailed in Appendix c7.6.3.i of Part iii of DICOM3.0 standard. The meaning means [the number of separate planes in this prototype], just similar the channels in Photoshop, each channel represents a color (in addition to the 3 RGB channels, there will also be a fourth permeability channel). For gray image (monochrome or gray) and color table prototype (palette), it is introduced in BMP formatpaletteBMP file), the label value is 1, RGB image or other color fashion image, the characterization value is 3. The BMP image used in this instance is in RGB format, and then sampleperpixel = iii. The initial file format error is acquired past setting this field to 1.
2)Photometric Interpretation:
The label is (00280004), which is detailed in Appendix c7.6.iii.1.2 of Part 3 of DICOM3.0 standard. Mutual values of this field include monochrome1, monochrome2, palette colour and RGB. Monochrome1 and monochrome2 stand for single channel gray image, but their mapping to black and white is contrary; Palette colour is the palette prototype mentioned in BMP. In this case, the samplesperpixel field needs to be 1,; RGB is a mutual R (red), K (dark-green) and B (blue) 3 channel color image. At this fourth dimension, the samplesperpixel field value is iii, which is the image used in our example. In addition, YBR is also given in DICOM3.0 standard_ Full, HSV, ARGB, CMYK and other methods are non described in detail here.
iii)Planar Configuration:
The label is (00280006), which is detailed in Appendix c7.6.3.one.3 of Part 3 of DICOM3.0 standard. When the value of samples per pixel field is greater than 1, the planar configuration field specifies the storage method of bodily pixel information, as follows:
Last consequence:
The case code in the blog finally generates the multibmp2dcmtest.dcm file in the root directory of deejay C. open up information technology with Sante DICOM editor, and you can see that the file contains the four BMP images we inserted, equally shown in the following figure:
So far, the job of writing multiple BMP images into DCM files has been successfully completed. In fact, writing multiple images into DCM files is exactly the aforementioned as writing a single bmp image. Only the pixel data of multiple BMP images (at this time, the width and summit of each BMP prototype are required to exist the same) needs to be written cease to finish under the pixeldata label in DCM, that is (7fe00010); At this time, assign the number of frames tag to the number of images, and the DCM file editor tin automatically recognize and extract each image.
Source code:
Baidu online disk:http://pan.baidu.com/s/1dDrhHlR
GitHub:https://github.com/zssure-thu/CSDN/tree/master
Introduction to subsequent weblog posts:
Multiple JPEG image data are stored in DCM file
Build a simple PACS server server with fo DICOM
Writer: zssure@163.com
Appointment: December 24, 2014
Source: http://prog3.com/sbdm/blog/zssureqh/article/details/42119303
0 Response to "How Dicomparser Can Read Multiple Dcm Files"
Post a Comment