在醫院實際環境中,經常遇到有問題的患者,對於一些特殊的場景,比如骨折,肺結節,心腦血管問題
需要圖像對比增強來更為清晰的顯示病灶助於醫生確診,先看效果:
肺紋理增強:

肺結節增強:

血管對比增強:

骨骼對比增強:

根據參考資料:
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#

通過調整各個參數來達到想要的效果:

