Wednesday, July 23, 2008

使用 DCMTK 函式庫 for Visual C++ 2005

這篇文章假設讀者已經透過 DCMTK 的編譯及設定 for Visual C++ 2005 一文編譯好適用於 VC++2005的函式庫。

創建一個新專案後,要如何跟我們已經設定好的 DCMTK 函式庫做連結呢?
1. 將 DCMTK 的 include 目錄設定給新專案
(1) 在方案總管中點選新專案
(2) 從主選單中選擇 "專案" - "屬性"
(3) 從對話盒左側選擇 "組態屬性" - "C/C++"
(4) 在右側的 "其他 Include 目錄" 屬性中,填入 "C:\DCMTK\include"

2. 將 DCMTK 的 lib 目錄設定給新專案
(1) 從屬性對話盒左側選擇 "組態屬性" - "連結器"
(2) 在右側的 "其他程式庫目錄" 屬性中,填入 "C:\DCMTK\lib"

3. 在新專案中指定引用的相關程式庫檔案
(1) 從屬性對話盒左側選擇 "組態屬性" - "連結器" - "輸入"
(2) 在右側的 "其他相依性" 屬性中填入以下字串,注意各程式庫檔的順序必須要正確。
"netapi32.lib wsock32.lib ofstd.lib dcmdata.lib dcmimgle.lib dcmimage.lib ijg8.lib ijg12.lib ijg16.lib dcmjpeg.lib dcmnet.lib dcmdsig.lib dcmsr.lib dcmtls.lib dcmpstat.lib dcmwlm.lib dcmqrdb.lib dcmtkeay.lib dcmtkssl.lib iconv.lib libtiff.lib libpng.lib libxml2.lib zlib.lib"
4. 指定新專案的執行階段程式庫(必須與DCMTK編譯時的設定相同,預設為 /MT /MTd)
(1) 從屬性對話盒左側選擇 "組態屬性" - "一般"
(2) 在右側的 "MFC的使用" 選擇 "使用標準的視窗程式庫"
(3) 從屬性對話盒左側選擇 "組態屬性" - "C/C++" - "程式碼產生"
(4) 在右側的 "執行階段程式庫" 選擇 "多執行緒(/MT)" (for release 組態) 或 "多緒行緒偵錯(/MTd)" (for debug 組態)

透過上述的設定,應該就可以在新專案中使用 DCMTK 了。

26 comments:

zhaoye said...

你好,安照你"使用 DCMTK 函式庫 for Visual C++ 2005"一文中的說法,我製作了VS2005的工程,但我怎么在VS2005中試用DCMTK生成的庫文件,能基於 EchoSCU 給個簡單的VS2005工程詳細的例子嗎?

chinsonyeh said...

To zhaoye,
DCMTK我僅僅使用在輸出入單一影像跟DICOMDIR,關於 EchoSCU 我並不了解。
不過關於使用函式庫的方式,如果你在 VC2005 的新專案中,已經正確的設定好各項參數,那之後的使用方式就僅僅是引用你要使用的 .h 檔及使用該類別或函式。

請參考 DCMTK 的說明文件囉

zhaoye said...

我是C#初學者,不太清楚C++和C# 間頭文件的使用方式,如果可以的話,能否將DICOMDIR for vs2005 工程發一份給我學習學習?

chinsonyeh said...
This comment has been removed by the author.
chinsonyeh said...

抱歉,不太清楚你要什麼東西,C# 我也沒學過

就C++來說,開啟 DICOM 的方法大概如下︰

// 開啟 DICOMDIR
DcmDicomDir dicomdir("DICOMDIR_FilePath");

// 讀取根位置
DcmDirectoryRecord * root = &(dicomdir.getRootRecord());

// 讀取特定 Patient 位置
DcmDirectoryRecord * PatientRecord = root->getSub(nPatientIndex);

// 讀取特定 Study 位置
DcmDirectoryRecord * StudyRecord = PatientRecord->getSub(nStudyIndex);

// 讀取特定 Series 位置
DcmDirectoryRecord * SeriesRecord = StudyRecord->getSub(nSeriesIndex);

// 讀取記錄的每張影像檔名
DcmDirectoryRecord * FileRecord;
while (((FileRecord = SeriesRecord->nextSub(FileRecord)) != NULL))
{

//取得DICOM檔案名稱
OFString tmpString;
FileRecord->findAndGetOFStringArray(DCM_ReferencedFileID, tmpString);

// 建立可存取 DICOM 影像物件
DicomImage *image = new DicomImage(tmpString.c_str());

}

建立 DicomImage 物件後,即可使用其成員函式抓取影像值。

我能提供的就是這樣了

zhaoye said...

謝謝,因最近正嘗試著將DCMTK354应用到 C# VS2008 上,而对C#本身也不太熟悉,看过此文后,收益非浅,收获颇丰,Thanks!

zhaoye said...

你好,不好意識又要打擾你,我安你在BLOG中所描述的,在VC++6 都下能順利的實現在MFC程式中使用DCMTK庫,但在VS2008中DCMTK自身能編譯通過,但在MFC程式中使用是,總是提示類似如下
“错误 1 error LNK2005: _malloc 已经在 libcmtd.lib(dbgmalloc.obj) 中定义 MSVCRTD.lib EchoScuW32”的錯誤,不知VS2005和VS2008中還有那些參數設置不一致否?


如果不能解决此问题,我再在vs2005中尝试一下!

chinsonyeh said...
This comment has been removed by the author.
chinsonyeh said...

我沒有 VS2008 可以測試,VS2005的設定可以參考一下 DCMTK 的編譯及設定 for Visual C++ 2005 的注意事項

chinsonyeh said...

也可以參考官方論譠的FAQ :
http://forum.dcmtk.org/viewtopic.php?t=35

zhaoye said...

謝謝,此問題最終在微軟MSDN中得到解決,原來是VS2008的問題,相關資料地址如下:
DCMTK:
http://forum.dcmtk.org/viewtopic.php?t=1881&highlight=2008

MSDN:
http://msdn.microsoft.com/en-us/library/70abkas3.aspx

chinsonyeh said...

Greate!
請問你是採用 /Force 參數嗎?
從論譠的說法來看,並不是好的解決方法。
比較好的方式還是應該讓函式庫與應用程式的編譯採用相同的 Runtime Library (FAQ #26)

zhaoye said...

已經將函式庫與應用程式的編譯採用相同的 Runtime Library,同時(FAQ #26)也看過了,此問題和(FAQ #26)描述的應該不一致,已經試過了,編譯出來的程式運行正常,只有暫且先這樣處理,看看日後DCMTK或VS2008還有沒有修改資料啦!
thanks!

chinsonyeh said...

嗯嗯,了解,也只能這樣了

Anonymous said...

你好,DCMTK中的命令行工具都是控制台程序,我想把一些用到我的MFC中,请问该如何更改,要把他们改写成类的形式吗?
谢谢

said...

你好,我刚开通博客就是为了和你交流向你学习。我要用到DCMTK中的DCMPSTAT子包,它的命令行都是控制台程序,请问我如何把它们应用到我的MFC工程中?是要把那些命令行改写成类吗?请给我一些指教,谢谢!我的邮箱dengzhengguang@yahoo.com.cn欢迎你给我回复。再次感谢

chinsonyeh said...

DCMTK 提供的Console模式程式,可以視為是範例程式,程式碼都在 source code 裡面,如果對 dcmtkstat 裡相關的程式有興趣,可以直接開各個程式的原始碼來看。

DCMTK 裡面有許多的C++類別,DCMTK的Console程式都是去呼叫這些類別來完成工作,所以是不需要自己去改類別的,只要知道怎麼去用它。

zhaoye said...

如Chinson所說,DCMTK 提供的Console模式程式,可以視為是範例程式,程式碼都在 source code 裡面,
不過可以功過參考并重新創建工程源代碼單元來實現在MFC中使用,本人業已經成功完成了ECHOSCU、dcmqrscp 範例的MFC 修改并在VS2008下成功编译成MFC程序,建议如果對裡相關的程式有興趣,可以直接開各個程式的原始碼來看,并尝试重最简单的ECHoSCU开始实现。

Anonymous said...

不好意思这么久才回复,不相信你会回复我。今天试试打开你的博客,竟发现你们两位都给我回复了。看了你们二位的指导,我有很大的帮助和信息。虽然我还不是很清楚具体怎么使用,但是我会好好看它们的源代码,遇到问题再麻烦你们。最后非常感谢你热心的回复!!谢谢!

said...

上面是我发的!光

CROMA said...

Hi Chinson:

感謝你的 blog 給我很大的幫助
我已經成功的編譯出 DCMTK 的 ofstd 與 dcmdata 兩個 sub-packages 並且完成一些測試了 ^ ^/

chinsonyeh said...

To CROMA:

:) 我很高興可以幫上忙,哈

CROMA said...

依序進行了下面幾個模組

ofstd
dcmdata
dcmimgle
dcmimage

剛開始學還弄不太清楚下面的部份如果有錯誤麻煩各位指正(@ @)a

因為 DcmFileFormat 繼承自 DcmObject 的介面所以我們可以透過 DcmDataset 抽取裡面的資料

// 宣告需要的資料變數
OFString PatientName;
OFString PatientSex;
OFString StudyDate;
// 宣告 DICOM 檔案變數
DcmFileFormat File;
// 讀入 DICOM 資料
File.loadFile("001");
// 取得資料集
DcmDataset *dset = File.getDataset();

// 搜尋指定的資料集並取得資料 dset->findAndGetOFString(DCM_PatientsName, PatientName);
dset->findAndGetOFString(DCM_PatientsSex, PatientSex);
dset->findAndGetOFString(DCM_StudyDate, StudyDate);

falconsyc said...

前輩你好,我是一個VS2008的新手,我最進再寫一個開啟DICOM圖片的程式,我依照你的方法將DCMTK裝入VS2008,可是執行的時候出現許多未宣告的類別,我該怎宣告DCMTK的工具呢?

falconsyc said...

'/MTd' 和 '/clr:pure' 的命令列選項不相容 cl
出現了這個該如何去更改呢?

chinsonyeh said...

To falconsyc,

是連結時期發生的錯誤嗎?DCMTK函式庫的編譯條件(ex.MTd)必須與應用程式一致。