ECG心电图并标注(Java实现)

  1. 成果展示

ecg心电图

  1. Java代码展示,算法比较简单暴力,有更优解可以评论,谢谢。
// package com.example.userservice80.Controller;

import com.example.userservice80.entity.heartResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.*;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;

@CrossOrigin
@RestController
@Slf4j
public class hiddenController {
    @RequestMapping("/hidden")
    public heartResult ArrhythmiaHeart(@RequestParam("str")String str) throws IOException {
        System.out.println(str);
        FileInputStream in = null;
        FileInputStream inatr = null;
        BufferedReader inhea = null;
        String path1 = "D:\\mitdatabase\\hidden\\"+str+".hea";
        String path2 = "D:\\mitdatabase\\hidden\\"+str+".dat";
        String path3 = "D:\\mitdatabase\\hidden\\"+str+".atr";
        inhea = new BufferedReader (new FileReader (path1) );
        in = new FileInputStream ( path2 );
        inatr = new FileInputStream (path3);


        heartResult heartResult = new heartResult();
        //解析hea文件
        String str9 = null;
        int h = 0;
        String[] heastr = new String[2];
        while( (str9 = inhea.readLine ()) != null ){
            if(h>2) break;
            if(h==1){
                int y = str9.lastIndexOf(' ');
                heastr[h-1] = str9.substring(y)+"导联一";
                System.out.println(heastr[0]);
            }
            if(h==2){
                int y = str9.lastIndexOf(' ');
                heastr[h-1] = str9.substring(y)+"导联二";
            }
            h++;
        }
        heartResult.setDaolian(heastr);


        //解析dat文件

        int num = 0;
//给数组赋予下标
        int k = 0;
        int n=0;
        DecimalFormat df = new DecimalFormat ("#.0000");
//这个数组就是存储字节数据,然后统一进行转换
        int[] messDate = new int[7500];
        double[] arr1 = new double[2500];
        double[] arr2 = new double[2500];
        double[] arr3 = new double[2500];

        //in = new FileInputStream ( "C:\\Users\\Yanminghui\\Desktop\\Hreat\\n40.dat" );
        int data;
        while ((data = in.read ()) != -1 && num<7500) {
//如果能确定数据项所占字节长度是3

            messDate[k] = data;
            if (k == 2 && n<7500) {
                String str1 = tenTransformSixteen1 ( messDate, k );
                String str2 = tenTransformSixteen2 ( messDate, k );
                long num1 = Integer.valueOf ( str1 );
                if(num1>=2048){
                    num1 -= 2048;
                    num1 = 2048 - num1;
                }
                long num2 = Integer.valueOf ( str2 );
                if(num2>=2048){
                    num2 -= 2048;
                    num2 = 2048 - num2;
                }
                double n1 = (double) (num1-0)/800;
                double n2 = (double) (num2-0)/800;

                n1 = Double.valueOf ( df.format ( n1 ) );
                n2 = Double.valueOf ( df.format ( n2 ) );
                arr1[n]=n1;
                arr2[n]=n2;

                /**
                 * 分析时间
                 */
                for(int i=0;i<2500;i++){
                    double db = (double) i/250;
                    arr3[i] = Double.parseDouble(df.format(db));
                }
                k = -1;
                n++;
            }

            k += 1;
            num += 1;
        }
        heartResult.setA1(arr1);
        heartResult.setA2(arr2);
        heartResult.setDtime(arr3);

        /**
         * ATR文件解析
         */

        int sum=0;
        double time = 0;
        double[] Atime0 = new double[2500];
        int[] Asymbol0 = new int[2500];
        Map<Double,Integer> map = new HashMap<>();

        int data0 = 0;
        int nn=0,i=0;
        int p=0;
        int[] messdata = new int[5000];
        while ((data0 = inatr.read ()) != -1 && time<10) {
            messdata[i] = data0;
            if(i%2!=0){
                int n1,n2;
                String str2 = Integer.toBinaryString(messdata[i-1]);
                String str1 = Integer.toBinaryString(messdata[i]);
                int len1=str1.length();
                int len2=str2.length();
                if(len1<8){
                    for(int l=0;l<8-len1;l++){
                        str1 = '0' + str1;
                    }
                }
                if(len2<8){
                    for(int l=0;l<8-len2;l++){
                        str2 = '0' + str2;
                    }
                }
//                    System.out.println(str1+" "+str2);
                String str0 = ""+str1+str2;
//                    System.out.println(str);
                n1 = Integer.parseInt(str0.substring(0,6));
                n2 = Integer.parseInt(str0.substring(6,16));
                int npre1 = Integer.parseInt(String.valueOf(n1),2);
                int npre2 = Integer.parseInt(String.valueOf(n2),2);



                //判断atr标记值
                if (npre1==60 || npre1==61 || npre1 ==62){

                } else if (npre1 == 59) {
                    //                       System.out.println(npre1);
                    int[] Mes = new int[6];
                    for(int j=0;j<6;j++){
                        Mes[j] = inatr.read();
                    }
                    String str3 = Integer.toBinaryString(Mes[5]);
                    int len3=str3.length();
                    if(len3<8){
                        for(int l=0;l<8-len3;l++){
                            str3 = '0' + str3;
                        }
                    }
                    int pre = Integer.parseInt(str3.substring(0,6),2);
                    //                       System.out.println(pre);
                    int p1 = Integer.parseInt(String.valueOf(Mes[0]));
                    int p2 = Integer.parseInt(String.valueOf(Mes[1]));
                    int p3 = Integer.parseInt(String.valueOf(Mes[2]));
                    int p4 = Integer.parseInt(String.valueOf(Mes[3]));
                    int o = p1+p2+p3+p4;
                    //                      System.out.println(o);
                    sum += o;
                    time = Double.parseDouble(df.format((double) sum/250));
                    System.out.print(" "+time);
                    System.out.println();
                    Atime0[p]=time;
                    Asymbol0[nn]=pre;
                    nn++;
                    p++;
                    i += 6;
                } else if (npre1==63) {
                    //                      System.out.print(npre1+" "+npre2);
                    if(npre2%2!=0){
                        npre2++;
                    }
                    int[] Mess = new int[npre2];
                    for(int j=0;j<npre2;j++){
                        Mess[j] = inatr.read();
                    }
                    //                      System.out.println();
                    i += npre2;
                } else {
                    sum += npre2;
                    time = Double.parseDouble(df.format((double) sum/250));
                    //System.out.println(npre1+" "+time);
                    map.put(time,npre1);
                    Atime0[p]=time;
                    Asymbol0[nn]=npre1;
                    nn++;
                    p++;
                }
            }
            i++;
        }
        int len = 0;
        for(int j=0;j<Atime0.length;j++){
            System.out.println(Atime0[j]);
            if(Atime0[j]<10){
                len++;
            }else{
                break;
            }
        }
        double[] arr4 = new double[len];
        int[] arr5 = new int[len];
        for(int j=0;j<len;j++){
            arr4[j] = Atime0[j];
            arr5[j] = Asymbol0[j];
        }
        int pr = 0;
        int[] arr = new int[len];
        for(int j=0;j<2500;j++){
            if(pr >= len){
                break;
            }
            if(arr4[pr] == arr3[j]){
                arr[pr] = j;
                System.out.println(pr);
                pr++;
            }
        }
        String[] s = new String[len];
        s = type(s,arr5);
        heartResult.setAtime(arr4);
        heartResult.setType(s);
        heartResult.setA(arr);
        heartResult.setAsymbol(arr5);

        heartResult.setStatusCode(200);
        System.out.println(heartResult);
        return heartResult;

    }
    /**
     * 十进制转十六进制转十进制
     * <p>
     * 需要将数组中每一个十进制字节转换成十六进制,然后拼接到一起,统一转换成十进制
     */
    public static String tenTransformSixteen1(int[] data, int k) {
        String str = "";
        for (int i = 0; i <= k; i++) {
// data为十进制,将每个十进制解析成十六进制,然后将数组中数值一起解析成十进制
            String hexString = Integer.toHexString ( data[i] );
            if (hexString.length () == 1) {
                hexString = "0" + hexString;
            }
            str = str + hexString;
        }
        str = str.charAt ( 3 ) + str.substring ( 0, 2 );
        str = String.valueOf ( Long.valueOf ( str, 16 ) );
        return str;
    }
    public static String tenTransformSixteen2(int[] data, int k) {
        String str = "";
        for (int i = 0; i <= k; i++) {
// data为十进制,将每个十进制解析成十六进制,然后将数组中数值一起解析成十进制
            String hexString = Integer.toHexString ( data[i] );
            if (hexString.length () == 1) {
                hexString = "0" + hexString;
            }
            str = str + hexString;
        }
        str = str.charAt ( 2 ) + str.substring ( 4, 6 );
        str = String.valueOf ( Long.valueOf ( str, 16 ) );
        return str;
    }

    public static String[] type(String[] s,int[] sy){
        int n = sy.length;
        for(int i=0;i<n;i++){
            if(sy[i]==0){
            }else if(sy[i]==1){
                s[i]="N--正常心搏";
            }else if(sy[i]==2){
                s[i]="L--左束支传导阻滞";
            }else if(sy[i]==3){
                s[i]="R--右束支传导阻滞";
            }else if(sy[i]==4){
                s[i]="a--异常心房早搏";
            }else if(sy[i]==5){
                s[i]="V--室性早搏";
            }else if(sy[i]==6){
                s[i]="F--心室融和心搏";
            }else if(sy[i]==7){
                s[i]="J--交界性早搏";
            }else if(sy[i]==8){
                s[i]="A--房性早搏";
            }else if(sy[i]==9){
                s[i]="S--早搏或室上性一尾心搏";
            }else if(sy[i]==10){
                s[i]="E--室性逸搏";
            }else if(sy[i]==11){
                s[i]="j--交界性逸搏";
            }else if(sy[i]==12){
                s[i]="/--起搏心拍";
            }else if(sy[i]==13){
                s[i]="Q--无法分类的节拍";
            }else if(sy[i]==14){
                s[i]="~--信号质量变化";
            }else if(sy[i]==16){
                s[i]="|--像人造的异位心搏";
            }else if(sy[i]==18){
                s[i]="s--St改变";
            }else if(sy[i]==19){
                s[i]="T--T波改变";
            }else if(sy[i]==20){
                s[i]="*--心脏收缩";
            }else if(sy[i]==21){
                s[i]="D--心脏舒张";
            }else if(sy[i]==22){
                s[i]="\"--注释注释";
            }else if(sy[i]==23){
                s[i]="=--测量注释";
            }else if(sy[i]==24){
                s[i]="p--P波峰值";
            }else if(sy[i]==25){
                s[i]="B--传导阻滞心搏";
            }else if(sy[i]==26){
                s[i]="^--起搏器伪迹";
            }else if(sy[i]==27){
                s[i]= "t--T波峰值";
            }else if(sy[i]==28){
                s[i]="+--节律变化";
            }else if(sy[i]==29){
                s[i]="u--U波峰值";
            }else if(sy[i]==30){
                s[i]="?--无";
            }else if(sy[i]==31){
                s[i]="!--心室颤动";
            }else if(sy[i]==32){
                s[i]="[--开始心室扑动/颤动";
            }else if(sy[i]==33){
                s[i]="]--结束心室扑动颤动";
            }else if(sy[i]==34){
                s[i]="e--房性逸搏";
            }else if(sy[i]==35){
                s[i]="n--室上性逸搏";
            }else if(sy[i]==36){
                s[i]="@--无";
            }else if(sy[i]==37){
                s[i]="x--未下传的P波";
            }else if(sy[i]==38){
                s[i]="f--起搏融合心跳";
            }else if(sy[i]==39){
                s[i]="(--QRS波开始";
            }else if(sy[i]==40){
                s[i]=")--QRS波结束";
            }else if(sy[i]==41){
                s[i]="r--R波落在T上的室性早搏";
            }else{
                System.out.println("错误");
            }
        }
        return s;
    }

}

  1. vue前端代码展示,使用echarts,但是这个代码没有实现标准心电图的那种红格子,对前端不是很在行,但是间距依旧是0.05ms,但是由于心电数据的dat文件中的记录有几十万甚至百万条数据,因此只选取了前7500条记录。

// <template>
  <div>
    <div id="main" style="width: 100%; height: 600px"></div>
  </div>
</template>
  
  <script>
import * as echarts from "echarts";
import axios from "axios";

export default {
  name: "echartName",
  data() {
    return {
      list: [],
      list1: [],
      list2: [],
      list3: [],
      list4: [],
      list5: [],
      list6: [],
      daolian: [],
      s: [],
      str: "",
    };
  },
  mounted() {
    this.drawLine();
  },
  created() {
    this.str = window.localStorage.getItem("str");
    const _this = this;
    axios
      .get("http://localhost:8082/Arrhythmia?str=" + this.str)
      .then(function (response) {
        if (response.data.statusCode === 200) {
          for (let i = 0; i < response.data.a1.length; i++) {
            _this.list1.push(response.data.a1[i]);
          }
          for (let i = 0; i < response.data.a2.length; i++) {
            _this.list2.push(response.data.a2[i]);
          }
          for (let i = 0; i < response.data.daolian.length; i++) {
            _this.daolian.push(response.data.daolian[i]);
          }
          for (let i = 0; i < response.data.dtime.length; i++) {
            _this.list3.push(response.data.dtime[i]);
          }
          for (let i = 0; i < response.data.atime.length; i++) {
            _this.list4.push(response.data.atime[i]);
          }
          for (let i = 0; i < response.data.asymbol.length; i++) {
            _this.list5.push(response.data.asymbol[i]);
          }
          for (let i = 0; i < response.data.a.length; i++) {
            _this.list6.push(response.data.a[i]);
          }
          for (let i = 0; i < response.data.type.length; i++) {
            _this.s.push(response.data.type[i]);
          }
        }
      });
  },
  watch: {
    list2: {
      handler: function () {
        this.drawLine();
      },
      deep: true,
    },
  },
  methods: {
    drawLine() {
      const _this = this;

      var chartDom = document.getElementById("main");
      var myChart = echarts.init(chartDom);

      var option;
      var xAxisData = [];
      for (let i = 0; i < 3600; i++) {
      //  xAxisData.push(Number(i / 360).toFixed(4));
        xAxisData.push(i);
      }

      myChart.showLoading({
        text: "loading",
        color: "#c23531",
        textColor: "#000",
        maskColor: "rgba(255, 255, 255, 0.2)",
        zlevel: 0,
      });
      setTimeout(() => {
        // setOption前隐藏loading事件
        myChart.hideLoading();
        myChart.setOption(option);
      }, 5000);

      option = {
        tooltip: {
          trigger: "axis",
          axisPointer: {
            type: "cross",
            label: {
              backgroundColor: "#6a7985",
            },
          },
        },
        legend: {
          data: _this.daolian,
          textStyle: { color: "#66b3ff" },
        },
        // title: {
        //   left: "left",
        //   text: "101",
        // },
        toolbox: {
          feature: {
            dataZoom: {
              yAxisIndex: "none",
            },
            restore: {},
            saveAsImage: {},
          },
        },
        xAxis: {
          data: xAxisData,
          show: false,
          boundaryGap: false,
          smooth: true,
          axisLine: { onZero: true },
        },
        yAxis: {
          axisTick: {
            show: false, // 不显示坐标轴刻度线
          },
          type: "value",
          boundaryGap: false,
          smooth: true,
        },
        dataZoom: [
          {
            type: "inside",
            start: 0,
            end: 20,
          },
          {
            start: 0,
            end: 20,
          },
        ],
        series: [
          {
            symbol: "none",
            name: _this.daolian[0],
            type: "line",

            data: _this.list1,
            smooth: true,

            lineStyle: {
              color: "#0770FF",
            },
            markPoint : {//数据全是markPoint
        	                symbolSize: 20,       // 标注大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize * 2
        	                // itemStyle: {
        	                //     normal: {
        	                //         borderColor: '#1e90ff',
        	                //         borderWidth: 1,            // 标注边线线宽,单位px,默认为1
        	                //         label: {
        	                //             show: false
        	                //         }
        	                //     },
        	                //     emphasis: {
        	                //         borderColor: '#1e90ff',
        	                //         borderWidth: 5,
        	                //         label: {
        	                //             show: false
        	                //         }
        	                //     }
        	                // },
        	                // effect : {
        	                //     show: true,
        	                //     shadowBlur : 0
        	                // },
                          label: {
                show: true
            },
                          // data:[{
                          //   xAxis: '0.5',
                          //   yAxis: '-0.315',
                          // }]
        	                data: (function() {
                  const dat = [[]];
                  let len = _this.list4.length;
                  while (len--) {
                    dat.push({
                      xAxis: _this.list6[len],
                      yAxis: _this.list1[_this.list6[len]],
                      value: _this.s[len]
                    })
                  }
                  // dat.push({
                  //     xAxis: [0.05, 0.2139, 1.0278, 1.8389, 2.6278, 3.4194, 4.2083, 5.025, 5.6778, 6.6722, 7.5167, 8.3278, 9.1167, 9.8889],
                  //     yAxis: [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,0.9,0.8,0.7,0.6,0.5],
                  //   })
                  return dat
                })()
        	            },//end markPoint
          },
          {
            symbol: "none",
            name: _this.daolian[1],
            type: "line",
            data: _this.list2,
            smooth: true,
            lineStyle: {
              color: "#F2597F",
            },
            markPoint : {
              symbolSize: 20,   
                          label: {
                show: true
            },
        	                data: (function() {
                  const dat = [[]];
                  let len = _this.list4.length;
                  while (len--) {
                    dat.push({
                      xAxis: _this.list6[len],
                      yAxis: _this.list2[_this.list6[len]],
                      value: _this.s[len]
                    })
                  }
                  return dat
                })()
        	            },//end markPoint
          },
        ],
      };

      option && myChart.setOption(option);
    },
  },
};
</script>
  
  
  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值