0

I'm trying to save in python a stack of 10 rgb images, but i get the following error:

rgb[:,:,:, i] = img
ValueError: could not broadcast input array from shape (256,340,3) into shape (256,340,30) 

I tried:

img = cv2.imread(img_file, cv2.IMREAD_UNCHANGED)
rgb[:,:,:, i] = img

I also tried:

chunks = 10
step = int(math.floor((duration - chunks + 1)/(num_samples)))
dims = (256, 340, chunks * 3, num_samples)
rgb = np.zeros(shape=dims, dtype=np.float64)
   for i in range(num_samples):
    for j in range(chunks):
         img_file = os.path.join(vid_name, 'image_{0:04d}.jpg'.format(i*step+j+1 + start_frame))
         img = cv2.imread(img_file, cv2.IMREAD_UNCHANGED)
         img = cv2.resize(img, dims[1::-1])
         rgb[:,:,(j+1)*3, i] = img

img_file keeps the path to the image, it gets it correct. I've tested it with

print("%r") % img_file

What I want to achive is 10 stacked rgb images.

Any help is appreciated. Thank you!

AMayer
  • 415
  • 5
  • 19

1 Answers1

1

Approach #1 : To make things simpler, I would suggest initializing a 5D array instead by splitting the second last axis into two axes, keeping chunks and 3 along them, like so -

dims = (256, 340, chunks , 3, num_samples)

To compensate for this edit, we need to make the assigning part of image into the output array inside the nested loops, like so -

rgb[:,:,j, :, i] = img

After performing all of those operations, at the end if needed, just reshape into 4D array -

rgb.shape = (256, 340, chunks* 3, num_samples)

So, in all three edits needed.


Approach #2 : Keeping the loopy code from the question as it is, we could just do -

rgb[:,:,j*3:(j+1)*3, i] = img
Divakar
  • 218,885
  • 19
  • 262
  • 358
  • One more thing. I want to flip the rgb. So in those for loops, instead of: rgb_flip[:,:,(j+1)*3, i] = img[:,::-1] I used as you suggested: rgb_flip[:,:,j, :, i] = img[:,::-1]. And then rgb_flip.shape = (25, 34, chunks* 3, num_samples). Does it has the same effect? – AMayer Dec 07 '16 at 19:30
  • @AMayer Depends. Which dimension of image do you want to flip? The first two dimensions would flip row/col and the last one would flip the color channel. – Divakar Dec 07 '16 at 19:31
  • Well, let's take an example, let's say that instead of 10 stacked rgb images, I have only 1 rgb image. The following code does the right thing: rgb_flip[:,:,:,i] = img[:,::-1,:]. I want to achive the same thing, but in my case I have 10 stacked rgb images.I hope my example is clear enough. Thank you! – AMayer Dec 07 '16 at 19:35
  • @AMayer Have you tried approach #1? With that approach flipping would be as easy as `rgb[:,:,::-1]` after coming out of nested loops. – Divakar Dec 07 '16 at 19:40
  • Yes, I've used it like this: rgb[:,:,j, :, i] = img .And after the 2 loops. rgb.shape = (256, 340, chunks* 3, num_samples) rgb_flip = rgb[:,:,::-1], as you suggested. Is it correct? I'm learning numpy and how python worsk with matrices as I write this questions, this is why I'm not too confident about how I use the code. Thank you! – AMayer Dec 07 '16 at 19:50
  • @AMayer No, the sequence is you use the first two steps from approach #1 , then you come out of nested loops. Then, you flip : `rgb = rgb[:,:,::-1]` and then change shape : `rgb.shape = (256, 340, chunks* 3, num_samples)`. Let me know how it goes. – Divakar Dec 07 '16 at 19:52
  • I've got an error. I've updated the main post with the full code and the error for a better view. The code is at the bottom of the post. Thank you! – AMayer Dec 07 '16 at 19:59
  • @AMayer `rgb_flip = rgb[:,:,::-1]` creates `rgb_flip` as a view of `rgb`. You want a copy, so do : `rgb_flip = rgb[:,:,::-1].copy()` instead. – Divakar Dec 07 '16 at 20:06
  • Oh, I understand now, it worked. I appreciate the support! – AMayer Dec 07 '16 at 20:13
  • @AMayer Feel free to rollback the edits in the question on the error issue with flipping as it will only confuse the future readers :) – Divakar Dec 07 '16 at 20:13