9

I divided a (512x512) 2-dimensional array to 2x2 blocks using this function.

skimage.util.view_as_blocks (arr_in, block_shape)
array([[ 0,  1,  2,  3],
   [ 4,  5,  6,  7],
   [ 8,  9, 10, 11],
   [12, 13, 14, 15]])
   >>> B = view_as_blocks(A, block_shape=(2, 2))
   >>> B[0, 0]
   array([[0, 1],
          [4, 5]])
   >>> B[0, 1]
   array([[2, 3],
          [6, 7]])

Now I need to put the same blocks to their original places after manipulation but I couldn't see any function in skimage for that.

What's the best way to merge the non-overlapping arrays as it was before?

Thank you!

2 Answers 2

7

Use transpose/swapaxes to swap the second and third axes and then reshape to have the last two axes merged -

B.transpose(0,2,1,3).reshape(-1,B.shape[1]*B.shape[3])
B.swapaxes(1,2).reshape(-1,B.shape[1]*B.shape[3])

Sample run -

In [41]: A
Out[41]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

In [42]: B = view_as_blocks(A, block_shape=(2, 2))

In [43]: B
Out[43]: 
array([[[[ 0,  1],
         [ 4,  5]],

        [[ 2,  3],
         [ 6,  7]]],


       [[[ 8,  9],
         [12, 13]],

        [[10, 11],
         [14, 15]]]])

In [44]: B.transpose(0,2,1,3).reshape(-1,B.shape[1]*B.shape[3])
Out[44]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
Sign up to request clarification or add additional context in comments.

7 Comments

Thank you for help your first answer also worked B.transpose(0,2,1,3).reshape(512,512). Have a question, what is this part means (-1,B.shape[1]*B.shape[3]) ?
@enterbutton Basically it means that the new shape would have B.shape[1]*B.shape[3] number of cols and the number of rows be decided by the reshape function by dividing the total number of elements with the number of cols as denoted by that -1. In layman terms, I am letting the computer compute the no. of rows for me with that -1. In most cases,, it meant to produce compact codes. Hope that makes sense!
@JeruLuke To do view_as_blocks or retrieve back/merge back? Sorry, there isn't any for either. Is there some specific usage that you are trying to exploit, because if you are using OpenCV on Python, then NumPy arrays should work just as well.
view_as_blocks uses as_strided. In this case the action is the same as: B=A.reshape(2,2,2,2).transpose(0,2,1,3). Going back to A is the reverse, the same transpose followed by reshape to (4,4).
How can I achieve it if A is 3 dimensional with num of channels?
|
1

This is where you'd better use einops:

from einops import rearrange

# that's how you could rewrite view_as_blocks
B = rearrange(A, '(x dx) (y dy) -> x y dx dy', dx=2, dy=2)

# that's an answer to your question
A = rearrange(B, 'x y dx dy -> (x dx) (y dy)')

See documentation for more operations on images

1 Comment

Finally something easily deployed and intuitive - I've looked 2 days for something like this - cheers

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.