2

What is the best way to transform an 1D array that contains rgb data into a 3D RGB array ?

If the array was in this order, it would be easy, (a single reshape)

RGB RGB RGB RGB...

However my array is in the form,

RRRR...GGGG....BBBB

or sometimes even,

GGGG....RRRR....BBBB (result still should be RGB not GRB)

I could of course derive some Python way to achieve this, I even did try a numpy solution, it works but It is obviously a bad solution, I wonder what is the best way, maybe a built-in numpy function ?

My solution:

for i in range(len(video_string) // 921600 - 1):        # Consecutive frames iterated over.
    frame = video_string[921600 * i: 921600 * (i + 1)]  # One frame
    array = numpy.fromstring(frame, dtype=numpy.uint8)  # Numpy array from one frame.
    r = array[:307200].reshape(480, 640)
    g = array[307200:614400].reshape(480, 640)
    b = array[614400:].reshape(480, 640)
    rgb = numpy.dstack((b, r, g))                       # Bring them together as 3rd dimention

Don't let the for loop confuse you, I just have frames concatenated to each other in a string, like a video, which is not a part of the question.

What did not help me: In this question, r, g, b values are already 2d arrays so not helping my situation.

Edit1: Desired array shape is 640 x 480 x 3

2
  • How can we reshape to 3D array without knowing height or width? Commented Nov 6, 2017 at 20:39
  • @Divakar Sorry I forgot to mention, I will edit, however it can be seen that a frame is 921600 bytes, divide that with three, we have 307200, which is the product of 640x480. Commented Nov 6, 2017 at 20:58

1 Answer 1

3

Reshape to 2D, transpose and then reshape back to 3D for RRRR...GGGG....BBBB form -

a1D.reshape(3,-1).T.reshape(height,-1,3) # assuming height is given

Or use reshape with Fortran order and then swap axes -

a1D.reshape(-1,height,3,order='F').swapaxes(0,1)

Sample run -

In [146]: np.random.seed(0)

In [147]: a = np.random.randint(11,99,(4,2,3)) # original rgb image

In [148]: a1D = np.ravel([a[...,0].ravel(), a[...,1].ravel(), a[...,2].ravel()])

In [149]: height = 4

In [150]: np.allclose(a, a1D.reshape(3,-1).T.reshape(height,-1,3))
Out[150]: True

In [151]: np.allclose(a, a1D.reshape(-1,height,3,order='F').swapaxes(0,1))
Out[151]: True

For GGGG....RRRR....BBBB form, simply append : [...,[1,0,2]].

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your answer, my code is performance dependant, so I will test the results and post them in the question, any advices towards performance is also accepted.
@Rockybilly Keep me posted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.