5 DICOM imaging protocol coding implementation - data group analysis

The following links are the shortcomings of this series of articles, which can be discussed in the comments area:
Series articles
  corresponding column of this article Explain DICOM protocol from zero - imaging protocol Articles in Analysis of DICOM imaging protocol and Implementation of DICOM imaging protocol , it is recommended to read the above two articles first to understand the underlying protocol of DICOM, which is helpful to understand the code implementation.

Last article DICOM imaging protocol coding implementation - Metadata group analysis The implementation idea and overall code framework of DICOM parsing engine are explained and completed

  1. The code implementation of reading DICOM file into memory.
  2. Read file header
  3. Read each DataElement in the metadata group according to the metadata group characteristics

This article will continue to explain and implement the following code ideas:

  1. Read each DataElement in the data group according to the data group properties
  2. If PixelData is in compressed format, decompress it with the corresponding decompression algorithm

Dependency:

class DcmRead : public FileRead
{
public:
	DcmRead(bool iscompress = false);
	DcmRead(string path, bool iscompress = false);
	DcmRead(char *buffer, int len, bool iscompress = false);
	~DcmRead();
public:
	virtual bool ReadFile(string path) override;
	vector<ElementData> ParseFile(TagName tagname);
	ElementFormat GetTransferSyntax();
	//Get elements other than pixeldata
	ElementValue GetElement(TagName tagname);
	ElementData GetPixelData();
	DcmToBmpTag GetBMPInfo();
	void SaveBMP(string path);
	virtual void Clear() override;
	bool IsCompress();
public:
	
	DcmTags * GetDcmTags();
	DcmFile *GetDcmFile();
	void SetClassify(DcmFilePeriod *dcmclassify);
private:

	//First 128 zeros and 4 "dicms" of dicom file
	virtual void GetHead() override;
	//dicom file 0x0002 group, metadata group
	virtual void GetMetadata() override;
	//dicom file information group
	virtual void GetInfodata(void *dcmelementset) override;
	//dicom all elements
	//virtual void GetElements(void *dcmelementset) override;

private:
	
	//Compressed image data
	ElementData UnCompressPixel(vector<ElementData> pixelset);
	vector<ElementData> GetUnCompressPixel();
	void TransferUnCompress();
private:
	
	void MemCopy(int len, int &datalen, char **data);
	void TagClassify(int startindex,vector<DcmElement> *dcmelementset);
	//Judge whether it is metadata group 0x0002 (explicit small end)
	bool IsMetaData(char *data);
	//Determine whether it is SQ
	bool IsSQ(char * data);
	int GetDataLen(char *data);
	//Whether to obtain SQ sequence completely
	bool IsSQEnd();
	//Whether the function operates recursively
	bool IsEmbed();
	void SetVrDataLen(char *data);
	void DeletePartPointer(DcmElement dcmelement);
	void DeletePointer(DcmElement dcmelement);
	void Init(bool iscompress);
private:
	void SetBinding();
	bool(DcmRead::*CompareModel)(char *source, char *des);
	int(DcmRead::*ElementIntValue)(char *buffer, int len);

	bool BigCompareModel(char *source, char *des);
	bool LittleCompareModel(char *source, char *des);
	int BigElementLen(char *buffer, int len);
	int LittleElementLen(char *buffer, int len);
private:
	void GetDcmClassifyInfo();
	void FileClassify();
private:
	bool status;
	bool isbigmodel;
	bool isin;
	bool iscompress;
	DcmFile dcmFile;
	int offset;
	//SQ sequence nesting levels
	int embednum;
	int vrlen;
	int datalen;
	ElementFormat ef;
	CompressFormat cf;
	ElementValueType et;
	vector<DcmElement> sqelementset;
	//Pipe *jpeg2k;
	SocketClient *sc;

private:
	DcmTags *dcmtags;
	DcmFilePeriod *dcmclassify;
};

  data group is the same as metadata group:
   data groups are composed of DataElement structure in DICOM protocol
   DataElement consists of Tag, VR, Length and Value
   Tag consists of group and element. VR can be divided into explicit and implicit. The byte of Length is determined by explicit and implicit and VR types, and the Length of Value is even
The difference is:
  metadata group is a small end explicit format
   data groups are affected by the transmission syntax in the metadata group. PixelData is affected by the transmission syntax, including size and compression. Data groups other than PixelData are only affected by the size format of the transmission syntax.

Main frame:

void DcmRead::GetInfodata(void *dcmelementset)
{
	int startindex = offset;
	TagClassify(startindex, (vector<DcmElement>*)dcmelementset);
}

TagClassify function is the function corresponding to the metadata group

memcpy(dcmelement.tag, buffer + offset, sizeof(dcmelement.tag));
SetVrDataLen(dcmelement.tag);
MemCopy(vrlen, dcmelement.vr.len, &dcmelement.vr.data);
MemCopy(datalen, dcmelement.datalen.len, &dcmelement.datalen.data);
int len = (this->*ElementIntValue)(dcmelement.datalen.data, dcmelement.datalen.len);
MemCopy(len, dcmelement.data.len, &dcmelement.data.data);

   so far, dicom file parsing is completed, the data of file header, metadata group and data group are encapsulated according to the DataElement structure, and finally the vector < dcmelement > type object is obtained.

Tags: OpenCV Computer Vision image processing

Posted on Wed, 17 Nov 2021 20:12:13 -0500 by akiratoya13