├── README.md ├── bin └── QRS.class └── src └── QRS.java /README.md: -------------------------------------------------------------------------------- 1 | QRS_algorithm 2 | ============= 3 | 4 | HC Chen, SW Chen , "A Moving Average based Filtering System with its Application to Real-time QRS Detection " , Computers in Cardiology, 2003 5 | -------------------------------------------------------------------------------- /bin/QRS.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cc79128/QRS_algorithm/bdb44dfe5c646490481f106e5bcea4fe2181145f/bin/QRS.class -------------------------------------------------------------------------------- /src/QRS.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.BufferedWriter; 3 | import java.io.FileNotFoundException; 4 | import java.io.FileReader; 5 | import java.io.FileWriter; 6 | import java.io.IOException; 7 | import java.util.ArrayList; 8 | 9 | public class QRS { 10 | 11 | public static final int M = 5; 12 | 13 | public static void main(String[] args) throws IOException { 14 | 15 | //CSV檔 16 | ArrayList data_list = readCSVToArrayList("/Users/mac/Desktop/samples.csv"); //檔案位置 17 | 18 | int nsamp = data_list.size()-2; 19 | float[] sig0 = new float[nsamp]; 20 | for(int i=2;i readCSVToArrayList(String csvpath) { 78 | 79 | /** 80 | * 讀取csv檔,回傳ArrayList,裡面的每一個元素都是另一個ArrayList,其中存放每個單列的資料 81 | * @param csvpath csv路徑 82 | * @return ArrayList,裡面的每一個元素都是一個ArrayList,其中存放每個單列的資料 83 | */ 84 | //存放所有檔案內容 85 | ArrayList dataAL = new ArrayList(); 86 | 87 | //讀取檔案 88 | BufferedReader reader; 89 | try { 90 | reader = new BufferedReader(new FileReader(csvpath)); 91 | //reader.readLine();// 是否讀取第一行 (加上註解代表會讀取,註解拿掉不會讀取) 92 | String line = null;// 暫存用(測試是否已讀完檔) 93 | 94 | int line_num = 0; 95 | // 讀取資料 96 | while ((line = reader.readLine()) != null) { 97 | 98 | String item[] = line.split(",");//csv文件為依據逗號切割 99 | 100 | //讀檔(單列資料) 101 | dataAL.add(item[1]); 102 | 103 | //dataAL.add(ticketStr); 104 | System.out.println(dataAL.get(line_num)); 105 | line_num++; 106 | } 107 | System.out.println(dataAL.size()); 108 | //System.out.print(ticketStr.toString()); 109 | 110 | } catch (FileNotFoundException e) { 111 | // TODO Auto-generated catch block 112 | e.printStackTrace(); 113 | } catch (IOException e) { 114 | // TODO Auto-generated catch block 115 | e.printStackTrace(); 116 | } 117 | 118 | return dataAL; 119 | } 120 | 121 | //===============High Pass Filter================================ 122 | // M是Window size, 5 or 7是較好的選擇(取奇數) 123 | // y1:前M個值(包括自己)加總除以M 124 | // y2:Group delay (M+1/2) 125 | 126 | public static float[] highPass(float[] sig0, int nsamp) { //nsamp: data數量 127 | float[] highPass = new float[nsamp]; 128 | float constant = (float) 1/M; 129 | 130 | for(int i=0; ii-M; j--) { 142 | int x_index = i - (i-j); 143 | if(x_index < 0) { 144 | x_index = nsamp + x_index; 145 | } 146 | y1_sum += sig0[x_index]; 147 | } 148 | 149 | y1 = constant * y1_sum; //constant = 1/M 150 | highPass[i] = y2 - y1; 151 | } 152 | 153 | return highPass; 154 | } 155 | 156 | //============Low pass filter================== 157 | //Non Linear 158 | //平方->加總 159 | public static float[] lowPass(float[] sig0, int nsamp) { 160 | float[] lowPass = new float[nsamp]; 161 | for(int i=0; i= sig0.length) { //超過array 170 | int over = i+30 - sig0.length; 171 | for(int j=i; j treshold) { 202 | treshold = lowPass[i]; 203 | } 204 | } 205 | 206 | int frame = 250; //window size 取前250個中最大的值當PEAK 207 | 208 | for(int i=0; i lowPass.length) { //如果超過則為最後一個 212 | index = lowPass.length; 213 | } 214 | else { 215 | index = i + frame; 216 | } 217 | for(int j=i; j max) max = lowPass[j]; //250個data中的最大值 219 | } 220 | boolean added = false; 221 | for(int j=i; j treshold && !added) { 223 | QRS[j] = 1; //找到R點,250個裡面就不再繼續找 (約0.5秒) 224 | //若之後改成real time則frame可以改為1 225 | added = true; 226 | } 227 | else { 228 | QRS[j] = 0; 229 | } 230 | } 231 | double gama = (Math.random() > 0.5) ? 0.15 : 0.20; 232 | double alpha = 0.01 + (Math.random() * ((0.1 - 0.01))); 233 | 234 | treshold = alpha * gama * max + (1 - alpha) * treshold; 235 | } 236 | 237 | return QRS; 238 | } 239 | 240 | } --------------------------------------------------------------------------------