2014-09-15 3 views
0

Я пытаюсь преобразовать приведенный ниже код Matlab в C++ с помощью codegen. Однако он не в сборке, и я получаю ошибку:Ошибка сборки Matlab Codegen

"??? Unless 'rows' is specified, the first input must be a vector. If the vector is variable-size, the either the first dimension or the second must have a fixed length of 1. The input [] is not supported. Use a 1-by-0 or 0-by-1 input (e.g., zeros(1,0) or zeros(0,1)) to represent the empty set."

Затем он указывает на [идентификатор, т, п] = уникальный идентификатор(); являясь виновником. Почему он не строится и как лучше всего это исправить?

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 

ответ

1

Просто FYI, если вы используете MATLAB R2013b или более поздней версии, вы можете заменить error(nargchk(1,2,nargin)) с narginchk(1,2).

Как указано в сообщении об ошибке, для codegen unique требуется, чтобы вход был вектором, если не передано «rows».

Если вы посмотрите на отчет (нажмите ссылку «Открыть отчет») и наведите указатель мыши на значок, вы увидите, что его размер не равен 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, чтобы быть сделано, но он может включать в себя меньше изменений в код.

1
  1. Удалить анонимную функцию, хранящуюся в переменной vec и сделать vec подфункцию:

    function y = vec(x) 
    coder.inline('always'); 
    y = x(:); 
    
  2. Без опции 'rows', вход функции unique всегда интерпретируется как вектор, и В любом случае выход всегда является вектором. Так, например, что-то вроде id = unique(id) будет иметь эффект id = id(:), если бы все элементы матрицы id были уникальными. Там нет никакого вреда в том, на входе вектор идет в. Таким образом, изменить линию

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

в

[id,m,n] = unique(id(:)); 
Смежные вопросы