Disini saya akan mengimplementasikan beberapa kode pemrosesan sinyal EEG. Kode ini tentang cara mengubah sinyal sinusoidal menjadi gambar.
- Wavelet Transform: Mengubah sinyal menjadi wavelet untuk analisis frekuensi dan lokasi. Ini efektif dalam membedakan sinyal yang memiliki perubahan frekuensi cepat.
- Spectrogram: Menggunakan Fast Fourier Transform (FFT) untuk mengkonversi sinyal ke domain frekuensi. Ini menghasilkan representasi waktu-frekuensi yang bisa divisualisasikan sebagai gambar.
- Scalogram: Mirip dengan spectrogram tapi menggunakan Continuous Wavelet Transform (CWT). Memberikan representasi waktu-frekuensi yang lebih detail untuk analisis sinyal non-stasioner.
- Time-Frequency Representations: Kombinasi analisis waktu dan frekuensi, seperti Short-Time Fourier Transform (STFT), untuk menghasilkan gambar yang mewakili kedua aspek sinyal.
- Feature Extraction and Mapping: Mengidentifikasi ciri-ciri penting dalam sinyal dan memetakan ciri tersebut ke dalam representasi visual.
- Signal Plotting: Cara sederhana memvisualisasikan sinyal dengan memplotnya terhadap waktu. Ini biasanya menunjukkan amplitudo sinyal seiring berjalannya waktu.
Saya menggunakan dataset yang dapat ditemukan di: https://physionet.org/content/chbmit/1.0.0/chb01/#files-panel
saat ini saya hanya menggunakan salah satu data saja yaitu data chb01_01.edf yang dapat anda temukan di https://physionet.org/content/chbmit/1.0.0/chb01/chb01_01.edf
In [5]:
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import spectrogram
def generate_random_signal_with_transforms(length, fs, freq_range):
"""
Fungsi untuk membangkitkan sinyal analog acak dan melakukan Wavelet Transform serta FFT Spectrogram.
Parameters:
length (int): Panjang sinyal dalam detik.
fs (int): Frekuensi sampling.
freq_range (tuple): Rentang frekuensi minimum dan maksimum dalam Hz.
Returns:
Tuple(numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray):
Sinyal analog yang dibangkitkan, array waktu, koefisien wavelet, skala, frekuensi FFT, waktu FFT.
"""
# Membangkitkan sinyal
t = np.linspace(0, length, int(fs * length), endpoint=False)
frequencies = np.random.uniform(freq_range[0], freq_range[1], size=(3,))
signal = sum(np.sin(2 * np.pi * f * t) for f in frequencies)
# Melakukan Continuous Wavelet Transform (CWT)
scales = np.arange(1, 128)
cwt_coefficients, _ = pywt.cwt(signal, scales, 'mexh')
# Melakukan FFT Spectrogram
fft_frequencies, fft_times, Sxx = spectrogram(signal, fs)
return signal, t, cwt_coefficients, scales, fft_frequencies, fft_times, Sxx
# Contoh penggunaan fungsi
fs = 1000 # Frekuensi sampling 1000 Hz
length = 2 # Panjang sinyal 2 detik
freq_range = (10, 100) # Rentang frekuensi antara 5 Hz hingga 50 Hz
# Contoh penggunaan fungsi dengan Wavelet Transform dan FFT Spectrogram
signal, t, cwt_coefficients, scales, fft_frequencies, fft_times, Sxx = generate_random_signal_with_transforms(length, fs, freq_range)
# Menambahkan visualisasi heatmap dan histogram
# Menghitung heatmap dan histogram
heatmap, xedges, yedges = np.histogram2d(t, signal, bins=50)
hist, bin_edges = np.histogram(signal, bins=50)
# Plot sinyal, Wavelet Transform, FFT Spectrogram, heatmap, dan histogram
fig, axs = plt.subplots(5, 1, figsize=(12, 20))
# Membuat koordinat 3D untuk visualisasi
X, Y = np.meshgrid(t, scales)
coefficients, frequencies = pywt.cwt(signal, scales, 'mexh')
Z = coefficients
# Plot sinyal asli
axs[0].plot(t, signal)
axs[0].set_title('Analog Signal')
axs[0].set_xlabel('Time [seconds]')
axs[0].set_ylabel('Amplitude')
# Plot Wavelet Transform
axs[1].pcolormesh(X, Y, cwt_coefficients, shading='gouraud', cmap='viridis')
axs[1].set_title('Visualisasi Transformasi Wavelet')
axs[1].set_xlabel('Time [seconds]')
axs[1].set_ylabel('Scale')
fig.colorbar(axs[1].pcolormesh(X, Y, cwt_coefficients, shading='gouraud', cmap='viridis'), ax=axs[1], label='Coefficient')
# Plot FFT Spectrogram
axs[2].pcolormesh(fft_times, fft_frequencies, 10 * np.log10(Sxx), shading='gouraud', cmap='plasma')
axs[2].set_ylabel('Frequency [Hz]')
axs[2].set_xlabel('Time [sec]')
axs[2].set_title('Visualisasi Spectrogram menggunakan FFT')
fig.colorbar(axs[2].pcolormesh(fft_times, fft_frequencies, 10 * np.log10(Sxx), shading='gouraud', cmap='plasma'), ax=axs[2], label='Intensity [dB]')
# Plot Heatmap
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
axs[3].imshow(heatmap.T, extent=extent, origin='lower', cmap='hot', aspect='auto')
axs[3].set_title('Heatmap dari sinyal')
axs[3].set_xlabel('Time [seconds]')
axs[3].set_ylabel('Amplitude')
# Plot Histogram
axs[4].bar(bin_edges[:-1], hist, width=np.diff(bin_edges), edgecolor='black')
axs[4].set_title('Histogram dari Sinyal')
axs[4].set_xlabel('Amplitude')
axs[4].set_ylabel('Frequency')
plt.tight_layout()
plt.show()
In [7]:
import mne
# Menentukan lokasi file .edf
file_path = 'chb01_01.edf'
# Membaca data dari file .edf
raw_data = mne.io.read_raw_edf(file_path, preload=True)
# Daftar semua nama channel
print("Available channels:", raw_data.ch_names)
scalings = {'eeg': 550e-6}
# Visualisasi data
plot = raw_data.plot(show=False) # Set 'show' ke True jika menjalankan secara lokal
# Menampilkan informasi dasar tentang data
print(raw_data.info)
Extracting EDF parameters from /Users/shiroamachi/chb01_01.edf... EDF file detected Setting channel info structure... Creating raw.info structure... Reading 0 ... 921599 = 0.000 ... 3599.996 secs...
/var/folders/m4/nbjk_4dn1cl6tzt14mn7dc100000gn/T/ipykernel_31201/1809506098.py:8: RuntimeWarning: Channel names are not unique, found duplicates for: {'T8-P8'}. Applying running numbers for duplicates. raw_data = mne.io.read_raw_edf(file_path, preload=True)
Available channels: ['FP1-F7', 'F7-T7', 'T7-P7', 'P7-O1', 'FP1-F3', 'F3-C3', 'C3-P3', 'P3-O1', 'FP2-F4', 'F4-C4', 'C4-P4', 'P4-O2', 'FP2-F8', 'F8-T8', 'T8-P8-0', 'P8-O2', 'FZ-CZ', 'CZ-PZ', 'P7-T7', 'T7-FT9', 'FT9-FT10', 'FT10-T8', 'T8-P8-1'] <Info | 8 non-empty values bads: [] ch_names: FP1-F7, F7-T7, T7-P7, P7-O1, FP1-F3, F3-C3, C3-P3, P3-O1, ... chs: 23 EEG custom_ref_applied: False highpass: 0.0 Hz lowpass: 128.0 Hz meas_date: 2076-11-06 11:42:54 UTC nchan: 23 projs: [] sfreq: 256.0 Hz subject_info: 1 item (dict) >
In [8]:
import mne
# Menentukan lokasi file .edf
file_path = 'chb01_01.edf'
# Membaca data dari file .edf
raw_data = mne.io.read_raw_edf(file_path, preload=True)
# Daftar semua nama channel
print("Available channels:", raw_data.ch_names)
scalings = {'eeg': 550e-6}
# Pilih channel yang ingin Anda visualisasikan, misalnya 'FP1'
selected_channel = 'FP1-F7'
# Memplot hanya channel tertentu
raw_data.plot(duration=60, n_channels=1, order=[1], scalings=scalings, show=True)
# Menampilkan informasi dasar tentang data
print(raw_data.info)
Extracting EDF parameters from /Users/shiroamachi/chb01_01.edf... EDF file detected Setting channel info structure... Creating raw.info structure... Reading 0 ... 921599 = 0.000 ... 3599.996 secs...
/var/folders/m4/nbjk_4dn1cl6tzt14mn7dc100000gn/T/ipykernel_31201/3082723664.py:8: RuntimeWarning: Channel names are not unique, found duplicates for: {'T8-P8'}. Applying running numbers for duplicates. raw_data = mne.io.read_raw_edf(file_path, preload=True)
Available channels: ['FP1-F7', 'F7-T7', 'T7-P7', 'P7-O1', 'FP1-F3', 'F3-C3', 'C3-P3', 'P3-O1', 'FP2-F4', 'F4-C4', 'C4-P4', 'P4-O2', 'FP2-F8', 'F8-T8', 'T8-P8-0', 'P8-O2', 'FZ-CZ', 'CZ-PZ', 'P7-T7', 'T7-FT9', 'FT9-FT10', 'FT10-T8', 'T8-P8-1']
<Info | 8 non-empty values bads: [] ch_names: FP1-F7, F7-T7, T7-P7, P7-O1, FP1-F3, F3-C3, C3-P3, P3-O1, ... chs: 23 EEG custom_ref_applied: False highpass: 0.0 Hz lowpass: 128.0 Hz meas_date: 2076-11-06 11:42:54 UTC nchan: 23 projs: [] sfreq: 256.0 Hz subject_info: 1 item (dict) >
In [9]:
import mne
import matplotlib.pyplot as plt
# Path ke file .edf
file_path = 'chb01_01.edf'
# Membaca data dari file .edf
raw = mne.io.read_raw_edf(file_path, preload=True)
# Pilih channel yang ingin Anda visualisasikan
selected_channel = 'FP1-F7'
channel_index = raw.ch_names.index(selected_channel)
# Ekstrak data dari channel tertentu
data, times = raw[selected_channel]
# Membuat plot dengan ukuran figure yang diinginkan
plt.figure(figsize=(15, 5)) # Lebar 15 inci dan tinggi 5 inci
plt.plot(times, data.T)
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.title(f'EEG Data - Channel: {selected_channel}')
plt.show()
Extracting EDF parameters from /Users/shiroamachi/chb01_01.edf... EDF file detected Setting channel info structure... Creating raw.info structure... Reading 0 ... 921599 = 0.000 ... 3599.996 secs...
/var/folders/m4/nbjk_4dn1cl6tzt14mn7dc100000gn/T/ipykernel_31201/351647700.py:8: RuntimeWarning: Channel names are not unique, found duplicates for: {'T8-P8'}. Applying running numbers for duplicates. raw = mne.io.read_raw_edf(file_path, preload=True)
In [10]:
import mne
import matplotlib.pyplot as plt
# Path ke file .edf
file_path = 'chb01_01.edf'
# Membaca data dari file .edf
raw = mne.io.read_raw_edf(file_path, preload=True)
# Tentukan channel yang ingin Anda visualisasikan
selected_channels = ['FP1-F7', 'F7-T7', 'T7-P7'] # Contoh: Menampilkan channel 'FP1', 'FP2', dan 'T8'
# Membuat figure dan axes
fig, axes = plt.subplots(len(selected_channels), 1, figsize=(15, 5 * len(selected_channels)))
# Loop melalui setiap channel yang dipilih dan plot data
for i, ch in enumerate(selected_channels):
data, times = raw[ch]
axes[i].plot(times, data.T)
axes[i].set_title(f'Channel: {ch}')
axes[i].set_xlabel('Time (s)')
axes[i].set_ylabel('Amplitude')
plt.tight_layout()
plt.show()
Extracting EDF parameters from /Users/shiroamachi/chb01_01.edf... EDF file detected Setting channel info structure... Creating raw.info structure... Reading 0 ... 921599 = 0.000 ... 3599.996 secs...
/var/folders/m4/nbjk_4dn1cl6tzt14mn7dc100000gn/T/ipykernel_31201/3356979345.py:8: RuntimeWarning: Channel names are not unique, found duplicates for: {'T8-P8'}. Applying running numbers for duplicates. raw = mne.io.read_raw_edf(file_path, preload=True)
In [ ]: