我正在研究結合 PET 和 CT 的 DICOM 查看器專案。
進步
將兩個 dicom 檔案之一的大小調整為較大的一個。
并更改一個 dicom 檔案的顏色
并合并兩個dicom檔案
示例 dicom 位圖 1

bitmap2 , newBitmap(改變顏色紅色)

我瞄準的結果影像

private void button1_Click(object sender, EventArgs e)
{
string ima_path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var bitmap1 = dicomImageViewControls[0].DicomElements[0].Bitmap;
var bitmap2 = dicomImageViewControls[1].DicomElements[0].Bitmap;
if( bitmap1.Width<bitmap2.Width)
{
bitmap1 = resizeImage(bitmap1, bitmap2.Width, bitmap2.Height);
bitmap1.Save(ima_path "\\res.png", ImageFormat.Png);
}
else
{
bitmap2 = resizeImage(bitmap2, bitmap1.Width, bitmap1.Height);
bitmap2.Save(ima_path "\\res.png", ImageFormat.Png);
}
Color actualColor;
Bitmap newBitmap = new Bitmap(bitmap2.Width, bitmap2.Height);
for (int i = 0; i < bitmap2.Width; i )
{
for (int j = 0; j < bitmap2.Height; j )
{
actualColor = bitmap2.GetPixel(i, j);
float a = actualColor.A;
float r = actualColor.R;
newBitmap.SetPixel(i, j, Color.FromArgb((int)a, (int)r, 0, 0));
}
}
var target = new Bitmap(newBitmap.Width, newBitmap.Height, PixelFormat.Format32bppArgb);
var graphics = Graphics.FromImage(target);
graphics.CompositingMode = CompositingMode.SourceOver; // this is the default, but just to be clear
graphics.DrawImage(newBitmap, 0, 0);
graphics.DrawImage(bitmap1, 0, 0);
newBitmap.Save(ima_path "\\Image2.png", ImageFormat.Png);
}
public static Bitmap resizeImage(Bitmap image, int width, int height)
{
var destinationRect = new Rectangle(0, 0, width, height);
var destinationImage = new Bitmap(width, height);
destinationImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destinationImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, destinationRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destinationImage;
}
目標位圖

看起來像第一張圖。
====================================== 我在清晰的畫布上發現了一個新演算法。
baseImageGraphicProvider.ImageGraphic.PixelData.ForEachPixel(
(n, x, y, i) =>
{
// and this is why the base and overlay slices must be unsigned precisely coincident
var patientLocation = baseImageSopProvider.Frame.ImagePlaneHelper.ConvertToPatient(new PointF(x, y));
var overlayCoordinate = overlayImageSopProvider.Frame.ImagePlaneHelper.ConvertToImagePlane(patientLocation);
var baseValue = (ushort) baseImageGraphicProvider.ImageGraphic.PixelData.GetPixel(i);
var overlayValue = overlayImageGraphicProvider.ImageGraphic.PixelData.GetPixel((int) overlayCoordinate.X, (int) overlayCoordinate.Y);
// the fusion operator: output = underlyingGrey*(1-alpha) overlayingColour*(alpha) (see DICOM 2009 PS 3.4 N.2.4.3)
var compositeColor = ToRgbVectorFromGrey(baseValue)*(1 - opacity) ToRgbVector(colorMap[overlayValue])*opacity;
pixelData[3*n] = (byte) compositeColor.X;
pixelData[3*n 1] = (byte) compositeColor.Y;
pixelData[3*n 2] = (byte) compositeColor.Z;
});
我認為這個演算法是
var compositeColor = ToRgbVectorFromGrey(baseValue)*(1 - opacity) ToRgbVector(colorMap[overlayValue])*opacity;
從灰色 (1-opactiy) 調色板(在我的例子中為紅色調色板)獲取原始像素 rgb *opacity 回傳每個像素的值。
https://github.com/ClearCanvas/ClearCanvas/blob/master/ImageViewer/AdvancedImaging/Fusion/Tests/FusionColorCompositingTest.cs
uj5u.com熱心網友回復:
很可能是bitmap1缺少alpha通道,所以在繪制時,它會覆寫所有內容。例如,您可能需要考慮制作newBitmap完全紅色,而是將顏色通道映射到 Alpha 通道。即newBitmap.SetPixel(i, j, Color.FromArgb((int)r, 1, 0, 0));并切換渲染順序,以便newBitmap最后繪制。
另外,不要忘記處理所有創建的位圖和圖形物件。
您還可以考慮創建一個自定義函式來融合像素資料,即從左右影像中獲取 16 位值并使用一些自定義函式來生成顏色值,因為這應該允許在如何可視化方面具有更大的靈活性資料。但是要使其作業,您需要訪問原始 16 位像素資料,并且可能為所述 16 位資料撰寫您自己的調整大小函式。這通常還涉及某種視窗函式以將 16 位資料映射到 8 位值。
您可能還需要某種注冊函式來準確組合每個資料集,因為通常無法保證僅通過調整大小就能正確對齊。
您可能還想查看Fast work with bitmaps以獲得任何型別的渲染速度。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/381457.html
