我想运行一个MATLAB脚本M-文件,以重建一个点云在八度.因此,我不得不重写代码的某些部分,以使其与Octave兼容。实际上,M文件在Octave中工作得很好(我没有任何错误),而且绘制的点云乍看上去也不错,但是看起来这些变量的大小只有原始MATLAB变量的一半。在附图中你可以看到我的意思。
八度:

MATLAB:

你可以看到,例如,八度M的维数是1311114x3,而在MATLAB中是2622227x3。我的原始文件中的实际行数也是2622227行。
在这里,您可以看到我使用的原始文件(原始数据)的摘录。
Rotation angle Measured distance
-0,090 26,295
-0,342 26,294
-0,594 26,294
-0,846 26,295
-1,098 26,294
-1,368 26,296
-1,620 26,296
-1,872 26,296在MATLAB中,我创建了输出变量如下所示。
data = table;
data.Rotationangle = cell2mat(raw(:, 1));
data.Measureddistance = cell2mat(raw(:, 2));由于八度没有table函数,所以我写到
data = cellfun(@(x)str2num(x), strrep(raw, ',', '.'))而不是。
八度也没有struct2array功能,所以我也不得不更换它。我用MATLAB写的。
data = table2array(data); 在“八达通”中,这样做有点困难。我必须创建一个struct2array函数,这是通过这个错误报告实现的。
%% Create a struct2array function
function retval = struct2array (input_struct)
%input check
if (~isstruct (input_struct) || (nargin ~= 1))
print_usage;
endif
%convert to cell array and flatten/concatenate output.
retval = [ (struct2cell (input_struct)){:}];
endfunction
clear b;
b.a = data;
data = struct2array(b);我是不是犯了什么错误,有人能帮我解决这个问题吗?
编辑:
下面是我的脚本中使用raw的部分。
delimiter = '\t';
startRow = 5;
formatSpec = '%s%s%[^\n\r]';
fileID = fopen(filename,'r');
dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, 'HeaderLines' ,startRow-1, 'ReturnOnError', false, 'EndOfLine', '\r\n');
fclose(fileID);
%% Convert the contents of columns containing numeric text to numbers.
% Replace non-numeric text with NaN.
raw = repmat({''},length(dataArray{1}),length(dataArray)-1);
for col=1:length(dataArray)-1
raw(1:length(dataArray{col}),col) = mat2cell(dataArray{col}, ones(length(dataArray{col}), 1));
end
numericData = NaN(size(dataArray{1},1),size(dataArray,2));
for col=[1,2]
% Converts text in the input cell array to numbers. Replaced non-numeric
% text with NaN.
rawData = dataArray{col};
for row=1:size(rawData, 1)
% Create a regular expression to detect and remove non-numeric prefixes and
% suffixes.
regexstr = '(?<prefix>.*?)(?<numbers>([-]*(\d+[\.]*)+[\,]{0,1}\d*[eEdD]{0,1}[-+]*\d*[i]{0,1})|([-]*(\d+[\.]*)*[\,]{1,1}\d+[eEdD]{0,1}[-+]*\d*[i]{0,1}))(?<suffix>.*)';
try
result = regexp(rawData(row), regexstr, 'names');
numbers = result.numbers;
% Detected commas in non-thousand locations.
invalidThousandsSeparator = false;
if numbers.contains('.')
thousandsRegExp = '^\d+?(\.\d{3})*\,{0,1}\d*$';
if isempty(regexp(numbers, thousandsRegExp, 'once'))
numbers = NaN;
invalidThousandsSeparator = true;
end
end
% Convert numeric text to numbers.
if ~invalidThousandsSeparator
numbers = strrep(numbers, '.', '');
numbers = strrep(numbers, ',', '.');
numbers = textscan(char(numbers), '%f');
numericData(row, col) = numbers{1};
raw{row, col} = numbers{1};
end
catch
raw{row, col} = rawData{row};
end
end
end您不会在我的工作区中看到任何raw,因为在重构点云之前,我清除了所有临时变量。此外,我在第1311114和1311115行中的原始数据看起来也很正常。
编辑2:
正如建议的那样,这里有一个小示例表,用于澄清我想要什么,以及在我的例子中,MATLAB如何处理table2array函数。
data =
-0.0900 26.2950
-0.3420 26.2940
-0.5940 26.2940
-0.8460 26.2950
-1.0980 26.2940
-1.3680 26.2960
-1.6200 26.2960
-1.8720 26.2960使用我在Octave中使用的struct2array函数,我得到了以下数组。
data =
-0.090000 26.295000
-0.594000 26.294000
-1.098000 26.294000
-1.620000 26.296000
-2.124000 26.295000
-2.646000 26.293000
-3.150000 26.294000
-3.654000 26.294000如果您将Octave数组与我的原始数据进行比较,您可以看到每第二行都被跳过。这似乎是1311114行而不是2622227行的原因。
编辑3:
我试图用@Tasos Papastylianou的建议来解决我的问题,但不幸的是,这一建议没有成功。首先,我用结构做了变体。
data = struct();
data.Rotationangle = [raw(:,1)];
data.Measureddistance = [raw(:,2)];
data = cell2mat( struct2cell (data ).' )但这将导致我的脚本中的结构如下。(不幸的是,结果并不如编辑2所示。不要惊讶,我只使用了原始文件的一小部分来加速脚本的运行,所以这里只有769行。)
[766,1] = -357,966
[767,1] = -358,506
[768,1] = -359,010
[769,1] = -359,514
[1,2] = 26,295
[2,2] = 26,294
[3,2] = 26,294
[4,2] = 26,296此外,我得到以下错误。
error: unary operator '-' not implemented for 'cell' operands
error: called from
Cloud_reconstruction at line 137 column 11同样,使用dataframe八度包的方法也不起作用。当我运行以下代码时,会导致以下错误。
dataframe2array = @(df) cell2mat( struct(df).x_data );
pkg load dataframe;
data = dataframe();
data.Rotationangle = [raw(:, 1)];
data.Measureddistance = [raw(:, 2)];
dataframe2array(data)错误:
warning: Trying to overwrite colum names
warning: called from
df_matassign at line 147 column 13
subsasgn at line 172 column 14
Cloud_reconstruction at line 106 column 20
warning: Trying to overwrite colum names
warning: called from
df_matassign at line 176 column 13
subsasgn at line 172 column 14
Cloud_reconstruction at line 106 column 20
warning: Trying to overwrite colum names
warning: called from
df_matassign at line 147 column 13
subsasgn at line 172 column 14
Cloud_reconstruction at line 107 column 23
warning: Trying to overwrite colum names
warning: called from
df_matassign at line 176 column 13
subsasgn at line 172 column 14
Cloud_reconstruction at line 107 column 23
error: RHS(_,2): but RHS has size 768x1
error: called from
df_matassign at line 179 column 11
subsasgn at line 172 column 14
Cloud_reconstruction at line 107 column 23这两条错误信息都引用了我的脚本的以下部分,我正在用柱面坐标重建点云。
distLaserCenter = 47; % Distance between the pipe centerline and the blind zone in mm
m = size(data,1); % Find the length of the first dimension of data
zincr = 0.4/360; % z increment in mm per deg
data(:,1) = -data(:,1);
for i = 1:m
data(i,2) = data(i,2) + distLaserCenter;
if i == 1
data(i,3) = 0;
elseif abs(data(i,1)-data(i-1)) < 100
data(i,3) = data(i-1,3) + zincr*(data(i,1)-data(i-1));
else abs(data(i,1)-data(i-1)) > 100;
data(i,3) = data(i-1,3) + zincr*(data(i,1)-(data(i-1)-360));
end
end给出一些背景信息,以便更好地理解。该脚本用于将管道重构为点云。用激光从内部对管道表面进行扫描,每次旋转时激光测量几个点(从激光到管道内壁的距离)。我希望这有助于理解我想用我的脚本做什么。
发布于 2019-11-13 14:01:29
不确定您到底想要做什么,但下面是一个如何以与表相同的方式使用结构的玩具示例:
matlab:
data = table;
data.A = [1;2;3;4;5];
data.B = [10;20;30;40;50];
table2array(data)八度:
data = struct();
data.A = [1;2;3;4;5];
data.B = [10;20;30;40;50];
cell2mat( struct2cell (data ).' )在将结果传递给.'之前,请注意换位操作( cell2mat ),因为在表中,“字段名”是水平排列在列中的,而struct2cell则将过去的“字段名”安排为行。
您可能还对dataframe八度包感兴趣,它执行类似于matlab表(或者实际上是R的dataframe对象)的功能:https://octave.sourceforge.io/dataframe/ (您可以通过在控制台中键入pkg install -forge dataframe来安装它)。
不幸的是,将数据显示为数组的方式仍然不理想(请参阅:https://stackoverflow.com/a/55417141/4183191),但您可以轻松地将其转换为一个很小的函数。
dataframe2array = @(df) cell2mat( struct(df).x_data );然后,您的代码可以变成:
pkg load dataframe;
data = dataframe();
data.A = [1;2;3;4;5];
data.B = [10;20;30;40;50];
dataframe2array(data)https://stackoverflow.com/questions/58836086
复制相似问题