how to use pynetdicom to get Orthanc dicom image?
See original GitHub issuehow to use pynetdicom to get Orthanc dicom image?
hello ! i have build Orthanc PACS server in windows for test "use python load PACS image " by this video https://www.youtube.com/watch?v=bsW4gYO4xrY&feature=youtu.be
in the video , radiant can simple to get dicom image from Orthanc . so i want to do that in python
now i can use “send_c_find” to get some dicom info, but dont have Modality this parameter. and i use “send_c_move” want to get dicom image but always show "Move SCP Result: 0xc000 (Failure) "
question 1 is : how to get more parameter in “send_c_find” ? question 2 is : how to get dicom image by “send_c_move” in windows Orthanc ?
here is my code
def handle_store(event):
mode_prefixes = {
'CT Image Storage' : 'CT',
'Enhanced CT Image Storage' : 'CTE',
'MR Image Storage' : 'MR',
'Enhanced MR Image Storage' : 'MRE',
'Positron Emission Tomography Image Storage' : 'PT',
'Enhanced PET Image Storage' : 'PTE',
'RT Image Storage' : 'RI',
'RT Dose Storage' : 'RD',
'RT Plan Storage' : 'RP',
'RT Structure Set Storage' : 'RS',
'Computed Radiography Image Storage' : 'CR',
'Ultrasound Image Storage' : 'US',
'Enhanced Ultrasound Image Storage' : 'USE',
'X-Ray Angiographic Image Storage' : 'XA',
'Enhanced XA Image Storage' : 'XAE',
'Nuclear Medicine Image Storage' : 'NM',
'Secondary Capture Image Storage' : 'SC'
}
ds = event.dataset
try:
sop_class = ds.SOPClassUID
sop_instance = ds.SOPInstanceUID
except Exception as exc:
# Unable to decode dataset
return 0xC210
try:
# Get the elements we need
mode_prefix = mode_prefixes[sop_class.name]
except KeyError:
mode_prefix = 'UN'
filename = '{0!s}.{1!s}'.format(mode_prefix, sop_instance)
LOGGER.info('Storing DICOM file: {0!s}'.format(filename))
if os.path.exists(filename):
LOGGER.warning('DICOM file already exists, overwriting')
# Presentation context
cx = event.context
meta = Dataset()
meta.MediaStorageSOPClassUID = sop_class
meta.MediaStorageSOPInstanceUID = sop_instance
meta.ImplementationClassUID = PYNETDICOM_IMPLEMENTATION_UID
meta.TransferSyntaxUID = cx.transfer_syntax
# The following is not mandatory, set for convenience
meta.ImplementationVersionName = PYNETDICOM_IMPLEMENTATION_VERSION
ds.file_meta = meta
ds.is_little_endian = cx.transfer_syntax.is_little_endian
ds.is_implicit_VR = cx.transfer_syntax.is_implicit_VR
status_ds = Dataset()
status_ds.Status = 0x0000
# Try to save to output-directory
filename = os.path.join(os.getcwd(), filename)
print(filename)
try:
ds.save_as(filename, write_like_original=False)
status_ds.Status = 0x0000 # Success
except IOError:
LOGGER.error('Could not write file to specified directory:')
LOGGER.error(" {0!s}".format(os.path.dirname(filename)))
LOGGER.error('Directory may not exist or you may not have write '
'permission')
# Failed - Out of Resources - IOError
status_ds.Status = 0xA700
except:
LOGGER.error('Could not write file to specified directory:')
LOGGER.error(" {0!s}".format(os.path.dirname(filename)))
# Failed - Out of Resources - Miscellaneous error
status_ds.Status = 0xA701
return status_ds
def on_c_store(ds, context, info):
print("ON_C_STORE")
meta = Dataset()
meta.MediaStorageSOPClassUID = ds.SOPClassUID
meta.MediaStorageSOPInstanceUID = ds.SOPInstanceUID
meta.ImplementationClassUID = PYNETDICOM_IMPLEMENTATION_UID
meta.ImplementationVersionName = PYNETDICOM_IMPLEMENTATION_VERSION
meta.TransferSyntaxUID = context.transfer_syntax
ds.file_meta = meta
ds.is_little_endian = context.transfer_syntax.is_little_endian
ds.is_implicit_VR = context.transfer_syntax.is_implicit_VR
ds.save_as(ds.SOPInstanceUID, write_like_original=False)
return 0x0000
from pydicom.dataset import Dataset
from pynetdicom import AE
from pynetdicom.sop_class import (
PatientRootQueryRetrieveInformationModelFind,
PatientRootQueryRetrieveInformationModelGet,
ProtocolApprovalInformationModelGet,
BasicWorklistManagementServiceClass,
CTImageStorage,
StudyRootQueryRetrieveInformationModelGet,
MRImageStorage,
VerificationSOPClass,
PatientRootQueryRetrieveInformationModelMove,
)
from pynetdicom import (
AE,
evt,
build_role,
BasicWorklistManagementPresentationContexts,
PYNETDICOM_IMPLEMENTATION_UID,
PYNETDICOM_IMPLEMENTATION_VERSION,
StoragePresentationContexts,
)
from pydicom.uid import (
ImplicitVRLittleEndian,
ExplicitVRLittleEndian,
ExplicitVRBigEndian)
# Initialise the Application Entity
myAETITE = b'RADIANT'
seAETITE = b'ORTHANC'
seIP = '127.0.0.1'
sePORT = 4242
#sePORT = 11112
#sePORT = 104
ae = AE()
ae.ae_title = myAETITE
print('PatientRootQueryRetrieveInformationModelGet = ', PatientRootQueryRetrieveInformationModelGet)
ae.add_requested_context(PatientRootQueryRetrieveInformationModelGet)
ae.add_requested_context(StudyRootQueryRetrieveInformationModelGet)
ae.add_requested_context(MRImageStorage)
ae.add_supported_context(VerificationSOPClass)
ae.add_requested_context(PatientRootQueryRetrieveInformationModelMove)
role = build_role(CTImageStorage, scp_role=True)
ext_neg = []
ext_neg.append(role)
ae.on_c_store = on_c_store
ae.add_requested_context('1.2.840.10008.5.1.4.1.1.4',
[ImplicitVRLittleEndian,
ExplicitVRLittleEndian,
ExplicitVRBigEndian,])
# Create our Identifier (query) dataset
ds = Dataset()
ds.PatientName = '*'
ds.QueryRetrieveLevel = 'STUDY'
print('TEST 219484 ae.associate ')
assoc = ae.associate(seIP, sePORT, ae_title=seAETITE, ext_neg=ext_neg)
print('TEST 013625 after ae.associate ')
i = 0
is_established = 'N'
hresponses = 'N'
if assoc.is_established:
print('TEST 944960 assoc.is_established ')
is_established = 'Y'
print('TEST 416830 send_c_move ')
responses = assoc.send_c_move(ds,
query_model=MRImageStorage,
move_aet=myAETITE,
)
print('TEST 459893 before in responses ')
i = 0
for (status, identifier) in responses:
print('TEST 454379 after in responses')
hresponses = 'Y'
if status and identifier:
i += 1
print('##############################')
print('C-FIND query status: 0x{0:04x}'.format(status.Status))
print('status = ', status)
print('type(status) = ', type(status))
print('status.Status = ', status.Status)
print('type(identifier) = ', type(identifier))
print('identifier = ',identifier)
print('status.keys() = ', status.keys() )
print('identifier.keys() = ', identifier.keys() )
print('status.items() = ', status.items() )
for elem in identifier.elements():
print('elem = ', elem)
if status.Status in (0xff00, 0xff01):
print(identifier)
print('##############################')
else:
print('Connection timed out, was aborted or received invalid response')
print('############# FIND ', i)
assoc.release()
else:
print('Association rejected, aborted or never connected')
thanks for everyone~
Issue Analytics
- State:
- Created 3 years ago
- Comments:12 (6 by maintainers)
Top Results From Across the Web
Re: Connect to ORTHANC with Pynetdicom - Google Groups
I am running on MacOS using ./Orthanc --verbose. I wish to query and retrieve images based on the Patient ID. So far, i...
Read more >Python plugin for Orthanc
This plugin can be used to write Orthanc plugins using the Python programming language instead of the more complex C/C++ programming languages. Python...
Read more >How to Import DICOM Images into your Orthanc DICOM Server
After our DICOM images are imported, we go over some of the different Orthanc DICOM features such as anonymization and the DICOMDIR.
Read more >How to Send DICOM Images with StoreSCU - YouTube
This DICOM Training / DICOM Tutorial video shows you how to send DICOM images from one DICOM device to your Orthanc DICOM server...
Read more >Magician's Corner: 8: How to Connect an Artificial Intelligence ...
This is a practical example of how to both get images needed by an AI tool for inference, and how to store the...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Yes, that sounds correct. Glad to help
@scaramallion Thank you very much ~ You are so nice