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

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

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

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

  1. C#处理医学图像(一):基于Hessian矩阵的血管肺纹理骨骼增强对比

    在医院实际环境中,经常遇到有问题的患者,对于一些特殊的场景,比如骨折,肺结节,心脑血管问题 需要图像对比增强来更为清晰的显示病灶助于医生确诊,先看效果: 肺纹理增强: 肺结节增强: 血管对比增强: 骨 ...

  2. Hessian矩阵与多元函数极值

    Hessian矩阵与多元函数极值 海塞矩阵(Hessian Matrix),又译作海森矩阵,是一个多元函数的二阶偏导数构成的方阵.虽然它是一个具有悠久历史的数学成果.可是在机器学习和图像处理(比如SI ...

  3. java学习-zxing生成二维码矩阵的简单例子

    这个例子需要使用google的开源项目zxing的核心jar包 core-3.2.0.jar 可以百度搜索下载jar文件,也可使用maven添加依赖 <dependency> <gr ...

  4. Hessian矩阵与牛顿法

    Hessian矩阵与牛顿法 牛顿法 主要有两方面的应用: 1. 求方程的根: 2. 求解最优化方法: 一. 为什么要用牛顿法求方程的根? 问题很多,牛顿法 是什么?目前还没有讲清楚,没关系,先直观理解 ...

  5. 【机器学习】梯度、Hessian矩阵、平面方程的法线以及函数导数的含义

    想必单独论及" 梯度.Hessian矩阵.平面方程的法线以及函数导数"等四个基本概念的时候,绝大部分人都能够很容易地谈个一二三,基本没有问题. 其实在应用的时候,这几个概念经常被混 ...

  6. 梯度、Hessian矩阵、平面方程的法线以及函数导数的含义

    本文转载自: Xianling Mao的专栏 =========================================================================== 想 ...

  7. Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401开发

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

  8. CRL快速开发框架系列教程二(基于Lambda表达式查询)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  9. Jacobian矩阵和Hessian矩阵

    1.Jacobian矩阵 在矩阵论中,Jacobian矩阵是一阶偏导矩阵,其行列式称为Jacobian行列式.假设 函数 $f:R^n \to R^m$, 输入是向量 $x \in R^n$ ,输出为 ...

随机推荐

  1. HTML引入外部字体

    HTML5如何引入外部字体 背景 现在我需要 "Montserrat-ExtraLight ExtraLight"类型的字体,但是html的font-family中找不到这个类型的 ...

  2. 认识css常见的hack

    一.认识css hack CSS Hack只要是来解决浏览器局部的兼容性问题,主要是因为每个浏览器对css的解析各不相同,导致输出到页面的效果的差异: 二.css hack的三种常见形式:css属性h ...

  3. 题解-Words

    题面 Words 有 \(n\) 天,每天插入一个字符集大小为 \(c\) 长度为 \(l\) 的字符串,求每一天建立 \(\tt Trie\) 树的期望节点数(根节点不算)模 \(998244353 ...

  4. antDesign获取表单组件的值

    子组件中:  getFormValue是在点击确定按钮获取表单值得事件函数,一旦执行就会执行里边的validate()回调函数 返回的数据中有error和value两种,如果存在error那就是其中某 ...

  5. mysql主从同步错误

    一.主从同步报错 mysql> show slave status\G; *************************** 1. row ************************* ...

  6. Fastjson 1.2.47 远程命令执行漏洞复现

    前言 这个漏洞出来有一段时间了,有人一直复现不成功来问我,就自己复现了下,顺便简单记录下这个漏洞原理,以便后面回忆. 复现过程 网上已经有很多文章了,这里就不在写了.主要记录一下复现过程中遇到的问题 ...

  7. fiddler抓APP的https接口

    吐槽一下,fiddler这工具很蛋疼,用的时候很好用,出bug的时候死活抓不了: ①为了少踩坑,我们在官网下最新的fiddler,官网:Fiddler - Free Web Debugging Pro ...

  8. MySQL误删除用户怎么解决

    前言:在不考虑到原来用户对关联数据库的授权问题的情况下,有以下两种思路解决 #1.安全模式修改 第一步:关闭数据库服务: [root@db01 ~]#/etc/init.d/mysqld stop 第 ...

  9. sql中筛选条件为空值

    <select id="getEmployeeBasicInformationList" resultType="org.springblade.entity.Al ...

  10. java中邮件通知

    // 客户信息 Tkhxx tkhxx = new Tkhxx(); try { String msg = tkhxx.toString(); MailUtil.simpleMailSend(Mail ...