【问题标题】:Run Length Encoding in MatlabMatlab中的运行长度编码
【发布时间】:2012-08-17 02:05:02
【问题描述】:

我是 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

但这不起作用,我仍然对如何打印这样的输出感到困惑。

我希望你能帮助我。谢谢你。

【问题讨论】:

  • 如果有人可以帮助如何计算现有输出的出现频率。例如:(1.2), (0.1), (1.1), (2.1), (3.1), (2.1), (1.2), (7.1), (0 , 1) (1,2) = 2 次 (0, 1) = 2 次 (1,1) = 1 次,依此类推。谢谢
  • 您应该修改您的原始帖子/问题(或作为新问题发布),以防您需要与发布的内容不同的内容。请参阅下面的更新答案以查找出现频率。

标签: matlab run-length-encoding


【解决方案1】:

这是一个没有循环、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])];

【讨论】:

    【解决方案2】:

    通过坚持您的原始实现,以下简单更改应该会起作用。

    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
    

    作为扩展,如果您的源序列中有字母数字,您应该修改上面的内容以便比较字符串而不是数字。

    更新:要计算原始 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 
    

    【讨论】:

    • 谢谢,这很有帮助,它帮助我理解 MatLab :)
    【解决方案3】:

    你可以避免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));
    

    【讨论】:

    • 谢谢你们,因为你们都帮助了我,所以我完成了。
    【解决方案4】:
    % 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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-27
      • 1970-01-01
      • 1970-01-01
      • 2013-02-01
      • 2012-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多