日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【转】DICOM医学图像处理:开源库mDCM与DCMTK的比較分析(一),JPEG无损压缩DCM图像

發布時間:2023/12/10 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】DICOM医学图像处理:开源库mDCM与DCMTK的比較分析(一),JPEG无损压缩DCM图像 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自:https://www.cnblogs.com/mfrbuaa/p/4004114.html?有修訂

背景介紹:

近期項目需求,需要使用C#進行最新的UI和相關DICOM3.0醫學圖像模塊的開發。在C++語言下,我使用的是應用最廣泛的DCMTK開源庫,在本專欄的起初階段的大多數博文都是對DCMTK開源庫的介紹和學習。眼下因為項目需要,現開始對mDCM開源庫繼續學習分析,因此本專欄接下來的文章大多以mDCM開源庫為例進行醫學圖像的解說,DCMTK因為是C++語言開發的,所以作為我學習和剖析mDCM開源庫的原始根據,我們并未放棄對DCMTK開源庫的學習,而是通過更加細致的研讀和分析DCMTK的C++源代碼,從而更好更迅速的切換到C#語言環境下的醫學圖像處理。

DCMTK、mDCM(fo-dicom)的關系:

DCMTK的官網上有具體的說明文檔,對該開源庫的各個類,以及類之間的依賴關系進行了清晰的闡述。是學習DICOM3.0醫學最新標準不可或缺的資源。其官網網址是:http://www.dcmtk.org/,活躍的開發人員論壇地址是:http://forum.dcmtk.org/index.php。

mDCM眼下了解是從DCMTK開源庫轉過來的,或者說是該開源項目的另一個分支,是用C#語言對C++版本號的醫學圖像開源庫的再次組織和封裝,其項目托管在GitHub上的官方網址是:https://github.com/rcd/mdcm。此處就需要提到fo-dicom了,該開源庫是mDCM的升級版本號,里面添加了幾大特性,詳情可參見GitHub網址:https://github.com/rcd/fo-dicom。

大致上這三者的關系就是如此,更說明了我們依舊要以DCMTK開源庫為根據,來高速學習和剖析mDCM(fo-dicom)開源庫,要非常好的借助于DCMTK開源庫豐富而具體的說明文檔,以及活躍的開發人員論壇。以下我們就通過對DCM圖像進行無損壓縮這一任務來對照學習一下mDCM與DCMTK開源庫的不同。

DCMTK與mDCM對DCM圖像進行JPEG無損壓縮的對照學習:

DCMTK的說明文檔中對于dcmjpeg包的介紹中,就直接給出了一個利用JPEG無損壓縮的實例。詳細代碼例如以下:

?

/***************************************************************************** dcmjpeg程序包 dcmjpeg提供了一個壓縮/解壓縮庫以及可用工具。該模塊包括一些類,可將DICOM圖像對象在非壓縮和JPEG壓縮表示(傳輸協議)之間轉換。無失真和有失真JPEG處理都被支持。這個模塊實現了一族codec(編碼解碼器,由DcmCodec類派生而來),能夠將這些codec在codec list中注冊,codec list是由dcmdata模塊保存的。 主要接口類: --DJEncoderRegistration: 一個singleton(孤立)類,為全部支持的JPEG處理注冊編碼器。在djencode.h中定義。 --DJDecoderRegistration: 一個singleton(孤立)類,為全部支持的JPEG處理注冊解碼器。在djdecode.h中定義。 --DJCodecEncoder: JPEG編碼器的一個抽象codec類。This abstract class contains most of the application logic needed for a dcmdata codec object that implements a JPEG encoder using the DJEncoder interface to the underlying JPEG implementation. This class only supports compression, it neither implements decoding nor transcoding. 在djcodece.h中定義。 --DJCodecDecoder: JPEG解碼器的一個抽象codec類。This abstract class contains most of the application logic needed for a dcmdata codec object that implements a JPEG decoder using the DJDecoder interface to the underlying JPEG implementation. This class only supports decompression, it neither implements encoding nor transcoding. 工具: dcmcjpeg: Encode DICOM file to JPEG transfer syntax dcmdjpeg: Decode JPEG-compressed DICOM file dcmj2pnm: Convert DICOM images to PGM, PPM, BMP, TIFF or JPEG dcmmkdir: Create a DICOMDIR file 舉例: --用無失真JPEG壓縮一幅DICOM圖像文件。 *****************************************************************************/ DJEncoderRegistration::registerCodecs(); // register JPEG codecs DcmFileFormat fileformat; if (fileformat.loadFile("test.dcm").good()) { DcmDataset *dataset = fileformat.getDataset(); DcmItem *metaInfo = fileformat.getMetaInfo(); DJ_RPLossless params; // codec parameters, we use the defaults // this causes the lossless JPEG version of the dataset to be created dataset->chooseRepresentation(EXS_JPEGProcess14SV1TransferSyntax, ?ms); // check if everything went well if (dataset->canWriteXfer(EXS_JPEGProcess14SV1TransferSyntax)) { // force the meta-header UIDs to be re-generated when storing the file // since the UIDs in the data set may have changed delete metaInfo->remove(DCM_MediaStorageSOPClassUID); delete metaInfo->remove(DCM_MediaStorageSOPInstanceUID); // store in lossless JPEG format fileformat.saveFile("test_jpeg.dcm", EXS_JPEGProcess14SV1TransferSyntax); } } DJEncoderRegistration::cleanup(); // deregister JPEG codecs

?

?

(詳細的project配置如前一篇博文所述http://blog.csdn.net/zssureqh/article/details/38460445,在此就不在反復介紹了)

通過這段代碼能夠順利實現對DCM圖像的JPEG無損壓縮。例如以下圖所看到的,

利用Sante DICOM Editor專業DCM圖像瀏覽編輯器打開壓縮前后的圖像,發現圖像質量沒有區別,壓縮前實際大小為4572K,壓縮后為1774K,壓縮效果良好。

? ?設想:既然mDCM開源庫就是對DCMTK開源庫的封裝,那么兩個開源庫中應該會有相應的功能,同樣或類似的函數。由DCMTK實例中的代碼可知,演示樣例中僅僅調用了DcmFileFormat的loadFile、saveFile和DcmDataset的chooseRepresentation和canWriteXfer四個函數,并且從函數名稱上看,就知道實際達到壓縮效果的應該是DcmDataset的chooseRepresentation和canWriteXfer的兩個函數,那么接下來我們看看mDCM開源庫下的DcmDataset是否有相相應的函數呢?

通過VS2012的對象瀏覽器能夠看到,mDCM開源庫下的Dicom.Data命名空間中DcmDataset類中的確擁有一個類似的函數ChangeTransferSyntax,例如以下圖:

? ?推測:直接調用mDCM的Load、ChangeTransferSyntax和Save三個函數,應該能夠實現與DCMTK同樣的效果,即完畢對DCM的JPEG無損壓縮。

詳細代碼例如以下,

?

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Dicom; using Dicom.Data; using Dicom.Codec; using Dicom.Codec.JpegLs; namespace JpegLossLess { class Program { static void Main(string[] args) { DicomCodec.RegisterCodecs(); //Dicom.Codec.JpegLs.DcmJpegLsCodec.Register(); string fName = string.Format("d:\\dcm\\test.dcm"); DicomFileFormat ff = new DicomFileFormat(); ff.Load(fName, DicomReadOptions.Default | DicomReadOptions.DeferLoadingPixelData);//ff.Load(fName, DicomReadOptions.None); DcmPixelData pixels = new DcmPixelData(ff.Dataset);DcmJpegLsParameters JpegParameters = new DcmJpegLsParameters(); ff.FileMetaInfo.TransferSyntax = DicomTransferSyntax.JPEGProcess14SV1;ff.Dataset.ChangeTransferSyntax(DicomTransferSyntax.JPEGProcess14SV1, JpegParameters);string OutFile = string.Format(@"d:\dcm\outfile.dcm"); ff.Save(OutFile, DicomWriteOptions.Default); } } }


?

?

project順利編譯成功,執行調試后,也相同出現了大小為1774K的文件,可是利用Sante DICOM Editor打開該文件時,出現錯誤,例如以下圖所看到的:

利用DCMTK開源庫的工具包dcmdump.exe查看利用mDCM壓縮后的文件outfile.dcm,輸出例如以下錯誤提示:

警告(Warning)提示(0008,0000)數據元素的數值有誤,錯誤(Error)是出現了無法識別的標簽和數據(f752,0e57),經過查看DICOM3.0標準,并未發現有(f752,0e57)該標簽,利用UltraEdit打開DCMTK壓縮后的文件test_jpeg.dcm和mDCM壓縮的文件outfile.dcm,通過查找功能發現,(f752,0e57)字段實際上是標準的JPEG無損壓縮后的(7fe0,0010)字段的Value Field內容(例如以下圖所看到的),因此推測應該是mDCM壓縮后的文件頭中某個字段寫入有誤,導致在讀取數據體的時候并未依照原本的DICOM3.0標準去讀取。

解決方法:

利用DCMTK的project來讀取我們利用mDCM壓縮后的文件outfile.dcm,結果單步調試進入后,利用Load函數讀取Jpeg壓縮后的圖像時,metainfo部分是沒有問題的。可是當讀取到dataset時,對于(0008,0000)元素的讀取有誤,正確的(0008,0000)元素的解析方式為

元素標簽,即(group,element)為:08 00 00 00——(0008,0000)

元素類型,即VR為:55 4C——UL

元素長度,即VL為:04 00——0004(長度為4)

元素值域,即Value Field:B8 00 00 00——00000008(值為184)

可是在讀取dataset時,將55 4c 04 00所有當成了長度來讀取,因此推測是將原本為ExplicitUL格式的元素當做了ImplicitVR格式來讀取了,文件流的指針_streamPosition直接從0x0000000000000160直接跳轉到了0x0000000000044db5,例如以下圖所看到的:

因此嘗試在mDCM的c#project中加入手動改動文件元信息中傳輸語義的語句,

?

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Dicom; using Dicom.Data; using Dicom.Codec; using Dicom.Codec.JpegLs; namespace JpegLossLess { class Program { static void Main(string[] args) { /**************************************************** * 對照C++中DCMTK對于DICOM進行JPEG無損壓縮,來學習C# * 中Dicom庫的使用 * 2014-08-06 * zssure ****************************************************/ DicomCodec.RegisterCodecs(); string fName = string.Format(@"d:\dcm\test.dcm"); DicomFileFormat ff = new DicomFileFormat(); ff.Load(fName, DicomReadOptions.Default | DicomReadOptions.DeferLoadingPixelData);DcmJpegLsParameters JpegParameters = new DcmJpegLsParameters();ff.FileMetaInfo.TransferSyntax = DicomTransferSyntax.JPEGProcess14SV1;ff.Dataset.ChangeTransferSyntax(DicomTransferSyntax.JPEGProcess14SV1, JpegParameters);string OutFile = string.Format(@"d:\dcm\outfileJpeg22.dcm"); ff.Save(OutFile, DicomWriteOptions.Default); } } }

project編譯后,可以順利完成壓縮DCM的功能,至此利用mDCM對DICOM圖像進行JPEG無損壓縮的目的已經實現。

總結:

DICOM3.0標準的第10部分中,有對于dcm文件存儲格式的具體介紹,當中對于傳輸語義的介紹例如以下:

1)Except for the 128 byte preamble and the 4 byte prefix, the?File Meta Information?shall be encoded using theExplicit VR Little Endian Transfer Syntax (UID=1.2.840.10008.1.2.1)?as defined in DICOM PS 3.5. Values of each File Meta Element shall be padded when necessary to achieve an even length, as specified in PS 3.5 by their corresponding Value Representation. The Unknown (UN) Value Representation shall not be used in the File Meta Information. For compatibility with future versions of this Standard, any Tag (0002,xxxx) not defined in Table 7.1-1 shall be ignored. Values of all Tags (0002,xxxx) are reserved for use bythis Standard and later versions of DICOM. Data Elements with a group of 0002 shall not be used in datasets other than within the File Meta Information

2)The Transfer Syntax used to encode the DataSet cannot be changed within the Data Set; i.e., the Transfer Syntax UID Data Element may not occur anywhere within the Data Set, e.g., nested within a Sequence Item.

因此DCM文件元信息中的標簽(0002,0010),即傳輸語義,對于DCM文件的數據體Dataset的讀取起到關鍵的作用。通過此次的mDCM開源庫與DCMTK開源庫的比較發現,兩者盡管大多的函數都同樣,且名稱和功能都類似,可是對于細節部分應該注意。

如今對兩個開源庫對DCM文件的JPEG無損壓縮功能所須要調用的函數進行一個對照分析,以找到兩者之間的區別所在,詳細分析例如以下表

mDCM

DCMTK

1) DicomFileFormat.Load,打開文件(也是通過文件流的方式一一讀取DCM文件的各個信息到內存中)

2) DicomFileFormat.Dataset.ChangeTransferSyntax,該函數與DCMTK中的chooseRepresentation函數類似,在參數中都須要指出新的傳輸語義,函數內部會依據新的傳輸語義來改動數據體的存儲方式。該函數主要完畢的功能是:

比較新舊傳輸語義、依據新舊語義決定數據體是否解壓縮或壓縮(Dicom.Codec.Encode或者Dicom.Codec.Decode)。

3) DicomFileFormat.Save,存儲文件,可是該函數中并不須要填寫新的傳輸語義

【注】:這一點與DCMTK中的saveFile函數不同。這也就是上個周C#版本號的mDCM實現對DCM數據的JPEG無損壓縮后無法順利讀取的原因。由于數據體存儲格式不是依照文件元信息中指定的傳輸語義存儲的,或者說文件元信息中的傳輸語義沒有改動為JPEG無損壓縮的方式。

1) DicomFileFormat::loadFile,導入文件,主要是DcmMetaInfo和DcmDataset兩部分;

2) Dataset::chooseReresentation,參數中會出現新舊傳輸語義TransferSyntax,函數依據新的語義對對應數據(主要是像素數據)進行處理,會調用DcmPixelData::canChooseRepresentation、DcmPixelData::chooseRepresentation

3) Dataset::canWriteXfer,參數中是新改動后的傳輸語義。

4) DcmFileFormat::saveFile,參數中須要指出改動后的傳輸語義。

——》隨后會調用dcfilefo.cc文件里的validateMetaInfo函數(該函數中也須要指定新的傳輸語義)。

——》對文件元信息的各個元素分別調用DcmMetaInfo::search和chekMetaHeaderValue兩個函數(在該函數內,會檢測各個元信息元素是否存在,不存在會新建之并插入,其參數中就須要指出新的傳輸語義)

——》DcmElement::putString將新的傳輸協議寫入到MetaInfo中。(基本調用流程例如以下圖。

總結

以上是生活随笔為你收集整理的【转】DICOM医学图像处理:开源库mDCM与DCMTK的比較分析(一),JPEG无损压缩DCM图像的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。