Run Length Encoding in Matlab

后端 未结 4 595
醉话见心
醉话见心 2020-11-27 08:24

I\'m very new with MatLab, I have Run Length Encoding code but it seems to not work, can you help me?

I have this input :

ChainCode  = 110123211707         


        
相关标签:
4条回答
  • 2020-11-27 08:57

    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 
    
    0 讨论(0)
  • 2020-11-27 09:00
    % 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;
    
    0 讨论(0)
  • 2020-11-27 09:10

    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])];
    
    0 讨论(0)
  • 2020-11-27 09:13

    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));
    
    0 讨论(0)
提交回复
热议问题