1

I am trying to load an image file in tif format and rearrange it into a long strip but preserve the horizontal order. When I have tried to use numpy reshape it just overlays the different rows onto each other or corrupts the image. Say I have an array like this

imagearray = [1,2,3,4,5,6,7,8,9,10],
             [0,0,0,0,0,0,0,0,0,0],
             [1,1,1,1,1,1,1,1,1,1],
             [2,2,2,2,2,2,2,2,2,2] 

I want to rearrange it so that it looks like this

[1,2],
[0,0],
[1,1],
[2,2],
[3,4],
[0,0],
[1,1],
[2,2]

and so on. My issue is keeping that order as I rearrange it without using any more memory as these are 3GB images using reshape or rearrange are ways that I can use less memory. I think that it is more difficult also because the image technically has shape (n,m,3) which I don't fully understand how to manipulate. this is what the output looks like from this image when it is supposed to look more similar to this

This is the basics of the file that I am using

import cv2
import matplotlib.pyplot as plt
from PIL import Image, ImageTk
Image.MAX_IMAGE_PIXELS = None
width =  4000
height = 4000
rollwidth = 1000
I = cv2.imread("image path")
print("read image")
resizedImage = cv2.resize(I,(height,width), interpolation= cv2.INTER_LANCZOS4)
print("combined done")
testimage = np.reshape(resizedImage,((np.ceil(width/rollwidth).astype(np.int64)*height),rollwidth,3), order ='C')
cv2.imwrite("save path", testimage)
print("done")

I think that this is slightly different to the duplicate flag as using the proposed steps I still can't get the needed result

  • From the linked Q&A's accepted answer, replace `.ravel()` with `.reshape(-1,2)`. – Divakar Oct 23 '19 at 10:07
  • doesnt look like it works for me with images. if you tried it with an image you might see my issue but say I wanted the image to be 16000 high and 1000 wide would I have to use it like this? testimage = np.reshape(image,(16000,1000,3),rollwidth).reshape(-1,1000) – Dominic.New.Work Oct 23 '19 at 10:35
  • Why are you skipping `swapaxes`? Think it would be - `a.reshape(a.shape[0],-1,ncols).swapaxes(0,1).reshape(-1,ncols)` with `a` being the input array. Also, isn't your input a 2D array? – Divakar Oct 23 '19 at 10:38
  • because it is an image it has (n,m,3) shape – Dominic.New.Work Oct 23 '19 at 10:43
  • Please add a minimal representative for your 3D array case and expected output. – Divakar Oct 23 '19 at 10:45
  • OK, I am struggling to visualise this as a 3d array but I assumer that the 3 depth layer is the rgb values, I am expecting z for newx, newy to equal the z for originalx,originaly. before moving it. I don't know how I would represent this exactly – Dominic.New.Work Oct 23 '19 at 10:52

1 Answers1

1

Based on this post, we will simply extend it to 3D case keeping in mind that we need to split-up the second axis, while keeping the third axis (color channel one) as it is -

# a is input 3D array
# ncols would be the width of the desired output image
m,n,r = a.shape
b = a.reshape(m,-1,ncols,r).swapaxes(0,1).reshape(-1,ncols,r)

The motivation behind is discussed in detail in this post.

Divakar
  • 218,885
  • 19
  • 262
  • 358