在Matlab中运行长度编码
我很新的MatLab,我有运行长度编码代码,但它似乎不工作,你能帮我吗?
我有这个input:
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
但是这不起作用,我仍然对如何打印输出感到困惑。
我希望你能帮助我。 谢谢。
这是一个没有循环,cellfun或arrayfun的紧凑解决scheme:
chainCode = '11012321170701000700000700766666666666665555555544443344444333221322222322'; numCode = chainCode - '0'; % turn to numerical array J=find(diff([numCode(1)-1, numCode])); relMat=[numCode(J); diff([J, numel(numCode)+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(:)';
或者将string格式化为build议的输出:
relString = []; for i = 1:length(relMat) relString = [relString, sprintf('(%d, %d), ', relMat(i,1), relMat(i,2))]; end
作为扩展,如果您的源序列中包含字母数字,则应修改上述内容以便比较string而不是数字。
更新 :要计算原始relMat
中唯一代码对的出现次数, 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
% 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;
你可以避免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));