在医院实际环境中,经常遇到有问题的患者,对于一些特殊的场景,比如骨折,肺结节,心脑血管问题

需要图像对比增强来更为清晰的显示病灶助于医生确诊,先看效果:

肺纹理增强:

肺结节增强:

血管对比增强:

骨骼对比增强:

根据参考资料:

MATLAB版本:

https://ww2.mathworks.cn/matlabcentral/fileexchange/24409-hessian-based-frangi-vesselness-filter

算法原理:

https://baike.baidu.com/item/%E9%BB%91%E5%A1%9E%E7%9F%A9%E9%98%B5/2248782?fr=aladdin

将其原理翻译写成C++类库,在C++中使用Opencv对于矩阵操作比较方便,导出dll后再由C#调用,

新建C++类库工程:

#include "stdafx.h"
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <vector>
#include "MatBase64.h"
#include "frangi.h"
#include "ET.Functions.h"
using namespace std;
using namespace cv;
char* GetFrangiBase64Code(char* base64code, int SIGMA_START, int SIGMA_END, int SIGMA_STEP, float BETA_ONE, float BETA_TWO, bool BLACKWHITE){ //初始化矩阵参数
frangi2d_opts_t opts;
frangi2d_createopts(&opts, SIGMA_START, SIGMA_END, SIGMA_STEP, BETA_ONE, BETA_TWO, BLACKWHITE); //处理传入的base64编码转为Mat对象
string imgcode =base64code;
string s_mat;
s_mat = base64Decode(imgcode.data(), imgcode.size());
vector<char> base64_img(s_mat.begin(), s_mat.end());
Mat input_img = cv::imdecode(Mat(base64_img), CV_LOAD_IMAGE_GRAYSCALE); //进行frangi算法处理
Mat input_img_fl;
input_img.convertTo(input_img_fl, CV_32FC1);
Mat vesselness, scale, angles;
frangi2d(input_img_fl, vesselness, scale, angles, opts); vector<uchar> buf;
imencode(".jpg", vesselness * 255, buf);
auto *enc_msg = reinterpret_cast<unsigned char*>(buf.data());
string encoded = base64Encode(enc_msg, buf.size()); //返回base64编码
char *result = new char[encoded.length() + 1];
for (int i = 0; i < encoded.length(); ++i)
{
result[i] = encoded[i];
}
result[encoded.length()] = '\0';
return result;
}

导出函数:

extern "C" _declspec(dllexport) char* GetFrangiBase64Code(char * base64code, int SIGMA_START, int SIGMA_END, int SIGMA_STEP, float BETA_ONE, float BETA_TWO, bool BLACKWHITE);

创建模块定义文件:

LIBRARY "ET.Functions"

EXPORTS
GetFrangiBase64Code @ 1,

导出32位dll,复制到C#debug目录下,C#调用:将目标图像转为base64,发送给C++,返回处理后的base64,在转为图像

        [DllImport(@"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);
private void ckcbw_CheckedChanged(object sender, EventArgs e)
{
getimg();
} private void trabarStart_ValueChanged(object sender, EventArgs e)
{
getimg();
} void getimg()
{
int start = trabarStart.Value;
int end = trabarEnd.Value;
int step = trabarStep.Value;
float zaosheng = (float)trabarZaosheng.Value / 10;
float bg = (float)trabarBG.Value / 10; IntPtr pRet = GetFrangiBase64Code(ToBase64(b), start, end, step, zaosheng, bg, ckcbw.Checked);
string strRet = Marshal.PtrToStringAnsi(pRet);
pictureBox1.BackgroundImage = Base64StringToImage(strRet);
}

如果不想用C++,直接用C#里面的opencv库也可以,直接用nuget搜索EmguCV,需要自己将MatLab代码或C++代码翻译成C#

通过调整各个参数来达到想要的效果:

C#开发PACS、RIS、3D医学影像处理系统系列教程目录整理:

菜鸟入门篇:

PACS客户端:

C#开发PACS医学影像处理系统(一):开发背景和功能预览

C#开发PACS医学影像处理系统(二):界面布局之菜单栏

C#开发PACS医学影像处理系统(三):界面布局之工具栏

C#开发PACS医学影像处理系统(四):界面布局之状态栏

C#开发PACS医学影像处理系统(五):查询病人信息列表

C#开发PACS医学影像处理系统(六):加载Dicom影像

C#开发PACS医学影像处理系统(七):读取影像Dicom信息

C#开发PACS医学影像处理系统(八):单元格变换

C#开发PACS医学影像处理系统(九):序列控件与拖拽

C#开发PACS医学影像处理系统(十):Dicom影像下载策略与算法

C#开发PACS医学影像处理系统(十一):Dicom影像挂片协议

C#开发PACS医学影像处理系统(十二):绘图处理之图形标记

C#开发PACS医学影像处理系统(十三):绘图处理之病灶测量

C#开发PACS医学影像处理系统(十四):处理Dicom影像窗宽窗位

C#开发PACS医学影像处理系统(十五):Dicom影像交叉定位线算法

C#开发PACS医学影像处理系统(十六):2D处理之影像平移和缩放

C#开发PACS医学影像处理系统(十七):2D处理之影像旋转和翻转

C#开发PACS医学影像处理系统(十八):Dicom使用LUT色彩增强和反色

C#开发PACS医学影像处理系统(十九):Dicom影像放大镜

PACS三维处理医学图像:

C#开发PACS医学影像三维重建(一):使用VTK重建3D影像

C#开发PACS医学影像三维重建(二):使用VTK进行体绘制

C#开发PACS医学影像三维重建(三):纹理映射与颜色传输

C#开发PACS医学影像三维重建(四):3D网格平滑效果

C#开发PACS医学影像三维重建(五):基于梯度透明的组织漫游

C#开发PACS医学影像三维重建(六):三维光源与阴影效果

C#开发PACS医学影像三维重建(七):空间测量与标注

C#开发PACS医学影像三维重建(八):VR体绘制

C#开发PACS医学影像三维重建(九):MPR三视图切面重建

C#开发PACS医学影像三维重建(十):MIP最小密度投影

C#开发PACS医学影像三维重建(十一):CPR曲面重建

C#开发PACS医学影像三维重建(十二):VE虚拟内镜技术

熟手进阶篇:

医学图像算法:

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

C#处理医学图像(二):图像锐化增强对比

PACS网页端 开发Web版本的PACS:

C#开发Web端PACS(一):基于PACS客户端思想重写Web端

C#开发Web端PACS(二):使用 .Net MVC 开发手机端PACS服务端

C#开发Web端PACS(三):使用HTML5和CSS3开发PACS手机端页面

C#开发Web端PACS(四):Web端与服务端的DICOM传输

C#开发Web端PACS(五):Web端的平移缩放旋转2D操作

C#开发Web端PACS(六):Web端的窗宽窗位调整

C#开发Web端PACS(七):将移动端接入微信公众号实现医院云胶片

登峰造极篇:

C#开发基于Python人工智能的肺结节自动检测

C#开发基于Python人工智能的脊柱侧弯曲率算法

C#开发基于Python机器学习的医学影像骨骼仿真动画

C#开发基于Python机器学习的术后恢复模拟

C#开发基于U3D的VR眼镜设备虚拟人体三维重建

C#开发基于全息投影的裸眼3D医学影像显示技术

周边附加篇:

胶片打印:

C#开发医学影像胶片打印系统(一):功能与胶片排版

C#开发医学影像胶片打印系统(二):胶片打印机通讯

C#开发医学影像胶片打印系统(三):不规则排版打印

PACS服务端:

C#开发PACS医学影像处理系统服务端(一):医疗设备的连接与收图

C#开发PACS医学影像处理系统服务端(二):高并发架构

PACS与RIS系统的通信与集成

在RIS系统中调起PACS并打开Dicom影像

云PACS与远程会诊

C#开发PACS医学影像处理系统之云PACS(区域PACS)(一):架构概述

C#开发PACS医学影像处理系统之云PACS(区域PACS)(二):远程会诊与双向转诊

科幻级视频特效:

使用Adobe After Effects 制作PACS影像处理系统宣传视频

QQ:1850969244

近10年开发经验,主攻C#、ASP MVC,HTML5,

B/S C/S 皆可,目前研究医疗领域医学影像相关技术,

任何技术问题欢迎加QQ交流。

C#处理医学图像(一):基于Hessian矩阵的血管肺纹理骨骼增强对比的更多相关文章

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

    根据本系列教程文章上一篇说到,在完成C++和Opencv对Hessian矩阵滤波算法的实现和封装后, 再由C#调用C++ 的DLL,(参考:C#处理医学图像(一):基于Hessian矩阵的血管肺纹理骨 ...

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

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

  3. Jacobian矩阵和Hessian矩阵

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

  4. Hessian矩阵

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

  5. Jacobian矩阵、Hessian矩阵和Newton's method

    在寻找极大极小值的过程中,有一个经典的算法叫做Newton's method,在学习Newton's method的过程中,会引入两个矩阵,使得理解的难度增大,下面就对这个问题进行描述. 1, Jac ...

  6. Hessian矩阵【转】

    http://blog.sina.com.cn/s/blog_7e1ecaf30100wgfw.html 在数学中,海塞矩阵是一个自变量为向量的实值函数的二阶偏导数组成的方块矩阵,一元函数就是二阶导, ...

  7. Hessian矩阵与牛顿法

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

  8. 三维重建面试4:Jacobian矩阵和Hessian矩阵

    在使用BA平差之前,对每一个观测方程,得到一个代价函数.对多个路标,会产生一个多个代价函数的和的形式,对这个和进行最小二乘法进行求解,使用优化方法.相当于同时对相机位姿和路标进行调整,这就是所谓的BA ...

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

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

随机推荐

  1. pandas 处理缺失值(连续值取平均,离散值fillna"<unk>")

    # 2.1处理缺失值,连续值用均值填充 continuous_fillna_number = [] for i in train_null_ix: if(i in continuous_ix): me ...

  2. NodeService Ensure that Node.js is installed and can be found in one of the PATH directories

    今天发布NodeService到服务器,服务器环境是window server 2012 一直报错: [1] Ensure that Node.js is installed and can be f ...

  3. 学习JUC源码(1)——AQS同步队列(源码分析结合图文理解)

    前言 最近结合书籍<Java并发编程艺术>一直在看AQS的源码,发现AQS核心就是:利用内置的FIFO双向队列结构来实现线程排队获取int变量的同步状态,以此奠定了很多并发包中大部分实现基 ...

  4. 第四篇 Scrum 冲刺博客

    一.站立式会议 1. 会议照片 2. 工作汇报 团队成员名称 昨日(25日)完成的工作 今天(26日)计划完成的工作 工作中遇到的困难 陈锐基 - 完善表白墙动态的全局状态管理 - 完成发布页面的布局 ...

  5. 百度前端技术学院-基础-day5.6

    今天学习了关于盒模型.浮动等页面布局的方法. 受到同学的启发,顺便学习了flex的布局. 还了解了一些编码的基本规则. 对我接下来的学习帮助很大. 交作业: HTML : https://github ...

  6. NetCDF格式.nc

    netcdf sfc_pres_temp { dimensions: latitude = 6 ; //纬度轴 longitude = 12 ; //经度轴 variables: float lati ...

  7. oracle DG搭建

    Oracle DG 搭建1. 环境 OS IP hostname db_name DB_UNIQUE_NAME主库 RHEL 5.4 192.168.12.20 edgzrip1.oracle.com ...

  8. vue 属性绑定 v-bind

    属性绑定 v-bind 可以通过v-bind将属性值与数据绑定,这样就可以统一化管理 通过这样我们就可以直接访问跳转到百度页面 同样的这个值我们也可以通过事件进行改变 这样就可以方便我们做一些其它的操 ...

  9. Windows单机安装hadoop

    版本信息 Hadoop 3.2.0 java version "1.8.0_201" Windows 7专业版,64位 安装过程 jdk安装 下载jdk,解压到目录,D:\Java ...

  10. 使用轮询&长轮询实现网页聊天室

    前言 如果有一个需求,让你构建一个网络的聊天室,你会怎么解决? 首先,对于HTTP请求来说,Server端总是处于被动的一方,即只能由Browser发送请求,Server才能够被动回应. 也就是说,如 ...