DicomDecodingSettings Constructor(Boolean,Boolean,DicomImagePixelFormat)
Инициализирует новый экземпляр класса
DicomDecodingSettings.
Вот C#/VB.NET код, который демонстрирует, как извлечь значения Хаунсфилда из кадра DICOM.
''' <summary>
''' Extracts Hounsfield values from DICOM frame.
''' </summary>
Public Class ExtractHounsfieldValuesFromDicomFrame
''' <summary>
''' Returns the Hounsfield values of DICOM frame.
''' </summary>
''' <param name="frame">The DICOM frame.</param>
''' <returns>
''' The Hounsfield values.
''' </returns>
Public Shared Function GetHounsfieldValuesOfFrame(frame As Vintasoft.Imaging.Codecs.ImageFiles.Dicom.DicomFrame) As Long(,)
' create DICOM decoding settings
Dim settings As New Vintasoft.Imaging.Codecs.Decoders.DicomDecodingSettings(True, False, Vintasoft.Imaging.Codecs.ImageFiles.Dicom.DicomImagePixelFormat.Source)
' load image of DICOM frame
Using image As Vintasoft.Imaging.VintasoftImage = frame.GetImage(settings, Nothing)
' pixel matrix of the image
Dim pixelValues As Long(,) = New Long(image.Width - 1, image.Height - 1) {}
' open the pixel manipulator
Using pixelManipulator As Vintasoft.Imaging.PixelManipulator = image.OpenPixelManipulator()
' lock image pixels
Dim lockRectangle As New System.Drawing.Rectangle(0, 0, image.Width, image.Height)
pixelManipulator.LockPixels(lockRectangle, Vintasoft.Imaging.BitmapLockMode.Read)
Dim stride As Integer = pixelManipulator.Stride
' get significant channel of image
Dim significantChannel As Vintasoft.Imaging.ChannelFormat = GetSignificantChannel(image)
' get count of bits per pixel
Dim bitsPerPixel As Integer = image.ColorChannelsFormat.BitsPerPixel
' get a value indicating whether pixel values are unsigned
Dim isUnsigned As Boolean = significantChannel.IsUnsigned
' read image pixels
For y As Integer = 0 To image.Height - 1
' read row
Dim row As Byte() = pixelManipulator.ReadRowData(y)
Select Case bitsPerPixel
Case 8
If isUnsigned Then
For x As Integer = 0 To image.Width - 1
pixelValues(x, y) = row(x)
Next
Else
For x As Integer = 0 To image.Width - 1
pixelValues(x, y) = CSByte(row(x))
Next
End If
Exit Select
Case 16
If isUnsigned Then
Dim x As Integer = 0, rowIndex As Integer = 0
While x < image.Width
pixelValues(x, y) = CUShort(row(rowIndex) Or (row(rowIndex + 1) << 8))
x += 1
rowIndex += 2
End While
Else
Dim x As Integer = 0, rowIndex As Integer = 0
While x < image.Width
pixelValues(x, y) = CShort(row(rowIndex) Or (row(rowIndex + 1) << 8))
x += 1
rowIndex += 2
End While
End If
Exit Select
Case 32
If isUnsigned Then
Dim x As Integer = 0, rowIndex As Integer = 0
While x < image.Width
pixelValues(x, y) = CUInt(row(rowIndex) Or (row(rowIndex + 1) << 8) Or (row(rowIndex + 2) << 16) Or (row(rowIndex + 3) << 24))
x += 1
rowIndex += 4
End While
Else
Dim x As Integer = 0, rowIndex As Integer = 0
While x < image.Width
pixelValues(x, y) = CInt(row(rowIndex) Or (row(rowIndex + 1) << 8) Or (row(rowIndex + 2) << 16) Or (row(rowIndex + 3) << 24))
x += 1
rowIndex += 4
End While
End If
Exit Select
Case Else
Throw New System.NotImplementedException()
End Select
Next
End Using
Return pixelValues
End Using
End Function
''' <summary>
''' Returns the significant channel of image.
''' </summary>
''' <param name="image">The image.</param>
''' <returns>
''' The significant channel.
''' </returns>
''' <exception cref="System.InvalidOperationException">The significant channel does not exist.</exception>
Private Shared Function GetSignificantChannel(image As Vintasoft.Imaging.VintasoftImage) As Vintasoft.Imaging.ChannelFormat
For Each channel As Vintasoft.Imaging.ChannelFormat In image.ColorChannelsFormat.Channels
If channel.IsSignificant Then
Return channel
End If
Next
Throw New System.InvalidOperationException("The significant channel does not exist.")
End Function
End Class
/// <summary>
/// Extracts Hounsfield values from DICOM frame.
/// </summary>
public class ExtractHounsfieldValuesFromDicomFrame
{
/// <summary>
/// Returns the Hounsfield values of DICOM frame.
/// </summary>
/// <param name="frame">The DICOM frame.</param>
/// <returns>
/// The Hounsfield values.
/// </returns>
public static long[,] GetHounsfieldValuesOfFrame(Vintasoft.Imaging.Codecs.ImageFiles.Dicom.DicomFrame frame)
{
// create DICOM decoding settings
Vintasoft.Imaging.Codecs.Decoders.DicomDecodingSettings settings =
new Vintasoft.Imaging.Codecs.Decoders.DicomDecodingSettings(
true, false, Vintasoft.Imaging.Codecs.ImageFiles.Dicom.DicomImagePixelFormat.Source);
// load image of DICOM frame
using (Vintasoft.Imaging.VintasoftImage image = frame.GetImage(settings, null))
{
// pixel matrix of the image
long[,] pixelValues = new long[image.Width, image.Height];
// open the pixel manipulator
using (Vintasoft.Imaging.PixelManipulator pixelManipulator = image.OpenPixelManipulator())
{
// lock image pixels
System.Drawing.Rectangle lockRectangle = new System.Drawing.Rectangle(0, 0, image.Width, image.Height);
pixelManipulator.LockPixels(lockRectangle, Vintasoft.Imaging.BitmapLockMode.Read);
int stride = pixelManipulator.Stride;
// get significant channel of image
Vintasoft.Imaging.ChannelFormat significantChannel = GetSignificantChannel(image);
// get count of bits per pixel
int bitsPerPixel = image.ColorChannelsFormat.BitsPerPixel;
// get a value indicating whether pixel values are unsigned
bool isUnsigned = significantChannel.IsUnsigned;
// read image pixels
for (int y = 0; y < image.Height; y++)
{
// read row
byte[] row = pixelManipulator.ReadRowData(y);
switch (bitsPerPixel)
{
case 8:
if (isUnsigned)
{
for (int x = 0; x < image.Width; x++)
pixelValues[x, y] = row[x];
}
else
{
for (int x = 0; x < image.Width; x++)
pixelValues[x, y] = (sbyte)row[x];
}
break;
case 16:
if (isUnsigned)
{
for (int x = 0, rowIndex = 0; x < image.Width; x++, rowIndex += 2)
pixelValues[x, y] = (ushort)(row[rowIndex] | (row[rowIndex + 1] << 8));
}
else
{
for (int x = 0, rowIndex = 0; x < image.Width; x++, rowIndex += 2)
pixelValues[x, y] = (short)(row[rowIndex] | (row[rowIndex + 1] << 8));
}
break;
case 32:
if (isUnsigned)
{
for (int x = 0, rowIndex = 0; x < image.Width; x++, rowIndex += 4)
{
pixelValues[x, y] = (uint)(row[rowIndex] |
(row[rowIndex + 1] << 8) |
(row[rowIndex + 2] << 16) |
(row[rowIndex + 3] << 24));
}
}
else
{
for (int x = 0, rowIndex = 0; x < image.Width; x++, rowIndex += 4)
{
pixelValues[x, y] = (int)(row[rowIndex] |
(row[rowIndex + 1] << 8) |
(row[rowIndex + 2] << 16) |
(row[rowIndex + 3] << 24));
}
}
break;
default:
throw new System.NotImplementedException();
}
}
}
return pixelValues;
}
}
/// <summary>
/// Returns the significant channel of image.
/// </summary>
/// <param name="image">The image.</param>
/// <returns>
/// The significant channel.
/// </returns>
/// <exception cref="System.InvalidOperationException">The significant channel does not exist.</exception>
private static Vintasoft.Imaging.ChannelFormat GetSignificantChannel(Vintasoft.Imaging.VintasoftImage image)
{
foreach (Vintasoft.Imaging.ChannelFormat channel in image.ColorChannelsFormat.Channels)
{
if (channel.IsSignificant)
return channel;
}
throw new System.InvalidOperationException("The significant channel does not exist.");
}
}
Целевые платформы: .NET 8; .NET 7; .NET 6; .NET Framework 4.8, 4.7, 4.6, 4.5, 4.0, 3.5