0

I'm calling this function on my laptop with (python version 2.72) and it works well; but when I move it to my PI (python ver 3.2.3) I get:

Traceback (most recent call last):
  File "/usr/src/scripts/areadetect_movie_pi_17.py", line 337, in <module>
    save_frame_deque(reduced, 10)
  File "/usr/src/scripts/areadetect_movie_pi_17.py", line 65, in save_frame_deque
    cv2.imwrite('/home/pi/Desktop/frame_2.jpg', q.popleft())
TypeError: <unknown> is not a numpy array

The code:

max_qlength = 10 
q = deque ([0,max_qlength]) 

    def save_frame_deque(picture, max_qlen):

        max_qlength = max_qlen

        q.append(picture)


        print(len(q))# actual length of que
        print (max_qlength)# max length of que

        if len(q) >  (max_qlength+1): # if actual length of q is bigger than 11

            #cv2.imwrite('/home/pi/Desktop/frame_1.jpg', picture)
            #cv2.imshow("frame", q.popleft())

            cv2.imwrite('/home/pi/Desktop/frame_2.jpg', q.popleft())
            cv2.imwrite('/home/pi/Desktop/frame_3.jpg', q.popleft())

            cv2.imwrite('/home/pi/Desktop/frame_4.jpg', q.popleft())
            cv2.imwrite('/home/pi/Desktop/frame_5.jpg', q.popleft())
            cv2.imwrite('/home/pi/Desktop/frame_6.jpg', q.popleft())
            cv2.imwrite('/home/pi/Desktop/frame_7.jpg', q.popleft())
            cv2.imwrite('/home/pi/Desktop/frame_8.jpg', q.popleft())
            cv2.imwrite('/home/pi/Desktop/frame_9.jpg', q.popleft())
            cv2.imwrite('/home/pi/Desktop/frame_10.jpg', q.popleft())
            cv2.imwrite('/home/pi/Desktop/frame_11.jpg', q.popleft())

when I change the code to:

    max_qlength = 10 
    q = deque ([0,max_qlength]) 

        def save_frame_deque(picture, max_qlen):

            max_qlength = max_qlen

            q.append(picture)


            print(len(q))# actual length of que
            print (max_qlength)# max length of que

            if len(q) >  (max_qlength+1): # if actual length of q is bigger than 11

                cv2.imwrite('/home/pi/Desktop/frame_1.jpg', picture)
                #cv2.imshow("frame", q.popleft())

                '''
                cv2.imwrite('/home/pi/Desktop/frame_2.jpg', q.popleft())
                cv2.imwrite('/home/pi/Desktop/frame_3.jpg', q.popleft())

                cv2.imwrite('/home/pi/Desktop/frame_4.jpg', q.popleft())
                cv2.imwrite('/home/pi/Desktop/frame_5.jpg', q.popleft())
                cv2.imwrite('/home/pi/Desktop/frame_6.jpg', q.popleft())
                cv2.imwrite('/home/pi/Desktop/frame_7.jpg', q.popleft())
                cv2.imwrite('/home/pi/Desktop/frame_8.jpg', q.popleft())
                cv2.imwrite('/home/pi/Desktop/frame_9.jpg', q.popleft())
                cv2.imwrite('/home/pi/Desktop/frame_10.jpg', q.popleft())
                cv2.imwrite('/home/pi/Desktop/frame_11.jpg', q.popleft())
                '''

it works, so this would appear that my pi doesn't like popleft()

1) Is this the case, i'm not sure how to check if popleft is available in Python 3.2.3? 2) How do I fix this? 3) if poleft isn't available in the newer version of python, then is there an equivalent? there an

4
  • 2
    It is morelikely that Python 3 doesn't like it. have you tried running it with Python 2.7x on your Pi? Commented Mar 7, 2015 at 14:52
  • how can i check if popleft() is available in python3?
    – reggie
    Commented Mar 7, 2015 at 14:57
  • 1
    docs.python.org/3.2/library/… Commented Mar 7, 2015 at 15:02
  • Why don't you just try it with 2.7? Most distros install it by default because it is required by other packages.
    – goldilocks
    Commented Mar 7, 2015 at 15:21

2 Answers 2

2

Arr, what a fool I am!

I opened the Python shell on the PI and did this:

Python 3.2.3 (default, Mar  1 2013, 11:53:50) 
[GCC 4.6.3] on linux2
Type "copyright", "credits" or "license()" for more information.
>>> from collections import deque
>>> q = deque ([0,10])
>>> q.append("1a")
>>> q.append("2a")
>>> q.append("3a")
>>> print(q.popleft())
0
>>> print(q.popleft())
10
>>> print(q.popleft())
1a
>>> print(q.popleft())
2a
>>> print(q.popleft())
3a
>>> print(q.popleft())
Traceback (most recent call last):
  File "<pyshell#10>", line 1, in <module>
    print(q.popleft())
IndexError: pop from an empty deque
>>>

Which, to me, suggested that I needed to flush the first two values i'd loaded!

Following this example, I could see that following a popleft I got 0 then 10 then 1a, so it dawned on me that I was preloading the dque with 2 integers not numpy arrays.

so I modified my script to flush out the 2 pre loaded integers and it worked:

max_qlength = 10 
q = deque ([0,max_qlength]) 

    def save_frame_deque(picture, max_qlen):

        max_qlength = max_qlen

        q.append(picture)

        if len(q) >  (max_qlength+1):


            q.popleft()
            q.popleft()

            cv2.imwrite('/home/pi/Desktop/frame_2.jpg', q.popleft())
            cv2.imwrite('/home/pi/Desktop/frame_3.jpg', q.popleft())

            cv2.imwrite('/home/pi/Desktop/frame_4.jpg', q.popleft())
            cv2.imwrite('/home/pi/Desktop/frame_5.jpg', q.popleft())
            cv2.imwrite('/home/pi/Desktop/frame_6.jpg', q.popleft())
            cv2.imwrite('/home/pi/Desktop/frame_7.jpg', q.popleft())
            cv2.imwrite('/home/pi/Desktop/frame_8.jpg', q.popleft())
            cv2.imwrite('/home/pi/Desktop/frame_9.jpg', q.popleft())
            cv2.imwrite('/home/pi/Desktop/frame_10.jpg', q.popleft())
            cv2.imwrite('/home/pi/Desktop/frame_11.jpg', q.popleft())

Or a more elegant solution is not to load the integers in in the first place, define an empty deque, and specify the max_qlen when one calls the function!

q = deque ([])

def save_frame_deque(picture, max_qlen):

    q.append(picture)

    if (len(q)) >  (max_qlen): 

        cv2.imwrite('/home/pi/Desktop/frame_1.jpg', q.popleft())
        cv2.imwrite('/home/pi/Desktop/frame_2.jpg', q.popleft())
        cv2.imwrite('/home/pi/Desktop/frame_3.jpg', q.popleft())

        cv2.imwrite('/home/pi/Desktop/frame_4.jpg', q.popleft())
        cv2.imwrite('/home/pi/Desktop/frame_5.jpg', q.popleft())
        cv2.imwrite('/home/pi/Desktop/frame_6.jpg', q.popleft())
        cv2.imwrite('/home/pi/Desktop/frame_7.jpg', q.popleft())
        cv2.imwrite('/home/pi/Desktop/frame_8.jpg', q.popleft())
        cv2.imwrite('/home/pi/Desktop/frame_9.jpg', q.popleft())
        cv2.imwrite('/home/pi/Desktop/frame_10.jpg', q.popleft())
        cv2.imwrite('/home/pi/Desktop/frame_11.jpg', q.popleft())

when the count (len(q)) > (max_qlen) becomes true (when len(q) == 13) the program running on the laptop empties the deque, saving the first two jpgs with the number ten, hence corrupt jpgs; whereas the PI complains with the already highlighted error.

see the eclipse screensot of when len(q) == 13: eclipse screenshot

and the resultant jpg output of an integer of value 10:

I'm assuming eclipse doesn't complain when you ask it to convert the number 10 to a jpg, but the PI does!

it's a small mark

3
  • but this doesn't explain why it worked on my laptop.
    – reggie
    Commented Mar 7, 2015 at 15:29
  • That was already explained. Python 2 != Python 3. Frankly stuff which works in Python 2.7.3 won't necessarily work in Python 2.7.4 but the change from 2 to 3 was much more significant.
    – joan
    Commented Mar 7, 2015 at 18:41
  • the only way to test this it to see if python version 3.2.3 can create a jpg with an integer, not a numpy array.
    – reggie
    Commented Mar 8, 2015 at 9:30
0

Python 3 is not backward compatible. Code written in one version will have to be ported to the other. You can not expect that code developed in Python 2 to be runnable in Python 3, or the other way around. See to that your development environment and your production environment run the same version on Python, down to the last decimal.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.