【问题标题】:Matlab Codegen build errorMatlab Codegen构建错误
【发布时间】:2014-09-15 00:17:30
【问题描述】:

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

"??? 除非指定 'rows',否则第一个输入必须是向量。如果向量是可变大小的,则第一个维度或第二个维度必须具有固定长度 1。输入 []不支持。使用 1×0 或 0×1 输入(例如 zeros(1,0) 或 zeros(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 

【问题讨论】:

    标签: c++ matlab matlab-coder


    【解决方案1】:

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

    正如错误消息所说,对于 codegen 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)
    

    那么id 将是一个行向量。

    您也可以保持代码不变并执行以下操作:

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

    显然,这将导致复制idtemp,但它可能需要对您的代码进行较少的更改。

    【讨论】:

      【解决方案2】:
      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(:));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多