zoukankan      html  css  js  c++  java
  • C#处理医学图像(一):基于Hessian矩阵的血管肺纹理骨骼增强对比

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

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

    肺纹理增强:

    肺结节增强:

     血管对比增强:

     

     骨骼对比增强:

     

    根据参考资料:

    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()] = '';
        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#

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

     

     

  • 相关阅读:
    querySelectorAll和getElementsByClassName获取元素的区别
    移动端的点透事件
    formidable处理node.js的post请求
    Node中流的概念
    关于Node.js中的路径问题
    前端设计模式——原型模式
    JavaScript中的循环和闭包
    为什么给函数表达式添加函数名
    作为一个初学者如何简单地理解闭包
    JS的with关键字到底是什么?
  • 原文地址:https://www.cnblogs.com/Uncle-Joker/p/14262455.html
Copyright © 2011-2022 走看看