---
tags: 偏鄉醫療進度報告
---
# 2022/07/28 偏鄉醫療進度報告
> 林興政、劉彥汝
## Heartpy相關資料整理
> https://hackmd.io/-TDtPG76T0aWMSs8z5EW2Q?view#Heartpy%E5%A5%97%E4%BB%B6%E4%BB%8B%E7%B4%B9%E5%8F%8A%E6%95%B4%E7%90%86
### 小結:
> 1. 之前了解可以透過移動平均線去標記最高點,但是有些點是並不是需要分析的
> 2. 為了過濾不必要的點,需要將心跳間隔的時間序列用==傅立葉變換==轉換成頻域去分析
> 3. Frequency Domain中的高頻區(HF 0.15-0.40赫茲)反映副交感神經的活性及低頻區(LF 0.04-0.15赫茲)同時受到交感與副交感神經系統的調控 -> 是否能判斷測試者當下的健康狀態?
> 4. 預計採用[巴特沃斯濾波器(Butterworth)](https://zh.wikipedia.org/wiki/%E5%B7%B4%E7%89%B9%E6%B2%83%E6%96%AF%E6%BB%A4%E6%B3%A2%E5%99%A8)(目前正在看相關資料)來過濾不必要的peak
> 5. 預計接下來要繼續完成最後的步驟與實際套用
## 心跳分析(前處理)
### 1. 手指按壓在鏡頭上並打開手電筒的影片 -> 可以很明顯觀察到亮暗變化
[影片連結](https://youtu.be/OMMcrgaHm5E)
> 1m01s
### 2. 把影片拆成一幀一幀的截圖並轉成灰階照片 -> 較好量化
> 總共有1451張
```python
import numpy as np
import cv2
def get_images_from_video(video_name, time_F):
video_images = []
vc = cv2.VideoCapture(video_name)
c = 1
if vc.isOpened(): #判斷是否開啟影片
rval, video_frame = vc.read()
else:
rval = False
while rval: #擷取影片至結束
rval, video_frame = vc.read()
if(c % time_F == 0): #每隔幾幀進行擷取
video_images.append(video_frame)
c = c + 1
vc.release()
cv2.destroyAllWindows
return video_images
time_F = 1 # time_F越小,取樣張數越多
video_name = 'blood.mp4' # 影片名稱
video_images = get_images_from_video(video_name, time_F) # 讀取影片並轉成圖片
for i in range(0, len(video_images) - 1): # 顯示出所有擷取之圖片並儲存進screenshot
bgr2gray = cv2.cvtColor(video_images[i], cv2.COLOR_BGR2GRAY) # 轉成灰階 -> 較好分析
# cv2.imshow('windows', bgr2gray)
cv2.imwrite('./screenshot/output' + str(i + 1) + '.jpg', bgr2gray, [cv2.IMWRITE_JPEG_QUALITY, 100])
cv2.waitKey(1)
cv2.destroyAllWindows
```

### 3. 算出每一張照片的灰階平均值
```python
def average_pixel(blood_img):
r, c = blood_img.shape[:2]
average = 0
for row in blood_img:
for column in row:
# print(column)
average = average + column
average = average / (r * c) * 1.0
average = format(average, '.2f')
# print('average = ', average)
return average
gray_value = [0] * 1452
for i in range(1, 1452):
blood_img = cv2.imread('./screenshot/output' + str(i) + '.jpg', cv2.IMREAD_GRAYSCALE)
#gray_value[i - 1] = int(float(average_pixel(blood_img))) * 10
gray_value[i - 1] = int(float(average_pixel(blood_img)) * 10)
print('gray_value', i-1, ' = ', gray_value[i - 1])
```

### 4. 利用matplot畫出波形圖,並加入移動平均線
```python
y_set = [0] * 1451
for i in range(1451):
y_set[i] = i / 25.0
def plot_MA_curve(gray):
# Data
plt.figure(figsize = (20, 5), dpi=100,linewidth = 2)
plt.plot(y_set, gray[:1451], label="gray")
plt.title('Heart Rate Signal (60s)')
plt.show()
# MA 移動平均線 (15)
plt.figure(figsize = (20, 5), dpi=100,linewidth = 2)
df = pd.DataFrame(gray[:1451], y_set)
MA = df.rolling(15).mean()
plt.plot(MA, label="ma", color='red')
plt.show()
# MA 移動平均線 (50)
plt.figure(figsize = (20, 5), dpi=100,linewidth = 2)
df = pd.DataFrame(gray[:1451], y_set)
MA = df.rolling(50).mean()
plt.plot(MA, label="ma", color='orange')
plt.show()
# combine
plt.figure(figsize = (20, 5), dpi=100,linewidth = 2)
plt.plot(y_set, gray[:1451], label="gray")
plt.title('Heart Rate Signal (60s)')
df = pd.DataFrame(gray[:1451], y_set)
MA = df.rolling(15).mean()
plt.plot(MA, label="ma", color='red')
df2 = pd.DataFrame(gray[:1451], y_set)
MA2 = df2.rolling(50).mean()
plt.plot(MA2, label="ma2", color='orange')
plt.show()
plot_MA_curve(gray_value)
```




### 5. 設定好區間,選出其中的最高峰,就可以找到peaks了
```python
peaks = []
gap = 23
for i in range(0, 1450, gap):
loc = np.where(gray_value[i:i+gap] == np.max(gray_value[i:i+gap]))
print(i + int(loc[0][0]), ' : ', gray_value[int(loc[0][0])])
peaks.append(i + int(loc[0][0]))
print('peaks: ', len(peaks))
def plot_annotate(gray, peaks):
# Data
plt.figure(figsize = (20, 5), dpi=100,linewidth = 2)
plt.plot(y_set, gray[:1451], label="gray")
plt.title('Heart Rate Signal (60s)')
for i in range(len(peaks)):
plt.plot(y_set[peaks[i]], gray[peaks[i]], 'ks')
plt.show()
plot_annotate(gray_value, peaks)
```

### 小結:
> 1. 目前測試可以發現肉眼可見的明暗變化,轉成灰階並量化也可呈現明確的週期性
> 2. 目前遇到的問題是Heartpy還有很多相關資料還沒看完,目前還不知道如何將數據套入Heartpy
> 3. 我們有試過求移動平均線的方法標記peak,不過有些點應該要捨棄
## 未來方向與規劃

如果結果準確可以考慮[透過人臉來量測心跳](https://pdf.hanspub.org/HJBM20190300000_63336771.pdf)

<br>