Convert Pixel value to HU on MicroCT without the Rescale Slope and Rescale Intercept Attribute
    9 visualizzazioni (ultimi 30 giorni)
  
       Mostra commenti meno recenti
    
    Keith Kunugi
 il 12 Mag 2023
  
    
    
    
    
    Commentato: Keith Kunugi
 il 17 Mag 2023
            I have a microCT scan that is labelled as a singular ".dicom" file, that contains all 1001 slices in that file. I opened the file in matlab and used dicominfo(file_name) to obtain a list of attributes, but I couldn't find the rescale slope or rescale intercept attribute in order to convert the pixel values to HU values. I have pasted below the attributes I get. I was wondering if maybe the rescale slope and intercept attribute was perhaps hidden in one of these fields, or if there was another way to obtain the HU values? I am using matlab by the way, and I would also really appreciate some guidance on any commands that would also be benefical! Thank you!
I should also mention that I also tried extracting a single slice in the dicom volume with 
slice500 = dicomVolume(:,:,:, 500);
and I am able to view this slice500 with an imshow() or imagesc() command, but I keep getting an error when I try using
dicominfo(slice500)
Filename: '\\poe\kvincent\Old Chamber KRex\2023-04-04_12h24_DeWerd_ExtradinA3_Ser256.dicom'
                         FileModDate: '13-Apr-2023 14:54:37'
                            FileSize: 2.0446e+09
                              Format: 'DICOM'
                       FormatVersion: 3
                               Width: 1015
                              Height: 1006
                            BitDepth: 16
                           ColorType: 'grayscale'
      FileMetaInformationGroupLength: 198
          FileMetaInformationVersion: [2×1 uint8]
             MediaStorageSOPClassUID: '1.2.840.10008.5.1.4.1.1.66'
          MediaStorageSOPInstanceUID: '1.2.276.0.7230010.3.1.4.1766961247.692.1680633232.851'
                   TransferSyntaxUID: '1.2.840.10008.1.2.1'
              ImplementationClassUID: '1.2.276.0.7230010.3.0.3.6.7'
           ImplementationVersionName: 'OFFIS_DCMTK_367'
                SpecificCharacterSet: 'ISO_IR 192'
                           ImageType: 'DERIVED\SECONDARY\DYNAMIC'
                InstanceCreationDate: '20230404'
                InstanceCreationTime: '133352'
                         SOPClassUID: '1.2.840.10008.5.1.4.1.1.66'
                      SOPInstanceUID: '1.2.276.0.7230010.3.1.4.1766961247.692.1680633232.851'
                           StudyDate: ''
                         ContentDate: '20230404'
                           StudyTime: ''
                         ContentTime: '133352'
                     AccessionNumber: ''
                            Modality: 'OT'
                        Manufacturer: ''
                     InstitutionName: 'Unknown'
                  InstitutionAddress: 'Unknown'
              ReferringPhysicianName: [1×1 struct]
               ManufacturerModelName: ''
               DerivationDescription: 'estimated parameter'
                         PatientName: [1×1 struct]
                           PatientID: ''
                    PatientBirthDate: ''
                          PatientSex: ''
                      SliceThickness: 0.0250
                SpacingBetweenSlices: 0.0250
                  DeviceSerialNumber: '0'
                    SoftwareVersions: 'IOFactory 9f23f3d83'
                         TableHeight: 0
                    StudyInstanceUID: '1.2.276.0.7230010.3.1.2.1766961247.692.1680633232.852'
                   SeriesInstanceUID: '1.2.276.0.7230010.3.1.3.1766961247.692.1680633232.853'
                             StudyID: ''
                        SeriesNumber: []
                   AcquisitionNumber: 1
                      InstanceNumber: 1
                ImagePositionPatient: [3×1 double]
             ImageOrientationPatient: [6×1 double]
                 FrameOfReferenceUID: '1.2.840.10008.1.4.1.7.1766961247.692.1680633232.854'
                          Laterality: 'L'
          PositionReferenceIndicator: ''
              DimensionIndexSequence: [1×1 struct]
           DimensionOrganizationType: '3D'
                     SamplesPerPixel: 1
           PhotometricInterpretation: 'MONOCHROME2'
                      NumberOfFrames: 1001
               FrameIncrementPointer: [84 256 84 128]
                                Rows: 1006
                             Columns: 1015
                        PixelSpacing: [2×1 double]
                       BitsAllocated: 16
                          BitsStored: 16
                             HighBit: 15
                 PixelRepresentation: 1
             SmallestImagePixelValue: -32768
              LargestImagePixelValue: 32767
           RepresentativeFrameNumber: 500
    PixelValueTransformationSequence: [1×1 struct]
       RealWorldValueMappingSequence: [1×1 struct]
                         PhaseVector: [1001×1 uint16]
                      NumberOfPhases: 1
            PhaseInformationSequence: [1×1 struct]
                         SliceVector: [1001×1 uint16]
                      NumberOfSlices: 1001
                     TimeSliceVector: [1001×1 uint16]
    PerFrameFunctionalGroupsSequence: [1×1 struct]
           Private_6d5b_aaxx_Creator: 'Gremse-IT - Additional image meta data'
0 Commenti
Risposta accettata
  Walter Roberson
      
      
 il 13 Mag 2023
        Rescale Slope and Rescale Intercept may be omitted when the slope is 1 and the intercept is 0.
When the pixel data is int16, then most commonly slope 1 and intercept 0 is in use. The fact that  SmallestImagePixelValue: -32768 tells us that this is int16 data.
When the pixel data is uint16 then it would be common for the fields to be present. 
I have never encounted a file in which there was an intercept but no slope, but I would need to study the standards to see whether such a combination is permitted. I never bothered to do that, though -- I just code two tests, if the field is absent set it to 1 or 0 as appropriate; saves worrying about the hypothetical situation where slope is absent but intercept is present, and if it basically turns out to be against the spec to have one but not the other... well, vendors do not always follow the spec perfectly anyhow.
0 Commenti
Più risposte (1)
  Simon Chan
      
 il 13 Mag 2023
        The variable 'slice500' in your code is a matrix only, and hence you can display it as an image by using function imshow() or imagesc(). However, when you want to read metadata from its original DICOM image using function dicominfo, you need to use the file name instead of its image content.
pathname = 'C:\.........';                             %% Specified folder of your DICOM file below
info = dicominfo(fullfile(pathname,'2023-04-04_12h24_DeWerd_ExtradinA3_Ser256.dicom'))
In order to retrieve the rescale slope and intercept attribute, you may use the following.
If it reports an error, that means the DICOM header does not contains these two fields or these two values are stored and hidden in some private fields.
info.(dicomlookup("0028","1053"))               %% Rescale Slope
info.(dicomlookup("0028","1052"))               %% Rescale Intercept
On the other hand, you may check the DICOM Conformance Statement from the microCT vendor to verify how they process the pixel value to HU.
Most vendor use Rescale Slope and Rescale Intercept to be 1 and -1024 resepctively. A quick way to verify this is to scan a small water phantom, check the pixel values of both air and water to verify this vendor is using these two values or not. 
Vedere anche
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!