根据本系列教程文章上一篇说到,在完成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. Hessian矩阵与多元函数极值

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

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

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

  3. Hessian矩阵与牛顿法

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

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

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

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

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

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

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

  7. Jacobian矩阵和Hessian矩阵

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

  8. Hessian矩阵

    http://baike.baidu.com/link?url=o1ts6Eirjn5mHQCZUHGykiI8tDIdtHHOe6IDXagtcvF9ncOfdDOzT8tmFj41_DEsiUCr ...

  9. Android消息推送(二)--基于MQTT协议实现的推送功能

    国内的Android设备,不能稳定的使用Google GCM(Google Cloud Messageing)消息推送服务. 1. 国内的Android设备,基本上从操作系统底层开始就去掉了Googl ...

  10. word2vec原理(二) 基于Hierarchical Softmax的模型

    word2vec原理(一) CBOW与Skip-Gram模型基础 word2vec原理(二) 基于Hierarchical Softmax的模型 word2vec原理(三) 基于Negative Sa ...

随机推荐

  1. [nRF51822] 9、基础实验代码解析大全 &#183; 实验12 - ADC

    一.本实验ADC 配置 分辨率:10 位. 输入通道:5,即使用输入通道AIN5 检测电位器的电压. ADC 基准电压:1.2V. 二.NRF51822 ADC 管脚分布 NRF51822 的ADC ...

  2. 【Unity3D基础教程】给初学者看的Unity教程(六):理解Unity的新GUI系统(UGUI)

    作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点推荐.谢谢! 理解UGUI的基础架构 UGUI是Unity在4 ...

  3. jcscriput

    关于h5,相比前端的同事们都很了解了吧!h5里面有个canvas,现在用的蛮火.但是canvas里面的代码确实是有点繁多,特别是要对于图形做什么操作的时候...我昨天无意间发现了一个canvas的插件 ...

  4. php核心知识要点

    Php:脚本语言,网站建设,服务器端运行 PHP定义:一种服务器端的 HTML 脚本/编程语言,是一种简单的.面向对象的.解释型的.健壮的.安全的.性能非常之高的.独立于架构的.可移植的.动态的脚本语 ...

  5. POJ 3393 Lucky and Good Months by Gregorian Calendar

    http://poj.org/problem?id=3393 题意 : 对于这篇长长的英语阅读,表示无语无语再无语,花了好长时间,终于读完了.题目中规定每周的周六日为假日,其他为工作日,若是一个月的第 ...

  6. bzoj1015:[JSOI2008]星球大战starwar

    思路:反着做用并查集维护连通块个数就好了. #include<iostream> #include<cstdio> #include<cstring> #inclu ...

  7. delphi TOpenDialog

        TOpenDialog     procedure TForm1.Button1Click(Sender: TObject);begin  with TOpenDialog.Create(ni ...

  8. JavaScript 中的正常任务与微任务

    正常情况下,JavaScript的任务是同步执行的,即执行完前一个任务,然后执行后一个任务.只有遇到异步任务的情况下,执行顺序才会改变. 这时,需要区分两种任务:正常任务(task)与微任务(micr ...

  9. Javascript中变量作用域(2)

    多层函数调用取变量时,无论在哪里调用,要到创建此函数的作用域中取值,如果找不到再往上一级,直到全局变量. 外面定义了很多的全局的变量,下面我们来一个个理一下. 定义三个变量a,b,c;将A1函数赋值给 ...

  10. 本地连接虚拟机_环境搭建01_VMWARE/XShell/CentOS

    今天起准备搭建一套环境用来学习redis,dubbo,docker,nginx. 环境准备: 1.VMware12:  https://pan.baidu.com/s/1-LnqfrWw8ZjQdmG ...