matlab run-length-encoding

Ejecutar la codificación de longitud en Matlab



run-length-encoding (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;

Soy muy nuevo con MatLab, tengo código Run Length Encoding pero parece que no funciona, ¿me pueden ayudar?

Tengo esta entrada:

ChainCode = 11012321170701000700000700766666666666665555555544443344444333221322222322

y quiero hacerlo en salida 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)

Este es mi código:

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

Pero esto no funciona, y todavía estoy confundido acerca de cómo puedo imprimir el resultado de esa manera.

Espero que puedas ayudarme. Gracias.


Al seguir su implementación original, los siguientes cambios simples deberían funcionar.

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

Puede formatear la salida como desee. Por ejemplo, como una secuencia:

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

o formatee una cadena al resultado sugerido:

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

Como una extensión, si tiene caracteres alfanuméricos en su secuencia fuente, debe modificar lo anterior para comparar cadenas en lugar de números.

ACTUALIZACIÓN : Para contar las ocurrencias de pares de códigos únicos en el relMat original, intente encontrar los pares y cuente cero-diferencias fila por partida. Por ejemplo:

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


Puede evitar el bucle 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));


Aquí hay una solución compacta sin loop, cellfun o 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])];