Matlab Codegen构建错误

Matlab Codegen build error

本文关键字:错误 构建 Codegen Matlab      更新时间:2023-10-16

我正在尝试使用codegen将下面的Matlab代码转换为C++。然而,它在构建时失败了,我得到了错误:

"??除非指定了"rows",否则第一个输入必须是矢量。如果矢量大小可变,则第一个维度或第二个维度的固定长度必须为1。不支持输入[]。使用1乘0或0乘1的输入(例如,零(1,0)或零(0,1))来表示空集。"

然后它指向[id,m,n]=unique(id);是罪魁祸首。为什么它不构建?修复它的最佳方法是什么?

function [L,num,sz] = label(I,n) %#codegen
% Check input arguments
error(nargchk(1,2,nargin));
if nargin==1, n=8; end
assert(ndims(I)==2,'The input I must be a 2-D array')
sizI = size(I);
id = reshape(1:prod(sizI),sizI);
sz = ones(sizI);
% Indexes of the adjacent pixels
vec = @(x) x(:);
if n==4 % 4-connected neighborhood
idx1 = [vec(id(:,1:end-1)); vec(id(1:end-1,:))];
idx2 = [vec(id(:,2:end)); vec(id(2:end,:))];
elseif n==8 % 8-connected neighborhood
idx1 = [vec(id(:,1:end-1)); vec(id(1:end-1,:))];
idx2 = [vec(id(:,2:end)); vec(id(2:end,:))];
idx1 = [idx1; vec(id(1:end-1,1:end-1)); vec(id(2:end,1:end-1))];
idx2 = [idx2; vec(id(2:end,2:end)); vec(id(1:end-1,2:end))];
else
error('The second input argument must be either 4 or 8.')
end
% Create the groups and merge them (Union/Find Algorithm)
for k = 1:length(idx1)
root1 = idx1(k);
root2 = idx2(k);
while root1~=id(root1)
id(root1) = id(id(root1));
root1 = id(root1);
end
while root2~=id(root2)
id(root2) = id(id(root2));
root2 = id(root2);
end
if root1==root2, continue, end
% (The two pixels belong to the same group)
N1 = sz(root1); % size of the group belonging to root1
N2 = sz(root2); % size of the group belonging to root2
if I(root1)==I(root2) % then merge the two groups
if N1 < N2
    id(root1) = root2;
    sz(root2) = N1+N2;
else
    id(root2) = root1;
    sz(root1) = N1+N2;
end
end
end
while 1
id0 = id;
id = id(id);
if isequal(id0,id), break, end
end
sz = sz(id);
% Label matrix
isNaNI = isnan(I);
id(isNaNI) = NaN;
[id,m,n] = unique(id);
I = 1:length(id);
L = reshape(I(n),sizI);
L(isNaNI) = 0;
if nargout>1, num = nnz(~isnan(id)); end 

仅供参考,如果您使用的是MATLAB R2013b或更新版本,则可以将error(nargchk(1,2,nargin))替换为narginchk(1,2)

正如错误消息所说,对于代码生成unique,除非传递了"行",否则要求输入为矢量。

如果您查看报告(单击显示的"打开报告"链接)并将鼠标悬停在id上,您可能会发现其大小既不是1-by-N也不是N-by-1。如果您在此处搜索unique,可以看到对unique的要求:

http://www.mathworks.com/help/coder/ug/functions-supported-for-code-generation--alphabetical-list.html

你可以做以下几件事之一:

id作为一个向量,并将其视为用于计算的向量。代替声明:

id = reshape(1:prod(sizI),sizI);

你可以使用:

id = 1:numel(I)

那么CCD_ 9将是行向量。

你也可以保持代码原样,并做一些类似的事情:

[idtemp,m,n] = unique(id(:));
id = reshape(idtemp,size(id));

显然,这将导致生成一个副本idtemp,但它可能会减少对代码的更改。

  1. 删除变量vec中存储的匿名函数,使vec成为一个子函数:

    function y = vec(x)
    coder.inline('always');
    y = x(:);
    
  2. 如果没有'rows'选项,unique函数的输入始终被解释为矢量,而输出始终是矢量。因此,例如,如果矩阵id的所有元素都是唯一的,那么类似id = unique(id)的东西将具有id = id(:)的效果。使输入成为一个进入的矢量没有害处。所以更改行

    [id,m,n] = unique(id);
    

    [id,m,n] = unique(id(:));