2017-09-04 107 views
1

我正在使用DCMTK library開發一個快速DICOM viewer,我遵循this link中提供的示例。DCMTK中的findAndGetString()在標記中返回null

API緩衝器總是對任何標籤ID返回null,例如:DCM_PatientName。 但findAndGetOFString() API工作正常,但只返回標記的第一個字符ASCII,這是如何API此工作?

有人可以讓我知道爲什麼緩衝區是空的前API?

另外DicomImage API也是同樣的問題。

片段1:

DcmFileFormat fileformat; 
OFCondition status = fileformat.loadFile(test_data_file_path.toStdString().c_str()); 
if (status.good()) 
{ 
    OFString patientName; 
    char* name; 
    if (fileformat.getDataset()->findAndGetOFString(DCM_PatientName, patientName).good()) 
    { 
     name = new char[patientName.length()]; 
     strcpy(name, patientName.c_str()); 
    } 
    else 
    { 
     qDebug() << "Error: cannot access Patient's Name!"; 
    } 
} 
else 
{ 
    qDebug() << "Error: cannot read DICOM file (" << status.text() << ")"; 
} 

在上述片斷name具有ASCII值 「50」 和實際的名稱是 「患者」。

片段2:

DcmFileFormat file_format; 
OFCondition status = file_format.loadFile(test_data_file_path.toStdString().c_str()); 
std::shared_ptr<DcmDataset> dataset(file_format.getDataset()); 
qDebug() << "\nInformation extracted from DICOM file: \n"; 
const char* buffer = nullptr; 
DcmTagKey key = DCM_PatientName; 
dataset->findAndGetString(key,buffer); 
std::string tag_value = buffer; 
qDebug() << "Patient name: " << tag_value.c_str(); 

在上面的代碼中,緩衝器是空的。它不會讀取名稱。

注:

這僅僅是一個樣品。我只是圍繞API學習 的目的。

+0

name = new char [patientName.length()];應該是name = new char [patientName.length()+ 1];包括空終止符。很可能調試器只顯示字符串中的第一個字符。試試qDebug()<< name –

+0

沒有運氣。打印50。我也收到了警告「W:DcmMetaInfo:元信息頭的組長度值不正確」,但.dcm文件可以在現有工具中正常打開。 –

+0

@ kaviergeoffrey如果文件是匿名的,你可以分享它嗎? –

回答

1

下面的示例方法從DcmDataset對象讀取患者姓名:

std::string getPatientName(DcmDataset& dataset) 
{ 
    // Get the tag's value in ofstring 
    OFString ofstring; 
    OFCondition condition = dataset.findAndGetOFString(DCM_PatientName, ofstring); 
    if(condition.good()) 
    { 
     // Tag found. Put it in a std::string and return it 
     return std::string(ofstring.c_str()); 
    } 

    // Tag not found 
    return ""; // or throw if you need the tag 
} 
+0

此代碼僅返回名稱爲tag的患者字母P的「50」ASCII ... –

+0

次要評論:當DCMTK使用自OFString啓用的STL進行編譯時,不需要將OFString實例轉換爲std :: string實例然後是std :: string的另一個名稱。 –

+0

@XavierGeoffrey:那麼我懷疑數據集是用一個字符集編碼的,我們不期望在這裏。 (0008,0005)特定字符集的屬性值是多少? –

1

我曾嘗試你的代碼與數據集。我只是將輸出替換爲QT控制檯類到std :: cout。它適用於我 - 即打印正確的患者姓名(例如,針對scan2.dcm的「PATIENT2」)。一切看起來都是正確的,除非你顯然想將數據集的所有權轉移到智能指針。

要從DcmFileFormat獲取DcmDataset的所有權,您必須調用getAndRemoveDataset()而不是getDataset()。但是,我不認爲你的問題是相關的。你可能想嘗試我修改的摘錄:

DcmFileFormat file_format; 
OFCondition status = file_format.loadFile("d:\\temp\\StackOverflow\\scan2.dcm"); 
std::shared_ptr<DcmDataset> dataset(file_format.getAndRemoveDataset()); 
std::cout << "\nInformation extracted from DICOM file: \n"; 
const char* buffer = nullptr; 
DcmTagKey key = DCM_PatientName; 
dataset->findAndGetString(key, buffer); 
std::string tag_value = buffer; 
std::cout << "Patient name: " << tag_value.c_str(); 

這或許可以幫助你知道你的代碼,並使用DCMTK方法是正確的,但這並不解決您的問題。我建議的另一件事是驗證file_format.loadFile()返回的結果。也許那裏有一個驚喜。

不知道我是否可以幫助更多,但我的下一步將是驗證您的構建環境,例如,您用於構建dcmtk的選項。你使用CMake來構建dcmtk嗎?

+0

謝謝:)很快就會檢查出來,讓你知道...... –