Matrix “Zigzag” Reordering

后端 未结 6 1547
名媛妹妹
名媛妹妹 2020-11-30 04:35

I have an NxM matrix in MATLAB that I would like to reorder in similar fashion to the way JPEG reorders its subblock pixels:

6条回答
  •  野性不改
    2020-11-30 05:07

    Here's a way how to do this. Basically, your array is a hankel matrix plus vectors of 1:m, where m is the number of elements in each diagonal. Maybe someone else has a neat idea on how to create the diagonal arrays that have to be added to the flipped hankel array without a loop.

    I think this should be generalizeable to a non-square array.

    % for a 3x3 array 
    n=3;
    
    numElementsPerDiagonal = [1:n,n-1:-1:1];
    hadaRC = cumsum([0,numElementsPerDiagonal(1:end-1)]);
    array2add = fliplr(hankel(hadaRC(1:n),hadaRC(end-n+1:n)));
    
    % loop through the hankel array and add numbers counting either up or down
    % if they are even or odd
    for d = 1:(2*n-1)
       if floor(d/2)==d/2
          % even, count down
          array2add = array2add + diag(1:numElementsPerDiagonal(d),d-n);
       else
          % odd, count up
          array2add = array2add + diag(numElementsPerDiagonal(d):-1:1,d-n);
       end
    end
    
    % now flip to get the result
    indexMatrix = fliplr(array2add)
    
    result =
         1     2     6
         3     5     7
         4     8     9
    

    Afterward, you just call reshape(image(indexMatrix),[],1) to get the vector of reordered elements.

    EDIT

    Ok, from your comment it looks like you need to use sort like Marc suggested.

    indexMatrixT = indexMatrix';   % ' SO formatting
    [dummy,sortedIdx] = sort(indexMatrixT(:));
    
    sortedIdx =
         1     2     4     7     5     3     6     8     9
    

    Note that you'd need to transpose your input matrix first before you index, because Matlab counts first down, then right.

提交回复
热议问题