GDCM 不正确的图像数据
GDCM incorrect image data
我正在使用 gdcm (nuget gdcm-sharp 2.4.4) 库从 *.dcm 文件中获取图像和患者数据。使用光度解释 MONOCHROME2 的文件一切都很好,但后来我得到了一些使用 MONOCHROME1 的文件,其中大约 30% 有一个奇怪的错误:图像 "sliced" 对角线,我找不到原因。
示例链接:incorrect image, correct image
每行像素都有行号的偏移量...容易修正,但我不知道哪个文件需要修正。
问题是:如何判断哪个文件需要更正,dcm 标签相同,.dcm 文件中唯一不同的是图像尺寸和像素数据...
还有一件事...我尝试查看这些图像的任何其他软件都能正确渲染它们。
显示已完成内容的一些代码
// pixel data copied to WriteableBitmap then saved by JpegBitmapEncoder
var reader = new gdcm.ImageReader();
var gimg = reader.GetImage();
WriteableBitmap wb = new WriteableBitmap((int)cols, (int)rows, 120, 120, PixelFormats.Gray16, null);
wb.Lock();
Marshal.Copy(buff, 0, wb.BackBuffer, buff.Length);
wb.Unlock();
using (var ms2 = new MemoryStream())
{
JpegBitmapEncoder enc = new JpegBitmapEncoder();
enc.QualityLevel = 95;
enc.Frames.Add(BitmapFrame.Create(wb));
enc.Save(ms2);
jpegfile = ms2.GetBuffer();
}
看看您提供的好与坏图片:
好的是 1290 x 1249 坏的是 1195 x 1193
自从我使用 windows 位图以来已经有一段时间了,但我几乎可以肯定它们是逐行填充的(不确定是 2 字节、4 字节(最有可能)还是其他alignment),但根据你的例子,这 99% 确定发生了什么。
与其对整个缓冲区执行单个 Marshal.Copy,不如逐行执行(只是我的伪代码):
Foreach row:
Marshal.Copy(buff + row_number * DicomImageRowLength, 0, wb.BackBuffer + row_number * wb.BackBufferStride, DicomImageRowLength);
如果 Marshal.Copy 需要将 buff 作为第一个参数:
Foreach row:
Marshal.Copy(buff, row_number * DicomImageRowLength, wb.BackBuffer + row_number * wb.BackBufferStride, DicomImageRowLength);
如果您逐行复制每个案例,希望这对所有图像都适用...
我认为您可以通过查看 wb.BackBuffer.Size 并将其与两种情况下的 wb.PixelWidth、wb.PixelHeight 和 wb.BackBufferStride 进行比较来验证是否正在发生这种情况。
我正在使用 gdcm (nuget gdcm-sharp 2.4.4) 库从 *.dcm 文件中获取图像和患者数据。使用光度解释 MONOCHROME2 的文件一切都很好,但后来我得到了一些使用 MONOCHROME1 的文件,其中大约 30% 有一个奇怪的错误:图像 "sliced" 对角线,我找不到原因。 示例链接:incorrect image, correct image
每行像素都有行号的偏移量...容易修正,但我不知道哪个文件需要修正。
问题是:如何判断哪个文件需要更正,dcm 标签相同,.dcm 文件中唯一不同的是图像尺寸和像素数据...
还有一件事...我尝试查看这些图像的任何其他软件都能正确渲染它们。
显示已完成内容的一些代码
// pixel data copied to WriteableBitmap then saved by JpegBitmapEncoder
var reader = new gdcm.ImageReader();
var gimg = reader.GetImage();
WriteableBitmap wb = new WriteableBitmap((int)cols, (int)rows, 120, 120, PixelFormats.Gray16, null);
wb.Lock();
Marshal.Copy(buff, 0, wb.BackBuffer, buff.Length);
wb.Unlock();
using (var ms2 = new MemoryStream())
{
JpegBitmapEncoder enc = new JpegBitmapEncoder();
enc.QualityLevel = 95;
enc.Frames.Add(BitmapFrame.Create(wb));
enc.Save(ms2);
jpegfile = ms2.GetBuffer();
}
看看您提供的好与坏图片: 好的是 1290 x 1249 坏的是 1195 x 1193
自从我使用 windows 位图以来已经有一段时间了,但我几乎可以肯定它们是逐行填充的(不确定是 2 字节、4 字节(最有可能)还是其他alignment),但根据你的例子,这 99% 确定发生了什么。
与其对整个缓冲区执行单个 Marshal.Copy,不如逐行执行(只是我的伪代码):
Foreach row:
Marshal.Copy(buff + row_number * DicomImageRowLength, 0, wb.BackBuffer + row_number * wb.BackBufferStride, DicomImageRowLength);
如果 Marshal.Copy 需要将 buff 作为第一个参数:
Foreach row:
Marshal.Copy(buff, row_number * DicomImageRowLength, wb.BackBuffer + row_number * wb.BackBufferStride, DicomImageRowLength);
如果您逐行复制每个案例,希望这对所有图像都适用...
我认为您可以通过查看 wb.BackBuffer.Size 并将其与两种情况下的 wb.PixelWidth、wb.PixelHeight 和 wb.BackBufferStride 进行比较来验证是否正在发生这种情况。