As a background of making a frequency analysis application this time, in the laboratory of the university I belong to, there are multiple groups studying pulse waves and electrocardiograms, but software for analyzing them ( The current situation is that there is only one PC with WaveLab paid software). Due to this situation, when one group is using the software, another group cannot be analyzed, so I decided to make it myself. Also, if frequency analysis can be performed online, it will be very convenient because it will be possible to perform analysis anywhere as long as you are connected to the Internet without having to install software.
I used Python to create this web application. The reason is that I wanted to create it using Numpy and Scipy, which are famous libraries in Python. These two libraries have a lot of functions for frequency analysis, so we will create them using them. The reason I used Django in the framework was because I thought that Python's FW was Django, so I used it.
Create a module for analyzing pulse waves and electrocardiograms. The module name is analysis.py.
analysis.py
import io
import pathlib
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
from .models import Pulse_Rate
def setPlt(pk):
#Get target data
pulse_rate = Pulse_Rate.objects.get(pk=pk)
path = pathlib.Path(pulse_rate.data.url)
#Read data
f = open(path.resolve())
lines = f.read().split()
# -----Variable preparation-----
N = 4096
lines_length = int(len(lines) / 2)
if lines_length < N:
N = 2048
dt = float(lines[2]) - float(lines[0])
pulse = []
for num in range(N - 1):
pulse.append(float(lines[num * 2 + 1]))
# -------------------
# -----Sampling frequency calculation-----
t = np.arange(0, N * dt, dt) # time
freq = np.linspace(0, 1.0 / dt, N) # frequency step
# -----------------------------
# -----Waveform generation-----
y = 0
for pl in pulse:
y += np.sin(2 * np.pi * pl * t)
# -------------------
# -----Fourier transform-----
yf = np.fft.fft(y) #Fast Fourier transform
# --------------------
#Power spectrum calculation
yf_abs = np.abs(yf)
# -----Graph generation-----
plt.figure()
plt.subplot(211)
plt.plot(t, y)
plt.xlabel("time")
plt.ylabel("amplitude")
plt.grid()
plt.subplot(212)
plt.plot(freq, yf_abs)
plt.xlim(0, 10)
plt.xlabel("frequency")
plt.ylabel("amplitude")
plt.grid()
plt.tight_layout()
A pulse wave or electrocardiogram graph and a power spectrum graph are generated like this. The data is read from the text file uploaded by the user.
In the module above, we are creating a graph with plot, so I would like to display this on a web page in svg format.
analysis.py
def pltToSvg():
buf = io.BytesIO()
plt.savefig(buf, format='svg', bbox_inches='tight')
s = buf.getvalue()
buf.close()
return s
Now you can convert the plot to svg and display it on your web page.
Write views.py using the above module.
views.py
def get_svg(request, pk):
setPlt(pk) # create the plot
svg = pltToSvg() # convert plot to SVG
response = HttpResponse(svg, content_type='image/svg+xml')
return response
This will return a response in HttpResponse (svg format).
Set the URL.
urls.py
urlpatterns = [
...
path('pulse_rate-detail/<int:pk>/plot/', views.get_svg, name="plot"),
]
I would like to make the page that displays the graph this time a detail screen.
pulse_rate_detail.html
<img src="{% url 'pulse_rate:plot' object.pk %}" width=600, height=300>
You can now view the graph.
The graph that can be actually created is as follows.
The figure above is a graph of unfiltered data, so you can't see anything as it is. Therefore, I added a filtering function to generate a graph. (I will omit the code) When you apply the filter, a pulse-like waveform appears. (Since this pulse wave is output using the G component of the RGB value taken by the camera, it will not be a perfect waveform.) The lower and upper frequencies of the filter can be adjusted by yourself from the web page.
The application created this time will be used in the laboratory in the future. Also, in the laboratory I belong to, there are groups that are doing research other than electrocardiogram and pulse wave, so I would like to create something for those groups as well. In fact, my research theme is to measure a person's stress level from the temperature of the person's nose.
I want to make my laboratory the coolest laboratory in the university, so I want to create such an application even in the 4th grade!
Recommended Posts