0

I found this very nice example, how to make an array of frames: https://stackoverflow.com/a/17394994/7489698

But I do not know how to use this in PIL correctly. To demonstrate it, I have sketched this commands:

import numpy as np
import cv2
from PIL import Image, ImageTk

nframes = 10
frame = cv2.imread('test.jpg')

(x,y,d)=frame.shape
frames = np.empty((nframes,x, y, d))

for k in range(nframes):
    frames[k,:,:,:] = frame

frame_avg=np.int8(np.mean(frames,0))
frame_avg.shape

cv2.imwrite('test_avg.jpg',frame_avg)

Image.fromarray(frame)
Image.fromarray(frame_avg)

The image test.jpg is read and 10 times stored in the array frames. The average thereof is stored in the file test_avg.jpg where it can be seen that it looks ok.

Converting the orignal frame to a PIL image is working, but the last line throws this error:

---> 20 Image.fromarray(frame_avg)

/usr/local/lib/python3.10/dist-packages/PIL/Image.py in fromarray(obj, mode)
   3313             typekey_shape, typestr = typekey
   3314             msg = f"Cannot handle this data type: {typekey_shape}, {typestr}"
-> 3315             raise TypeError(msg) from e
   3316     else:
   3317         rawmode = mode

TypeError: Cannot handle this data type: (1, 1, 3), |i1

What did I do wrong???

KR, Christof

3
  • if there is an error message, I would generally recommend putting the exception in the title. when there is an error message, that is usually much more relevant than the goal of the project. Commented May 22 at 14:25
  • I have no idea what you are trying to do, but there is no need to store 10 frames in RAM in order to average them - it just creates large demand on memory. Just store the first frame in a large enough type and add subsequent frames as they arrive. Then divide by the number of frames at the end. Same as you don't need to store 10, 11 and 12 to calculate their average, you just need to know the sum is 33. Commented May 22 at 17:02
  • I would like a moving average filter (as in en.wikipedia.org/wiki/Moving_average) that's why I need all of the images Commented May 23 at 10:10

1 Answer 1

4

That's a typo.

You did convert to np.int8 (signed), but you should have converted to np.uint8 (unsigned).

The PIL exception's message does not specifically say this, but that element type is a problem for the library.


NB: The typekey_shape is as it should be. Elsewhere, the typekey is constructed as typekey = (1, 1) + shape[2:], arr["typestr"]

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

3 Comments

Thanks a lot, this fixed my problem. (to be honest this was not a typo, I did not know that PIL expects unsigned integers - RTMF :-) )
just to point out the obvious: the other answer came five hours after my answer and says the same thing (likely based on my answer), and adds at least one utterly irrelevant link (Kotlin...?). I guess you like the other one better.
you are right, I fully appreciate your answer. But the other one is much more informative and that's why I voted for this

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.