2015-01-27 1 views
0

DICOM 이미지를 생성 할 수있는 기존 프로젝트에서 DCMTK 3.6.1 라이브러리를 사용하고 싶습니다. DICOM 이미지를 압축하기 때문에이 라이브러리를 사용하고 싶습니다. 새로운 솔루션 (Visual Studio 2013/C++) DCMTK 공식 문서의 예제에 따라이 코드가 제대로 작동합니다.바이트 (DCMTK)에서 DICOM 이미지를 만드는 방법

using namespace std; 

int main() 
{ 

    DJEncoderRegistration::registerCodecs(); 
    DcmFileFormat fileformat; 

    /**** MONO FILE ******/ 

    if (fileformat.loadFile("Files/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 EXS_JPEGProcess14SV1 
     dataset->chooseRepresentation(EXS_JPEGProcess14SV1, &params); 

     // check if everything went well 
     if (dataset->canWriteXfer(EXS_JPEGProcess14SV1)) 
     { 
      // 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); 

      metaInfo->putAndInsertString(DCM_ImplementationVersionName, "New Implementation Version Name"); 
      //delete metaInfo->remove(DCM_ImplementationVersionName); 
      //dataset->remove(DCM_ImplementationVersionName); 

      // store in lossless JPEG format 
      fileformat.saveFile("Files/carrellata_esami_compresso.dcm", EXS_JPEGProcess14SV1); 
     } 
    } 

    DJEncoderRegistration::cleanup(); 

    return 0; 
} 

는 지금은

if (infoDicom.arrayImgDicom.GetSize() != 0) //Things of existing previous code 
     { 

    //I have added here the registration 
    DJEncoderRegistration::registerCodecs(); // register JPEG codecs 

    DcmFileFormat fileformat; 
    DcmDataset *dataset = fileformat.getDataset(); 
    DJ_RPLossless params; 

     dataset->putAndInsertUint16(DCM_Rows, infoDicom.rows); 
    dataset->putAndInsertUint16(DCM_Columns, infoDicom.columns,); 
    dataset->putAndInsertUint16(DCM_BitsStored, infoDicom.m_bitstor); 
    dataset->putAndInsertUint16(DCM_HighBit, infoDicom.highbit); 
    dataset->putAndInsertUint16(DCM_PixelRepresentation, infoDicom.pixelrapresentation); 
    dataset->putAndInsertUint16(DCM_RescaleIntercept, infoDicom.rescaleintercept); 
    dataset->putAndInsertString(DCM_PhotometricInterpretation,"MONOCHROME2"); 
    dataset->putAndInsertString(DCM_PixelSpacing, "0.086\\0.086"); 
    dataset->putAndInsertString(DCM_ImagerPixelSpacing, "0.096\\0.096"); 
    BYTE* pData = new BYTE[sizeBuffer]; 

    LPBYTE pSorg; 

    for (int nf=0; nf<iNumberFrames; nf++) 
    { 
     //this contains all the PixelData and I put it into the dataset 
     pSorg = (BYTE*)infoDicom.arrayImgDicom.GetAt(nf); 
     dataset->putAndInsertUint8Array(DCM_PixelData, pSorg, sizeBuffer); 

     dataset->chooseRepresentation(EXS_JPEGProcess14SV1, &params); 
     //and I put it in my data set    


     //but this IF return false so che canWriteXfer fails... 
     if (dataset->canWriteXfer(EXS_JPEGProcess14SV1)) 
     { 
      dataset->remove(DCM_MediaStorageSOPClassUID); 
      dataset->remove(DCM_MediaStorageSOPInstanceUID); 
     } 

      //the saveFile fails too, and the error is "Pixel 
//rappresentation non found" but I have set the Pixel rep with 
//dataset->putAndInsertUint16(DCM_PixelRepresentation, infoDicom.pixelrapresentation); 

    OFCondition status = fileformat.saveFile("test1.dcm", EXS_JPEGProcess14SV1); 

    DJEncoderRegistration::cleanup(); 

     if (status.bad()) 
     { 
      int error = 0; //only for test 
     } 

     thefile.Write(pSorg, sizeBuffer); //previous code 
    } 

는 사실 내가 한 프레임에있는 이미지와 테스트를 만들어 기존 C++ 프로그램에서 동일한 코드를 사용하려면, 그래서주기위한 한 번만 이루어집니다. 이해가되지 않는 이유는 완벽하지만 dataset->chooseRepresentation(EXS_LittleEndianImplicit, &params); 또는 dataset->chooseRepresentation(EXS_LittleEndianEXplicit, &params); 작품을 선택하면되지 내가 선택할 때 dataset->chooseRepresentation(EXS_JPEGProcess14SV1, &params);

내가 처음 프로그램에서 동일한 이미지를 사용하는 경우, 나는 문제없이 이미지를 압축 할 수 있습니다 ...

편집 : 내가 해결할 주요 문제는 status = dataset->chooseRepresentation(EXS_JPEGProcess14SV1, &rp_lossless) 해당 "태그를 찾을 수 없습니다"라고 생각합니다. 태그가 누락되었음을 어떻게 알 수 있습니까?

EDIT2

: 나는 할당 된 비트에 대한 태그를 추가 한 DCMTK 포럼에서 제안하고 지금 은 모두 몇 이미지을 작동하지만 비로서. 일부 이미지의 경우 다시 "태그를 찾을 수 없습니다.": 태그 중 하나가 누락되었음을 어떻게 알 수 있습니까? 일반적으로 모든 태그를 삽입하는 것이 좋습니다.

답변

1

DCM_BitsAllocated 및 DCM_PlanarConfiguration 태그를 추가하면 문제가 해결됩니다. 이것은 놓친 태그입니다. 그게 누군가에게 도움이되기를 바랍니다.

0

데이터를 적용한 후에 적어도 chooseRepresentation 함수를 호출해야합니다.

**dataset->putAndInsertUint8Array(DCM_PixelData, pSorg, sizeBuffer);** 
dataset->chooseRepresentation(EXS_JPEGProcess14SV1, &params); 
+0

답변 해 주셔서 감사합니다. Ops .. 이것은 질문을 썼을 때 copy-paste에서 에러가 났지만 코드를 적용한 후에는 데이터를 적용한 후 chooseRepresentation이 수행됩니다. 나는 문제를 해결할 것이지만이 문제는 문제를 해결하지 못한다. 디버그를 통해 나는 chooseRepresentation 메서드 후에 Xfer가 LittleEndian에 남아 JPEGProcess14SV1에서 변경되지 않는다는 것을 알았습니다 .... 어떤 이유로 코덱이 등록되지 않았을 가능성이 있습니까 ?? – GiordiX

+0

chooseRepresentation은 어떤 조건을 반환합니까? – JohnnyQ

+0

이 경우 상태는 "태그를 찾을 수 없음"이며 이유를 알 수 없습니다. 또 다른 실험을했습니다 :'status = dataset-> chooseRepresentation (EXS_LittleEndianExplicit, & rp_lossless); // 여기서 상태는 OK입니다. 파일을 다시로드 한 후'status = dataset-> chooseRepresentation (EXS_JPEGProcess14SV1, & rp_lossless);을 수행 한 후 status = fileformat.saveFile ("file_esplicito.dcm", EXS_LittleEndianExplicit); // 여기 상태는 OK입니다.하지만 'status = fileformat.saveFile ("prova1.dcm", EXS_JPEGProcess14SV1); 파일을 저장하려고하면 여기에 "여기에 픽셀 표시가 없습니다"라고 표시됩니다. – GiordiX

관련 문제