我对MatLab很新,我有运行长度编码代码,但它似乎不起作用,你能帮助我吗?
我有这个输入:
ChainCode = 11012321170701000700000700766666666666665555555544443344444333221322222322
我想把它变成RLE输出:
(1,2), (0,1), (1,1), (2,1), (3,1), (2,1), (1,2), (7,1), (0,1), (7,1), (0,1),
(1,1), (0,3), (7,1), (0,5), (7,1), (0,2), (7,1), (6,13), (5,8), (4,4), (3,2),
(4,5), (3,3), (2,2), (1,1), (3,1), (2,5), (3,1), (2,2)
这是我的代码:
lengthcode = 1;
N = 1;
for i = 2:length(ChainCode)
if x(i)==x(i-1)
N = N + 1;
valuecode(N) = x(i);
lengthcode(N) = lengthcode(N) + 1;
else
N = 1;
lengthcode = 1;
end
i = i + 1;
end
但这不起作用,我仍然对如何打印这样的输出感到困惑。
我希望你能帮助我。谢谢。
答案 0 :(得分:10)
这是一个没有循环,cellfun或arrayfun的紧凑型解决方案:
chainCode = '11012321170701000700000700766666666666665555555544443344444333221322222322';
numCode = chainCode - '0'; % turn to numerical array
J=find(diff([numCode(1)-1, numCode]));
relMat=[numCode(J); diff([J, numel(numCode)+1])];
答案 1 :(得分:1)
通过坚持原始实现,以下简单更改应该有效。
chainCode = '11012321170701000700000700766666666666665555555544443344444333221322222322';
numCode = chainCode - '0'; % turn to numerical array
relMat = [];
numCode = [numCode nan]; % dummy ending
N = 1;
for i = 1:length(numCode)-1
if numCode(i)==numCode(i+1)
N = N + 1;
else
valuecode = numCode(i);
lengthcode = N;
relMat = [relMat; valuecode lengthcode];
N = 1;
end
end
您可以根据需要格式化输出。例如,作为序列:
relMatT = relMat';
relSeq = relMatT(:)';
或将字符串格式化为建议的输出:
relString = [];
for i = 1:length(relMat)
relString = [relString, sprintf('(%d, %d), ', relMat(i,1), relMat(i,2))];
end
作为扩展,如果你的源序列中有字母数字,你应该修改上面的内容,以便比较字符串而不是数字。
UPDATE :要计算原始relMat
中唯一代码对的出现次数,请尝试查找对,并按行计数零差异。例如:
relMatUnique = unique(relMat, 'rows'); % find unique pairs
nPairs = length(relMatUnique);
nOccur = zeros(nPairs, 1);
for i = 1:nPairs
pairInMat = bsxfun(@minus, relMat, relMatUnique(i,:)); % find pair in relMat
nOccur(i) = sum(~sum(pairInMat, 2));
end
relMatOccur = [relMatUnique nOccur]; % unique pairs and number of occurrences
答案 2 :(得分:1)
您可以避免使用for循环:
chainCode = '11012321170701000700000700766666666666665555555544443344444333221322222322';
numCode = chainCode - '0'; % turn to numerical array
% detect edges (changes)
edges = arrayfun( @(x,y) x ~= y, ...
numCode(1:end-1), ...
numCode(2:end));
% get indexes
idx = find(edges);
% create tuples
relMat = cell2mat(arrayfun( ...
@(b,e) [ numCode(b) ; e-b+1 ], ...
[ 1 (idx + 1) ], ...
[ idx length(numCode) ], ...
'UniformOutput', false));
答案 3 :(得分:0)
% Convert string to numeric array
ChainCodeString = '11012321170701000700000700766666666666665555555544443344444333221322222322';
ChainCodeArray = ChainCodeString - '0';
% Initialize
CurrentRleValue = ChainCodeArray(1);
CurrentRleCount = 1;
RleCodeIndex = 1;
for i = 2 : length(ChainCodeArray)
if ChainCodeArray(i)==ChainCodeArray(i-1)
% Increment current run-length count
CurrentRleCount = CurrentRleCount + 1;
else
% Store current run-length
valuecode(RleCodeIndex) = CurrentRleValue;
lengthcode(RleCodeIndex) = CurrentRleCount;
RleCodeIndex = RleCodeIndex + 1;
% Initialize next run-length
CurrentRleValue = ChainCodeArray(i);
CurrentRleCount = 1;
end;
end;