C#處理醫學影像(二):基於Hessian矩陣的醫學影像增強與窗寬窗位

喬克灬叔叔發表於2021-01-14

根據本系列教程文章上一篇說到,在完成C++和Opencv對Hessian矩陣濾波演算法的實現和封裝後,

再由C#呼叫C++ 的DLL,(參考:C#處理醫學影像(一):基於Hessian矩陣的血管肺紋理骨骼增強對比)

功能雖然已經實現,但在實際應用中要考慮到效能和耦合,本篇將介紹效能方面的注意點以及和其他功能的聯動。

 

我們將Demo裡面的功能整合到正式工程中:

1.新建一個新窗體,用來顯示結果和調整濾波引數:

 

其中滑塊控制元件選擇工具箱中的Slider,定義好控制元件樣式,變化事件選擇PreviewMouseLeftButtonUp,不要用ValueChanged,

考慮到效能問題,因為是base64轉碼和解碼,所以不推薦用ValueChanged,它的觸發頻率要高得多,

而在影像大小比較大的時候 base64加解密的效率顯得不是很高,會造成主執行緒UI卡頓,所以只要響應滑鼠抬起時計算影像即可。

<Slider x:Name="SgStart" Style="{StaticResource Slider_CustomStyle}" Width="132" Height="19"  Value="1" IsMoveToPointEnabled="True"  PreviewMouseLeftButtonUp="SgStart_PreviewMouseLeftButtonUp" />

 

2.顯示計算結果:

在Slider控制元件滑鼠抬起的事件中,先將目標單元格內WPF影像轉為base64,傳送給我們生成的C++介面,再將返回的base64轉為WPF影像

       [DllImport(@"opencv\ET.Functions.dll", EntryPoint = "GetFrangiBase64Code", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr GetFrangiBase64Code(string base64code, int SIGMA_START, int SIGMA_END, int SIGMA_STEP, float BETA_ONE, float BETA_TWO, bool BLACKWHITE);

      /// <summary>
        /// 獲取濾波影像
        /// </summary>
        /// <param name="filterParm">濾波引數物件</param>
        public void GetFilterImg(FilterParm filterParm)
        {
            try
            {
                string base64 = WriteableBitmapToBase64(Wbp);
                IntPtr intPtr = GetFrangiBase64Code(base64,
                                    filterParm.Start,
                                    filterParm.End,
                                    filterParm.Step,
                                    filterParm.DenoiseNum,
                                    filterParm.BgArgs,
                                    filterParm.BgType);

                if (intPtr != IntPtr.Zero)
                {
                    string filterCode = Marshal.PtrToStringAnsi(intPtr);
                    ImgBox.Source = Base64ToWriteableBitmap(filterCode);
                }
            }
            catch (Exception e)
            {
                LogApi.WriteErrLog(e);
            }
        }


      /// <summary>
        /// base64轉WriteableBitmap
        /// </summary>
        /// <param name="base64">base64字串</param>
        public WriteableBitmap Base64ToWriteableBitmap(string base64)
        {
            byte[] streamBase = Convert.FromBase64String(base64);
            BitmapImage bi = new BitmapImage();
            bi.BeginInit();
            bi.StreamSource = new MemoryStream(streamBase);
            bi.EndInit();
            WriteableBitmap wbp = new WriteableBitmap(bi);
            return wbp;
        }


        /// <summary>
        /// WriteableBitmap轉base64
        /// </summary>
        /// <param name="writeableBitmap">影像物件</param>
        public string WriteableBitmapToBase64(WriteableBitmap writeableBitmap)
        {
            MemoryStream memStream = new MemoryStream();
            JpegBitmapEncoder encoder = new JpegBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(writeableBitmap));
            encoder.Save(memStream);
            byte[] bytes = memStream.ToArray();
            string code = Convert.ToBase64String(bytes);
            return code;
        }

看效果:

乳腺影像由原始dcm顯示的絮狀腺體在影像增強下變成絲狀,對於乳腺中存在腫瘤或其他病症的顯示更為明顯,亦可自由調整引數達到自己想要的效果。

 

但有的情況下,增強效果卻很差,顯示的結果對於提取有價值的病灶資訊幾乎沒有意義:

 

根據Hessian矩陣部分概念:

 

 

由原理中得知,求得特徵值和特徵向量反應出的變化上的各向異性,在二維影像中,

圓(點)具有各向同性,線性強度與各向異性程度成正比,

而在窗寬與窗位個概念中,血管的CT值為30左右,將窗寬窗位調整至增強前肉眼可見的差別,

最大程度降低二維影像上的無用資訊,再利用海森矩陣加強線性結構,過濾圓(點)和降噪。

 

綜上總結:先調整窗寬窗位,再影像增強和調整引數,使得效果最大化:

 

相關文章