ECGPrint/1200Gxml心电图绘制/Form3.cs

511 lines
20 KiB
C#

using HTTPServerLib;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Windows.Forms;
using ;
namespace _1200Gxml心电图绘制
{
public partial class Form3 : Form
{
ExampleServer server;
public Form3()
{
InitializeComponent();
}
void DataRead()
{
}
private void Form3_Load(object sender, EventArgs e)
{
string strip = ConfigurationManager.AppSettings["ip"];
string stport = ConfigurationManager.AppSettings["port"];
server = new ExampleServer(strip, int.Parse(stport), txt_msg);
EcgDataDraw_New EDDN = new EcgDataDraw_New();
var btmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
pictureBox1.Image = btmp;
Graphics Ecg_Graphics = Graphics.FromImage(pictureBox1.Image);
combo_reportModel.SelectedIndex = 0;
cBoxSpeed.SelectedIndex = 3;
cBoxAmplitude.SelectedIndex = 2;
Start();
//加载心电数据
// #region
//Dictionary<int, List<float>> EcgTable = new Dictionary<int, List<float>>();
//for (int k = 0; k < 8; k++)
// EcgTable.Add(k, new List<float>());
//string contentStr = File.ReadAllText(Application.StartupPath + @"\蓝牙holter数据\dc93ee94-c0e8-4dba-8d29-ed86b2dcb6e8.ecg");
//var contenList = JsonConvert.DeserializeObject<List<byte[]>>(contentStr);
////这里是把8个通道的数据转换出来 放到一个 字典里
//for (int i = 0; i < contenList.Count; i++)
//{
// for (int j = 0; j < contenList[i].Length; j += 16)
// {
// EcgTable[0].Add((float)((short)(byteToShort(contenList[i][j], contenList[i][j + 1]))));
// EcgTable[1].Add((float)((short)(byteToShort(contenList[i][j + 2], contenList[i][j + 3]))));
// EcgTable[2].Add((float)((short)(byteToShort(contenList[i][j + 4], contenList[i][j + 5]))));
// EcgTable[3].Add((float)((short)(byteToShort(contenList[i][j + 6], contenList[i][j + 7]))));
// EcgTable[4].Add((float)((short)(byteToShort(contenList[i][j + 8], contenList[i][j + 9]))));
// EcgTable[5].Add((float)((short)(byteToShort(contenList[i][j + 10], contenList[i][j + 11]))));
// EcgTable[6].Add((float)((short)(byteToShort(contenList[i][j + 12], contenList[i][j + 13]))));
// EcgTable[7].Add((float)((short)(byteToShort(contenList[i][j + 14], contenList[i][j + 15]))));
// }
//}
////在这里你就可以对这8个通道的数据进行滤波了 在这里写滤波代码
//Dictionary<int, List<float>> EcgTable2 = new Dictionary<int, List<float>>();
////把 I II导联加入字典中
//for (int i = 0; i < 2; i++)
// EcgTable2.Add(i, EcgTable[i]);
//List<float> list3 = new List<float>();
//List<float> list4 = new List<float>();
//List<float> list5 = new List<float>();
//List<float> list6 = new List<float>();
////把 III AVR AVL AVF 这四个导联计算出来 加入字典
//for (int A = 0; A < EcgTable[0].Count; A++)
//{
// list3.Add(EcgTable[1][A] - EcgTable[0][A]);//III
// list4.Add(-(EcgTable[1][A] + EcgTable[0][A]) / 2);//avR
// list5.Add(EcgTable[0][A] - EcgTable[1][A] / 2);//avL
// list6.Add(EcgTable[1][A] - EcgTable[0][A] / 2);//avF
//}
//EcgTable2.Add(2, list3);
//EcgTable2.Add(3, list4);
//EcgTable2.Add(4, list5);
//EcgTable2.Add(5, list6);
////把 V1-V6导联 加入字典
//for (int i = 6; i < 12; i++)
// EcgTable2.Add(i, EcgTable[i - 4]);
//Dictionary<int, List<float>> EcgTable3 = new Dictionary<int, List<float>>();
//for (int i = 0; i < EcgTable2.Count; i++)
// EcgTable3.Add(i, baseLineFilter(i, EcgTable2[i]));
//this.samplingRate = 300;
//this.windowSize = 60000;
//List<int> rPosList = DetectRWave(EcgTable3[1].ToArray());
////for (int i = 0; i < 12; i++)
//// EcgTable2[i].RemoveRange(0, 500);
////string[] ecgDataArray = dataStr.Split(' ');//把xml中每一导联的数据 变成数组 然后把数据赋值给 EcgTable 字典中的每一导联
////List<float> ecg_List = new List<float>();
////for (int i = 0; i < ecgDataArray.Length; i++)
//// ecg_List.Add(float.Parse(ecgDataArray[i]));
////for (int i = 0; i < 12; i++)
//// EcgTable.Add(i, ecg_List);
//#endregion
//List<int> leadInfo = new List<int>();
//for (int i = 0; i < 12; i++)
// leadInfo.Add(i);
//EDDN.InitEcgParameter(btmp, 12, EcgTable3, 96, leadInfo);//初始化
//EDDN.Draw_EcgBackGroundGrid();//画背景网格
//EDDN.Draw_EcgWave();//画波形
//EDDN.Draw_CalibrationVoltage_And_LeadName();//画定标电压和导联名称
// EDDN.drawRWavePos(rPosList);//绘制R波位置
}
private void groupBox2_Enter(object sender, EventArgs e)
{
}
private void pictureBox1_Click(object sender, EventArgs e)
{
}
short byteToShort(byte a, byte b)
{
short volV = (short)((a << 8) + b);//正确
return (short)(volV / 45);
}
private void pictureBox1_DoubleClick(object sender, EventArgs e)
{
}
List<float> baseLineFilter(int leadIndex, List<float> inputDatas)
{
List<float> outPutDatas = new List<float>();
float sum = 0;
for (int i = 0; i < inputDatas.Count; i++)
sum += inputDatas[i];
float avgVal = sum / inputDatas.Count;
for (int i = 0; i < inputDatas.Count; i++)
outPutDatas.Add(inputDatas[i] - avgVal);
if (leadIndex == 1)
{
float sum2 = 0;
int indexCount = 0;
for (int i = 0; i < outPutDatas.Count; i++)
{
if (outPutDatas[i] > 0)
{
sum2 += outPutDatas[i];
indexCount++;
}
}
float avgVal1 = sum2 / indexCount;
threshold = avgVal1 + 130;
}
return outPutDatas;
}
private int samplingRate;
private int windowSize;
private double threshold;
public List<int> DetectRWave(float[] ecg_data)
{
List<int> rWaveIndices = new List<int>(); int maxIndex = 0;
// R波识别
int r_wave_count = 0;
for (int i = 1; i < ecg_data.Length; i++)
{
if (ecg_data[i] > ecg_data[i - 1] && ecg_data[i] > ecg_data[i + 1] && ecg_data[i] > threshold)
{
if (!rWaveIndices.Contains(i))
rWaveIndices.Add(i);
}
}
return rWaveIndices;
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
GetEcgViewDataImage(null, "这是地址"); //普通打印
}
float[] valueConvert(float[] valueArray)
{
float[] quotients = valueArray.Select(n => n / 500).ToArray();
return quotients;
}
private string _printFilter = "0Hz";
private Bitmap _ecgBitMap;
private static int _printDpi = 300;//打印DPI
private const int Dpi = 96; //屏幕DIP
private readonly string _isQiBo;//是否是起搏信号
private int _leadindexdata;
private const string LeaderName15 = "5x3+1导报告模式";
private const string LeaderName18 = "18导报告模式";
private string _reportTitleContent = string.Empty;
private string _idStr;
private string collectTime;//心电数据采集时间
private const double Coefficient = 1.02; //放大缩小的系数
private List<int> _longLeadInfo = new List<int>(); //存储任意长两导联的导联下标
private readonly List<int> _longLeadInfo3 = new List<int>(); //存储任意长三导联的导联下标
public string LeaderType; //导联类别
private Dictionary<int, List<float>> _ecgDataDicAfterFilter = new Dictionary<int, List<float>>(); //滤波后的数据都存在这个字典中
private int _filterIndex; //滤波时 此标志 指示从数组中 哪一个位置开始滤波
/// <summary>
/// 获得心电诊断快照数据
/// </summary>
public void GetEcgViewDataImage(Image img, string addr)
{
//_ecgDataDicAfterFilter.Clear();
//string ecgDataJsonStr = File.ReadAllText(Application.StartupPath + @"\60心拍心电图数据JSON.txt");
//leadDataModel LDM = JsonConvert.DeserializeObject<leadDataModel>(ecgDataJsonStr);
//float[] LEAD_I = valueConvert(Array.ConvertAll(LDM.LEAD_I.Split(' '), float.Parse));
//_ecgDataDicAfterFilter.Add(0, LEAD_I.ToList());
//float[] LEAD_II = valueConvert(Array.ConvertAll(LDM.LEAD_II.Split(' '), float.Parse));
//_ecgDataDicAfterFilter.Add(1, LEAD_II.ToList());
//float[] LEAD_III = valueConvert(Array.ConvertAll(LDM.LEAD_III.Split(' '), float.Parse));
//_ecgDataDicAfterFilter.Add(2, LEAD_III.ToList());
//float[] LEAD_AVR = valueConvert(Array.ConvertAll(LDM.LEAD_AVR.Split(' '), float.Parse));
//_ecgDataDicAfterFilter.Add(3, LEAD_AVR.ToList());
//float[] LEAD_AVL = valueConvert(Array.ConvertAll(LDM.LEAD_AVL.Split(' '), float.Parse));
//_ecgDataDicAfterFilter.Add(4, LEAD_AVL.ToList());
//float[] LEAD_AVF = valueConvert(Array.ConvertAll(LDM.LEAD_AVF.Split(' '), float.Parse));
//_ecgDataDicAfterFilter.Add(5, LEAD_AVF.ToList());
//float[] LEAD_V1 = valueConvert(Array.ConvertAll(LDM.LEAD_V1.Split(' '), float.Parse));
//_ecgDataDicAfterFilter.Add(6, LEAD_V1.ToList());
//float[] LEAD_V2 = valueConvert(Array.ConvertAll(LDM.LEAD_V2.Split(' '), float.Parse));
//_ecgDataDicAfterFilter.Add(7, LEAD_V2.ToList());
//float[] LEAD_V3 = valueConvert(Array.ConvertAll(LDM.LEAD_V3.Split(' '), float.Parse));
//_ecgDataDicAfterFilter.Add(8, LEAD_V3.ToList());
//float[] LEAD_V4 = valueConvert(Array.ConvertAll(LDM.LEAD_V4.Split(' '), float.Parse));
//_ecgDataDicAfterFilter.Add(9, LEAD_V4.ToList());
//float[] LEAD_V5 = valueConvert(Array.ConvertAll(LDM.LEAD_V5.Split(' '), float.Parse));
//_ecgDataDicAfterFilter.Add(10, LEAD_V5.ToList());
//float[] LEAD_V6 = valueConvert(Array.ConvertAll(LDM.LEAD_V6.Split(' '), float.Parse));
//_ecgDataDicAfterFilter.Add(11, LEAD_V6.ToList());
//_reportTitleContent = "十二导联静态心电图报告";
//_idStr = "5566778899";
//collectTime = "2024-12-20 13:28:51";
////长两导的模式下 默认添加 第一导 和 第二导联 为 长显示两导联
//_longLeadInfo.Add(0);
//_longLeadInfo.Add(1);
////长三导的模式下 默认添加 第一导 和 第二导联和第三导联 为 长显示三导联
//_longLeadInfo3.Add(0);
//_longLeadInfo3.Add(1);
//_longLeadInfo3.Add(2);
//var cpew = new CommonPrintEcgWave();
//var filter = _printFilter;
//_ecgBitMap = new Bitmap(1090 * _printDpi / Dpi, 760 * _printDpi / Dpi);
//_ecgBitMap.SetResolution(_printDpi, _printDpi);
//cpew.InitEcgParameter(_ecgBitMap, _ecgDataDicAfterFilter, _isQiBo, _paperSpeed, _amplitude);
////************************************************************************
//var ecgInfoList = new string[13];
//ecgInfoList[0] = "张三";
//ecgInfoList[1] = "女";
//ecgInfoList[2] = "28";
//ecgInfoList[3] = "RV5+SV1";
//ecgInfoList[4] = "PR间期";
//ecgInfoList[5] = "QRS间期";
//ecgInfoList[6] = "QT/QTC";
//ecgInfoList[7] = "QRS电轴";
//ecgInfoList[8] = "RV5/SV1";
//ecgInfoList[9] = "心率";
//ecgInfoList[10] = "病室";
//ecgInfoList[11] = "床号";
//ecgInfoList[12] = "住院号";
//SetAandP(); //设置增益和走速
//var diagContent = "这里是心电图的诊断结论";
//var diagArray = diagContent.Split('\n');
//diagContent = string.Empty;
//for (var i = 0; i < diagArray.Length; i++) diagContent += diagArray[i].Trim();
//if (_ecgDataDicAfterFilter.Count > 0)
// _filterIndex = 0;
//else
// _filterIndex = 0;
//// _leadindexdata = hScrollBar_Lead.Value * _filterIndex;
//_leadindexdata = _filterIndex;
//if (combo_reportModel.Text == LeaderName15) filter += " 十五加一长导模式";
//if (combo_reportModel.Text == LeaderName18) filter += " 十八导模式";
//if (combo_reportModel.SelectedIndex == 2)
//{
// cpew.PrintBackGroundGrid(16, 196);
// cpew.PrintLongReportHeadInfo(_reportTitleContent);
// cpew.PrintLongEcgInfo(ecgInfoList, _idStr);
// cpew.PrintLongDiagInfo(diagContent, "医生姓名",
// "2024-12-20", filter,
// collectTime, "心电图科", _amp, _ps, img, addr);
//}
//else
//{
// cpew.PrintBackGroundGrid(40, 196); //(197-42)*12=1860像素
// cpew.PrintReportHeadInfo(_reportTitleContent, "2024-12-20");
// cpew.PrintEcgInfo(ecgInfoList, _idStr);
// cpew.PrintDiagInfo(diagContent, "医生姓名", filter,
// collectTime, "心电图科", _amp, _ps, img, addr);
//}
////6x2
//if (combo_reportModel.SelectedIndex == 0)
//{
// cpew.PrintEcgWave(8, 1, _leadindexdata);
// cpew.PrintEcgLeadName(_calibrationVoltage * Coefficient);
//}
////6x2+2
//if (combo_reportModel.SelectedIndex == 1)
//{
// cpew.PrintEcgWave(8, 1, _longLeadInfo, _leadindexdata, _leadindexdata);
// cpew.PrintEcgLeadName(_calibrationVoltage * Coefficient, _longLeadInfo);
//}
////十二长导
//if (combo_reportModel.SelectedIndex == 2)
//{
// cpew.PrintLongEcgWave(5, 1, _leadindexdata);
// //cpew.PrintLongEcgWave(8, 1, _leadindexdata);
// cpew.PrintLongEcgLeadName(_calibrationVoltage * Coefficient);
//}
////4*3 II长导模式
//if (combo_reportModel.SelectedIndex == 3)
//{
// cpew.PrintEcgWaveFourOne(8, 1, _leadindexdata, _leadindexdata);
// cpew.PrintLeadNameFourOne(_calibrationVoltage * Coefficient, _longLeadInfo);
//}
////4*3+3 长导模式
//if (combo_reportModel.SelectedIndex == 4)
//{
// cpew.PrintEcgWaveFourThree(8, 1, _longLeadInfo3, _leadindexdata, _leadindexdata);
// cpew.PrintLeadNameFourThree(_calibrationVoltage * Coefficient, _longLeadInfo3);
//}
////15x1+1导
//if (combo_reportModel.Text.Trim() == LeaderName15)
//{
// cpew.PrintEcgWaveFifteen(8, 1, _leadindexdata);
// cpew.PrintLeadNameFifteen(_calibrationVoltage * Coefficient, LeaderType);
//}
////十八导
//if (combo_reportModel.Text.Trim() == LeaderName18)
//{
// cpew.PrintEcgWaveEighteen(8, 1, _leadindexdata);
// cpew.PrintLeadNameEighteen(_calibrationVoltage * Coefficient);
//}
////_sourceCegBmp = _ecgBitMap;
//_ecgBitMap.Save("1.jpg", ImageFormat.Jpeg);
}
private double _paperSpeed = 25.0; //走速
private string _ps = "25mm/s"; //打印时的走速
private double _amplitude = 10.0; //振幅
private string _amp = "10mm/mV"; //打印时的振幅
private double _calibrationVoltage = 2.0;//定标电压
/// <summary>
/// 设置增益和走速和定标电压
/// </summary>
private void SetAandP()
{
if (cBoxSpeed.SelectedIndex == 0) //走速
{
_paperSpeed = 5;
_ps = "5mm/s";
}
if (cBoxSpeed.SelectedIndex == 1)
{
_paperSpeed = 10;
_ps = "10mm/s";
}
if (cBoxSpeed.SelectedIndex == 2) //走速
{
_paperSpeed = 12.5;
_ps = "12.5mm/s";
}
if (cBoxSpeed.SelectedIndex == 3)
{
_paperSpeed = 25.0;
_ps = "25mm/s";
}
if (cBoxSpeed.SelectedIndex == 4)
{
_paperSpeed = 50.0;
_ps = "50mm/s";
}
if (cBoxAmplitude.SelectedIndex == 0) //振幅
{
_amplitude = 2.5;
_amp = "2.5mm/mV";
_calibrationVoltage = 0.5;
}
if (cBoxAmplitude.SelectedIndex == 1)
{
_amplitude = 5.0;
_amp = "5mm/mV";
_calibrationVoltage = 1.0;
}
if (cBoxAmplitude.SelectedIndex == 2)
{
_amplitude = 10.0;
_amp = "10mm/mV";
_calibrationVoltage = 2.0;
}
if (cBoxAmplitude.SelectedIndex == 3)
{
_amplitude = 20.0;
_amp = "20mm/mV";
_calibrationVoltage = 4.0;
}
if (cBoxAmplitude.SelectedIndex == 4)
{
_amplitude = 40.0;
_amp = "40mm/mV";
_calibrationVoltage = 8.0;
}
}
/// <summary>
/// 开启服务
/// </summary>
private void Start()
{
server.SetRoot(AppDomain.CurrentDomain.BaseDirectory);
server.Logger = new ConsoleLogger(txt_msg);
server.Start();
}
#region
private void combo_reportModel_SelectedIndexChanged(object sender, EventArgs e)
{
server.reportMode = combo_reportModel.SelectedIndex;
server.strreportMode = combo_reportModel.Text.Trim();
}
private void cBoxSpeed_SelectedIndexChanged(object sender, EventArgs e)
{
server.cBoxSpeed = cBoxSpeed.SelectedIndex;
}
private void cBoxAmplitude_SelectedIndexChanged(object sender, EventArgs e)
{
server.cBoxAmplitude = cBoxAmplitude.SelectedIndex;
}
#endregion
private void Form3_FormClosed(object sender, FormClosedEventArgs e)
{
server.Stop();
}
}
}