
Lab Streaming Layer (LSL) để đồng bộ hóa nhiều luồng dữ liệu
Tiến sĩ Roshini Randeniya và Lucas Kleine
Đã cập nhật vào
17 thg 5, 2024

Lab Streaming Layer (LSL) để đồng bộ hóa nhiều luồng dữ liệu
Tiến sĩ Roshini Randeniya và Lucas Kleine
Đã cập nhật vào
17 thg 5, 2024

Lab Streaming Layer (LSL) để đồng bộ hóa nhiều luồng dữ liệu
Tiến sĩ Roshini Randeniya và Lucas Kleine
Đã cập nhật vào
17 thg 5, 2024
Chào mừng! Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách sử dụng Lab Streaming Layer (LSL) trong Python để thu thập và đồng bộ hóa dữ liệu EEG Emotiv từ nhiều thiết bị. Điều này đòi hỏi bạn phải có kiến thức làm việc cơ bản về ngôn ngữ lập trình Python.
Những gì bạn sẽ học
Lab Streaming Layer (LSL) là gì và tại sao các nhà nghiên cứu lại sử dụng nó
Cách thu thập dữ liệu đồng bộ từ nhiều thiết bị EEG Emotiv
Cách nhập và kiểm tra dữ liệu đã thu thập
1.1 LSL là gì và nó có ích gì?
Lab streaming layer (LSL) là một bộ công cụ mã nguồn mở có thể được sử dụng để gửi, nhận & đồng bộ hóa các luồng dữ liệu thần kinh, sinh lý và hành vi từ nhiều phần cứng cảm biến khác nhau. Các thiết bị phần cứng cảm biến cơ thể và não bộ ngày càng có khả năng tốt hơn, chính xác và di động hơn (như hệ thống EEG Emotiv) đang đưa khoa học thần kinh ra ngoài phòng thí nghiệm vào thế giới dữ liệu thời gian thực. Trong khi các phép đo não như EEG và MEG từng bị giới hạn trong phòng thí nghiệm nghiên cứu, các thiết bị di động cho phép chúng ta thu thập nhiều dữ liệu trong môi trường tự nhiên hơn và từ nhiều người cùng một lúc.
Một nhà nghiên cứu có thể quan tâm đến sự đồng bộ sinh lý giữa hai người đang nghe cùng một bản nhạc. LSL có thể giúp chúng ta thu thập dữ liệu từ hai thiết bị đeo đầu EEG riêng biệt, dữ liệu này cũng được đồng bộ hóa với việc phát âm thanh.
Một số ví dụ về các công dụng khác của LSL:
Thêm các điểm đánh dấu sự kiện từ một thí nghiệm vào dữ liệu EEG đang diễn ra
Căn chỉnh thời gian dữ liệu từ nhiều nguồn cho một người tham gia duy nhất (ví dụ: nhịp tim, EMG, EEG)
Căn chỉnh thời gian dữ liệu từ nhiều người tham gia (ví dụ: Các nghiên cứu siêu quét EEG)
1.2 LSL hoạt động như thế nào?
Lab Streaming Layer là một giao thức để trao đổi dữ liệu chuỗi thời gian theo thời gian thực giữa nhiều thiết bị. LSL có thể được triển khai bằng cách sử dụng các thư viện mã nguồn mở cho các ngôn ngữ lập trình như Python, MATLAB, C++, Java và các ngôn ngữ khác.

Chức năng cốt lõi xoay quanh các luồng dữ liệu LSL:
1. Một thiết bị/phần mềm thu thập dữ liệu và tạo ra một luồng dữ liệu - Dữ liệu sinh lý có thể được truyền trực tuyến đến LSL từ các thiết bị ghi EEG, thiết bị theo dõi mắt, hệ thống ghi chuyển động, thiết bị theo dõi nhịp tim, v.v., bao gồm cả siêu dữ liệu (tốc độ lấy mẫu, loại dữ liệu, thông tin kênh, v.v.) - Các điểm đánh dấu sự kiện từ các thí nghiệm (ví dụ: sử dụng PsychoPy) cũng có thể được gửi dưới dạng luồng dữ liệu bằng LSL
2. Luồng dữ liệu được xuất bản lên mạng - Đây là cách dữ liệu được gửi bằng LSL; luồng dữ liệu được "phát sóng" lên mạng - Các luồng được xuất bản có sẵn trên mạng và có thể được phát hiện bởi các thiết bị hỗ trợ LSL khác trên cùng một mạng - LSL gán cho mỗi phân đoạn hoặc mẫu dữ liệu một nhãn thời gian dựa trên một đồng hồ chung (theo Giao thức thời gian mạng). - Luồng dữ liệu được đẩy theo từng mẫu (hoặc từng phân đoạn) qua một "cổng ra" (outlet)
3. (Các) thiết bị thu thập "đăng ký" các luồng dữ liệu - Đây là cách nhận dữ liệu bằng LSL - Các thiết bị thu thập trên cùng một mạng nhận các luồng dữ liệu được xuất bản thông qua "cổng vào" (inlets). - Mỗi cổng vào nhận các mẫu luồng và siêu dữ liệu chỉ từ một cổng ra
4. Lưu dữ liệu - Sau khi đăng ký một luồng dữ liệu, bạn có thể lưu nó vào một biến trong ngôn ngữ lập trình ưa thích của mình, hoặc sử dụng phần mềm hỗ trợ LabRecorder của LSL để lưu nó vào một định dạng tiêu chuẩn như .xdf.
2.0 Tổng quan về hướng dẫn
Trong hướng dẫn này, chúng tôi sẽ lấy một thiết lập thí nghiệm làm ví dụ và hướng dẫn bạn qua các bước và mã cần thiết để triển khai nó bằng LSL trong Python. Chúng ta sẽ sử dụng Python phát một âm thanh trong khi thu thập dữ liệu EEG từ hai người đang đeo thiết bị đeo đầu Emotiv. Chúng ta sẽ sử dụng hai máy tính, mỗi máy chạy EmotivPRO để thu thập dữ liệu EEG và phát sóng mỗi luồng qua một cổng ra LSL riêng biệt. Chúng ta sẽ sử dụng một thư viện Python để phát một tệp âm thanh và đồng thời gửi một kích hoạt mỗi khi tệp bắt đầu.
CÁC BƯỚC:
1. Sử dụng EmotivPRO để truyền dữ liệu qua các cổng ra LSL bao gồm dữ liệu EEG (và/hoặc chuyển động, chất lượng tiếp xúc, chất lượng tín hiệu, v.v.) 2. Phát một bản nhạc âm thanh bằng tập lệnh Python và đồng thời gửi một kích hoạt qua một LSL khác Sử dụng LabRecorder để ghi lại và lưu cả ba luồng dữ liệu qua một cổng vào LSL.

2.1 BƯỚC 1 - Thiết lập và cài đặt
Bạn sẽ cần các thiết bị thu thập dữ liệu được hỗ trợ để thu thập dữ liệu
• Tất cả thiết bị não bộ của Emotiv kết nối với LSL thông qua phần mềm EmotivPROCài đặt EmotivPRO trên (các) thiết bị của bạn. Bạn sẽ cần một giấy phép EmotivPRO hợp lệ để sử dụng LSL.
Cài đặt thư viện Python LSL bằng lệnh sau:
pip install pylslTải xuống phần mềm LabRecorder. Đây là một ứng dụng đơn giản, miễn phí có thể chạy từ
dòng lệnh hoặc sử dụng bản tải xuống độc lậpĐối với thí nghiệm của chúng ta: Cài đặt các gói cần thiết để phát âm thanh bằng Python
pip install sounddevice soundfile
2.2 BƯỚC 3 - Gửi dữ liệu từ EmotivPRO qua luồng LSL
Tìm biểu tượng “…” ở góc trên cùng bên phải của ứng dụng, điều hướng đến Cài đặt (Settings)
Tìm phần 'Lab Streaming Layer' và phần phụ 'Outlet'
Chọn tất cả các loại dữ liệu mà bạn muốn phát sóng
Chọn định dạng dữ liệu (số thực 32-bit float hoặc số thực dấu phẩy động kép 64-bit double)
Chọn gửi dữ liệu theo từng mẫu hay theo từng phân đoạn mẫu
Nhấp vào 'Start' để phát sóng một luồng dữ liệu LSL
2.3 BƯỚC 4 - Sử dụng tập lệnh Python để phát âm thanh và gửi kích hoạt
Sao chép và dán khối mã sau vào một tệp python và lưu nó vào máy tính của bạn.
Tìm một tệp âm thanh (lý tưởng là tệp .wav) mà bạn muốn phát và chỉnh sửa tập lệnh bằng cách thay đổi
biếnaudio_filepaththành đường dẫn tệp đến tệp âm thanh của bạn trên máy tínhMở dấu nhắc lệnh để tương tác với dòng lệnh và điều hướng đến thư mục nơi
tệp Python của bạn được lưu trữNhập:
python3 filename.py
• Tùy thuộc vào bản cài đặt Python của bạn, bạn có thể sử dụngpythonthay vìpython3
Lưu ý: Thay thế/path/to/audio.wavbằng vị trí của tệp âm thanh bạn muốn phát trong quá trình thí nghiệm.
""" LSL Example: Play audio and send a trigger marker This script creates an LSL marker stream, waits for the user to press ENTER, then plays an audio file and sends a marker that can be synchronized with EEG data collected through LabRecorder. """ import sounddevice as sd import soundfile as sf from pylsl import StreamInfo, StreamOutlet def wait_for_keypress(): print("Press ENTER to start audio playback and send an LSL marker.") while True: if input() == "": break def play_audio_and_send_marker(audio_file, outlet): data, fs = sf.read(audio_file) print("Playing audio and sending LSL marker...") marker_val = [1] outlet.push_sample(marker_val) sd.play(data, fs) sd.wait() print("Audio playback finished.") if __name__ == "__main__": info = StreamInfo( name="AudioMarkers", type="Markers", channel_count=1, nominal_srate=0, channel_format="int32", source_id="uniqueMarkerID12345" ) outlet = StreamOutlet(info) while True: wait_for_keypress() audio_filepath = "/path/to/audio.wav" play_audio_and_send_marker( audio_filepath, outlet )
""" LSL Example: Play audio and send a trigger marker This script creates an LSL marker stream, waits for the user to press ENTER, then plays an audio file and sends a marker that can be synchronized with EEG data collected through LabRecorder. """ import sounddevice as sd import soundfile as sf from pylsl import StreamInfo, StreamOutlet def wait_for_keypress(): print("Press ENTER to start audio playback and send an LSL marker.") while True: if input() == "": break def play_audio_and_send_marker(audio_file, outlet): data, fs = sf.read(audio_file) print("Playing audio and sending LSL marker...") marker_val = [1] outlet.push_sample(marker_val) sd.play(data, fs) sd.wait() print("Audio playback finished.") if __name__ == "__main__": info = StreamInfo( name="AudioMarkers", type="Markers", channel_count=1, nominal_srate=0, channel_format="int32", source_id="uniqueMarkerID12345" ) outlet = StreamOutlet(info) while True: wait_for_keypress() audio_filepath = "/path/to/audio.wav" play_audio_and_send_marker( audio_filepath, outlet )
""" LSL Example: Play audio and send a trigger marker This script creates an LSL marker stream, waits for the user to press ENTER, then plays an audio file and sends a marker that can be synchronized with EEG data collected through LabRecorder. """ import sounddevice as sd import soundfile as sf from pylsl import StreamInfo, StreamOutlet def wait_for_keypress(): print("Press ENTER to start audio playback and send an LSL marker.") while True: if input() == "": break def play_audio_and_send_marker(audio_file, outlet): data, fs = sf.read(audio_file) print("Playing audio and sending LSL marker...") marker_val = [1] outlet.push_sample(marker_val) sd.play(data, fs) sd.wait() print("Audio playback finished.") if __name__ == "__main__": info = StreamInfo( name="AudioMarkers", type="Markers", channel_count=1, nominal_srate=0, channel_format="int32", source_id="uniqueMarkerID12345" ) outlet = StreamOutlet(info) while True: wait_for_keypress() audio_filepath = "/path/to/audio.wav" play_audio_and_send_marker( audio_filepath, outlet )
2.4 BƯỚC 5 - Sử dụng LabRecorder để xem và lưu tất cả các luồng LSL
Mở LabRecorder
Nhấn
Update. Các luồng LSL hiện có sẽ hiển thị trong danh sách luồng
• Bạn sẽ có thể thấy các luồng từ cả hai phần mềm EmotivPRO (thường được gọi là “Emotiv-
DataStream”) và luồng đánh dấu (được gọi là “AudioMarkers”)Nhấp vào
Browseđể chọn vị trí lưu trữ dữ liệu (và thiết lập các thông số khác)Chọn tất cả các luồng và nhấn
Recordđể bắt đầu ghi
3.0 Làm việc với dữ liệu
LabRecorder xuất ra một tệp XDF (Định dạng dữ liệu mở rộng - Extensible Data Format) chứa dữ liệu từ tất cả các luồng. Các tệp XDF được cấu trúc thành các luồng, mỗi luồng có một phần tiêu đề khác nhau mô tả những gì nó chứa (tên thiết bị, loại dữ liệu, tốc độ lấy mẫu, các kênh, v.v.). Bạn có thể sử dụng khối mã dưới đây để mở tệp XDF của mình và hiển thị một số thông tin cơ bản.
Lưu ý: Thay thế /path/to/your/file.xdf bằng đường dẫn tệp cho tệp đầu ra LabRecorder XDF của bạn.
import pyxdf import mne import matplotlib.pyplot as plt import numpy as np # Give the path to your LSL output file here. data_path = "/path/to/your/file.xdf" # Load the XDF file. streams, fileheader = pyxdf.load_xdf(data_path) print("XDF File Header:", fileheader) print("Number of streams found:", len(streams)) for i, stream in enumerate(streams): print("\nStream", i + 1) print("Stream Name:", stream["info"]["name"][0]) print("Stream Type:", stream["info"]["type"][0]) print("Number of Channels:", stream["info"]["channel_count"][0]) sfreq = float(stream["info"]["nominal_srate"][0]) print("Sampling Rate:", sfreq) print("Number of Samples:", len(stream["time_series"])) print("First 5 data points:", stream["time_series"][:5]) channel_names = [ chan["label"][0] for chan in stream["info"]["desc"][0]["channels"][0]["channel"] ] print("Channel Names:", channel_names) channel_types = "eeg"
import pyxdf import mne import matplotlib.pyplot as plt import numpy as np # Give the path to your LSL output file here. data_path = "/path/to/your/file.xdf" # Load the XDF file. streams, fileheader = pyxdf.load_xdf(data_path) print("XDF File Header:", fileheader) print("Number of streams found:", len(streams)) for i, stream in enumerate(streams): print("\nStream", i + 1) print("Stream Name:", stream["info"]["name"][0]) print("Stream Type:", stream["info"]["type"][0]) print("Number of Channels:", stream["info"]["channel_count"][0]) sfreq = float(stream["info"]["nominal_srate"][0]) print("Sampling Rate:", sfreq) print("Number of Samples:", len(stream["time_series"])) print("First 5 data points:", stream["time_series"][:5]) channel_names = [ chan["label"][0] for chan in stream["info"]["desc"][0]["channels"][0]["channel"] ] print("Channel Names:", channel_names) channel_types = "eeg"
import pyxdf import mne import matplotlib.pyplot as plt import numpy as np # Give the path to your LSL output file here. data_path = "/path/to/your/file.xdf" # Load the XDF file. streams, fileheader = pyxdf.load_xdf(data_path) print("XDF File Header:", fileheader) print("Number of streams found:", len(streams)) for i, stream in enumerate(streams): print("\nStream", i + 1) print("Stream Name:", stream["info"]["name"][0]) print("Stream Type:", stream["info"]["type"][0]) print("Number of Channels:", stream["info"]["channel_count"][0]) sfreq = float(stream["info"]["nominal_srate"][0]) print("Sampling Rate:", sfreq) print("Number of Samples:", len(stream["time_series"])) print("First 5 data points:", stream["time_series"][:5]) channel_names = [ chan["label"][0] for chan in stream["info"]["desc"][0]["channels"][0]["channel"] ] print("Channel Names:", channel_names) channel_types = "eeg"
4.0 Tài nguyên bổ sung
Tài liệu chính thức
Kiểm tra tài liệu trực tuyến, bao gồm cả tệp README chính thức trên GitHub
Tài nguyên bổ sung:
• Mã để chạy LSL bằng các thiết bị của Emotiv, kèm theo các tập lệnh ví dụ
• Video demo LSL hữu ích trên YouTube
• Kho lưu trữ GitHub SCCN LSL cho tất cả các thư viện liên quan
• Kho lưu trữ GitHub LSL cho một tập hợp các mô-đun phụ và ứng dụngQuy trình phân tích HyPyP cho các nghiên cứu siêu quét
Chào mừng! Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách sử dụng Lab Streaming Layer (LSL) trong Python để thu thập và đồng bộ hóa dữ liệu EEG Emotiv từ nhiều thiết bị. Điều này đòi hỏi bạn phải có kiến thức làm việc cơ bản về ngôn ngữ lập trình Python.
Những gì bạn sẽ học
Lab Streaming Layer (LSL) là gì và tại sao các nhà nghiên cứu lại sử dụng nó
Cách thu thập dữ liệu đồng bộ từ nhiều thiết bị EEG Emotiv
Cách nhập và kiểm tra dữ liệu đã thu thập
1.1 LSL là gì và nó có ích gì?
Lab streaming layer (LSL) là một bộ công cụ mã nguồn mở có thể được sử dụng để gửi, nhận & đồng bộ hóa các luồng dữ liệu thần kinh, sinh lý và hành vi từ nhiều phần cứng cảm biến khác nhau. Các thiết bị phần cứng cảm biến cơ thể và não bộ ngày càng có khả năng tốt hơn, chính xác và di động hơn (như hệ thống EEG Emotiv) đang đưa khoa học thần kinh ra ngoài phòng thí nghiệm vào thế giới dữ liệu thời gian thực. Trong khi các phép đo não như EEG và MEG từng bị giới hạn trong phòng thí nghiệm nghiên cứu, các thiết bị di động cho phép chúng ta thu thập nhiều dữ liệu trong môi trường tự nhiên hơn và từ nhiều người cùng một lúc.
Một nhà nghiên cứu có thể quan tâm đến sự đồng bộ sinh lý giữa hai người đang nghe cùng một bản nhạc. LSL có thể giúp chúng ta thu thập dữ liệu từ hai thiết bị đeo đầu EEG riêng biệt, dữ liệu này cũng được đồng bộ hóa với việc phát âm thanh.
Một số ví dụ về các công dụng khác của LSL:
Thêm các điểm đánh dấu sự kiện từ một thí nghiệm vào dữ liệu EEG đang diễn ra
Căn chỉnh thời gian dữ liệu từ nhiều nguồn cho một người tham gia duy nhất (ví dụ: nhịp tim, EMG, EEG)
Căn chỉnh thời gian dữ liệu từ nhiều người tham gia (ví dụ: Các nghiên cứu siêu quét EEG)
1.2 LSL hoạt động như thế nào?
Lab Streaming Layer là một giao thức để trao đổi dữ liệu chuỗi thời gian theo thời gian thực giữa nhiều thiết bị. LSL có thể được triển khai bằng cách sử dụng các thư viện mã nguồn mở cho các ngôn ngữ lập trình như Python, MATLAB, C++, Java và các ngôn ngữ khác.

Chức năng cốt lõi xoay quanh các luồng dữ liệu LSL:
1. Một thiết bị/phần mềm thu thập dữ liệu và tạo ra một luồng dữ liệu - Dữ liệu sinh lý có thể được truyền trực tuyến đến LSL từ các thiết bị ghi EEG, thiết bị theo dõi mắt, hệ thống ghi chuyển động, thiết bị theo dõi nhịp tim, v.v., bao gồm cả siêu dữ liệu (tốc độ lấy mẫu, loại dữ liệu, thông tin kênh, v.v.) - Các điểm đánh dấu sự kiện từ các thí nghiệm (ví dụ: sử dụng PsychoPy) cũng có thể được gửi dưới dạng luồng dữ liệu bằng LSL
2. Luồng dữ liệu được xuất bản lên mạng - Đây là cách dữ liệu được gửi bằng LSL; luồng dữ liệu được "phát sóng" lên mạng - Các luồng được xuất bản có sẵn trên mạng và có thể được phát hiện bởi các thiết bị hỗ trợ LSL khác trên cùng một mạng - LSL gán cho mỗi phân đoạn hoặc mẫu dữ liệu một nhãn thời gian dựa trên một đồng hồ chung (theo Giao thức thời gian mạng). - Luồng dữ liệu được đẩy theo từng mẫu (hoặc từng phân đoạn) qua một "cổng ra" (outlet)
3. (Các) thiết bị thu thập "đăng ký" các luồng dữ liệu - Đây là cách nhận dữ liệu bằng LSL - Các thiết bị thu thập trên cùng một mạng nhận các luồng dữ liệu được xuất bản thông qua "cổng vào" (inlets). - Mỗi cổng vào nhận các mẫu luồng và siêu dữ liệu chỉ từ một cổng ra
4. Lưu dữ liệu - Sau khi đăng ký một luồng dữ liệu, bạn có thể lưu nó vào một biến trong ngôn ngữ lập trình ưa thích của mình, hoặc sử dụng phần mềm hỗ trợ LabRecorder của LSL để lưu nó vào một định dạng tiêu chuẩn như .xdf.
2.0 Tổng quan về hướng dẫn
Trong hướng dẫn này, chúng tôi sẽ lấy một thiết lập thí nghiệm làm ví dụ và hướng dẫn bạn qua các bước và mã cần thiết để triển khai nó bằng LSL trong Python. Chúng ta sẽ sử dụng Python phát một âm thanh trong khi thu thập dữ liệu EEG từ hai người đang đeo thiết bị đeo đầu Emotiv. Chúng ta sẽ sử dụng hai máy tính, mỗi máy chạy EmotivPRO để thu thập dữ liệu EEG và phát sóng mỗi luồng qua một cổng ra LSL riêng biệt. Chúng ta sẽ sử dụng một thư viện Python để phát một tệp âm thanh và đồng thời gửi một kích hoạt mỗi khi tệp bắt đầu.
CÁC BƯỚC:
1. Sử dụng EmotivPRO để truyền dữ liệu qua các cổng ra LSL bao gồm dữ liệu EEG (và/hoặc chuyển động, chất lượng tiếp xúc, chất lượng tín hiệu, v.v.) 2. Phát một bản nhạc âm thanh bằng tập lệnh Python và đồng thời gửi một kích hoạt qua một LSL khác Sử dụng LabRecorder để ghi lại và lưu cả ba luồng dữ liệu qua một cổng vào LSL.

2.1 BƯỚC 1 - Thiết lập và cài đặt
Bạn sẽ cần các thiết bị thu thập dữ liệu được hỗ trợ để thu thập dữ liệu
• Tất cả thiết bị não bộ của Emotiv kết nối với LSL thông qua phần mềm EmotivPROCài đặt EmotivPRO trên (các) thiết bị của bạn. Bạn sẽ cần một giấy phép EmotivPRO hợp lệ để sử dụng LSL.
Cài đặt thư viện Python LSL bằng lệnh sau:
pip install pylslTải xuống phần mềm LabRecorder. Đây là một ứng dụng đơn giản, miễn phí có thể chạy từ
dòng lệnh hoặc sử dụng bản tải xuống độc lậpĐối với thí nghiệm của chúng ta: Cài đặt các gói cần thiết để phát âm thanh bằng Python
pip install sounddevice soundfile
2.2 BƯỚC 3 - Gửi dữ liệu từ EmotivPRO qua luồng LSL
Tìm biểu tượng “…” ở góc trên cùng bên phải của ứng dụng, điều hướng đến Cài đặt (Settings)
Tìm phần 'Lab Streaming Layer' và phần phụ 'Outlet'
Chọn tất cả các loại dữ liệu mà bạn muốn phát sóng
Chọn định dạng dữ liệu (số thực 32-bit float hoặc số thực dấu phẩy động kép 64-bit double)
Chọn gửi dữ liệu theo từng mẫu hay theo từng phân đoạn mẫu
Nhấp vào 'Start' để phát sóng một luồng dữ liệu LSL
2.3 BƯỚC 4 - Sử dụng tập lệnh Python để phát âm thanh và gửi kích hoạt
Sao chép và dán khối mã sau vào một tệp python và lưu nó vào máy tính của bạn.
Tìm một tệp âm thanh (lý tưởng là tệp .wav) mà bạn muốn phát và chỉnh sửa tập lệnh bằng cách thay đổi
biếnaudio_filepaththành đường dẫn tệp đến tệp âm thanh của bạn trên máy tínhMở dấu nhắc lệnh để tương tác với dòng lệnh và điều hướng đến thư mục nơi
tệp Python của bạn được lưu trữNhập:
python3 filename.py
• Tùy thuộc vào bản cài đặt Python của bạn, bạn có thể sử dụngpythonthay vìpython3
Lưu ý: Thay thế/path/to/audio.wavbằng vị trí của tệp âm thanh bạn muốn phát trong quá trình thí nghiệm.
""" LSL Example: Play audio and send a trigger marker This script creates an LSL marker stream, waits for the user to press ENTER, then plays an audio file and sends a marker that can be synchronized with EEG data collected through LabRecorder. """ import sounddevice as sd import soundfile as sf from pylsl import StreamInfo, StreamOutlet def wait_for_keypress(): print("Press ENTER to start audio playback and send an LSL marker.") while True: if input() == "": break def play_audio_and_send_marker(audio_file, outlet): data, fs = sf.read(audio_file) print("Playing audio and sending LSL marker...") marker_val = [1] outlet.push_sample(marker_val) sd.play(data, fs) sd.wait() print("Audio playback finished.") if __name__ == "__main__": info = StreamInfo( name="AudioMarkers", type="Markers", channel_count=1, nominal_srate=0, channel_format="int32", source_id="uniqueMarkerID12345" ) outlet = StreamOutlet(info) while True: wait_for_keypress() audio_filepath = "/path/to/audio.wav" play_audio_and_send_marker( audio_filepath, outlet )
2.4 BƯỚC 5 - Sử dụng LabRecorder để xem và lưu tất cả các luồng LSL
Mở LabRecorder
Nhấn
Update. Các luồng LSL hiện có sẽ hiển thị trong danh sách luồng
• Bạn sẽ có thể thấy các luồng từ cả hai phần mềm EmotivPRO (thường được gọi là “Emotiv-
DataStream”) và luồng đánh dấu (được gọi là “AudioMarkers”)Nhấp vào
Browseđể chọn vị trí lưu trữ dữ liệu (và thiết lập các thông số khác)Chọn tất cả các luồng và nhấn
Recordđể bắt đầu ghi
3.0 Làm việc với dữ liệu
LabRecorder xuất ra một tệp XDF (Định dạng dữ liệu mở rộng - Extensible Data Format) chứa dữ liệu từ tất cả các luồng. Các tệp XDF được cấu trúc thành các luồng, mỗi luồng có một phần tiêu đề khác nhau mô tả những gì nó chứa (tên thiết bị, loại dữ liệu, tốc độ lấy mẫu, các kênh, v.v.). Bạn có thể sử dụng khối mã dưới đây để mở tệp XDF của mình và hiển thị một số thông tin cơ bản.
Lưu ý: Thay thế /path/to/your/file.xdf bằng đường dẫn tệp cho tệp đầu ra LabRecorder XDF của bạn.
import pyxdf import mne import matplotlib.pyplot as plt import numpy as np # Give the path to your LSL output file here. data_path = "/path/to/your/file.xdf" # Load the XDF file. streams, fileheader = pyxdf.load_xdf(data_path) print("XDF File Header:", fileheader) print("Number of streams found:", len(streams)) for i, stream in enumerate(streams): print("\nStream", i + 1) print("Stream Name:", stream["info"]["name"][0]) print("Stream Type:", stream["info"]["type"][0]) print("Number of Channels:", stream["info"]["channel_count"][0]) sfreq = float(stream["info"]["nominal_srate"][0]) print("Sampling Rate:", sfreq) print("Number of Samples:", len(stream["time_series"])) print("First 5 data points:", stream["time_series"][:5]) channel_names = [ chan["label"][0] for chan in stream["info"]["desc"][0]["channels"][0]["channel"] ] print("Channel Names:", channel_names) channel_types = "eeg"
4.0 Tài nguyên bổ sung
Tài liệu chính thức
Kiểm tra tài liệu trực tuyến, bao gồm cả tệp README chính thức trên GitHub
Tài nguyên bổ sung:
• Mã để chạy LSL bằng các thiết bị của Emotiv, kèm theo các tập lệnh ví dụ
• Video demo LSL hữu ích trên YouTube
• Kho lưu trữ GitHub SCCN LSL cho tất cả các thư viện liên quan
• Kho lưu trữ GitHub LSL cho một tập hợp các mô-đun phụ và ứng dụngQuy trình phân tích HyPyP cho các nghiên cứu siêu quét
Chào mừng! Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách sử dụng Lab Streaming Layer (LSL) trong Python để thu thập và đồng bộ hóa dữ liệu EEG Emotiv từ nhiều thiết bị. Điều này đòi hỏi bạn phải có kiến thức làm việc cơ bản về ngôn ngữ lập trình Python.
Những gì bạn sẽ học
Lab Streaming Layer (LSL) là gì và tại sao các nhà nghiên cứu lại sử dụng nó
Cách thu thập dữ liệu đồng bộ từ nhiều thiết bị EEG Emotiv
Cách nhập và kiểm tra dữ liệu đã thu thập
1.1 LSL là gì và nó có ích gì?
Lab streaming layer (LSL) là một bộ công cụ mã nguồn mở có thể được sử dụng để gửi, nhận & đồng bộ hóa các luồng dữ liệu thần kinh, sinh lý và hành vi từ nhiều phần cứng cảm biến khác nhau. Các thiết bị phần cứng cảm biến cơ thể và não bộ ngày càng có khả năng tốt hơn, chính xác và di động hơn (như hệ thống EEG Emotiv) đang đưa khoa học thần kinh ra ngoài phòng thí nghiệm vào thế giới dữ liệu thời gian thực. Trong khi các phép đo não như EEG và MEG từng bị giới hạn trong phòng thí nghiệm nghiên cứu, các thiết bị di động cho phép chúng ta thu thập nhiều dữ liệu trong môi trường tự nhiên hơn và từ nhiều người cùng một lúc.
Một nhà nghiên cứu có thể quan tâm đến sự đồng bộ sinh lý giữa hai người đang nghe cùng một bản nhạc. LSL có thể giúp chúng ta thu thập dữ liệu từ hai thiết bị đeo đầu EEG riêng biệt, dữ liệu này cũng được đồng bộ hóa với việc phát âm thanh.
Một số ví dụ về các công dụng khác của LSL:
Thêm các điểm đánh dấu sự kiện từ một thí nghiệm vào dữ liệu EEG đang diễn ra
Căn chỉnh thời gian dữ liệu từ nhiều nguồn cho một người tham gia duy nhất (ví dụ: nhịp tim, EMG, EEG)
Căn chỉnh thời gian dữ liệu từ nhiều người tham gia (ví dụ: Các nghiên cứu siêu quét EEG)
1.2 LSL hoạt động như thế nào?
Lab Streaming Layer là một giao thức để trao đổi dữ liệu chuỗi thời gian theo thời gian thực giữa nhiều thiết bị. LSL có thể được triển khai bằng cách sử dụng các thư viện mã nguồn mở cho các ngôn ngữ lập trình như Python, MATLAB, C++, Java và các ngôn ngữ khác.

Chức năng cốt lõi xoay quanh các luồng dữ liệu LSL:
1. Một thiết bị/phần mềm thu thập dữ liệu và tạo ra một luồng dữ liệu - Dữ liệu sinh lý có thể được truyền trực tuyến đến LSL từ các thiết bị ghi EEG, thiết bị theo dõi mắt, hệ thống ghi chuyển động, thiết bị theo dõi nhịp tim, v.v., bao gồm cả siêu dữ liệu (tốc độ lấy mẫu, loại dữ liệu, thông tin kênh, v.v.) - Các điểm đánh dấu sự kiện từ các thí nghiệm (ví dụ: sử dụng PsychoPy) cũng có thể được gửi dưới dạng luồng dữ liệu bằng LSL
2. Luồng dữ liệu được xuất bản lên mạng - Đây là cách dữ liệu được gửi bằng LSL; luồng dữ liệu được "phát sóng" lên mạng - Các luồng được xuất bản có sẵn trên mạng và có thể được phát hiện bởi các thiết bị hỗ trợ LSL khác trên cùng một mạng - LSL gán cho mỗi phân đoạn hoặc mẫu dữ liệu một nhãn thời gian dựa trên một đồng hồ chung (theo Giao thức thời gian mạng). - Luồng dữ liệu được đẩy theo từng mẫu (hoặc từng phân đoạn) qua một "cổng ra" (outlet)
3. (Các) thiết bị thu thập "đăng ký" các luồng dữ liệu - Đây là cách nhận dữ liệu bằng LSL - Các thiết bị thu thập trên cùng một mạng nhận các luồng dữ liệu được xuất bản thông qua "cổng vào" (inlets). - Mỗi cổng vào nhận các mẫu luồng và siêu dữ liệu chỉ từ một cổng ra
4. Lưu dữ liệu - Sau khi đăng ký một luồng dữ liệu, bạn có thể lưu nó vào một biến trong ngôn ngữ lập trình ưa thích của mình, hoặc sử dụng phần mềm hỗ trợ LabRecorder của LSL để lưu nó vào một định dạng tiêu chuẩn như .xdf.
2.0 Tổng quan về hướng dẫn
Trong hướng dẫn này, chúng tôi sẽ lấy một thiết lập thí nghiệm làm ví dụ và hướng dẫn bạn qua các bước và mã cần thiết để triển khai nó bằng LSL trong Python. Chúng ta sẽ sử dụng Python phát một âm thanh trong khi thu thập dữ liệu EEG từ hai người đang đeo thiết bị đeo đầu Emotiv. Chúng ta sẽ sử dụng hai máy tính, mỗi máy chạy EmotivPRO để thu thập dữ liệu EEG và phát sóng mỗi luồng qua một cổng ra LSL riêng biệt. Chúng ta sẽ sử dụng một thư viện Python để phát một tệp âm thanh và đồng thời gửi một kích hoạt mỗi khi tệp bắt đầu.
CÁC BƯỚC:
1. Sử dụng EmotivPRO để truyền dữ liệu qua các cổng ra LSL bao gồm dữ liệu EEG (và/hoặc chuyển động, chất lượng tiếp xúc, chất lượng tín hiệu, v.v.) 2. Phát một bản nhạc âm thanh bằng tập lệnh Python và đồng thời gửi một kích hoạt qua một LSL khác Sử dụng LabRecorder để ghi lại và lưu cả ba luồng dữ liệu qua một cổng vào LSL.

2.1 BƯỚC 1 - Thiết lập và cài đặt
Bạn sẽ cần các thiết bị thu thập dữ liệu được hỗ trợ để thu thập dữ liệu
• Tất cả thiết bị não bộ của Emotiv kết nối với LSL thông qua phần mềm EmotivPROCài đặt EmotivPRO trên (các) thiết bị của bạn. Bạn sẽ cần một giấy phép EmotivPRO hợp lệ để sử dụng LSL.
Cài đặt thư viện Python LSL bằng lệnh sau:
pip install pylslTải xuống phần mềm LabRecorder. Đây là một ứng dụng đơn giản, miễn phí có thể chạy từ
dòng lệnh hoặc sử dụng bản tải xuống độc lậpĐối với thí nghiệm của chúng ta: Cài đặt các gói cần thiết để phát âm thanh bằng Python
pip install sounddevice soundfile
2.2 BƯỚC 3 - Gửi dữ liệu từ EmotivPRO qua luồng LSL
Tìm biểu tượng “…” ở góc trên cùng bên phải của ứng dụng, điều hướng đến Cài đặt (Settings)
Tìm phần 'Lab Streaming Layer' và phần phụ 'Outlet'
Chọn tất cả các loại dữ liệu mà bạn muốn phát sóng
Chọn định dạng dữ liệu (số thực 32-bit float hoặc số thực dấu phẩy động kép 64-bit double)
Chọn gửi dữ liệu theo từng mẫu hay theo từng phân đoạn mẫu
Nhấp vào 'Start' để phát sóng một luồng dữ liệu LSL
2.3 BƯỚC 4 - Sử dụng tập lệnh Python để phát âm thanh và gửi kích hoạt
Sao chép và dán khối mã sau vào một tệp python và lưu nó vào máy tính của bạn.
Tìm một tệp âm thanh (lý tưởng là tệp .wav) mà bạn muốn phát và chỉnh sửa tập lệnh bằng cách thay đổi
biếnaudio_filepaththành đường dẫn tệp đến tệp âm thanh của bạn trên máy tínhMở dấu nhắc lệnh để tương tác với dòng lệnh và điều hướng đến thư mục nơi
tệp Python của bạn được lưu trữNhập:
python3 filename.py
• Tùy thuộc vào bản cài đặt Python của bạn, bạn có thể sử dụngpythonthay vìpython3
Lưu ý: Thay thế/path/to/audio.wavbằng vị trí của tệp âm thanh bạn muốn phát trong quá trình thí nghiệm.
""" LSL Example: Play audio and send a trigger marker This script creates an LSL marker stream, waits for the user to press ENTER, then plays an audio file and sends a marker that can be synchronized with EEG data collected through LabRecorder. """ import sounddevice as sd import soundfile as sf from pylsl import StreamInfo, StreamOutlet def wait_for_keypress(): print("Press ENTER to start audio playback and send an LSL marker.") while True: if input() == "": break def play_audio_and_send_marker(audio_file, outlet): data, fs = sf.read(audio_file) print("Playing audio and sending LSL marker...") marker_val = [1] outlet.push_sample(marker_val) sd.play(data, fs) sd.wait() print("Audio playback finished.") if __name__ == "__main__": info = StreamInfo( name="AudioMarkers", type="Markers", channel_count=1, nominal_srate=0, channel_format="int32", source_id="uniqueMarkerID12345" ) outlet = StreamOutlet(info) while True: wait_for_keypress() audio_filepath = "/path/to/audio.wav" play_audio_and_send_marker( audio_filepath, outlet )
2.4 BƯỚC 5 - Sử dụng LabRecorder để xem và lưu tất cả các luồng LSL
Mở LabRecorder
Nhấn
Update. Các luồng LSL hiện có sẽ hiển thị trong danh sách luồng
• Bạn sẽ có thể thấy các luồng từ cả hai phần mềm EmotivPRO (thường được gọi là “Emotiv-
DataStream”) và luồng đánh dấu (được gọi là “AudioMarkers”)Nhấp vào
Browseđể chọn vị trí lưu trữ dữ liệu (và thiết lập các thông số khác)Chọn tất cả các luồng và nhấn
Recordđể bắt đầu ghi
3.0 Làm việc với dữ liệu
LabRecorder xuất ra một tệp XDF (Định dạng dữ liệu mở rộng - Extensible Data Format) chứa dữ liệu từ tất cả các luồng. Các tệp XDF được cấu trúc thành các luồng, mỗi luồng có một phần tiêu đề khác nhau mô tả những gì nó chứa (tên thiết bị, loại dữ liệu, tốc độ lấy mẫu, các kênh, v.v.). Bạn có thể sử dụng khối mã dưới đây để mở tệp XDF của mình và hiển thị một số thông tin cơ bản.
Lưu ý: Thay thế /path/to/your/file.xdf bằng đường dẫn tệp cho tệp đầu ra LabRecorder XDF của bạn.
import pyxdf import mne import matplotlib.pyplot as plt import numpy as np # Give the path to your LSL output file here. data_path = "/path/to/your/file.xdf" # Load the XDF file. streams, fileheader = pyxdf.load_xdf(data_path) print("XDF File Header:", fileheader) print("Number of streams found:", len(streams)) for i, stream in enumerate(streams): print("\nStream", i + 1) print("Stream Name:", stream["info"]["name"][0]) print("Stream Type:", stream["info"]["type"][0]) print("Number of Channels:", stream["info"]["channel_count"][0]) sfreq = float(stream["info"]["nominal_srate"][0]) print("Sampling Rate:", sfreq) print("Number of Samples:", len(stream["time_series"])) print("First 5 data points:", stream["time_series"][:5]) channel_names = [ chan["label"][0] for chan in stream["info"]["desc"][0]["channels"][0]["channel"] ] print("Channel Names:", channel_names) channel_types = "eeg"
4.0 Tài nguyên bổ sung
Tài liệu chính thức
Kiểm tra tài liệu trực tuyến, bao gồm cả tệp README chính thức trên GitHub
Tài nguyên bổ sung:
• Mã để chạy LSL bằng các thiết bị của Emotiv, kèm theo các tập lệnh ví dụ
• Video demo LSL hữu ích trên YouTube
• Kho lưu trữ GitHub SCCN LSL cho tất cả các thư viện liên quan
• Kho lưu trữ GitHub LSL cho một tập hợp các mô-đun phụ và ứng dụngQuy trình phân tích HyPyP cho các nghiên cứu siêu quét

Tiếp tục đọc