程序地带

C#处理医学图像(二):基于Hessian矩阵的医学图像增强与窗宽窗位


根据本系列教程文章上一篇说到,在完成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(@"opencvET.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左右,将窗宽窗位调整至增强前肉眼可见的差别,


最大程度降低二维图像上的无用信息,再利用海森矩阵加强线性结构,过滤圆(点)和降噪。


 


综上总结:先调整窗宽窗位,再图像增强和调整参数,使得效果最大化:



 


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/Uncle-Joker/p/14272728.html

随机推荐

实现数组去重最好的办法

实现数组去重最好的办法Set是一种新的数据结构,它可以接收一个数组或者是类数组对象,自动去重其中的重复项目。letarr=[4,1,10,3,3,2,'2&...

小怪兽学前端 阅读(216)

node 模块化导出导入的方式

#第一种module.exportsCommonJs的写法导出constage=15;module.exports=age;导入//此处的age与导出的age可以不一样constage...

code_std 阅读(694)

Spring 依赖注入

依赖注入依赖注入属于IoC。五种关系:继承、依赖、关联、聚合、组合当创建User对象时,(dept对象不能为空),如何自动的创建D...

二饭 阅读(735)

redis复制key的数据_Redis常见面试题

redis复制key的数据_Redis常见面试题

介绍:Redis是一个开源的使用ANSIC语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API的非关系型数据库...

weixin_39805180 阅读(136)

redis复制key的数据_Redis常见面试题

redis复制key的数据_Redis常见面试题

介绍:Redis是一个开源的使用ANSIC语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API的非关系型数据库...

weixin_39807954 阅读(712)