Code Monkey home page Code Monkey logo

evil-dicom's Introduction

Logo

A simple to use C# library for reading and manipulating DICOM files. New documentation added to github via Github pages.

  • Online API via DocFX
  • Dot Net Standard Compliant (multiplatform)
  • MIT Open Source license
  • Examples On GH Pages
  • NuGet packages released with each build
  • 10,000+ downloads

Wickedly Simple

var dcm = DICOMObject.Read("MyDICOMFile.dcm");
//***COOL CODE GOES HERE***
//Writing is equally easy
dcm.Write("MyHackedDICOMFile.dcm");

Read more at the project website at http://rexcardan.github.io/Evil-DICOM/

Content Link
Introductory Video Youtube
Examples Example Operations
Online API API Documentation

Evil-DICOM used and featured in publications

  1. Mayo, C., et al., Demonstration of a software design and statistical analysis methodology with application to patient outcomes data sets. Medical physics, 2013. 40(11): p. 111718.

  2. Vickress, J., R. Barnett, and S. Yartsev, Data Inventory for Cancer Patients Receiving Radiotherapy for Outcome Analysis and Modeling. Biomedical Data Mining, 2014. 3(105): p. 2.

  3. Saalfeld, P., et al., Touchless measurement of medical image data for interventional support. Mensch und Computer 2017-Tagungsband, 2017.

  4. Miras, H., et al., Monte Carlo verification of radiotherapy treatments with CloudMC. Radiation Oncology, 2018. 13(1): p. 99.

  5. Patrick Saalfeld, D.K. and C.H. Bernhard Preim, Image Data for Interventional Support. Mensch und Computer 2017-Tagungsband: Spielend einfach interagieren, 2018. 17: p. 83.

  6. Pyyry, E.J. and W. Keranen, Varian APIs: A handbook for programming in the Varian oncology software ecosystem. 2018.

  7. Saalfeld, P., J. Patzschke, and B. Preim, An immersive system for exploring and measuring medical image data. Mensch und Computer 2017-Tagungsband: Spielend einfach interagieren, 2018. 17: p. 73.

  8. Alkhimova, S. and V. Kuleshov, Analysis of turning angle in scope of brain tissue segmentation with CUSUM filter. 2019.

  9. Alkhimova, S. and S. Sliusar, Analysis of effectiveness of thresholding in perfusion ROI detection on T2-weighted MR images with abnormal brain anatomy. arXiv preprint arXiv:1912.05469, 2019.


Supported by JetBrains' ReSharper

JetBrain's Logo

evil-dicom's People

Contributors

anders9ustafsson avatar brianmanderson avatar jazb83 avatar jmeridth avatar kulbachinskii avatar profoundmedicaldeveloper avatar rexcardan avatar sunebuur avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

evil-dicom's Issues

Resize image using EvilDicom

Hi,

I'm trying to resize an image and I've got this so far:

int width = imgFile.Properties.Columns;
int height = imgFile.Properties.Rows;

imgFile.Properties.Columns = width/2;
imgFile.Properties.Rows = height / 2;

Now, when it gets resized, the image gets corrupt, is there a way to do this?

thanks!

Adding element Image Plane Pixel Spacing (30020011)

I am a newbie for both programming and dicom. I cannot find method to add an element to an existing dicom file. I went through this #27 article and tried the code like this:

Dim dcm = New DICOMObject
Dim fs = New FloatingPointDouble(New Tag("30020011"), 0.252)
dcm.Add(fs)
dcm.Write("d:\dcmeditor\new.dcm")

The output is written but missing the new Element. Is there a better way of doing this. Actually the Plane Pixel values are like 0.25, 0.25.

Kindly help.

Senthil

Arithmetic operation resulted in an overflow.

Hi,

I'm using latest version of Evil-DICOM-1.5.1.2. it is giving "Arithmetic operation resulted in an overflow." error when using large dcm file.
can you please share new version with fix of this error.

Unit test project does not build

Hi Rex,

I am trying out your latest updates of Evil-DICOM, but the unit tests do not seem to have been updated with the Core project?

First of all, there is one curly bracket } too much at the end of the DataTests class. Even with that part corrected, I get compilation errors:

2> \DICOMReadTests.cs(26,35,26,51): error CS1061: 'float' does not contain a definition for 'MultipicityValue' and no extension method 'MultipicityValue' accepting a first argument of type 'float' could be found (are you missing a using directive or an assembly reference?)
2> \DataTests.cs(33,45,33,56): error CS1061: 'string' does not contain a definition for 'SingleValue' and no extension method 'SingleValue' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?)
2> \DataTests.cs(43,39,43,50): error CS1061: 'string' does not contain a definition for 'SingleValue' and no extension method 'SingleValue' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?)
2> \DataTests.cs(49,38,49,54): error CS1061: 'double' does not contain a definition for 'MultipicityValue' and no extension method 'MultipicityValue' accepting a first argument of type 'double' could be found (are you missing a using directive or an assembly reference?)

It is not immediately obvious to me how SingleValue and MultiplicityValue are intended to be used (if at all in this updated version). Can you please advice how to workaround these errors?

Best regards,
Anders @ Cureos

Private DICOM Elements?

Is there a way to read private DICOM elements? I've tried to just specify the tag but this did not work as I thought it would. Thanks.

Compilation warnings

Rex,

just wanted to highlight some compilation warnings that I experience with the latest source code. regarding the new Tag class. If I am not mistaken, you may run into performance issues with collections if GetHashCode is not overridden while Equals is.

Here is the warning log:

1>C:\Users\Anders\Documents\Visual Studio 2012\Projects\Evil-DICOM\EvilDICOM.Core\EvilDICOM.Core\Element\Tag.cs(13,18,13,21): warning CS0659: 'EvilDICOM.Core.Element.Tag' overrides Object.Equals(object o) but does not override Object.GetHashCode()
1>C:\Users\Anders\Documents\Visual Studio 2012\Projects\Evil-DICOM\EvilDICOM.Core\EvilDICOM.Core\Element\Tag.cs(13,18,13,21): warning CS0661: 'EvilDICOM.Core.Element.Tag' defines operator == or operator != but does not override Object.GetHashCode()

Best regards,
Anders

Private tags after anonymization

I have a DICOM dataset that I wish to anonymize which I do using the anonymization queue. I have a possible problem with the DICOM RT REG files where a private tag is changed (remove private tags settings false). The original is (3275,1000), VR=LO and value 'Online3D' but when passed through the anonymization queue (3275,1000), VR=unknown and value appears to be Online3d as an ascii array.

I am using the current version.

Any Ideas

Failed to CSTORE

Hi,
When I Send CSTORE it not work.
I use dcmtk storescp and this piece of code:

var obj = DICOMObject.Read(f);
var store = new DICOMSCU(new Entity(Config.SourceAET, ip, 21012));
var target = new Entity("AN_TEST", Config.TargetIP, Config.TargetPort);
var request = store.GenerateCStoreRequest(obj, Count);
store.SendMessage(request, target);

When debugger arrived to SendMessage it launch a IOException and said:

It has forced the interruption of an existing connection by the remote host

On the another hand the dcmtk storescp said:

W: DcmItem: Length of element (0002,0010) is odd
E: DcmElement: TransferSyntaxUID (0002,0010) larger (1198421) than remaining bytes (18) in file, premature end of stream
E: DIMSE failure (aborting association): 0006:020d DIMSE: receiveCommand: cmdSet->read() Failed
E: 0001:0004 Invalid stream

Floating Point Single - Private element

I may not be doing something right but I have tried everything I can think of.
I have a file that has a private element that is an array of floating point single (VR = FL)

If I do this, I get the expected number "count" of items but of course the type is incorrect.
var valTest1 = dcm.FindAll("30091047");

I thought this should do the trick but the "count" of items is still what is expected but they are all null.
var valTest2 = dcm.FindAll("30091047").Select(d => d as FloatingPointSingle).ToList();

I also tried this and both work as expected.

var valTest3 = dcm.FindAll(TagHelper.SCAN_SPOT_METERSETS_DELIVERED);
var valTest4 = dcm.FindAll(TagHelper.SCAN_SPOT_METERSETS_DELIVERED).Select(d => d as FloatingPointSingle).ToList();

Any suggestions?

Dicom Print

I need to create a tool for printing single Dicom Images(Maybe jpg images too).

I Could find this:(Looking at EvilDicom)

        Dim Ent As Entity
        Ent.AeTitle = "DRYPIX"
        Ent.Port = 104
        Ent.IpAddress = "192.168.0.180"

I have to build my own printer software.
Is that possible using evilDicom?
I also need set film size and Printer Settings (Resolution, Orientation, Film Size)
Anyone could point me to the right direction?

Specific Character Set support.

Hi,

Thanks for a great library, since fo-dicom was shut down recently I have tried using Evil-DICOM for my project and thus far it is working great.

My issue is that Evil-DICOM doesn't seem to utilize C.12.1.1.2 Specific Character Set when reading SH, LO, ST, PN, LT or UT data elements, and its causing a bit of a headache since I live in Sweden and most of the data we have uses ISO_IR 100.

Perhaps there is something I missed or is it a planned feature?

Insert Multiframe Pixel Data into US DICOM

Would really like some help on how to insert a multiframe pixel data into a dicom using Evil-DICOM selector. Currently my pixel data is in 2 dimensional Byte array (Byte[][]) Where it holds a byte array for each frame.
Any help on this would be much appreciated

Thanks

Destination array is not long enough to copy all the items in the collection. Check array index and length.

I am getting the following error while trying to parse a DICOM file. This is the file with the Transfer Syntax of Explicit Little Endian (EXPLICIT_VR_LITTLE_ENDIAN).

Destination array is not long enough to copy all the items in the collection. Check array index and length. System.Exception {System.ArgumentException}

Below is my code:

var dicomFile = System.IO.File.ReadAllBytes(file);
var tst = DICOMFileReader.ReadFileMetadata(file);
var dcm = DICOMObject.Read(file);

Any Help would be highly appreciated.
Thanks,
Robin

Writing DoseMatrix.DoseValues

I want to modify some dose values. I can read a DoseMatrix and change some dosevalues, but when when I write the dosefile and open it again, I see that nothing has changed.

Looping through the elements in DICOM file

I'm working on a project to retrieve specific tags from the DICOM RT information within existing DICOM files. I've reviewed the sample code under "getting started" and the API. Not sure if this is the correct place to post questions or if there is a forum specific to EvilDICOM.

Initially I started out using OpenDICOM.Net and was able to loop through the DICOM dataset and extract the raw data, subsequences, children, etc. But then I found that the OpenDICOM.Net library was no longer being maintained, which affected the tag and VR dictionaries available, among other things.

So I'm in the process of converting the .Net project over to use the EvilDICOM library. I am able to read in files and can loop through the IDICOMElements in the EvilDICOM.Core.DICOMObject. There are a couple things that I'm trying to do but are evading me.

First, I would like to pull the description for the tag associated with the IDICOMElement. In the prior library this would be done like de.VR.Tag.GetDictionaryEntry().Description. I see the TagInfo class in EvilDICOM but not sure how to utilize it given a IDICOMElement. I can see where the Tag and VR properties exist in the AbstractElement class but I'm not sure how to convert the IDICOMElement to the AbstractElement class without specifying the class type. And I don't know the class type as I'm looping through all the elements, do I?

Also, I would just use the UntypedData but I'm not sure how to get at multiplicity or subsequences within this.

Here's a small section of my code:

        EvilDICOM.Core.DICOMObject DICOMFile = EvilDICOM.Core.IO.Reading.DICOMFileReader.Read(DICOMFileInfo.File);

        EvilDICOM.Core.Interfaces.IDICOMElement[] allElements = new EvilDICOM.Core.Interfaces.IDICOMElement[DICOMFile.AllElements.Count()];
        DICOMFile.AllElements.CopyTo(allElements);

        foreach (EvilDICOM.Core.Interfaces.IDICOMElement de in allElements)
        {

string tag = de.Tag.CompleteID.ToString();
}

Special Characters in strings

I have some clinical CT data here and some strings contain ugly special characters (umlaut: öäü). I know, this is very problematic (I already had troubles in the past). E.g. ö has the hex value 0xF6 and will be replaced by a question mark character. Is it possible to change the encoding (or maybe adding a configuration parameter)?

Image corrupted

Hi!
I'm trying to use the library to anonymize a dicom image.
In some cases it works fine, but in other cases the final image is corrupted. I mean, the pixels of the image are wrong and also the FileMetaInformationGroupLength tag of final image has changed.
This also happen when I dont anonymize the image, I just read and write the image in a new file.

This is my code:
string dir = @"C:\Users\Desktop\CT.dcm";
var dcmBytes = System.IO.File.ReadAllBytes(@dir);
try
{

            var dcm = EvilDICOM.Core.DICOMObject.Read(dcmBytes);
            var refName = new EvilDICOM.Core.Element.PersonName
            {
                FirstName = "",
                Tag = EvilDICOM.Core.Helpers.TagHelper.PATIENT_NAME
            };


            dcm.ReplaceOrAdd(refName);
            dcm.Write(@"C:\Users\Desktop\CT2.dcm");
            // return dcm.GetBytes();
        }
        catch (Exception ex)
        {
            throw new Exception("EXCEPTION: " + ex.Message);
        }

Thank you in advance!

Unable to read Gamma Knife files using EvilDICOM.Core.IO.Reading.DICOMFileReader.Read

I'm receiving an error while attempting to read sample GK files provided by the vendor:
Explicit VR syntax used but VR string is missing

Any ideas?

I've attached the files. They include RT Dose and Structure. Total size is around 12mb on dose and was prevented from including it here. The files were given a jpg extension to allow upload but can be renamed with dcm to work properly. I tested this using MicroDICOM as the viewer.

copy of rtss dcm

copy of rtplan dcm

"Destination array is not long enough to copy all the items in the collection " Error when reading DICOMDIR file

Hello

Using version 2.0.2.8

I'm attempting to read a 2.2MB DICOMDIR file using the following:
[Evildicom.core.Dicomobject]::Read('E:\dicomdir')

I get the following error:
Exception calling "Read" with "1" argument(s): "Destination array is not long enough to copy all the items in the collection. Check array index and length."

Now from what I can see in the DICOMDIR file, it seems to contain multiple reports with VR = UT of varying lengths.

I will try to provide you with an anonymized version of the said file.

Is it something you believe can be addressed ? I tried reading the file with another DICOM library and it is able to do so but I prefer EvilDICOM much more for my current project

Trailing zero are removed at writing

Hi!

Nice library and also nice documentation on your website!

Problem: time stamps with trailing zeros will be truncated on writing. To give an example:
(0018,1201) TM [from file 1] [075937.000000 ] # Time of Last Calibration (this is the original file)
(0018,1201) TM [from file 2] [075937] # Time of Last Calibration (this is the file written by Evil DICOM)

The original file is from a clinical CT system.
I don't know if this problem can happen with doubles, too.

Unable to load large iPlan structure files

I am receiving an error when attempting to read large iPlan structure files. It appears that the problem occurs when the files are larger than 20mb because I am able to read in a 9mb file. I have done a bit of debugging and found that it does get past the preamble and metadata. GitHub is preventing me from uploading a sample problem file because of it's 5mb limit. Is there an alternative way to get the file to you?

Thanks for your help.

Arithmetic operation resulted in an overflow.
at EvilDICOM.Core.IO.Reading.DICOMBinaryReader.ReadBytes(Int32 count) in c:\U
sers\Rex\Desktop\EvilDICOM.Core\EvilDICOM.Core\EvilDICOM.Core\IO\Reading\DICOMBi
naryReader.cs:line 49
at EvilDICOM.Core.IO.Reading.DataReader.ReadLittleEndian(Int32 lengthToRead,
DICOMBinaryReader dr, TransferSyntax syntax) in c:\Users\Rex\Desktop\EvilDICOM.C
ore\EvilDICOM.Core\EvilDICOM.Core\IO\Reading\DataReader.cs:line 25
at EvilDICOM.Core.IO.Reading.DICOMElementReader.ReadElementExplicitLittleEndi
an(DICOMBinaryReader dr) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICOM.Core\E
vilDICOM.Core\IO\Reading\DICOMElementReader.cs:line 35
at EvilDICOM.Core.IO.Reading.DICOMElementReader.ReadAllElementsExplicitLittle
Endian(DICOMBinaryReader dr) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICOM.Co
re\EvilDICOM.Core\IO\Reading\DICOMElementReader.cs:line 177
at EvilDICOM.Core.IO.Reading.DICOMElementReader.ReadAllElements(DICOMBinaryRe
ader dr, TransferSyntax syntax) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICOM
.Core\EvilDICOM.Core\IO\Reading\DICOMElementReader.cs:line 131
at EvilDICOM.Core.IO.Reading.DICOMObjectReader.ReadObject(Byte[] objectBytes,
TransferSyntax syntax) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICOM.Core\Ev
ilDICOM.Core\IO\Reading\DICOMObjectReader.cs:line 23
at EvilDICOM.Core.IO.Reading.SequenceItemReader.ReadLittleEndian(DICOMBinaryR
eader dr, TransferSyntax syntax) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICO
M.Core\EvilDICOM.Core\IO\Reading\SequenceItemReader.cs:line 26
at EvilDICOM.Core.IO.Reading.SequenceReader.ReadItems(Byte[] data, TransferSy
ntax syntax) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICOM.Core\EvilDICOM.Cor
e\IO\Reading\SequenceReader.cs:line 70
at EvilDICOM.Core.Element.ElementFactory.GenerateElement(Tag tag, VR vr, Obje
ct data, TransferSyntax syntax) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICOM
.Core\EvilDICOM.Core\Element_ElementFactory.cs:line 78
at EvilDICOM.Core.IO.Reading.DICOMElementReader.ReadElementExplicitLittleEndi
an(DICOMBinaryReader dr) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICOM.Core\E
vilDICOM.Core\IO\Reading\DICOMElementReader.cs:line 36
at EvilDICOM.Core.IO.Reading.DICOMElementReader.ReadAllElementsExplicitLittle
Endian(DICOMBinaryReader dr) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICOM.Co
re\EvilDICOM.Core\IO\Reading\DICOMElementReader.cs:line 177
at EvilDICOM.Core.IO.Reading.DICOMElementReader.ReadAllElements(DICOMBinaryRe
ader dr, TransferSyntax syntax) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICOM
.Core\EvilDICOM.Core\IO\Reading\DICOMElementReader.cs:line 131
at EvilDICOM.Core.IO.Reading.DICOMObjectReader.ReadObject(Byte[] objectBytes,
TransferSyntax syntax) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICOM.Core\Ev
ilDICOM.Core\IO\Reading\DICOMObjectReader.cs:line 23
at EvilDICOM.Core.IO.Reading.SequenceItemReader.ReadLittleEndian(DICOMBinaryR
eader dr, TransferSyntax syntax) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICO
M.Core\EvilDICOM.Core\IO\Reading\SequenceItemReader.cs:line 26
at EvilDICOM.Core.IO.Reading.SequenceReader.ReadItems(Byte[] data, TransferSy
ntax syntax) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICOM.Core\EvilDICOM.Cor
e\IO\Reading\SequenceReader.cs:line 70
at EvilDICOM.Core.Element.ElementFactory.GenerateElement(Tag tag, VR vr, Obje
ct data, TransferSyntax syntax) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICOM
.Core\EvilDICOM.Core\Element_ElementFactory.cs:line 78
at EvilDICOM.Core.IO.Reading.DICOMElementReader.ReadElementExplicitLittleEndi
an(DICOMBinaryReader dr) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICOM.Core\E
vilDICOM.Core\IO\Reading\DICOMElementReader.cs:line 36
at EvilDICOM.Core.IO.Reading.DICOMElementReader.ReadAllElementsExplicitLittle
Endian(DICOMBinaryReader dr) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICOM.Co
re\EvilDICOM.Core\IO\Reading\DICOMElementReader.cs:line 177
at EvilDICOM.Core.IO.Reading.DICOMElementReader.ReadAllElements(DICOMBinaryRe
ader dr, TransferSyntax syntax) in c:\Users\Rex\Desktop\EvilDICOM.Core\EvilDICOM
.Core\EvilDICOM.Core\IO\Reading\DICOMElementReader.cs:line 131
at EvilDICOM.Core.IO.Reading.DICOMFileReader.Read(String filePath) in c:\User
s\Rex\Desktop\EvilDICOM.Core\EvilDICOM.Core\EvilDICOM.Core\IO\Reading\DICOMFileR
eader.cs:line 32
at NortonRTDICOMParser.frmDICOMDataExtractor.processFile() in C:\Documents an
d Settings\vendpkr9\My Documents\Visual Studio 2010\Projects\NortonRTDICOMParser
\NortonRTDICOMParser\Form1.cs:line 195

Sorting of elements in DICOMObject

Rex,

When reading a Dicom File and enumrating the IDicomElements I noticed the following in the output

(0002,0012) ImplementationClassUID ,Type: UniqueIdentifier/System.String value 1.2.40.0.13.1.1
(0002,0013) ImplementationVersionName,Type: ShortString/System.String value dcm4che-1.4.29
(0008,9205) PixelPresentation ,Type: CodeString/System.String value MONOCHROME
(0008,9206) VolumetricProperties ,Type: CodeString/System.String value SAMPLED
(0008,9207) VolumeBasedCalculationTechnique,Type: CodeString/System.String value MAX_IP
(0008,0005) SpecificCharacterSet ,Type: CodeString/System.String value ISO_IR 100
(0008,0008) ImageType ,Type: CodeString/System.String value DERIVED\PRIMARY\TOMOSYNTHESIS\MAXIMUM

I quickly found the bug to be located in the TagSorter;
The code uses BitConverter.ToInt16(tagBytes_#,0)
for 9205 that results in a negative value (-28155)
So the solution is to use BitConverter.ToUInt16(tagBytes_#,0) instead

Andre Sikma

[Discussion] [Question] DoseMatrix and lack of understanding

The dose matrix functionality for importing Dicom Dose structures has, by design, memory inefficiencies on the order of 4x, I get that being able to send Dose Value objects with location as property has huge benefits for most use cases. However (isn't there always a however) I'm trying to build a C# program that can import two dose files for the same patient, with the same calculation conditions and compare them. The design here prevents me from parallelizing the calculation.

Is there a lower level structure that is just the array of doses that I could access? Or am I going to have to code this myself

I got confused with DoseValue and DoseValues. Please ignore

SOP Instance not recognized by TPS

I have a small app doing minor changes to TPS exported DICOM objects (RT Plan and RT Dose).
This is all that is modified for the RT Plan

DICOMObject plan = DICOMObject.Read(fileName);
var sel = new DICOMSelector(plan);
if (sel.RTPlanDescription == null)
    sel.RTPlanDescription = new ShortText(TagHelper.RTPLAN_DESCRIPTION, description);
else
    sel.RTPlanDescription.Data += description;
sel.SOPInstanceUID.Data = UIDHelper.GenerateUID();
sel.SeriesInstanceUID.Data = UIDHelper.GenerateUID();
sel.ApprovalStatus.Data = "REJECTED";
sel.RTPlanLabel.Data = "EQD2_" + sel.RTPlanLabel.Data;
plan = sel.ToDICOMObject();
DICOMFileWriter.WriteLittleEndian(path + this.planUID + ".dcm", plan);

When trying to import it to my TPS I get the following errors:

Mandatory element not found (Element: (0008,0018) 'SOP Instance UID')
Mandatory element not found (Element: (0008,0016) 'SOP Class UID')
Dicom Module: SOP Common: Read Error.

loading the DICOMObject usingEvilDICOM (or pydicom for that matter) show that the elements do exist.

If I also write
MediaStorageSOPClassUID, MediaStorageSOPInstanceUID and ImplementationClassUID to the file. Read it i pydicom and resave it

ds = pydicom.read_file(fileName)
ds.save_as(fileName)

it is accepted by the TPS.

Unable to read files with specific tranfert syntax using EvilDICOM.Core.IO.Reading.DICOMFileReader.Read

Hi,

I used this library in visualisation station DICOM fonctionalities tests. In this context, I try to read some DICOM files with different transfer syntax.
I encounter issues with JPEG_SpectralSelectionNon-Hierarchical_6-8 1.2.840.10008.1.2.4.53

---> code :
static void Main(string[] args)
{
DICOMObject dcmObject = DICOMObject.Read(args[0]);
foreach (IDICOMElement item in dcmObject.AllElements)
{
Console.WriteLine(item);
}
}

---> I paste the stacktrace :
Unhandled Exception: System.OverflowException: Arithmetic operation resulted in an overflow.
at EvilDICOM.Core.IO.Reading.DICOMBinaryReader.ReadBytes(Int32 count)
at EvilDICOM.Core.IO.Reading.DataReader.ReadLittleEndian(Int32 lengthToRead, DICOMBinaryReader dr, TransferSyntax syntax)
at EvilDICOM.Core.IO.Reading.DICOMElementReader.ReadElementImplicitLittleEndian(DICOMBinaryReader dr, StringEncoding enc)
at EvilDICOM.Core.IO.Reading.DICOMElementReader.ReadAllElementsImplicitLittleEndian(DICOMBinaryReader dr, StringEncoding enc)
at EvilDICOM.Core.IO.Reading.DICOMElementReader.ReadAllElements(DICOMBinaryReader dr, TransferSyntax syntax, StringEncoding enc)
at EvilDICOM.Core.IO.Reading.DICOMFileReader.Read(String filePath, TransferSyntax trySyntax)
at EvilDICOM.Core.DICOMObject.Read(String filePath, TransferSyntax trySyntax)
at TestDicom.Program.Main(String[] args) in C:\Users\silvan.salgues\Documents\Visual Studio 2015\Projects\TestDicom\TestDicom\Program.cs:line 20

Any ideas?

I've attached the file.
JPEG_SpectralSelectionNon-Hierarchical_6-8_1.2.840.10008.1.2.4.53.zip

İmageMatrix

Hi,
I cannot find image matrix in asp.net. Why not? Pls help

Allow reading from System.IO.Stream

Hello,

the DICOMObject.Read function only accepts a string to a file or a byte array. For convenience & performance reasons it would be nice if it also accepted a plain Stream objects, which covers both of these cases and allows for more advanced scenarios. I'd do a PR for that if this gets accepted.

SequenceSelector.DataType hides IDicomElement.DataType

One of the selectors in the new SequenceSelector class, DataType, has been named unsuitably. DataType is also the name of one property in the IDicomElement interface that the SequenceSelector class ultimately implements.

Currently, when building the EvilDICOM.Core assembly, the following warning message is displayed:

...\Evil-DICOM\EvilDICOM.Core\EvilDICOM.Core\Selection\SequenceSelector.cs(2302,27,2302,35): warning CS0108: 'EvilDICOM.Core.Selection.SequenceSelector.DataType' hides inherited member 'EvilDICOM.Core.Element.AbstractElement<EvilDICOM.Core.DICOMObject>.DataType'. Use the new keyword if hiding was intended.

Correct me if I am wrong, but in this specific case hiding is not intended, right? I therefore recommend that the DataType selector (and possibly also the DataType_ selector) is renamed to ensure that the IDicomElement.DataType property is sufficiently visible.

Sorting DICOMObject

The current default sorting of all DICOMObjects means my DICOM annotations change order which breaks my DICOM viewer. If the sorting is made optional via a property on the DICOMObject this allows things to continue working as is and resolves the issue I have. I've pulled the code from Github and done the change required. If you want the code I have it here (very simple change).

Thanks HSG

By the way great job on the library.

Exception of type 'System.OutOfMemoryException' was thrown reading .dcm file

I am trying to upload a .dcm file to read and am getting the exception marked above in the title. My code seems to be stepping into the DICOMObject.Read method without any issues until it gets to this:

(Since i am very new to using GitHub, I would also like to reference my question which is way easier on the eyes to review my code here: https://stackoverflow.com/questions/27954233/can-not-find-open-method-in-evil-dicom-using-latest-version-from-gethub?noredirect=1#comment44335595_27954233)

public static IDICOMElement ReadElementImplicitLittleEndian(DICOMBinaryReader dr)
{
var tag = TagReader.ReadLittleEndian(dr);
var vr = TagDictionary.GetVRFromTag(tag);
int length = LengthReader.ReadLittleEndian(VR.Null, dr);
var data = DataReader.ReadLittleEndian(length, dr, ransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN);
var el = ElementFactory.GenerateElement(tag, vr, data, TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN);
return el;
}

When the code gets to:

int length = LengthReader.ReadLittleEndian(VR.Null, dr);
length returns an int of 1919252000 bytes which is ~2GB. Then the code steps to:

var data = DataReader.ReadLittleEndian(length, dr, TransferSyntax.IMPLICIT_VR_LITTLE_ENDIAN);
Which checks to see if there are any bytes to read (which there is) and goes to the read bytes here:

public byte[] ReadBytes(int count)
{
byte[] buffer = new byte[count];
_binaryReader.Read(buffer, 0, count);
return buffer;
}
byte[] buffer = new byte[count]; is where the actual exception occurs in the code. I have tested the amount of bytes that it can handle and it seems to be around .6 - .7 GB which is not even half of what I need. Is there away to expand the buffer to accept all of what I need?

DICOMBinaryWriter closes stream on Dispose

Since DICOMBinaryWriter closes stream on Dispose it's hard to use it with MemoryStream
i want to write Dicom file in one class and read the result in other.
In order to make it possible one more cstor could be added to DICOMBinaryWriter
public DICOMBinaryWriter(Stream stream, bool leaveOpen)
{
this._writer = new BinaryWriter(stream, Encoding.UTF8, leaveOpen);
}
(since BinaryWriter supports such behavior )

Old version on hosted server

Hi
Few years ago I purchased the older version of the program, I am using it as a simple viewer. It works on my local machine, however it does not work on the hosted server (Godaddy). The dll is present in the bin directory.
I would appreciate your assistance.
Hesham

New Dicom File

Hi Rex, i would like to know the procedure to create a new DICOMFile and add objects to the new file..

We could do this with your older version of EvilDicom as follows:

DICOMFile df = new DICOMFile();

after this we could add as many objects as we want..

I want to know how to do this with the newer version of EvilDicom..

Please let me know at the earliest..

Thanks in advance..

Reading .dcm

Hello,

what can i do, when i read Dicom files with DICOMFileReader.Read(filename); but he can not parse every element . e.g. times or dates, because i have dicom files from a PACS, which is programmed in delphi, and he can not parse the times, so this tags stay empty. or in other tags, which are originally empty he write this string inside: "EvilDICOM.Core.Object"

By the way, i really like ur lib.

Representation of PixelSpacing

When I look at the item (0028,0030) Pixel Spacing in DicomBrowser I see a value "1\1",
but when I see the result of DICOMObject.GetSelector().PixelSpacing.GetDataOrDefault();
I only get one double value. Is this correct?

from PS 3.3-2011:
Physical distance in the patient between the center of each pixel, specified by a numeric pair - adjacent row spacing (delimiter) adjacent column spacing in mm. See 10.7.1.1 and 10.7.1.3. Required if the image has been calibrated. May be present otherwise.

CodeString doesn't seem to support mulitplicity > 1?

I'm writing DX Image SOP compliant images and testing for validation with DXVt. It looks like any fields using CodeString with a multiplicity > 1 just drop the remaining items. I'm using the V2.0.0 release. Functionally what I"m writing is this:

ReplaceOrAdd( new CodeString { Tag = TagHelper.ImageType, Data_ = new List<string>{"PRIMARY", "ORIGINAL"});

But when it does the write I only get "PRIMARY". Other places with higher multiplicity work OK (so far) But not with code strings.

Am I doing something wrong or is this a bug? I can see in DataComposer.cs where I could change the routine to use the DataContainer instead but I'm unsure if that's the right solution. ImageType and PatientOrientation are both good examples of this.

Thanks, Matt

Classic DLL Vs. New version

Hi,
The new dll missing EvilDicom.Components. Are you planning to add this class?

The second question: I can open DICOM CAD images, how can I play or advance the frames? Would you have a .Net sample, that will be greatly appreciated.

Thanks

Selection files missing in EvilDICOM.Core directory

When building the EvilDICOM.Core project from the latest commit, the build fails with the following error report:

1>------ Rebuild All started: Project: EvilDICOM.Core, Configuration: Release Any CPU ------
1>CSC : error CS2001: Source file 'Selection\DICOMSelector.cs' could not be found
1>CSC : error CS2001: Source file 'Selection\ListExtensions.cs' could not be found
1>CSC : error CS2001: Source file 'Selection\SequenceSelector.cs' could not be found

A quick review of the repository confirms that this directory and corresponding files are indeed missing here on Github.

Non-conformant Decimal Strings

I think I've got another one for you.

Some of the data I must output has to be rescaled using RescaleSlope and RescaleIntercept. I do some double precision math to determine those values and assign them to the DICOMObject tags.

It appears when the write happens, the maximum length and formatting of the exponent is not enforced. In Evil DICOM produced file for slope I have a value of "3.05171124637127E-05". DICOM only allows 16 bytes there so DVTk is rejecting it for being too long.

Also it claims "E-05" is an invalid exponent. From what I can determine it doesn't like leading zeroes in the exponent.

I dropped the leading zero from the exponent and removed 3 more characters from the end of the decimal string and that made DVTk happy. The result was 3.05171124637E-5

So I think a bit more formatting needs to happen when you write a DS VR.

Thanks, Matt

BTW, your CodeString fix was perfect. Thanks for that!

How to decode .dcm to .bmp

I want to decode .dcm to .bmp , but i can't find the method DecodeToBMP in IEncoderDecoder Class.How can I use the method.
I would very appreciate it if you have time to answer my question.

modifying tag values

Mr Cardan, hello!

I would like to modify a specific tag/element, for example the row number -> dcm.AllElements[39]

I know there are the properties .DData (non casted) and DData_ (casted). I know I have to change both of them, but how to do it with DData?

For example, Im managing dicom files with dcm.AllElements[39] as object{ushort}

I appreciate the help

Saludos!

DicomRT

I'm trying to access the RTDose of a give coordinate. I see the DoseCube class, but;

  • how do I load the Dicom dose into the DoseCube, and
  • how do I access data from the DoseCube.

Similarly, how do I go around accessing the beam information, DVH structures, contours and other elements of the RTPlan?

Thanks!

(great work btw!)

Image problem

I am putting the data from a bitmapped image into my DICOM and it turns out like this. Thanks!

github upload

This is the relevant code.

   Image image = Image.FromFile(phantomFile.Text);             
                image.RotateFlip(RotateFlipType.Rotate180FlipX);
                
                var elements = new List<IDICOMElement>
                {
                    #region patient
                    new LongString(TagHelper.PATIENT_ID, patientsID.Text),
                    new LongString(TagHelper.TYPE_OF_PATIENT_ID, patientIDType.Text),
                    new PersonName(TagHelper.PATIENT_NAME, patientsName.Text),
                    new AgeString(TagHelper.PATIENT_AGE, patientsAge.Text),
                    new LongString(TagHelper.PATIENT_BIRTH_DATE, patientsDOB.Text ),
                    new CodeString(TagHelper.PATIENT_SEX, patientsSex.Text),
                    #endregion
                    #region study
                    new LongString(TagHelper.STUDY_INSTANCE_UID, studyIdentifier.Text),
                    new LongString(TagHelper.STUDY_ID, studyID.Text),
                    new LongString(TagHelper.STUDY_DATE, studyDate.Text),
                    new LongString(TagHelper.STUDY_TIME, studyTime.Text),
                    new LongString(TagHelper.REFERRING_PHYSICIAN_NAME, referringPhysiciansName.Text),
                    new LongString(TagHelper.ACCESSION_NUMBER, accessionNumber.Text),
                    #endregion
                    #region series
                    new LongString(TagHelper.MODALITY, modality.Text),
                    new LongString(TagHelper.SERIES_INSTANCE_UID, seriesInstanceUID.Text),
                    new LongString(TagHelper.SERIES_NUMBER, seriesNumber.Text),
                    #endregion
                    #region equipment
                    new LongString(TagHelper.CONVERSION_TYPE, conversionType.Text),
                    #endregion
                    #region image
                    new IntegerString(TagHelper.INSTANCE_NUMBER, instanceNumber.Text),
                    new OtherByteString(TagHelper.PIXEL_DATA, imageToByte(image)),
                    new UnsignedShort(TagHelper.ROWS,image.Height),
                    new UnsignedShort(TagHelper.COLUMNS,image.Width),
                    new UnsignedShort(TagHelper.BITS_ALLOCATED, 8),
                    new UnsignedShort(TagHelper.BITS_STORED, 8),
                    new UnsignedShort(TagHelper.HIGH_BIT, 7),
                    new UnsignedShort(TagHelper.PIXEL_REPRESENTATION, 0),
                    new DecimalString(TagHelper.WINDOW_CENTER, 128),
                    new DecimalString(TagHelper.WINDOW_WIDTH, 256),
                    new LongString(TagHelper.PHOTOMETRIC_INTERPRETATION, "MONOCHROME2"),
                    new UnsignedShort(TagHelper.SAMPLES_PER_PIXEL,1),
                   // new DecimalString(TagHelper.PIXEL_SPACING, 0),
                   
                   
                    #endregion
                };
            
            
        
                DICOM obj = new DICOM(elements);
                
                obj.Write(outputDirectory.Text + "/" + fileName.Text + ".dcm");
   public byte[] imageToByte(Image toConvert)
        {
            MemoryStream stream = new MemoryStream();
            toConvert.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
            Byte[] bytes = stream.ToArray();
            return bytes;
        }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.