Run Length Encoding in Matlab

£可爱£侵袭症+ 提交于 2019-11-26 21:03:56

Here is a compact solution without loop, cellfun or 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])];

By sticking to your original implementation, the following simple changes should work.

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

You can format the output however you like. For example as a sequence:

relMatT = relMat';
relSeq = relMatT(:)';

or format a string to the suggested output:

relString = [];
for i = 1:length(relMat)
    relString = [relString, sprintf('(%d, %d), ', relMat(i,1), relMat(i,2))];
end

As an extension, if you have alphanumerics in your source sequence you should modify the above in order to compare strings instead of numbers.

UPDATE: To count the occurrences of unique code pairs in the original relMat try finding the pairs and count zero-diffs row-wise. For example:

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 

You can avoid the for loop:

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));
% 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;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!