MATLAB 到 Python 代码转换(NumPy、SciPy、MatplotLib?)

发布于 2024-08-22 18:26:31 字数 3593 浏览 4 评论 0原文

我正在尝试将以下代码从 MATLAB 转换为 Python 以进行脑电图项目(部分原因是 Python 稍微便宜一些!)

希望有人能指出我正确的方向:我已经开始改变它,但陷入了困境:特别是试图找到等价的函数。

尝试过 scipy.org (NumPy_for_Matlab_Users 等),但我不确定我的参数是否具有正确的格式/数字)

我最初使用 pyserial

ser.read()

读取数据,然后

ord()

将其转换为整数,但此 MATLAB 代码关于它的另一种方式(“uchar”)

我的主要问题是

fopen
fread
find
repmat

整个绘图部分,因为我对Python(MatPlotLib?)中的绘图部分了解更少,

MATLAB也倾向于以“1”开头,而Python使用0:我我也尝试过改变这些,但遗漏了一些我不确定的内容。

满意用冒号分隔的整个范围

...repmat(0:2:10, .....

Python是否

?所以,这是 MATLAB:

% EEG data grabber and plotter

N = 256;    % Required number of sample frames

% Read in a block of data from the OpenEEG board
hCom = serial('COM1','BaudRate',57600,'timeout',5);
fopen(hCom);
numBlocks = (ceil(17*N/256) + 1);
rawdata = zeros(numBlocks*256,1);
for n = 1:numBlocks
    rawdata((0:255) + n*256) = fread(hCom, 256, 'uchar');  % Read data
end
fclose(hCom);

% Convert raw data into a Matlab matrix
% First find the first frame start
startIndex = find(rawdata == 165);
while(rawdata(startIndex(1) + 1) ~= 90)
   startIndex = startIndex(2:end);
end
% Now extract the samples
frameStarts = (0:(N-1))'*17 + startIndex(1);
indices = 4 + repmat(frameStarts, 1, 6) + repmat(0:2:10, length(frameStarts), 1);
eegData = (rawdata(indices)*256 + rawdata(indices + 1)) - 512;
% eegData is now a N by 6 matrix, each column is a channel of sampled data

% Plot time-series data
figure(1)
subplot(2,1,1)
plot((0:255)/256,eegData(:,1:2))
xlabel('Time [s]');
ylabel('EEG data'); 
% Calculate FFT and plot spectra
subplot(2,1,2)
window = 0.5 - 0.5 * cos(2*pi*(0:255)/255); % Von-Hann Window
f = abs(fft(repmat(window',1,2) .* eegData(:,1:2)));
plot((0:127),f(1:128,:))
xlabel('Frequency [Hz]');
ylabel('EEG FFT');

这是我可怜的表弟版本

import scipy
import serial                       #Serial Module to read serial port
from numpy import ceil,zeros        #Ceil module & zeros for blank matrix

N = 256    #no of sample frames (256 = 1s)

#Reads a block of data from the serial port

ser = serial.Serial('COM18',57600,timeout=5)

scipy.fopen(ser)       #MATLAB CODE: fopen(ser)  is this correct????

numBlocks = (ceil(17*N/256) + 1)
rawdata = scipy.zeros(numBlocks*256,1)
for n = 1:numBlocks
    rawdata((0:255) + n*256) = numpyio.fread(ser,256,'i')  # read each byte as     unsigned integer
end
ser.close()


#convert raw data to MATLAB matrix
#find start of frame (1st Byte always 165, 2nd always 90)

startIndex = find(rawdata == 165);
while (rawdata(startIndex(0) + 1) ~=90) #confirms 165,90 sequence
    startIndex = startIndex(1:end) #uses rest of frame as data
end

#Extraction of sample values

#MATLAB CODE
frameStarts = (0: (N-1))'*17 + startIndex(1);      #'#how to transpose matrix('): zip()??
indices = 4 + (numpy.tile(frameStarts, 1,6)) + (numpy.tile(0:2:10,length(frameStarts), 1); 
eegData = (rawdata(indices)*256 + rawdata(indices +1)) - 512  #values are unsigned     integers 0-1023 and must subtract 512 for actual value
#eeg data now N*6 Matrix each column is a channel of data

#MATLAB CODE: plot time series data  (MatPlotLib?)

figure(1)
subplot (2,1,1)
plot((0:255)/256,eegData(:,1:2))
xlabel('Time [s]')
ylabel('EEG Voltage')
#fft
subplot(2,1,2)
window = 0.5 - 0.5*cos(2*pi*(0:255)/255);
f = abs(fft(repmat(window',1,2) .* eegData(:,1:2)))    '#repmat=tile()? matrix     transposition (')?
plot((0:127),f(1:128,:))
xlabel('Freq [Hz]')
ylabel('EEG FFT')

感谢收到所有建议!

戴夫!

I'm trying to convert the following code to Python from MATLAB for an EEG Project (partly because Python's slightly cheaper!)

Hopefully someone can point me in the right direction: I've started to alter it but got bogged down: Particularly trying to find equivalent functions.

Tried scipy.org (NumPy_for_Matlab_Users etc.) but I'm not sure if my arguments are of the right format/number)

I was originally using pyserial

ser.read()

To read the data in and then

ord()

To convert it into an integer, but this MATLAB code goes about it another way ('uchar')

My main issues were with

fopen
fread
find
repmat

And the whole plotting section as I have even less of an idea about that in Python (MatPlotLib?)

MATLAB also tends to start with '1' whereas Python uses 0: I've tried to alter these also but have missed a few I wasn't sure of.

Is Python happy with the whole range separated by colons

...repmat(0:2:10, .....

or not?

So, here is the MATLAB:

% EEG data grabber and plotter

N = 256;    % Required number of sample frames

% Read in a block of data from the OpenEEG board
hCom = serial('COM1','BaudRate',57600,'timeout',5);
fopen(hCom);
numBlocks = (ceil(17*N/256) + 1);
rawdata = zeros(numBlocks*256,1);
for n = 1:numBlocks
    rawdata((0:255) + n*256) = fread(hCom, 256, 'uchar');  % Read data
end
fclose(hCom);

% Convert raw data into a Matlab matrix
% First find the first frame start
startIndex = find(rawdata == 165);
while(rawdata(startIndex(1) + 1) ~= 90)
   startIndex = startIndex(2:end);
end
% Now extract the samples
frameStarts = (0:(N-1))'*17 + startIndex(1);
indices = 4 + repmat(frameStarts, 1, 6) + repmat(0:2:10, length(frameStarts), 1);
eegData = (rawdata(indices)*256 + rawdata(indices + 1)) - 512;
% eegData is now a N by 6 matrix, each column is a channel of sampled data

% Plot time-series data
figure(1)
subplot(2,1,1)
plot((0:255)/256,eegData(:,1:2))
xlabel('Time [s]');
ylabel('EEG data'); 
% Calculate FFT and plot spectra
subplot(2,1,2)
window = 0.5 - 0.5 * cos(2*pi*(0:255)/255); % Von-Hann Window
f = abs(fft(repmat(window',1,2) .* eegData(:,1:2)));
plot((0:127),f(1:128,:))
xlabel('Frequency [Hz]');
ylabel('EEG FFT');

And here's my poor cousin version

import scipy
import serial                       #Serial Module to read serial port
from numpy import ceil,zeros        #Ceil module & zeros for blank matrix

N = 256    #no of sample frames (256 = 1s)

#Reads a block of data from the serial port

ser = serial.Serial('COM18',57600,timeout=5)

scipy.fopen(ser)       #MATLAB CODE: fopen(ser)  is this correct????

numBlocks = (ceil(17*N/256) + 1)
rawdata = scipy.zeros(numBlocks*256,1)
for n = 1:numBlocks
    rawdata((0:255) + n*256) = numpyio.fread(ser,256,'i')  # read each byte as     unsigned integer
end
ser.close()


#convert raw data to MATLAB matrix
#find start of frame (1st Byte always 165, 2nd always 90)

startIndex = find(rawdata == 165);
while (rawdata(startIndex(0) + 1) ~=90) #confirms 165,90 sequence
    startIndex = startIndex(1:end) #uses rest of frame as data
end

#Extraction of sample values

#MATLAB CODE
frameStarts = (0: (N-1))'*17 + startIndex(1);      #'#how to transpose matrix('): zip()??
indices = 4 + (numpy.tile(frameStarts, 1,6)) + (numpy.tile(0:2:10,length(frameStarts), 1); 
eegData = (rawdata(indices)*256 + rawdata(indices +1)) - 512  #values are unsigned     integers 0-1023 and must subtract 512 for actual value
#eeg data now N*6 Matrix each column is a channel of data

#MATLAB CODE: plot time series data  (MatPlotLib?)

figure(1)
subplot (2,1,1)
plot((0:255)/256,eegData(:,1:2))
xlabel('Time [s]')
ylabel('EEG Voltage')
#fft
subplot(2,1,2)
window = 0.5 - 0.5*cos(2*pi*(0:255)/255);
f = abs(fft(repmat(window',1,2) .* eegData(:,1:2)))    '#repmat=tile()? matrix     transposition (')?
plot((0:127),f(1:128,:))
xlabel('Freq [Hz]')
ylabel('EEG FFT')

All suggestions gratefully received!

Dave!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

也只是曾经 2024-08-29 18:26:31

嗯...很多事情。

Python 没有 end 关键字,因此您显然需要阅读有关 Python 语法的更多信息。

Python 数组和切片使用 [] 而非 () 进行索引。例如,范围表示为 range(0,10),但 Matlab 意义上的切片仅存在于 numpy 等扩展包中,并且每个扩展包都有自己的接口。

是的,您想使用 matplotlib 进行绘图,它具有与 Matlab 绘图界面几乎相同的功能,至少在这个级别上如此。

看起来您猜测 Python 在某些随机包中将具有与 Matlab 相同的方法名称。这不是一个好计划。相反,请在其在线文档中查找 Matlab 方法,准确了解它的作用,然后阅读 Python 包文档,找到可以执行您想要的操作的方法。这可能不存在,但我敢打赌,在这么简单的程序中,您需要的大多数程序都会存在。

在将任何 Matlab 代码转换为其他语言时,您需要了解的最重要的事情是 Matlab 数组的工作方式,这是极其不寻常的(但对于其目标应用程序来说非常好)。 Numpy 具有大致相同的功能,但它们的表示法完全不同。

串行模块已经在端口上为您提供了一个打开的文件对象,因此您不需要 fopen。

我认为您需要花费大量时间来阅读 Python 和 Matlab 的文档,因为很明显您目前两者都不懂。

不要让我让你泄气,我只是诚实地告诉你你的处境。

Um... lots of things.

Python has no end keyword, so you clearly need to read more about Python's syntax.

Python arrays and slices are indexed with [] not (). Ranges are expressed as range(0,10) for example, but slices in the Matlab sense only exist in extension packages like numpy and each one has its own interface.

Yes, you want to use matplotlib for plotting, it has pretty much the same capabilities as Matlab's plotting interface, at least at this level.

It looks like you're guessing that Python will have the same method names as Matlab in some random package. This is not a good plan. Instead, look up the Matlab method in its documentation, which is online, find out exactly what it does, and then read into the Python package documentation for a method that does what you want. This may not exist, but I'm betting that in a program this simple, most of the ones you need will.

The most important thing you need to understand in converting any Matlab code to other languages is the way Matlab arrays work, which is extremely unusual (but excellent for its target applications). Numpy has about the same capabilities, but a completely different notation for them.

The serial module has already given you an open file object on the port, so you don't need the fopen.

I think you need to spend a LOT of time with the documentation for both Python and Matlab, because it's quite clear you understand neither at the moment.

Don't let me discourage you, I'm just being honest about where you're at.

玩心态 2024-08-29 18:26:31

一个小问题 - 两者之间的索引是不同的。如果您只是将 MATLAB 中的所有内容复制到 Python(就像您似乎所做的那样),您会感到非常非常困惑。 MATLAB x(1:5:end) 转换为 Python x[0::5]。返回 NumPy for MATLAB Users 并向下扫描到名为“线性代数等价”的部分(大约在页面的中间)。它给出了如何来回的字典。

One small point - indexing between the two is different. If you just copy everything from MATLAB to Python, as you seem to have done, you'll be very very confused. MATLAB x(1:5:end) translates to Python x[0::5]. Go back to NumPy for MATLAB Users and scan down to the section called "Linear Algebra Equivalents" (about halfway down the page). It gives a dictionary of how to go back and forth.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文