DICOM: Implementation of C-find SCU based on DCMTK

Source: Internet
Author: User


Background:


The column has written a number of related articles about the DICOM protocol, and there are theoretical articles on conceptual analysis, as well as application articles for example demonstrations. The goal is only one, hoping to guide you to quickly master the DICOM protocol, and proceed to custom development.
There are many open source libraries, such as C + + based DCMTK, C #-based fo-dicom, Java-based Dcm4che, which are implemented in the DICOM protocol. Because the relevant examples in the time relationship blog are often interspersed with the use of three open source libraries, it is not possible to give a demonstration project to a particular library. For example, a recent Netizen consulting hope to use the DCMTK Open Source Library to implement the C-find query request, and the information returned by the server to customize the processing. So the weekend to write a minimalist version of the example, code cut in the DCMTK Open Source Library Findscu project, for everyone to exchange learning.


Preparation of Knowledge:


To get a better understanding of the code examples, please read the relevant articles in the previous column, if you already know the DICOM protocol well and have developed experience, or simply want to start by tapping the code and want to learn from the practice, then jump to the next section yourself.
Read DICOM medical image processing before starting work: DICOM Network transmission understand the meaning of Dicom protocol and simple rules to establish Then read the Dicom medical image processing: A comprehensive analysis of the communication service modules in the DICOM3.0 Standard and the DICOM:DICOM3.0 Network Communication Protocol (continued) Learn more about the DICOM protocol, and familiarize yourself with the specific implementation of the DICOM protocol in the DCMTK Open Source Library. After reading the above conceptual articles, explore the following two examples to demonstrate the DICOM medical image processing: Learning and analyzing worklist, dicom medical image processing based on DCMTK Toolkit: fo-dicom send c-find query worklist.


DCMTK implementation of the C-find SCU:


After all prior knowledge reserves are completed, you can enter our topic, the needs of netizens are:



Reading Dicom medical image processing: Learning and analyzing worklist, dicom medical image processing based on DCMTK Toolkit: fo-dicom send c-find query worklist Two instance blog post, Hope Use DCMTK to attempt to send a C-FIND-RQ request and then parse and post-process the returned C-FIND-RSP message .


After the "preparation of knowledge" stage, presumably you have already understood the C-find request to establish the subject process, so do not wordy directly paste the code, with a simple example to do the actual explanation.


A) network environment initialization
//1) Initialize network environment
WSAData winSockData;
/* we need at least version 1.1 */
WORD winSockVersionNeeded = MAKEWORD( 1, 1 );
WSAStartup(winSockVersionNeeded, &winSockData);
b) DCMTK Library initialization
//2) DCMTK environmental monitoring
if(!dcmDataDict.isDictionaryLoaded())
{
printf("No data dictionary loaded, check environment variable\n");
}
c) Establish Dul connection
//3) Network layer ASC initialization
T_ASC_Network* cfindNetwork=NULL;
int timeout=50;
OFCondition cond=ASC_initializeNetwork(NET_REQUESTOR,0,timeout,&cfindNetwork);
if(cond.bad())
{
Printf ("DICOM underlying network initialization failed \ n");
Return -1;
}
//4) Create the underlying connection, the TCP layer
T_ASC_Association* assoc=NULL;
T_ASC_Parameters* params=NULL;
DIC_NODENAME localHost;
DIC_NODENAME peerHost;
OFString temp_str;
cond=ASC_createAssociationParameters(?ms,maxReceivePDULength);
if(cond.bad())
{
Printf ("DCMTK failed to create connection \ n");
Return -2;
}
d) discriminant Connection
//5) Set DICOM related properties, presentation context
ASC_setAPTitles(params, ourTitle, peerTitle, NULL);
cond = ASC_setTransportLayerType(params, false);
if (cond.bad()) return -3;
gethostname(localHost, sizeof(localHost) - 1);
sprintf(peerHost, "%s:%d", peer, OFstatic_cast(int, port));
ASC_setPresentationAddresses(params, localHost, peerHost);
cond=ASC_addPresentationContext(params,1,abstractSyntax,transferSyntaxs,transferSyntaxNum);
if(cond.bad())
Return -4;
//6) Really create a connection
cond=ASC_requestAssociation(cfindNetwork,params,&assoc);
if (cond.bad()) {
if (cond == DUL_ASSOCIATIONREJECTED) {
T_ASC_RejectParameters rej;
ASC_getRejectParameters(params, &rej);
DCMNET_ERROR("Association Rejected:" << OFendl << ASC_printRejectParameters(temp_str, &amp;rej));
Return -5;
} else {
DCMNET_ERROR("Association Request Failed: " << DimseCondition::dump(temp_str, cond));
Return -6;
}
}
//7) Judge return result
//7.1) connection verification stage, verification of presentation context
if(ASC_countAcceptedPresentationContexts(params)==0)
{
printf("No acceptable Presentation Contexts\n");
Return -7;
}
T_ASC_PresentationContextID presID;
T_DIMSE_C_FindRQ req;
T_DIMSE_C_FindRSP rsp;
DcmFileFormat dcmff;
presID=ASC_findAcceptedPresentationContextID(assoc,abstractSyntax);
if(presID==0)
{
printf("No presentation context\n");
Return -8;
} 
e) Send C-find-rq
//8) Initiate c-find request
//8.1) prepare c-find-rq message
BZero (ofreinterpret \ cast (char *, &amp; req, sizeof (req)); / / memory initialization is empty;
strcpy(req.AffectedSOPClassUID,abstractSyntax);
req.DataSetType=DIMSE_DATASET_PRESENT;
req.Priority=DIMSE_PRIORITY_LOW;
//When the information to be queried is set to null, it will be returned in the query results later
DcmDataset* dataset=new DcmDataset();
InsertQueryItems(dataset,"A^B^C");
//Assign a custom callback function, which is the operation of related information in the callback function
ZSCFindCallback zsCallback;
DcmFindSCUCallback* callback=&amp;zsCallback;
callback->setAssociation(assoc);
callback->setPresentationContextID(presID);
/* as long as no error occured and the counter does not equal 0 */
cond = EC_Normal; 
f) Set the callback function for custom processing
class ZSCFindCallback:public DcmFindSCUCallback
{ public: ZSCFindCallback()
    {

    }

    ~ZSCFindCallback()
    {

    } void callback( T_DIMSE_C_FindRQ *request, int responseCount,
        T_DIMSE_C_FindRSP *rsp,
        DcmDataset *rspMessage
        );

};
g) Get C-FIND-RSP
while (cond.good())
{
DcmDataset *statusDetail = NULL;
/* complete preparation of C-FIND-RQ message */
req.MessageID = assoc->nextMsgID++;
/* finally conduct transmission of data */
cond = DIMSE_findUser(assoc, presID, &amp;req, dataset,
progressCallback, callback, DIMSE_BLOCKING, timeout,
&amp;rsp, &amp;statusDetail);
//Set the blocking mode for query, dimse "blocking
//Set connection timeout to 50
/ *
*Add exception discrimination
*
* /
Cond = EC ﹤ endofstream; / / assuming an exception, return
} 
Example test:


Reference before DICOM medical image processing: Based on the DCMTK Toolkit learning and Analysis worklist, dicom medical image processing: The use of fo-dicom send c-find Query worklist blog post Introduction to test can, specific details not much to say, a brief introduction:


Start worklist SCP:


Follow the previous blog post to build the Worklist database and enter it at the command line:
Wlmscpfs.exe-d-DFR-DFP./wlistdb 2234
See the following results to illustrate the smooth start of the worklist server.


Start C-find SCP:


In the VS environment, run the Dumpcfindresponse project directly and see the following results:


At this point, the C-find SCU I built successfully implemented the send C-FIND-RQ, and customized the purpose of processing c-find-rsp.
PS: Here is simply a demonstration, to actually develop their own c-find SCU and C-find SCP need to consider more details, such as Presentationcontext, Transfersyntax and so on.


Sample Project Download:


"GitHub:" dumpcfindresponse
"Baidu:" dumpcfindresponse
"CSDN:" dumpcfindresponse Resources Download



[Email protected]
Date: 2015-03-28



DICOM: Implementation of C-find SCU based on DCMTK


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.